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 | 使用 | 教程 | 文本客戶端}}