Implemented server sending world data to client
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
package io.anuke.mindustry.net;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
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;
|
||||
|
||||
//TODO stub
|
||||
@@ -15,6 +21,8 @@ public class Net{
|
||||
private static ObjectMap<Class<?>, Consumer> serverListeners = new ObjectMap<>();
|
||||
private static ClientProvider clientProvider;
|
||||
private static ServerProvider serverProvider;
|
||||
|
||||
private static IntMap<StreamBuilder> streams = new IntMap<>();
|
||||
|
||||
/**Connect to an address.*/
|
||||
public static void connect(String ip, int port) throws IOException{
|
||||
@@ -51,6 +59,16 @@ public class Net{
|
||||
clientProvider.send(object, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**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.*/
|
||||
public static void setClientProvider(ClientProvider provider){
|
||||
@@ -74,7 +92,21 @@ public class Net{
|
||||
|
||||
/**Call to handle a packet being recieved for the client.*/
|
||||
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);
|
||||
}else{
|
||||
Gdx.app.error("Mindustry::Net", "Unhandled packet type: '" + object.getClass() + "'!");
|
||||
@@ -131,6 +163,8 @@ public class Net{
|
||||
public static interface ServerProvider {
|
||||
/**Host a server at specified port.*/
|
||||
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.*/
|
||||
public void send(Object object, SendMode mode);
|
||||
/**Send an object to a specific client ID.*/
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.anuke.mindustry.net;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**Class for storing all packets.*/
|
||||
public class Packets {
|
||||
|
||||
@@ -13,7 +15,7 @@ public class Packets {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user