Marauroa Chat Tutorial/Text Client

来自gamedev
跳转到导航 跳转到搜索


Marauroa Tutorial


编码[编辑]

为了使用Marauroa框架字创建客户端,您应该使用您的逻辑扩展marauroa.client.ClientFramework类。 这是聊天客户端的源代码

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.LinkedList;

import marauroa.client.ClientFramework;
import marauroa.client.net.IPerceptionListener;
import marauroa.client.net.PerceptionHandler;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPObject;
import marauroa.common.net.message.MessageS2CPerception;
import marauroa.common.net.message.TransferContent;

public class Client extends ClientFramework {
  private PerceptionHandler handler;
  private static Client client;
  private Map<RPObject.ID, RPObject> worldObjects;
  private String[] availableCharacters;
  private LinkedList<String> quotes = new LinkedList<String>();
  
  public static Client get() {
    if (client == null) {
      client = new Client();
    }
    return client;
  }

  protected Client() {
    super("log4j.properties");
    worldObjects = new HashMap<RPObject.ID, RPObject>();
    handler = new PerceptionHandler(new PerceptionListener());
  }

  public String[] getAvailableCharacters() {
    return availableCharacters;
  }

  public String popQuote() {
    if (quotes.isEmpty()) {
      return null;
    }
    return quotes.pop();
  }
  
  public void sendMessage(String text) {
    RPAction action;
    action = new RPAction();
    action.put("type", "chat");
    action.put("text", text);
    send(action);
  }
  
  @Override
  protected void onPerception(MessageS2CPerception message) {
    try {
      handler.apply(message, worldObjects);
    } catch (java.lang.Exception e) {
      // Something weird happened while applying perception
    }
  }

  @Override
  protected List<TransferContent> onTransferREQ(List<TransferContent> items) {
    return items;
  }

  @Override
  protected void onTransfer(List<TransferContent> items) {
  }

  @Override
  protected void onAvailableCharacters(String[] characters) {
    availableCharacters = characters;
  }

  @Override
  protected void onServerInfo(String[] info) {
    for (String s : info) {
      quotes.add(s);
    }
  }

  @Override
  protected String getGameName() {
    return "Chat";
  }

  @Override
  protected String getVersionNumber() {
    return "0.5";
  }

  @Override
  protected void onPreviousLogins(List<String> previousLogins) {
  }
  
  class PerceptionListener implements IPerceptionListener {
    @Override
    public boolean onAdded(RPObject object) {
      if (object.has("text")) {
        quotes.add("*" + object.get("from") + "* : " + object.get("text"));
      }
      return false;
    }

    @Override
    public boolean onModifiedAdded(RPObject object, RPObject changes) {
      return false;
    }

    @Override
    public boolean onModifiedDeleted(RPObject object, RPObject changes) {
      return false;
    }

    @Override
    public boolean onDeleted(RPObject object) {
      return false;
    }

    @Override
    public boolean onMyRPObject(RPObject added, RPObject deleted) {
      return false;
    }

    @Override
    public void onSynced() {
    }

    @Override
    public void onUnsynced() {
    }

    @Override
    public void onException(Exception e, MessageS2CPerception perception) {
      e.printStackTrace();
      System.exit(-1);
    }

    @Override
    public boolean onClear() {
      return false;
    }

    @Override
    public void onPerceptionBegin(byte type, int timestamp) {
    }

    @Override
    public void onPerceptionEnd(byte type, int timestamp) {
    }
  }
}

这主要是样板代码。 我们声称我们是“聊天”客户端,版本为“ 0.5”。您还记得,我们的服务器将接受任何“聊天”客户端,而没有版本限制。

您应该注意的是,我们使用了Marauroa提供的感知处理程序,请参见onPerception。 我们仍然引入了自己的感知侦听器,以便在添加,修改或删除对象时能够采取措施。

PerceptionListener是我们的实现。 我们仅使用onAdded处理程序,该处理程序允许我们在出现新对象时做出反应,即将新的聊天消息添加到消息列表中。 在其他处理程序中返回的假值非常重要,因为它们向Marauroa表示您要继续当前操作(例如添加对象)。

收到的所有消息都存储在消息列表中。 一个人可以使用popQuote()方法一一访问存储的消息.

最后,您可以使用SendMessage方法发送消息。 它构造服务器可理解的RPAction并将其发送。

Marauroa框架为服务器提供了主要方法,因此您无需关心执行循环。 对于客户端而言并非如此,因此我们还需要实现客户端的主要模块。 这是一个非常简单的解决方案

import marauroa.common.game.RPObject;

public class Test {
  public static void main(String[] args) {
    boolean runClient = true;
    Client client = Client.get();
    try {
      client.connect("localhost", 5555);
      if (args.length == 3) {
        client.createAccount(args[0], args[1], args[2]);
      }
      client.login(args[0], args[1]);
      if (client.getAvailableCharacters().length == 0) {
        RPObject character = new RPObject();
        client.createCharacter(args[0], character);
      }
      client.chooseCharacter(args[0]);
    } catch (Exception e) {
      runClient = false;
    }
    int i = 0;
    while (runClient) {
      i++;
      client.loop(0);
      if (i % 100 == 50) {
        client.sendMessage("test" + i);
      }
      String s = client.popQuote();
      while (s != null) {
        System.out.println(s);
        s = client.popQuote();
      }
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        runClient = false;
      }
    }
  }
}

我们的main方法做两件事。 首先,如果提供了三个命令行参数(登录,密码,电子邮件),我们将创建一个新帐户。 否则,我们仅使用指定的登录名和密码登录。

然后是时候选择一个角色了。 如果服务器报告该帐户没有可用的角色,那么我们将创建一个新名称,该名称与帐户名称相同。 请注意,不可能直接在Client类的onAvailableCharacters处理程序中选择角色。

随后开始心跳循环。 在每一步中,我们都调用loop(0),其中浮点参数在这一点上没有任何意义。 每100步,我们就会向服务器发送一条消息。 没有互动的方式来控制消息,但是看到您自己的客户端创建的聊天仍然令人赞叹。

部署[编辑]

运行客户端非常简单,您只需要一堆jar(客户端不需要数据库)和已编译的客户端代码。 我使用以下行进行编译

javac -cp marauroa.jar;log4j.jar;. *.java

确保所需的jar位于当前目录中。 运行使用

java -cp marauroa.jar;log4j.jar;h2.jar;. Test login password

同样,在Linux和MacOSX上,所有“;” 必须替换为“:”。

不要忘记用实际的登录名和密码替换。 要创建一个新帐户,只需添加第三个命令行参数(应该是电子邮件,但目前尚无验证)。.

输出[编辑]

理想情况下,您应该会看到类似

>java -cp marauroa.jar;log4j.jar;h2.jar;. Test test1 test1
Cannot find log4j.properties in classpath. Using default properties.
*test1* : test50
*test1* : test150
*test1* : test250
...

请注意有关log4j.properties的消息:您可以创建该文件以便在Marauroa框架内配置Log4J用法.

下一步[编辑]

在本教程的下一部分中,我们将编写一个 Swing 客户端 它带有图形用户接口. {{#breadcrumbs: Marauroa | 使用 | 教程 | 文本客户端}}