Marauroa Chat Tutorial/Text Client: Difference between revisions

Jump to navigation Jump to search
Content deleted Content added
imported>Hendrik Brummermann
imported>Fjacob
Cleaned up java code to adhere to the java coding conventions, changed some variable names to be more explicit.
 
(27 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Navigation for Marauroa Top|Using}}
{{Navigation for Marauroa Users}}
{{Marauroa Chat Tutorial}}



== Text client ==

=== Code ===
== Code ==
In order to create a client using Marauroa frameword you should extend the marauroa.client.ClientFramework class with your logic. Here is the source code for the chat client
In order to create a client using Marauroa frameword you should extend the marauroa.client.ClientFramework class with your logic. Here is the source code for the chat client
<source lang="java">
<source lang="java">
import java.util.Map;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.net.SocketException;
import java.util.LinkedList;


import marauroa.client.ClientFramework;
import marauroa.client.ClientFramework;
import marauroa.client.net.IPerceptionListener;
import marauroa.client.net.IPerceptionListener;
import marauroa.client.net.PerceptionHandler;
import marauroa.client.net.PerceptionHandler;
import marauroa.common.game.Perception;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPEvent;
import marauroa.common.net.message.MessageS2CPerception;
import marauroa.common.net.message.MessageS2CPerception;
import marauroa.common.net.message.TransferContent;
import marauroa.common.net.message.TransferContent;
Line 22: Line 23:
public class Client extends ClientFramework {
public class Client extends ClientFramework {
private PerceptionHandler handler;
private PerceptionHandler handler;
protected static Client client;
private static Client client;
private Map<RPObject.ID, RPObject> world_objects;
private Map<RPObject.ID, RPObject> worldObjects;
private String[] available_characters;
private String[] availableCharacters;
private List<String> quotes = new ArrayList<String>();
private LinkedList<String> quotes = new LinkedList<String>();
public static Client get() {
public static Client get() {
Line 36: Line 37:
protected Client() {
protected Client() {
super("log4j.properties");
super("log4j.properties");
world_objects = new HashMap<RPObject.ID, RPObject>();
worldObjects = new HashMap<RPObject.ID, RPObject>();
handler = new PerceptionHandler(new PerceptionListener());
handler = new PerceptionHandler(new PerceptionListener());
}
}


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


String popQuote() {
public String popQuote() {
if (quotes.isEmpty()) {
if (quotes.isEmpty()) {
return null;
return null;
}
}
String result = quotes.get(0);
return quotes.pop();
quotes.remove(0);
return result;
}
}
public void SendMessage(String text) {
public void sendMessage(String text) {
RPAction action;
RPAction action;
action = new RPAction();
action = new RPAction();
Line 61: Line 60:
}
}
@Override
protected void onPerception(MessageS2CPerception message) {
protected void onPerception(MessageS2CPerception message) {
try {
try {
handler.apply(message, world_objects);
handler.apply(message, worldObjects);
} catch (java.lang.Exception e) {
} catch (java.lang.Exception e) {
// Something weird happened while applying perception
// Something weird happened while applying perception
Line 69: Line 69:
}
}


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


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


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


@Override
protected void onServerInfo(String[] info) {
protected void onServerInfo(String[] info) {
for (String s : info) {
for (String s : info) {
Line 86: Line 90:
}
}


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


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


@Override
protected void onPreviousLogins(List<String> previousLogins) {
protected void onPreviousLogins(List<String> previousLogins) {
}
}
class PerceptionListener implements IPerceptionListener {
class PerceptionListener implements IPerceptionListener {
@Override
public boolean onAdded(RPObject object) {
public boolean onAdded(RPObject object) {
if (object.has("text")) {
if (object.has("text")) {
Line 105: Line 113:
}
}


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


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


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


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


@Override
public void onSynced() {
public void onSynced() {
}
}


@Override
public void onUnsynced() {
public void onUnsynced() {
}
}


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


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


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


@Override
public void onPerceptionEnd(byte type, int timestamp) {
public void onPerceptionEnd(byte type, int timestamp) {
}
}
Line 157: Line 175:
Marauroa frameword provides the main method for server, so that you don't need to care about execution loop. It is not true for server, so we will also need to implement the main module of our client. Here is a very easy solution
Marauroa frameword provides the main method for server, so that you don't need to care about execution loop. It is not true for server, so we will also need to implement the main module of our client. Here is a very easy solution
<source lang="java">
<source lang="java">
import java.io.IOException;
import java.lang.Thread;

import marauroa.common.Log4J;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPObject;


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


A heart-beat loop is started afterwards. At each step we invoke loop(0), where floating point parameter means nothing at this point. Once in 100 steps we send a message to server. There is no interactive way to control messages, still it is amazing to see chat created by your own client.
A heart-beat loop is started afterwards. At each step we invoke loop(0), where floating point parameter means nothing at this point. Once in 100 steps we send a message to server. There is no interactive way to control messages, still it is amazing to see chat created by your own client.

=== Deployment ===
== Deployment ==
Running a client is very simple, all you need is a bunch of jars (database is not required on the client side) and compiled client code. I use following line for compilation
Running a client is very simple, all you need is a bunch of jars (database is not required on the client side) and compiled client code. I use following line for compilation
<pre>
<pre>
Line 219: Line 233:
java -cp marauroa.jar;log4j.jar;. Test login password
java -cp marauroa.jar;log4j.jar;. Test login password
</pre>
</pre>
Again, on Linux & MacOSX, all ";" have to be replaced with ":".


Don't forget to replace login and password with the actual ones. To create a new account just add a third command-line parameter (that should be an email, but no validation at the moment).
Don't forget to replace login and password with the actual ones. To create a new account just add a third command-line parameter (that should be an email, but no validation at the moment).

=== Output ===
== Output ==
Ideally you should see something like
Ideally you should see something like
<pre>
<pre>
>java -cp marauroa.jar;log4j.jar;. Test test1 test1
>java -cp marauroa.jar;log4j.jar;. Test test1 test1
Cannot find log4j.properties in classpath. Using default properties.
Cannot find log4j.properties in classpath. Using default properties.
0.5
Do not contact us!
Marauroa server
Chat
*test1* : test50
*test1* : test50
*test1* : test150
*test1* : test150
*test1* : test250
...
</pre>
</pre>


Note the message about log4j.properties: you can create that file in order to configure the Log4J usage inside Marauroa framework.
Note the message about log4j.properties: you can create that file in order to configure the Log4J usage inside the Marauroa framework.

== Next Steps ==

In the next section of this tutorial, we will write a '''[[Marauroa Chat Tutorial/Swing Client|Swing client]]''' with a graphical user interface.


[[Category:Marauroa]]
{{#breadcrumbs: [[Marauroa]] | [[Navigation for Marauroa Users|Using]] | [[Marauroa Chat Tutorial|Tutorial]] | [[Marauroa Chat Tutorial/Text Client|Text Client]]}}