Implemented new custom serialization

This commit is contained in:
Anuken
2018-01-16 23:30:24 -05:00
parent f6a465d917
commit b266516fad
16 changed files with 638 additions and 105 deletions

View File

@@ -16,6 +16,7 @@ text.about.button=About
text.name=Name: text.name=Name:
text.public=Public text.public=Public
text.players={0} players online text.players={0} players online
text.server.player.host={0} (host)
text.players.single={0} player online text.players.single={0} player online
text.server.mismatch=Packet error: possible client/server version mismatch.\nMake sure you and the host have the\nlatest version of Mindustry! text.server.mismatch=Packet error: possible client/server version mismatch.\nMake sure you and the host have the\nlatest version of Mindustry!
text.server.closing=[accent]Closing server... text.server.closing=[accent]Closing server...

View File

@@ -272,12 +272,21 @@ public class NetClient extends Module {
} }
}); });
Net.handle(Player.class, player -> { Net.handle(PlayerSpawnPacket.class, packet -> {
Gdx.app.postRunnable(() -> { Gdx.app.postRunnable(() -> {
//duplicates. //duplicates.
if(Vars.control.enemyGroup.getByID(player.id) != null || if(Vars.control.enemyGroup.getByID(packet.id) != null ||
recieved.contains(player.id)) return; recieved.contains(packet.id)) return;
recieved.add(player.id); recieved.add(packet.id);
Player player = new Player();
player.x = packet.x;
player.y = packet.y;
player.isAndroid = packet.android;
player.name = packet.name;
player.id = packet.id;
player.weaponLeft = (Weapon) Upgrade.getByID(packet.weaponleft);
player.weaponRight = (Weapon) Upgrade.getByID(packet.weaponright);
player.interpolator.last.set(player.x, player.y); player.interpolator.last.set(player.x, player.y);
player.interpolator.target.set(player.x, player.y); player.interpolator.target.set(player.x, player.y);
@@ -291,7 +300,7 @@ public class NetClient extends Module {
kicked = true; kicked = true;
Net.disconnect(); Net.disconnect();
GameState.set(State.menu); GameState.set(State.menu);
Gdx.app.postRunnable(() -> Vars.ui.showError("$text.server.kicked." + KickReason.values()[packet.reason].name())); Gdx.app.postRunnable(() -> Vars.ui.showError("$text.server.kicked." + packet.reason.name()));
}); });
Net.handle(WeaponSwitchPacket.class, packet -> { Net.handle(WeaponSwitchPacket.class, packet -> {

View File

@@ -190,7 +190,16 @@ public class NetServer extends Module{
int dest = Net.getLastConnection(); int dest = Net.getLastConnection();
Gdx.app.postRunnable(() -> { Gdx.app.postRunnable(() -> {
if(Vars.control.playerGroup.getByID(id) != null){ if(Vars.control.playerGroup.getByID(id) != null){
Net.sendTo(dest, Vars.control.playerGroup.getByID(id), SendMode.tcp); Player player = Vars.control.playerGroup.getByID(id);
PlayerSpawnPacket p = new PlayerSpawnPacket();
p.x = player.x;
p.y = player.y;
p.id = player.id;
p.name = player.name;
p.weaponleft = player.weaponLeft.id;
p.weaponright = player.weaponRight.id;
p.android = player.isAndroid;
Net.sendTo(dest, p, SendMode.tcp);
Gdx.app.error("Mindustry", "Replying to entity request ("+Net.getLastConnection()+"): player, " + id); Gdx.app.error("Mindustry", "Replying to entity request ("+Net.getLastConnection()+"): player, " + id);
}else if (Vars.control.enemyGroup.getByID(id) != null){ }else if (Vars.control.enemyGroup.getByID(id) != null){
Enemy enemy = Vars.control.enemyGroup.getByID(id); Enemy enemy = Vars.control.enemyGroup.getByID(id);

View File

@@ -352,7 +352,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
public void draw(Bullet b){ public void draw(Bullet b){
Draw.thick(2f); Draw.thick(2f);
Draw.color(lightOrange, Color.WHITE, 0.4f); Draw.color(lightOrange, Color.WHITE, 0.4f);
Draw.polygon(b.y, b.x, 3, 1.6f, b.angle()); Draw.polygon(b.x, b.y, 3, 1.6f, b.angle());
Draw.thick(1f); Draw.thick(1f);
Draw.color(Color.WHITE, lightOrange, b.ifract()/2f); Draw.color(Color.WHITE, lightOrange, b.ifract()/2f);
Draw.alpha(b.ifract()); Draw.alpha(b.ifract());

View File

@@ -84,7 +84,7 @@ public class EMP extends TimedEntity{
} }
Draw.thick(fract()*2f); Draw.thick(fract()*2f);
Draw.polygon(y, x, 34, radius * Vars.tilesize); Draw.polygon(x, y, 34, radius * Vars.tilesize);
Draw.reset(); Draw.reset();
} }

View File

@@ -121,7 +121,7 @@ public class Fx{
nuclearShockwave = new Effect(10f, 200f, e -> { nuclearShockwave = new Effect(10f, 200f, e -> {
Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract()); Draw.color(Color.WHITE, Color.LIGHT_GRAY, e.ifract());
Draw.thick(e.fract()*3f + 0.2f); Draw.thick(e.fract()*3f + 0.2f);
Draw.polygon(e.y, e.x, 40, e.ifract()*140f); Draw.polygon(e.x, e.y, 40, e.ifract()*140f);
Draw.reset(); Draw.reset();
}), }),
@@ -452,7 +452,7 @@ public class Fx{
clusterbomb = new Effect(10f, e -> { clusterbomb = new Effect(10f, e -> {
Draw.color(Color.WHITE, lightOrange, e.ifract()); Draw.color(Color.WHITE, lightOrange, e.ifract());
Draw.thick(e.fract()*1.5f); Draw.thick(e.fract()*1.5f);
Draw.polygon(e.y, e.x, 4, e.fract()*8f); Draw.polygon(e.x, e.y, 4, e.fract()*8f);
Draw.circle(e.x, e.y, e.ifract()*14f); Draw.circle(e.x, e.y, e.ifract()*14f);
Draw.reset(); Draw.reset();
}), }),

View File

@@ -96,7 +96,7 @@ public enum PlaceMode{
if(android && control.getInput().breaktime > 0){ if(android && control.getInput().breaktime > 0){
Draw.color(Colors.get("breakStart"), Colors.get("break"), fract); Draw.color(Colors.get("breakStart"), Colors.get("break"), fract);
Draw.polygon(tile.worldx() + offset.y, tile.worldy() + offset.x, 25, 4 + (1f - fract) * 26); Draw.polygon(tile.worldx() + offset.x, tile.worldy() + offset.y, 25, 4 + (1f - fract) * 26);
} }
Draw.reset(); Draw.reset();
} }

View File

@@ -238,9 +238,9 @@ public class MapView extends Element implements GestureListener{
Draw.thick(Unit.dp.scl(3f * zoom)); Draw.thick(Unit.dp.scl(3f * zoom));
Draw.line(sx, sy, v2.x, v2.y); Draw.line(sx, sy, v2.x, v2.y);
Draw.polygon(sy, sx, 40, editor.getBrushSize() * zoom * 3); Draw.polygon(sx, sy, 40, editor.getBrushSize() * zoom * 3);
Draw.polygon(v2.y, v2.x, 40, editor.getBrushSize() * zoom * 3); Draw.polygon(v2.x, v2.y, 40, editor.getBrushSize() * zoom * 3);
} }
batch.flush(); batch.flush();

View File

@@ -0,0 +1,8 @@
package io.anuke.mindustry.net;
import java.nio.ByteBuffer;
public interface Packet {
void read(ByteBuffer buffer);
void write(ByteBuffer buffer);
}

View File

@@ -1,9 +1,15 @@
package io.anuke.mindustry.net; package io.anuke.mindustry.net;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.resource.Item;
import java.nio.ByteBuffer;
/**Class for storing all packets.*/ /**Class for storing all packets.*/
public class Packets { public class Packets {
public static class Connect { public static class Connect{
public int id; public int id;
public String addressTCP; public String addressTCP;
} }
@@ -17,128 +23,477 @@ public class Packets {
} }
public static class SyncPacket{ public static class SyncPacket implements Packet{
public byte[] data; public byte[] data;
@Override
public void write(ByteBuffer buffer) {
buffer.putShort((short)data.length);
buffer.put(data);
}
@Override
public void read(ByteBuffer buffer) {
data = new byte[buffer.getShort()];
buffer.get(data);
}
} }
public static class BlockSyncPacket extends Streamable{ public static class BlockSyncPacket extends Streamable{
} }
public static class ConnectPacket{ public static class ConnectPacket implements Packet{
public String name; public String name;
public boolean android; public boolean android;
@Override
public void write(ByteBuffer buffer) {
buffer.put((byte)name.length());
buffer.put(name.getBytes());
buffer.put(android ? (byte)1 : 0);
}
@Override
public void read(ByteBuffer buffer) {
byte length = buffer.get();
byte[] bytes = new byte[length];
buffer.get(bytes);
name = new String(bytes);
android = buffer.get() == 1;
}
} }
public static class ConnectConfirmPacket{ public static class ConnectConfirmPacket implements Packet{
@Override
public void write(ByteBuffer buffer) { }
@Override
public void read(ByteBuffer buffer) { }
} }
public static class DisconnectPacket{ public static class DisconnectPacket implements Packet{
public int playerid; public int playerid;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(playerid);
}
@Override
public void read(ByteBuffer buffer) {
playerid = buffer.getInt();
}
} }
public static class StateSyncPacket{ public static class StateSyncPacket implements Packet{
public int[] items; public int[] items;
public float countdown, time; public float countdown, time;
public int enemies, wave; public int enemies, wave;
public long timestamp; public long timestamp;
@Override
public void write(ByteBuffer buffer) {
for(int i = 0; i < items.length; i ++){
buffer.putInt(items[i]);
}
buffer.putFloat(countdown);
buffer.putFloat(time);
buffer.putShort((short)enemies);
buffer.putShort((short)wave);
buffer.putLong(timestamp);
}
@Override
public void read(ByteBuffer buffer) {
items = new int[Item.getAllItems().size];
for(int i = 0; i < items.length; i ++){
items[i] = buffer.getInt();
}
countdown = buffer.getFloat();
time = buffer.getFloat();
enemies = buffer.getShort();
wave = buffer.getShort();
timestamp = buffer.getLong();
}
} }
public static class PositionPacket{ public static class PositionPacket implements Packet{
public byte[] data; public byte[] data;
@Override
public void write(ByteBuffer buffer) {
buffer.put(data);
}
@Override
public void read(ByteBuffer buffer) {
data = new byte[SyncEntity.getWriteSize(Player.class)];
buffer.get(data);
}
} }
//not a real packet.
public static class EffectPacket{ public static class EffectPacket{
public int id; public int id;
public float x, y, rotation; public float x, y, rotation;
public int color; public int color;
} }
public static class ShootPacket{ public static class ShootPacket implements Packet{
public byte weaponid; public byte weaponid;
public float x, y, rotation; public float x, y, rotation;
public int playerid; public int playerid;
@Override
public void write(ByteBuffer buffer) {
buffer.put(weaponid);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putFloat(rotation);
buffer.putInt(playerid);
}
@Override
public void read(ByteBuffer buffer) {
weaponid = buffer.get();
x = buffer.getFloat();
y = buffer.getFloat();
rotation = buffer.getFloat();
playerid = buffer.getInt();
}
} }
public static class BulletPacket{ public static class BulletPacket implements Packet{
public int type, owner; public int type, owner;
public float x, y, angle; public float x, y, angle;
public short damage; public short damage;
@Override
public void write(ByteBuffer buffer) {
buffer.putShort((short)type);
buffer.putInt(owner);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putFloat(angle);
buffer.putShort(damage);
}
@Override
public void read(ByteBuffer buffer) {
type = buffer.getShort();
owner = buffer.getInt();
x = buffer.getFloat();
y = buffer.getFloat();
angle = buffer.getFloat();
damage = buffer.getShort();
}
} }
public static class PlacePacket{ public static class PlacePacket implements Packet{
public int playerid; public int playerid;
public byte rotation; public byte rotation;
public short x, y; public short x, y;
public int block; public int block;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(playerid);
buffer.put(rotation);
buffer.putShort(x);
buffer.putShort(y);
buffer.putInt(block);
}
@Override
public void read(ByteBuffer buffer) {
playerid = buffer.getInt();
rotation = buffer.get();
x = buffer.getShort();
y = buffer.getShort();
block = buffer.getInt();
}
} }
public static class BreakPacket{ public static class BreakPacket implements Packet{
public int playerid; public int playerid;
public short x, y; public short x, y;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(playerid);
buffer.putShort(x);
buffer.putShort(y);
}
@Override
public void read(ByteBuffer buffer) {
playerid = buffer.getInt();
x = buffer.getShort();
y = buffer.getShort();
}
} }
public static class EnemySpawnPacket{ public static class EnemySpawnPacket implements Packet{
public byte type, lane, tier; public byte type, lane, tier;
public float x, y; public float x, y;
public short health; public short health;
public int id; public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.put(type);
buffer.put(lane);
buffer.put(tier);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putShort(health);
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
type = buffer.get();
lane = buffer.get();
tier = buffer.get();
x = buffer.getFloat();
y = buffer.getFloat();
health = buffer.getShort();
id = buffer.getInt();
}
} }
public static class EnemyDeathPacket{ public static class PlayerSpawnPacket implements Packet{
public byte weaponleft, weaponright;
public boolean android;
public String name;
public float x, y;
public int id; public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.put((byte)name.length());
buffer.put(name.getBytes());
buffer.put(weaponleft);
buffer.put(weaponright);
buffer.put(android ? 1 : (byte)0);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
byte nlength = buffer.get();
byte[] n = new byte[nlength];
buffer.get(n);
name = new String(n);
weaponleft = buffer.get();
weaponright = buffer.get();
android = buffer.get() == 1;
x = buffer.getFloat();
y = buffer.getFloat();
id = buffer.getInt();
}
} }
public static class BlockDestroyPacket{ public static class EnemyDeathPacket implements Packet{
public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
}
}
public static class BlockDestroyPacket implements Packet{
public int position; public int position;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(position);
}
@Override
public void read(ByteBuffer buffer) {
position = buffer.getInt();
}
} }
public static class BlockUpdatePacket{ public static class BlockUpdatePacket implements Packet{
public int health, position; public int health, position;
@Override
public void write(ByteBuffer buffer) {
buffer.putShort((short)health);
buffer.putInt(position);
}
@Override
public void read(ByteBuffer buffer) {
health = buffer.getShort();
position = buffer.getInt();
}
} }
public static class ChatPacket{ public static class ChatPacket implements Packet{
public String name; public String name;
public String text; public String text;
public int id; public int id;
@Override
public void write(ByteBuffer buffer) {
if(name != null) {
buffer.putShort((short) name.length());
buffer.put(name.getBytes());
}else{
buffer.putShort((short)-1);
}
buffer.putShort((short)text.length());
buffer.put(text.getBytes());
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
short nlength = buffer.getShort();
if(nlength != -1) {
byte[] n = new byte[nlength];
buffer.get(n);
name = new String(n);
}
short tlength = buffer.getShort();
byte[] t = new byte[tlength];
buffer.get(t);
id = buffer.getInt();
text = new String(t);
}
} }
public static class KickPacket{ public static class KickPacket implements Packet{
public byte reason; public KickReason reason;
@Override
public void write(ByteBuffer buffer) {
buffer.put((byte)reason.ordinal());
}
@Override
public void read(ByteBuffer buffer) {
reason = KickReason.values()[buffer.get()];
}
} }
public enum KickReason{ public enum KickReason{
kick, invalidPassword kick, invalidPassword
} }
public static class UpgradePacket{ public static class UpgradePacket implements Packet{
public byte id; //weapon ID only, currently public byte id; //weapon ID only, currently
@Override
public void write(ByteBuffer buffer) {
buffer.put(id);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.get();
}
} }
public static class WeaponSwitchPacket{ public static class WeaponSwitchPacket implements Packet{
public int playerid; public int playerid;
public byte left, right; public byte left, right;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(playerid);
buffer.put(left);
buffer.put(right);
}
@Override
public void read(ByteBuffer buffer) {
playerid = buffer.getInt();
left = buffer.get();
right = buffer.get();
}
} }
public static class BlockTapPacket{ public static class BlockTapPacket implements Packet{
public int position; public int position;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(position);
}
@Override
public void read(ByteBuffer buffer) {
position = buffer.getInt();
}
} }
public static class BlockConfigPacket{ public static class BlockConfigPacket implements Packet{
public int position; public int position;
public byte data; public byte data;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(position);
buffer.put(data);
}
@Override
public void read(ByteBuffer buffer) {
position = buffer.getInt();
data = buffer.get();
}
} }
public static class EntityRequestPacket{ public static class EntityRequestPacket implements Packet{
public int id; public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
}
} }
public static class GameOverPacket{ public static class GameOverPacket implements Packet{
@Override
public void write(ByteBuffer buffer) { }
@Override
public void read(ByteBuffer buffer) { }
} }
public static class FriendlyFireChangePacket{ public static class FriendlyFireChangePacket implements Packet{
public boolean enabled; public boolean enabled;
@Override
public void write(ByteBuffer buffer) {
buffer.put(enabled ? 1 : (byte)0);
}
@Override
public void read(ByteBuffer buffer) {
enabled = buffer.get() == 1;
}
} }
} }

View File

@@ -1,59 +1,62 @@
package io.anuke.mindustry.net; package io.anuke.mindustry.net;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.ObjectIntMap;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.Streamable.StreamBegin; import io.anuke.mindustry.net.Streamable.StreamBegin;
import io.anuke.mindustry.net.Streamable.StreamChunk; import io.anuke.mindustry.net.Streamable.StreamChunk;
import io.anuke.ucore.entities.Entity;
public class Registrator { public class Registrator {
private static Class<?>[] classes = {
StreamBegin.class,
StreamChunk.class,
WorldData.class,
SyncPacket.class,
PositionPacket.class,
ShootPacket.class,
PlacePacket.class,
BreakPacket.class,
StateSyncPacket.class,
BlockSyncPacket.class,
EnemySpawnPacket.class,
PlayerSpawnPacket.class,
BulletPacket.class,
EnemyDeathPacket.class,
BlockUpdatePacket.class,
BlockDestroyPacket.class,
ConnectPacket.class,
DisconnectPacket.class,
ChatPacket.class,
KickPacket.class,
UpgradePacket.class,
WeaponSwitchPacket.class,
BlockTapPacket.class,
BlockConfigPacket.class,
EntityRequestPacket.class,
ConnectConfirmPacket.class,
GameOverPacket.class,
FriendlyFireChangePacket.class,
};
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
static{
if(classes.length > 127) throw new RuntimeException("Can't have more than 127 registered classes!");
for(int i = 0; i < classes.length; i ++){
if(!ClassReflection.isAssignableFrom(Packet.class, classes[i]) &&
!ClassReflection.isAssignableFrom(Streamable.class, classes[i])) throw new RuntimeException("Not a packet: " + classes[i]);
ids.put(classes[i], i);
}
}
public static Class<?> getByID(byte id){
return classes[id];
}
public static byte getID(Class<?> type){
return (byte)ids.get(type, -1);
}
public static Class<?>[] getClasses(){ public static Class<?>[] getClasses(){
return new Class<?>[]{ return classes;
StreamBegin.class,
StreamChunk.class,
WorldData.class,
SyncPacket.class,
PositionPacket.class,
ShootPacket.class,
PlacePacket.class,
BreakPacket.class,
StateSyncPacket.class,
BlockSyncPacket.class,
EnemySpawnPacket.class,
BulletPacket.class,
EnemyDeathPacket.class,
BlockUpdatePacket.class,
BlockDestroyPacket.class,
ConnectPacket.class,
DisconnectPacket.class,
ChatPacket.class,
KickPacket.class,
UpgradePacket.class,
WeaponSwitchPacket.class,
BlockTapPacket.class,
BlockConfigPacket.class,
EntityRequestPacket.class,
ConnectConfirmPacket.class,
GameOverPacket.class,
FriendlyFireChangePacket.class,
Class.class,
byte[].class,
float[].class,
float[][].class,
int[].class,
int[][].class,
Entity[].class,
Array.class,
Vector2.class,
Entity.class,
Player.class,
Enemy.class
};
} }
} }

View File

@@ -6,23 +6,51 @@ import com.badlogic.gdx.utils.reflect.ReflectionException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.nio.ByteBuffer;
public class Streamable { public class Streamable{
public transient ByteArrayInputStream stream; public transient ByteArrayInputStream stream;
/**Marks the beginning of a stream.*/ /**Marks the beginning of a stream.*/
public static class StreamBegin{ public static class StreamBegin implements Packet{
private static int lastid; private static int lastid;
public int id = lastid ++; public int id = lastid ++;
public int total; public int total;
public Class<? extends Streamable> type; public Class<? extends Streamable> type;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
buffer.putInt(total);
buffer.put(Registrator.getID(type));
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
total = buffer.getInt();
type = (Class<? extends Streamable>)Registrator.getByID(buffer.get());
}
} }
public static class StreamChunk{ public static class StreamChunk implements Packet{
public int id; public int id;
public byte[] data; public byte[] data;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
buffer.putShort((short)data.length);
buffer.put(data);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
data = new byte[buffer.getShort()];
buffer.get(data);
}
} }
public static class StreamBuilder{ public static class StreamBuilder{

View File

@@ -0,0 +1,61 @@
package io.anuke.kryonet;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;
import com.esotericsoftware.kryonet.FrameworkMessage;
import com.esotericsoftware.kryonet.serialization.Serialization;
import io.anuke.mindustry.net.Packet;
import io.anuke.mindustry.net.Registrator;
import java.nio.ByteBuffer;
public class ByteSerializer implements Serialization {
@Override
public void write(ByteBuffer byteBuffer, Object o) {
if(o instanceof FrameworkMessage){
byteBuffer.put((byte)-2); //code for framework message
FrameworkSerializer.write(byteBuffer, (FrameworkMessage)o);
}else {
if (!(o instanceof Packet))
throw new RuntimeException("All sent objects must implement be Packets! Class: " + o.getClass());
byte id = Registrator.getID(o.getClass());
if (id == -1)
throw new RuntimeException("Unregistered class: " + ClassReflection.getSimpleName(o.getClass()));
byteBuffer.put(id);
((Packet) o).write(byteBuffer);
}
}
@Override
public Object read(ByteBuffer byteBuffer) {
try {
byte id = byteBuffer.get();
if(id == -2){
return FrameworkSerializer.read(byteBuffer);
}else {
Class<?> type = Registrator.getByID(id);
Packet packet = (Packet) ClassReflection.newInstance(type);
packet.read(byteBuffer);
return packet;
}
}catch (ReflectionException e){
throw new RuntimeException(e);
}
}
@Override
public int getLengthLength() {
return 2;
}
@Override
public void writeLength(ByteBuffer byteBuffer, int i) {
byteBuffer.putShort((short)i);
}
@Override
public int readLength(ByteBuffer byteBuffer) {
return byteBuffer.getShort();
}
}

View File

@@ -0,0 +1,69 @@
package io.anuke.kryonet;
import com.esotericsoftware.kryonet.FrameworkMessage;
import com.esotericsoftware.kryonet.FrameworkMessage.*;
import java.nio.ByteBuffer;
public class FrameworkSerializer {
public static void write(ByteBuffer buffer, FrameworkMessage message){
if(message instanceof Ping){
Ping p = (Ping)message;
buffer.put((byte)0);
buffer.putInt(p.id);
buffer.put(p.isReply ? 1 : (byte)0);
}else if(message instanceof DiscoverHost){
DiscoverHost p = (DiscoverHost)message;
buffer.put((byte)1);
}else if(message instanceof KeepAlive){
KeepAlive p = (KeepAlive)message;
buffer.put((byte)2);
}else if(message instanceof RegisterUDP){
RegisterUDP p = (RegisterUDP)message;
buffer.put((byte)3);
buffer.putInt(p.connectionID);
}else if(message instanceof RegisterTCP){
RegisterTCP p = (RegisterTCP)message;
buffer.put((byte)4);
buffer.putInt(p.connectionID);
}
}
public static FrameworkMessage read(ByteBuffer buffer){
byte id = buffer.get();
if(id == 0){
Ping p = new Ping();
p.id = buffer.getInt();
p.isReply = buffer.get() == 1;
return p;
}else if(id == 1){
DiscoverHost p = new DiscoverHost();
return p;
}else if(id == 2){
KeepAlive p = new KeepAlive();
return p;
}else if(id == 3){
RegisterUDP p = new RegisterUDP();
p.connectionID = buffer.getInt();
return p;
}else if(id == 4){
RegisterTCP p = new RegisterTCP();
p.connectionID = buffer.getInt();
return p;
}else{
throw new RuntimeException("Unknown framework message!");
}
}
}

View File

@@ -52,7 +52,7 @@ public class KryoClient implements ClientProvider{
} }
}; };
client = new Client(8192, 2048); client = new Client(8192, 2048, connection -> new ByteSerializer());
client.setDiscoveryHandler(handler); client.setDiscoveryHandler(handler);
Listener listener = new Listener(){ Listener listener = new Listener(){
@@ -211,12 +211,7 @@ public class KryoClient implements ClientProvider{
} }
@Override @Override
public void register(Class<?>... types) { public void register(Class<?>... types) { }
for(Class<?> c : types){
client.getKryo().register(c);
}
KryoRegistrator.register(client.getKryo());
}
@Override @Override
public void dispose(){ public void dispose(){

View File

@@ -30,7 +30,7 @@ public class KryoServer implements ServerProvider {
IntArray connections = new IntArray(); IntArray connections = new IntArray();
public KryoServer(){ public KryoServer(){
server = new Server(4096*2, 2048); //TODO tweak server = new Server(4096*2, 2048, connection -> new ByteSerializer()); //TODO tweak
server.setDiscoveryHandler((datagramChannel, fromAddress) -> { server.setDiscoveryHandler((datagramChannel, fromAddress) -> {
ByteBuffer buffer = KryoRegistrator.writeServerData(); ByteBuffer buffer = KryoRegistrator.writeServerData();
UCore.log("Replying to discover request with buffer of size " + buffer.capacity()); UCore.log("Replying to discover request with buffer of size " + buffer.capacity());
@@ -107,7 +107,7 @@ public class KryoServer implements ServerProvider {
} }
KickPacket p = new KickPacket(); KickPacket p = new KickPacket();
p.reason = (byte)KickReason.kick.ordinal(); p.reason = KickReason.kick;
conn.sendTCP(p); conn.sendTCP(p);
Timers.runTask(1f, () -> { Timers.runTask(1f, () -> {
@@ -198,12 +198,7 @@ public class KryoServer implements ServerProvider {
} }
@Override @Override
public void register(Class<?>... types) { public void register(Class<?>... types) { }
for(Class<?> c : types){
server.getKryo().register(c);
}
KryoRegistrator.register(server.getKryo());
}
@Override @Override
public void dispose(){ public void dispose(){