Implemented server sending world data to client
This commit is contained in:
@@ -15,6 +15,7 @@ text.quit=Quit
|
|||||||
text.hostserver=Host Server
|
text.hostserver=Host Server
|
||||||
text.joingame.title=Join Game
|
text.joingame.title=Join Game
|
||||||
text.joingame.ip=IP:
|
text.joingame.ip=IP:
|
||||||
|
text.disconnect=Disconnected.
|
||||||
text.connecting=[accent]Connecting...
|
text.connecting=[accent]Connecting...
|
||||||
text.connecting.data=[accent]Loading world data...
|
text.connecting.data=[accent]Loading world data...
|
||||||
text.connectfail=[crimson]Failed to connect to server: [orange]{0}
|
text.connectfail=[crimson]Failed to connect to server: [orange]{0}
|
||||||
|
|||||||
@@ -1,24 +1,53 @@
|
|||||||
package io.anuke.mindustry.core;
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.io.SaveIO;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Packets.Connect;
|
import io.anuke.mindustry.net.Packets.Connect;
|
||||||
|
import io.anuke.mindustry.net.Packets.Disconnect;
|
||||||
|
import io.anuke.mindustry.net.Packets.WorldData;
|
||||||
|
import io.anuke.ucore.UCore;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.modules.Module;
|
import io.anuke.ucore.modules.Module;
|
||||||
|
|
||||||
public class NetClient extends Module {
|
public class NetClient extends Module {
|
||||||
|
boolean connecting = false;
|
||||||
|
|
||||||
public NetClient(){
|
public NetClient(){
|
||||||
|
|
||||||
Net.handle(Connect.class, packet -> {
|
Net.handle(Connect.class, packet -> {
|
||||||
|
connecting = true;
|
||||||
Gdx.app.postRunnable(() -> {
|
Gdx.app.postRunnable(() -> {
|
||||||
Vars.ui.hideLoading();
|
Vars.ui.hideLoading();
|
||||||
Vars.ui.showLoading("$text.connecting.data");
|
Vars.ui.showLoading("$text.connecting.data");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Net.handle(Disconnect.class, packet -> {
|
||||||
|
Gdx.app.postRunnable(() -> {
|
||||||
|
Timers.runFor(3f, () -> {
|
||||||
|
Vars.ui.hideLoading();
|
||||||
|
});
|
||||||
|
|
||||||
|
Vars.ui.showError("$text.disconnect");
|
||||||
|
connecting = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Net.handle(WorldData.class, data -> {
|
||||||
|
Gdx.app.postRunnable(() -> {
|
||||||
|
UCore.log("Recieved world data: " + data.stream.available() + " bytes.");
|
||||||
|
SaveIO.load(data.stream);
|
||||||
|
GameState.set(State.playing);
|
||||||
|
connecting = false;
|
||||||
|
Vars.ui.hideLoading();
|
||||||
|
Vars.ui.hideJoinGame();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(){
|
public void update(){
|
||||||
@@ -26,7 +55,7 @@ public class NetClient extends Module {
|
|||||||
|
|
||||||
if(!GameState.is(State.menu) && Net.active()){
|
if(!GameState.is(State.menu) && Net.active()){
|
||||||
|
|
||||||
}else{
|
}else if(!connecting){
|
||||||
Net.disconnect();
|
Net.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,33 @@ package io.anuke.mindustry.core;
|
|||||||
|
|
||||||
import io.anuke.mindustry.Vars;
|
import io.anuke.mindustry.Vars;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
|
import io.anuke.mindustry.io.SaveIO;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
|
import io.anuke.mindustry.net.Packets.Connect;
|
||||||
|
import io.anuke.mindustry.net.Packets.WorldData;
|
||||||
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.modules.Module;
|
import io.anuke.ucore.modules.Module;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class NetServer extends Module{
|
public class NetServer extends Module{
|
||||||
|
|
||||||
public NetServer(){
|
public NetServer(){
|
||||||
|
|
||||||
|
Net.handleServer(Connect.class, packet -> {
|
||||||
|
UCore.log("Sending world data to client (ID="+packet.id+"/"+packet.addressTCP+")");
|
||||||
|
|
||||||
|
WorldData data = new WorldData();
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
SaveIO.write(stream);
|
||||||
|
|
||||||
|
UCore.log("Packed " + stream.size() + " bytes of data.");
|
||||||
|
|
||||||
|
data.stream = new ByteArrayInputStream(stream.toByteArray());
|
||||||
|
Net.sendStream(packet.id, data);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(){
|
public void update(){
|
||||||
|
|||||||
@@ -455,6 +455,10 @@ public class UI extends SceneModule{
|
|||||||
join.show();
|
join.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void hideJoinGame(){
|
||||||
|
join.hide();
|
||||||
|
}
|
||||||
|
|
||||||
public void showMenu(){
|
public void showMenu(){
|
||||||
menu.show();
|
menu.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public enum PlaceMode{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
areaDelete{
|
areaDelete{
|
||||||
int maxlen = 10;
|
int maxlen = 20;
|
||||||
int tilex;
|
int tilex;
|
||||||
int tiley;
|
int tiley;
|
||||||
int endx;
|
int endx;
|
||||||
@@ -236,7 +236,7 @@ public enum PlaceMode{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
hold{
|
hold{
|
||||||
int maxlen = 10;
|
int maxlen = 20;
|
||||||
int tilex;
|
int tilex;
|
||||||
int tiley;
|
int tiley;
|
||||||
int endx;
|
int endx;
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package io.anuke.mindustry.io;
|
|||||||
|
|
||||||
import static io.anuke.mindustry.Vars.android;
|
import static io.anuke.mindustry.Vars.android;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.*;
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@@ -182,8 +180,12 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void write(FileHandle file){
|
public static void write(FileHandle file){
|
||||||
|
write(file.write(false));
|
||||||
|
}
|
||||||
|
|
||||||
try(DataOutputStream stream = new DataOutputStream(file.write(false))){
|
public static void write(OutputStream os){
|
||||||
|
|
||||||
|
try(DataOutputStream stream = new DataOutputStream(os)){
|
||||||
|
|
||||||
//--META--
|
//--META--
|
||||||
stream.writeInt(fileVersionID); //version id
|
stream.writeInt(fileVersionID); //version id
|
||||||
@@ -309,10 +311,14 @@ public class SaveIO{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO GWT support
|
|
||||||
public static void load(FileHandle file){
|
public static void load(FileHandle file){
|
||||||
|
load(file.read());
|
||||||
|
}
|
||||||
|
|
||||||
try(DataInputStream stream = new DataInputStream(file.read())){
|
//TODO GWT support
|
||||||
|
public static void load(InputStream is){
|
||||||
|
|
||||||
|
try(DataInputStream stream = new DataInputStream(is)){
|
||||||
|
|
||||||
int version = stream.readInt();
|
int version = stream.readInt();
|
||||||
/*long loadTime = */stream.readLong();
|
/*long loadTime = */stream.readLong();
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
package io.anuke.mindustry.net;
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamBegin;
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamBuilder;
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamChunk;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
|
|
||||||
//TODO stub
|
//TODO stub
|
||||||
@@ -16,6 +22,8 @@ public class Net{
|
|||||||
private static ClientProvider clientProvider;
|
private static ClientProvider clientProvider;
|
||||||
private static ServerProvider serverProvider;
|
private static ServerProvider serverProvider;
|
||||||
|
|
||||||
|
private static IntMap<StreamBuilder> streams = new IntMap<>();
|
||||||
|
|
||||||
/**Connect to an address.*/
|
/**Connect to an address.*/
|
||||||
public static void connect(String ip, int port) throws IOException{
|
public static void connect(String ip, int port) throws IOException{
|
||||||
clientProvider.connect(ip, port);
|
clientProvider.connect(ip, port);
|
||||||
@@ -52,6 +60,16 @@ public class Net{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Send an object to a certain client. Server-side only*/
|
||||||
|
public static void sendTo(int id, Object object, SendMode mode){
|
||||||
|
serverProvider.sendTo(id, object, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Send a stream to a specific client. Server-side only.*/
|
||||||
|
public static void sendStream(int id, Streamable stream){
|
||||||
|
serverProvider.sendStream(id, stream);
|
||||||
|
}
|
||||||
|
|
||||||
/**Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.*/
|
/**Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.*/
|
||||||
public static void setClientProvider(ClientProvider provider){
|
public static void setClientProvider(ClientProvider provider){
|
||||||
Net.clientProvider = provider;
|
Net.clientProvider = provider;
|
||||||
@@ -74,7 +92,21 @@ public class Net{
|
|||||||
|
|
||||||
/**Call to handle a packet being recieved for the client.*/
|
/**Call to handle a packet being recieved for the client.*/
|
||||||
public static void handleClientReceived(Object object){
|
public static void handleClientReceived(Object object){
|
||||||
if(clientListeners.get(object.getClass()) != null){
|
if(object instanceof StreamBegin) {
|
||||||
|
StreamBegin b = (StreamBegin) object;
|
||||||
|
streams.put(b.id, new StreamBuilder(b));
|
||||||
|
}else if(object instanceof StreamChunk) {
|
||||||
|
StreamChunk c = (StreamChunk)object;
|
||||||
|
StreamBuilder builder = streams.get(c.id);
|
||||||
|
if(builder == null){
|
||||||
|
throw new RuntimeException("Recieved stream chunk without a StreamBegin beforehand!");
|
||||||
|
}
|
||||||
|
builder.add(c.data);
|
||||||
|
if(builder.isDone()){
|
||||||
|
streams.remove(builder.id);
|
||||||
|
handleClientReceived(builder.build());
|
||||||
|
}
|
||||||
|
}else if(clientListeners.get(object.getClass()) != null){
|
||||||
clientListeners.get(object.getClass()).accept(object);
|
clientListeners.get(object.getClass()).accept(object);
|
||||||
}else{
|
}else{
|
||||||
Gdx.app.error("Mindustry::Net", "Unhandled packet type: '" + object.getClass() + "'!");
|
Gdx.app.error("Mindustry::Net", "Unhandled packet type: '" + object.getClass() + "'!");
|
||||||
@@ -131,6 +163,8 @@ public class Net{
|
|||||||
public static interface ServerProvider {
|
public static interface ServerProvider {
|
||||||
/**Host a server at specified port.*/
|
/**Host a server at specified port.*/
|
||||||
public void host(int port) throws IOException;
|
public void host(int port) throws IOException;
|
||||||
|
/**Sends a large stream of data to a specific client.*/
|
||||||
|
public void sendStream(int id, Streamable stream);
|
||||||
/**Send an object to everyone connected.*/
|
/**Send an object to everyone connected.*/
|
||||||
public void send(Object object, SendMode mode);
|
public void send(Object object, SendMode mode);
|
||||||
/**Send an object to a specific client ID.*/
|
/**Send an object to a specific client ID.*/
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package io.anuke.mindustry.net;
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**Class for storing all packets.*/
|
/**Class for storing all packets.*/
|
||||||
public class Packets {
|
public class Packets {
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ public class Packets {
|
|||||||
public String addressTCP;
|
public String addressTCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WorldData {
|
public static class WorldData extends Streamable{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
core/src/io/anuke/mindustry/net/Registrator.java
Normal file
18
core/src/io/anuke/mindustry/net/Registrator.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
|
import io.anuke.mindustry.net.Packets.WorldData;
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamBegin;
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamChunk;
|
||||||
|
|
||||||
|
public class Registrator {
|
||||||
|
|
||||||
|
public static Class<?>[] getClasses(){
|
||||||
|
return new Class<?>[]{
|
||||||
|
StreamBegin.class,
|
||||||
|
StreamChunk.class,
|
||||||
|
WorldData.class,
|
||||||
|
Class.class,
|
||||||
|
byte[].class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
63
core/src/io/anuke/mindustry/net/Streamable.java
Normal file
63
core/src/io/anuke/mindustry/net/Streamable.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
|
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class Streamable {
|
||||||
|
public transient ByteArrayInputStream stream;
|
||||||
|
|
||||||
|
/**Marks the beginning of a stream.*/
|
||||||
|
public static class StreamBegin{
|
||||||
|
private static int lastid;
|
||||||
|
|
||||||
|
public int id = lastid ++;
|
||||||
|
public int total;
|
||||||
|
public Class<? extends Streamable> type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StreamChunk{
|
||||||
|
public int id;
|
||||||
|
public byte[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StreamBuilder{
|
||||||
|
public final int id;
|
||||||
|
public final Class<? extends Streamable> type;
|
||||||
|
public final int total;
|
||||||
|
public final ByteArrayOutputStream stream;
|
||||||
|
|
||||||
|
public StreamBuilder(StreamBegin begin){
|
||||||
|
id = begin.id;
|
||||||
|
type = begin.type;
|
||||||
|
total = begin.total;
|
||||||
|
stream = new ByteArrayOutputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(byte[] bytes){
|
||||||
|
try {
|
||||||
|
stream.write(bytes);
|
||||||
|
}catch (IOException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Streamable build(){
|
||||||
|
try {
|
||||||
|
Streamable s = ClassReflection.newInstance(type);
|
||||||
|
s.stream = new ByteArrayInputStream(stream.toByteArray());
|
||||||
|
return s;
|
||||||
|
}catch(ReflectionException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDone(){
|
||||||
|
return stream.size() >= total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import java.net.URI;
|
|||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||||
@@ -13,6 +14,8 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
import com.esotericsoftware.kryonet.*;
|
import com.esotericsoftware.kryonet.*;
|
||||||
|
import com.esotericsoftware.kryonet.util.InputStreamSender;
|
||||||
|
import com.esotericsoftware.minlog.Log;
|
||||||
import io.anuke.mindustry.Mindustry;
|
import io.anuke.mindustry.Mindustry;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Net.ClientProvider;
|
import io.anuke.mindustry.net.Net.ClientProvider;
|
||||||
@@ -22,6 +25,11 @@ import io.anuke.mindustry.io.PlatformFunction;
|
|||||||
import io.anuke.mindustry.net.Net.ServerProvider;
|
import io.anuke.mindustry.net.Net.ServerProvider;
|
||||||
import io.anuke.mindustry.net.Packets.Connect;
|
import io.anuke.mindustry.net.Packets.Connect;
|
||||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
import io.anuke.mindustry.net.Packets.Disconnect;
|
||||||
|
import io.anuke.mindustry.net.Registrator;
|
||||||
|
import io.anuke.mindustry.net.Streamable;
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamBegin;
|
||||||
|
import io.anuke.mindustry.net.Streamable.StreamChunk;
|
||||||
|
import io.anuke.ucore.UCore;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.ucore.scene.ui.TextField;
|
||||||
|
|
||||||
public class DesktopLauncher {
|
public class DesktopLauncher {
|
||||||
@@ -65,6 +73,8 @@ public class DesktopLauncher {
|
|||||||
|
|
||||||
Mindustry.args = Array.with(arg);
|
Mindustry.args = Array.with(arg);
|
||||||
|
|
||||||
|
Log.set(Log.LEVEL_DEBUG);
|
||||||
|
|
||||||
Net.setClientProvider(new ClientProvider() {
|
Net.setClientProvider(new ClientProvider() {
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
@@ -92,6 +102,8 @@ public class DesktopLauncher {
|
|||||||
Net.handleClientReceived(object);
|
Net.handleClientReceived(object);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
register(Registrator.getClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,15 +157,14 @@ public class DesktopLauncher {
|
|||||||
Connect c = new Connect();
|
Connect c = new Connect();
|
||||||
c.id = connection.getID();
|
c.id = connection.getID();
|
||||||
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
||||||
Net.handleClientReceived(c);
|
Net.handleServerReceived(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnected (Connection connection) {
|
public void disconnected (Connection connection) {
|
||||||
Disconnect c = new Disconnect();
|
Disconnect c = new Disconnect();
|
||||||
c.id = connection.getID();
|
c.id = connection.getID();
|
||||||
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
Net.handleServerReceived(c);
|
||||||
Net.handleClientReceived(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -162,6 +173,8 @@ public class DesktopLauncher {
|
|||||||
Net.handleServerReceived(object);
|
Net.handleServerReceived(object);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
register(Registrator.getClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,6 +187,33 @@ public class DesktopLauncher {
|
|||||||
server.close();
|
server.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendStream(int id, Streamable stream) {
|
||||||
|
Connection connection = getByID(id);
|
||||||
|
|
||||||
|
connection.addListener(new InputStreamSender(stream.stream, 512) {
|
||||||
|
int id;
|
||||||
|
|
||||||
|
protected void start () {
|
||||||
|
//send an object so the receiving side knows how to handle the following chunks
|
||||||
|
StreamBegin begin = new StreamBegin();
|
||||||
|
begin.total = stream.stream.available();
|
||||||
|
begin.type = stream.getClass();
|
||||||
|
connection.sendTCP(begin);
|
||||||
|
id = begin.id;
|
||||||
|
UCore.log("Sending begin packet: " + begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object next (byte[] bytes) {
|
||||||
|
StreamChunk chunk = new StreamChunk();
|
||||||
|
chunk.id = id;
|
||||||
|
chunk.data = bytes;
|
||||||
|
UCore.log("Sending chunk of size " + chunk.data.length);
|
||||||
|
return chunk; //wrap the byte[] with an object so the receiving side knows how to handle it.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(Object object, SendMode mode) {
|
public void send(Object object, SendMode mode) {
|
||||||
if(mode == SendMode.tcp){
|
if(mode == SendMode.tcp){
|
||||||
@@ -207,6 +247,18 @@ public class DesktopLauncher {
|
|||||||
server.getKryo().register(c);
|
server.getKryo().register(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connection getByID(int id){
|
||||||
|
for(Connection con : server.getConnections()){
|
||||||
|
if(con.getID() == id){
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("Unable to find connection with ID " + id + "! Current connections: "
|
||||||
|
+ Arrays.toString(server.getConnections()));
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new Lwjgl3Application(new Mindustry(), config);
|
new Lwjgl3Application(new Mindustry(), config);
|
||||||
|
|||||||
Reference in New Issue
Block a user