Marauroa Chat Tutorial/Text Client
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 | 使用 | 教程 | 文本客户端}}