编辑“︁
Marauroa Chat Tutorial/Server
”︁(章节)
跳转到导航
跳转到搜索
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
== 编码 == 为了创建基于Marauroa的游戏服务器,您必须至少提供marauroa.server.game.rp.IRPRuleProcessor接口的实现以及用于区域管理的类,即marauroa.server.game.rp.RPWorld的子类。 您可以使用marauroa.server.game.rp.RPWorld本身,但它不会为您提供任何RPZone,您几乎肯定需要至少一个RPZone。 我们从RPWorld的以下实现开始 <pre> import marauroa.server.game.rp.RPWorld; import marauroa.server.game.rp.MarauroaRPZone; public class World extends RPWorld { private static World instance; public static World get() { if (instance == null) { instance = new World(); } return instance; } @Override public void onInit() { super.onInit(); MarauroaRPZone zone = new MarauroaRPZone("lobby"); addRPZone(zone); } } </pre> 不要忘记实现静态的get方法,该方法由Marauroa框架用来检索您的类的实例。 创建世界时将调用onInit方法。 我们唯一要做的就是创建区域(因为我们有一个聊天应用程序,我们称之为“大厅”)。 区域是Marauroa的一般概念。 它代表一个游戏区。 停留在特定区域中的所有客户端仅会收到有关该区域中数据更改的通知。 聊天室就是一个很好的例子,就像您在聊天室中一样,您看不到其他聊天室中的对话,即您仅在当前房间中收到有关新事物的通知。 实现IRPRuleProcessor将需要更多代码,因为我们必须实现接口的所有方法。 我们将从以下存根开始 <!-- Updated due to refactoring database access in Marauroa. --> <!-- Please, see details here http://stendhal.game-host.org/wiki/index.php/Refactoring_Database_Access_in_Marauroa. --> <pre> import java.sql.SQLException; import marauroa.common.crypto.Hash; import marauroa.common.game.AccountResult; import marauroa.common.game.CharacterResult; import marauroa.common.game.IRPZone; import marauroa.common.game.RPAction; import marauroa.common.game.RPObject; import marauroa.common.game.Result; import marauroa.server.game.db.DAORegister; import marauroa.server.game.db.AccountDAO; import marauroa.server.game.db.CharacterDAO; import marauroa.server.db.TransactionPool; import marauroa.server.db.DBTransaction; import marauroa.server.game.rp.IRPRuleProcessor; import marauroa.server.game.rp.RPServerManager; public class Rule implements IRPRuleProcessor { private static Rule instance; private World world = World.get(); private RPServerManager manager; public static IRPRuleProcessor get() { if (instance == null) { instance = new Rule(); } return instance; } @Override public void setContext(RPServerManager rpman) { manager = rpman; } @Override public boolean checkGameVersion(String game, String version) { return game.equals("Chat"); } @Override public synchronized void onTimeout(RPObject character) { onExit(character); } @Override public synchronized boolean onExit(RPObject character) { world.remove(character.getID()); return true; } @Override public synchronized boolean onInit(RPObject character) { IRPZone zone = world.getRPZone(new IRPZone.ID("lobby")); zone.add(character); return true; } @Override public synchronized void beginTurn() { } @Override public boolean onActionAdd(RPObject caster, RPAction action, List<RPAction> actionList) { return true; } @Override public synchronized void endTurn() { } @Override public void execute(RPObject caster, RPAction action) { if (action.get("type").equals("chat")) { RPObject chatEntry = new RPObject(); chatEntry.put("text", action.get("text")); chatEntry.put("from", caster.get("nick")); chatEntry.put("turn", manager.getTurn()); IRPZone zone = world.getRPZone(new IRPZone.ID(caster.getID().getZoneID())); zone.assignRPObjectID(chatEntry); zone.add(chatEntry); } } @Override public AccountResult createAccount(String username, String password, String email) { TransactionPool transactionPool = TransactionPool.get(); DBTransaction trans = transactionPool.beginWork(); AccountDAO accountDAO = DAORegister.get().get(AccountDAO.class); try { if (accountDAO.hasPlayer(trans, username)) { return new AccountResult(Result.FAILED_PLAYER_EXISTS, username); } accountDAO.addPlayer(trans, username, Hash.hash(password), email); transactionPool.commit(trans); return new AccountResult(Result.OK_CREATED, username); } catch (SQLException e1) { transactionPool.rollback(trans); return new AccountResult(Result.FAILED_EXCEPTION, username); } } @Override public CharacterResult createCharacter(String username, String characterName, RPObject template) { TransactionPool transactionPool = TransactionPool.get(); DBTransaction trans = transactionPool.beginWork(); CharacterDAO characterDAO = DAORegister.get().get(CharacterDAO.class); try { if (characterDAO.hasCharacter(trans, username, characterName)) { return new CharacterResult(Result.FAILED_CHARACTER_EXISTS, characterName, template); } IRPZone zone = world.getRPZone(new IRPZone.ID("lobby")); RPObject character = new RPObject(template); character.put("nick", characterName); zone.assignRPObjectID(character); characterDAO.addCharacter(trans, username, characterName, character); transactionPool.commit(trans); return new CharacterResult(Result.OK_CREATED, characterName, character); } catch (Exception e1) { transactionPool.rollback(trans); return new CharacterResult(Result.FAILED_EXCEPTION, characterName, template); } } } </pre> 我们再次实现静态的get()方法,该方法由Marauroa用于检索RuleProcessor实例。 大多数功能都是简单的存根,可以将其替换为实际起作用的代码。 您可以使用checkGameVersion()拒绝版本过旧的客户端。 在我们的情况下,我们只要求游戏名称为“聊天”即可。 每当玩家成功登录游戏时,就会调用onInit()函数。 他的角色是从数据库中加载的。 我们会立即将玩家添加到大厅区域,因为连接到聊天室的每个人都首先进入大厅。 最重要的函数是execute(),每次服务器从一个客户端接收到操作时都会调用该函数。 在这种情况下,我们正在等待“聊天”动作。 一旦我们收到一个消息,就会创建一个代表一个聊天消息的新对象。 我们还设置了消息的其他一些属性:发送此消息的人的昵称,发送消息时的回合码(turn code)。 创建帐户和角色的功能应确定是否创建一个新帐户/角色。 在我们的例子中,我们总是这样做(当然不能重复)。 此操作的结果将立即写入数据库。 请注意,客户端可以为头像对象(与角色关联的RPObject)提供模板。 由您决定如何在构建实际的头像对象时使用它。 我们采用客户端提供的内容,添加一个“ nick”属性(与角色名称相同),并将得到的属性用作化身对象。
摘要:
请注意,所有对gamedev的贡献均可能会被其他贡献者编辑、修改或删除。如果您不希望您的文字作品被随意编辑,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源(详情请见
Gamedev:著作权
)。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
导航菜单
个人工具
未登录
讨论
贡献
创建账号
登录
命名空间
页面
讨论
不转换
不转换
简体
繁體
大陆简体
香港繁體
澳門繁體
大马简体
新加坡简体
臺灣正體
查看
阅读
编辑
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息