mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-07-08 23:07:46 +07:00
Added basic server event objects
Added very simple rendering of character "Tirant" position in another client
This commit is contained in:
@ -318,6 +318,11 @@ public class Entity {
|
||||
return origin;
|
||||
}
|
||||
|
||||
// TODO: Delete
|
||||
public void setOrigin(GridPoint2 origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
public void move() {
|
||||
if (!mode.equalsIgnoreCase("WL")
|
||||
&& !mode.equalsIgnoreCase("RN")
|
||||
|
@ -22,7 +22,16 @@ import gdx.diablo.codec.excel.Weapons;
|
||||
import gdx.diablo.item.BodyLoc;
|
||||
import gdx.diablo.item.Item;
|
||||
|
||||
public class Player extends Entity {
|
||||
public class Player extends Entity implements Cloneable {
|
||||
@Override
|
||||
public Player clone() {
|
||||
try {
|
||||
return (Player) super.clone();
|
||||
} catch (CloneNotSupportedException t) {
|
||||
throw new GdxRuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TAG = "Player";
|
||||
private static final boolean DEBUG = true;
|
||||
private static final boolean DEBUG_WCLASS = DEBUG && !true;
|
||||
@ -61,7 +70,7 @@ public class Player extends Entity {
|
||||
|
||||
|
||||
public Player(String name, CharClass clazz) {
|
||||
super(null);
|
||||
super(Diablo.files.PlrType.get(clazz.id).Token, EntType.CHARS);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.UIUtils;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.Timer;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@ -47,6 +48,12 @@ import gdx.diablo.panel.EscapePanel;
|
||||
import gdx.diablo.panel.InventoryPanel;
|
||||
import gdx.diablo.panel.MobilePanel;
|
||||
import gdx.diablo.panel.StashPanel;
|
||||
import gdx.diablo.server.Connect;
|
||||
import gdx.diablo.server.Disconnect;
|
||||
import gdx.diablo.server.Message;
|
||||
import gdx.diablo.server.MoveTo;
|
||||
import gdx.diablo.server.Packet;
|
||||
import gdx.diablo.server.Packets;
|
||||
import gdx.diablo.server.PipedSocket;
|
||||
import gdx.diablo.widget.TextArea;
|
||||
|
||||
@ -85,6 +92,7 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
||||
|
||||
//Char character;
|
||||
public Player player;
|
||||
ObjectMap<String, Player> otherPlayers = new ObjectMap<>();
|
||||
Timer.Task updateTask;
|
||||
|
||||
Socket socket;
|
||||
@ -228,7 +236,8 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
||||
String text = input.getText();
|
||||
if (!text.isEmpty()) {
|
||||
Gdx.app.debug(TAG, text);
|
||||
out.println(text);
|
||||
Message message = new Message(player.stats.getName(), text);
|
||||
out.println(Packets.build(message));
|
||||
input.setText("");
|
||||
}
|
||||
}
|
||||
@ -301,8 +310,33 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
||||
public void render(float delta) {
|
||||
try {
|
||||
for (String str; in.ready() && (str = in.readLine()) != null;) {
|
||||
output.appendText(str);
|
||||
output.appendText("\n");
|
||||
Packet packet = Packets.parse(str);
|
||||
switch (packet.type) {
|
||||
case Packets.MESSAGE:
|
||||
Message message = packet.readValue(Message.class);
|
||||
output.appendText(message.toString());
|
||||
output.appendText("\n");
|
||||
break;
|
||||
case Packets.CONNECT:
|
||||
Connect connect = packet.readValue(Connect.class);
|
||||
output.appendText(Diablo.string.format(3641, connect.name));
|
||||
output.appendText("\n");
|
||||
Player q = player.clone();
|
||||
q.setOrigin(player.origin().cpy());
|
||||
otherPlayers.put(connect.name, q);
|
||||
break;
|
||||
case Packets.DISCONNECT:
|
||||
Disconnect disconnect = packet.readValue(Disconnect.class);
|
||||
output.appendText(Diablo.string.format(3642, disconnect.name));
|
||||
output.appendText("\n");
|
||||
otherPlayers.remove(disconnect.name);
|
||||
break;
|
||||
case Packets.MOVETO:
|
||||
MoveTo moveTo = packet.readValue(MoveTo.class);
|
||||
Player p = otherPlayers.get(moveTo.name);
|
||||
if (p != null) p.origin().set(moveTo.x, moveTo.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Gdx.app.error(TAG, e.getMessage());
|
||||
@ -324,6 +358,11 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
||||
//int spy = - (player.getOrigin().x * Tile.SUBTILE_HEIGHT50) - (player.getOrigin().y * Tile.SUBTILE_HEIGHT50);
|
||||
//player.draw(b, spx, spy);
|
||||
player.draw(b);
|
||||
|
||||
for (Player p : otherPlayers.values()) {
|
||||
p.draw(b);
|
||||
}
|
||||
|
||||
b.end();
|
||||
b.setProjectionMatrix(Diablo.viewport.getCamera().combined);
|
||||
|
||||
@ -371,20 +410,22 @@ public class GameScreen extends ScreenAdapter implements LoadingScreen.Loadable
|
||||
Diablo.input.addProcessor(stage);
|
||||
Diablo.input.addProcessor(inputProcessorTest);
|
||||
|
||||
if (socket != null && socket.isConnected()) {
|
||||
Gdx.app.log(TAG, "connecting to " + socket.getRemoteAddress() + "...");
|
||||
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
}
|
||||
|
||||
updateTask = Timer.schedule(new Timer.Task() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (UIUtils.shift()) return;
|
||||
player.move();
|
||||
mapRenderer.setPosition(player.origin());
|
||||
String moveTo = Packets.build(new MoveTo(player.stats.getName(), player.origin()));
|
||||
out.println(moveTo);
|
||||
}
|
||||
}, 0, 1 / 25f);
|
||||
|
||||
if (socket != null && socket.isConnected()) {
|
||||
Gdx.app.log(TAG, "connecting to " + socket.getRemoteAddress() + "...");
|
||||
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
13
core/src/gdx/diablo/server/Connect.java
Normal file
13
core/src/gdx/diablo/server/Connect.java
Normal file
@ -0,0 +1,13 @@
|
||||
package gdx.diablo.server;
|
||||
|
||||
public class Connect {
|
||||
|
||||
public String name;
|
||||
|
||||
private Connect() {}
|
||||
|
||||
public Connect(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
13
core/src/gdx/diablo/server/Disconnect.java
Normal file
13
core/src/gdx/diablo/server/Disconnect.java
Normal file
@ -0,0 +1,13 @@
|
||||
package gdx.diablo.server;
|
||||
|
||||
public class Disconnect {
|
||||
|
||||
public String name;
|
||||
|
||||
private Disconnect() {}
|
||||
|
||||
public Disconnect(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
@ -2,9 +2,18 @@ package gdx.diablo.server;
|
||||
|
||||
public class Message {
|
||||
|
||||
public String from;
|
||||
public String name;
|
||||
public String text;
|
||||
|
||||
private Message() {}
|
||||
|
||||
public Message(String name, String text) {
|
||||
this.name = name;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ": " + text;
|
||||
}
|
||||
}
|
||||
|
19
core/src/gdx/diablo/server/MoveTo.java
Normal file
19
core/src/gdx/diablo/server/MoveTo.java
Normal file
@ -0,0 +1,19 @@
|
||||
package gdx.diablo.server;
|
||||
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
|
||||
public class MoveTo {
|
||||
|
||||
public String name;
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
private MoveTo() {}
|
||||
|
||||
public MoveTo(String name, GridPoint2 origin) {
|
||||
this.name = name;
|
||||
x = origin.x;
|
||||
y = origin.y;
|
||||
}
|
||||
|
||||
}
|
28
core/src/gdx/diablo/server/Packet.java
Normal file
28
core/src/gdx/diablo/server/Packet.java
Normal file
@ -0,0 +1,28 @@
|
||||
package gdx.diablo.server;
|
||||
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.JsonValue;
|
||||
|
||||
public class Packet {
|
||||
|
||||
private static final Json JSON = new Json();
|
||||
|
||||
public int type;
|
||||
public int version;
|
||||
public JsonValue data;
|
||||
|
||||
Packet(int type, int version, JsonValue data) {
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public <T> T readValue(Class<T> type) {
|
||||
return JSON.readValue(type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return JSON.toJson(this);
|
||||
}
|
||||
}
|
65
core/src/gdx/diablo/server/Packets.java
Normal file
65
core/src/gdx/diablo/server/Packets.java
Normal file
@ -0,0 +1,65 @@
|
||||
package gdx.diablo.server;
|
||||
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.JsonReader;
|
||||
import com.badlogic.gdx.utils.JsonValue;
|
||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||
|
||||
public class Packets {
|
||||
|
||||
private static final Json JSON = new Json();
|
||||
|
||||
private Packets() {}
|
||||
|
||||
public static final int MESSAGE = 1;
|
||||
public static final int CONNECT = 2;
|
||||
public static final int DISCONNECT = 3;
|
||||
public static final int MOVETO = 4;
|
||||
|
||||
private static final ObjectIntMap<Class> MAP;
|
||||
static {
|
||||
MAP = new ObjectIntMap<>();
|
||||
MAP.put(Message.class, 1);
|
||||
MAP.put(Connect.class, 2);
|
||||
MAP.put(Disconnect.class, 3);
|
||||
MAP.put(MoveTo.class, 4);
|
||||
}
|
||||
|
||||
public static <T> T parse(Class<T> type, String json) {
|
||||
return parse(json).readValue(type);
|
||||
}
|
||||
|
||||
public static Packet parse(String json) {
|
||||
// TODO: Replace with indexes when well-formed later on
|
||||
JsonValue value = new JsonReader().parse(json);
|
||||
int type = value.getInt("type", 0);
|
||||
int version = value.getInt("version", 0);
|
||||
JsonValue data = value.get("data");
|
||||
return new Packet(type, version, data);
|
||||
}
|
||||
|
||||
public static int getType(String json) {
|
||||
return new JsonReader().parse(json).getInt("type", 0);
|
||||
}
|
||||
|
||||
public static String build(Object instance) {
|
||||
int type = MAP.get(instance.getClass(), 0);
|
||||
if (type == 0) return null;
|
||||
//JsonValue data = new JsonReader().parse(JSON.toJson(instance));
|
||||
EncodedJsonPacket obj = new EncodedJsonPacket(type, 0, instance);
|
||||
return JSON.toJson(obj);
|
||||
}
|
||||
|
||||
private static class EncodedJsonPacket {
|
||||
int type;
|
||||
int version;
|
||||
Object data;
|
||||
|
||||
EncodedJsonPacket() {}
|
||||
EncodedJsonPacket(int type, int version, Object data) {
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import com.badlogic.gdx.net.ServerSocket;
|
||||
import com.badlogic.gdx.net.Socket;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
import com.badlogic.gdx.utils.JsonReader;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@ -51,7 +52,7 @@ public class Server implements Disposable, Runnable {
|
||||
while (!kill.get()) {
|
||||
try {
|
||||
Socket socket = server.accept(null);
|
||||
new Client(socket).start();
|
||||
new Client(socket, "Tirant").start();
|
||||
Gdx.app.log(name, "connection from " + socket.getRemoteAddress());
|
||||
} catch (Throwable t) {
|
||||
Gdx.app.log(name, t.getMessage(), t);
|
||||
@ -122,10 +123,12 @@ public class Server implements Disposable, Runnable {
|
||||
Socket socket;
|
||||
BufferedReader in;
|
||||
PrintWriter out;
|
||||
String name;
|
||||
|
||||
public Client(Socket socket) {
|
||||
public Client(Socket socket, String name) {
|
||||
super(clientThreads, "Client-" + String.format("%08X", MathUtils.random(1, Integer.MAX_VALUE - 1)));
|
||||
this.socket = socket;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -134,33 +137,55 @@ public class Server implements Disposable, Runnable {
|
||||
in = IOUtils.buffer(new InputStreamReader(socket.getInputStream()));
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
|
||||
String connect = Packets.build(new Connect(name));
|
||||
for (Client client : clients) {
|
||||
client.out.println("CONNECT " + socket.getRemoteAddress());
|
||||
client.out.println(connect);
|
||||
//client.out.println("CONNECT " + socket.getRemoteAddress());
|
||||
}
|
||||
|
||||
clients.add(this);
|
||||
|
||||
for (String input; (input = in.readLine()) != null; ) {
|
||||
for (String input; (input = in.readLine()) != null;) {
|
||||
//Message message = Packets.parse(Message.class, input);
|
||||
|
||||
String message = "MESSAGE " + socket.getRemoteAddress() + ": " + input;
|
||||
Gdx.app.log(getName(), message);
|
||||
for (Client client : clients) {
|
||||
client.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
Packet packet = Packets.parse(input);
|
||||
switch (packet.type) {
|
||||
case Packets.MESSAGE:
|
||||
for (Client client : clients) {
|
||||
//client.out.println(message);
|
||||
client.out.println(input);
|
||||
}
|
||||
break;
|
||||
case Packets.MOVETO:
|
||||
for (Client client : clients) {
|
||||
if (client == this) continue;
|
||||
client.out.println(input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Gdx.app.log(getName(), "ERROR " + socket.getRemoteAddress() + ": " + t.getMessage());
|
||||
} finally {
|
||||
clients.remove(this);
|
||||
String message = "DISCONNECT " + socket.getRemoteAddress();
|
||||
Gdx.app.log(getName(), message);
|
||||
String disconnect = Packets.build(new Disconnect(name));
|
||||
for (Client client : clients) {
|
||||
client.out.println(message);
|
||||
client.out.println(disconnect);
|
||||
}
|
||||
//IOUtils.closeQuietly(in);
|
||||
IOUtils.closeQuietly(out);
|
||||
if (socket != null) socket.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void tmp() {
|
||||
JsonReader reader = new JsonReader();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
core/test/gdx/diablo/server/PacketsTest.java
Normal file
61
core/test/gdx/diablo/server/PacketsTest.java
Normal file
@ -0,0 +1,61 @@
|
||||
package gdx.diablo.server;
|
||||
|
||||
import com.badlogic.gdx.ApplicationAdapter;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.backends.headless.HeadlessApplication;
|
||||
import com.badlogic.gdx.utils.Json;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import gdx.diablo.Diablo;
|
||||
import gdx.diablo.codec.StringTBLs;
|
||||
import gdx.diablo.mpq.MPQFileHandleResolver;
|
||||
|
||||
public class PacketsTest {
|
||||
|
||||
@Test
|
||||
public void getType() {
|
||||
int type = Packets.getType("{ \"type\": 1, \"version\": 1, \"data\": { \"name\": \"Tirant\", \"text\": \"Hello World!\" } }");
|
||||
Assert.assertEquals(Packets.MESSAGE, type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsePacketType() {
|
||||
Packet packet = Packets.parse("{ \"type\": 1, \"version\": 1, \"data\": { \"name\": \"Tirant\", \"text\": \"Hello World!\" } }");
|
||||
Assert.assertEquals(Packets.MESSAGE, packet.type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsePacketVersion() {
|
||||
Packet packet = Packets.parse("{ \"type\": 1, \"version\": 1, \"data\": { \"name\": \"Tirant\", \"text\": \"Hello World!\" } }");
|
||||
Assert.assertEquals(1, packet.version);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsePacketData() {
|
||||
Packet packet = Packets.parse("{ \"type\": 1, \"version\": 1, \"data\": { \"name\": \"Tirant\", \"text\": \"Hello World!\" } }");
|
||||
Message message = new Json().readValue(Message.class, packet.data);
|
||||
System.out.println("message " + message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parsePacketData_Event() {
|
||||
new HeadlessApplication(new ApplicationAdapter() {}, null);
|
||||
MPQFileHandleResolver resolver = new MPQFileHandleResolver();
|
||||
resolver.add(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\patch_d2.mpq"));
|
||||
resolver.add(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2exp.mpq"));
|
||||
resolver.add(Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II\\d2data.mpq"));
|
||||
Diablo.string = new StringTBLs(resolver);
|
||||
Packet packet = Packets.parse("{ \"type\": 2, \"version\": 1, \"data\": { \"id\": 3643, \"args\": [ \"Tirant\", \"email\" ] } }");
|
||||
Event event = packet.readValue(Event.class);
|
||||
System.out.println("event " + event);
|
||||
Gdx.app.exit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildPacket() {
|
||||
Message message = new Message("Tirant", "Hello World!");
|
||||
System.out.println("msg:" + Packets.build(message));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user