diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index e65c3be427..4792bd6d89 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -129,8 +129,8 @@ public class AndroidLauncher extends AndroidApplication{ } config.hideStatusBar = true; - Net.setClientProvider(new MClient()); - Net.setServerProvider(new MServer()); + Net.setClientProvider(new ArcNetClient()); + Net.setServerProvider(new ArcNetServer()); initialize(new Mindustry(), config); checkFiles(getIntent()); } diff --git a/build.gradle b/build.gradle index c4d50ab828..c08d3dcdac 100644 --- a/build.gradle +++ b/build.gradle @@ -232,7 +232,7 @@ project(":core"){ compile "org.lz4:lz4-java:1.4.1" compile arcModule("arc-core") compile arcModule("extensions:freetype") - compile arcModule("extensions:mnet") + compile arcModule("extensions:arcnet") if(localArc() && debugged()) compile arcModule("extensions:recorder") compileOnly project(":annotations") diff --git a/desktop/build.gradle b/desktop/build.gradle index 7804844687..2a99053dc6 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -9,6 +9,7 @@ sourceSets.main.java.srcDirs = [ "src/" ] project.ext.mainClassName = "io.anuke.mindustry.desktop.DesktopLauncher" project.ext.assetsDir = new File("../core/assets") +def enableTemplates = true def JDK_DIR = "$System.env.PACKR_DIR" def ICON_DIR = new File("core/assets/icons/icon.icns") @@ -63,7 +64,7 @@ PackrConfig.Platform.values().each{ platform -> delete "build/packr/output/" } - if(platform == PackrConfig.Platform.Windows32 || platform == PackrConfig.Platform.Windows64){ + if(enableTemplates && (platform == PackrConfig.Platform.Windows64)){ copy{ into "build/packr/output" from "${JDK_DIR}/templates/${platform.toString().toLowerCase()}" diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index 5838584185..59f3b8a960 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -12,8 +12,8 @@ public class DesktopLauncher{ try{ Platform.instance = new DesktopPlatform(arg); - Net.setClientProvider(new MClient()); - Net.setServerProvider(new MServer()); + Net.setClientProvider(new ArcNetClient()); + Net.setServerProvider(new ArcNetServer()); new SdlApplication(new Mindustry(), new SdlConfig(){{ title = "Mindustry"; diff --git a/ios/src/io/anuke/mindustry/IOSLauncher.java b/ios/src/io/anuke/mindustry/IOSLauncher.java index c8dcc9b510..4161d44017 100644 --- a/ios/src/io/anuke/mindustry/IOSLauncher.java +++ b/ios/src/io/anuke/mindustry/IOSLauncher.java @@ -26,8 +26,8 @@ public class IOSLauncher extends IOSApplication.Delegate{ @Override protected IOSApplication createApplication(){ - Net.setClientProvider(new MClient()); - Net.setServerProvider(new MServer()); + Net.setClientProvider(new ArcNetClient()); + Net.setServerProvider(new ArcNetServer()); if(UIDevice.getCurrentDevice().getUserInterfaceIdiom() == UIUserInterfaceIdiom.Pad){ UnitScl.dp.addition = 0.5f; diff --git a/net/src/io/anuke/mindustry/net/ArcNetClient.java b/net/src/io/anuke/mindustry/net/ArcNetClient.java new file mode 100644 index 0000000000..ffb40bb38f --- /dev/null +++ b/net/src/io/anuke/mindustry/net/ArcNetClient.java @@ -0,0 +1,189 @@ +package io.anuke.mindustry.net; + +import io.anuke.arc.*; +import io.anuke.arc.collection.*; +import io.anuke.arc.function.*; +import io.anuke.arc.net.*; +import io.anuke.arc.util.async.*; +import io.anuke.arc.util.pooling.*; +import io.anuke.mindustry.net.Net.*; +import io.anuke.mindustry.net.Packets.*; + +import java.io.*; +import java.net.*; +import java.nio.*; +import java.nio.channels.*; + +import static io.anuke.mindustry.Vars.*; + +public class ArcNetClient implements ClientProvider{ + final Client client; + final Supplier packetSupplier = () -> new DatagramPacket(new byte[256], 256); + + public ArcNetClient(){ + client = new Client(8192, 4096, new PacketSerializer()); + client.setDiscoveryPacket(packetSupplier); + + NetListener listener = new NetListener(){ + @Override + public void connected(Connection connection){ + Connect c = new Connect(); + c.addressTCP = connection.getRemoteAddressTCP().getAddress().getHostAddress(); + c.id = connection.getID(); + if(connection.getRemoteAddressTCP() != null) c.addressTCP = connection.getRemoteAddressTCP().toString(); + + Core.app.post(() -> Net.handleClientReceived(c)); + } + + @Override + public void disconnected(Connection connection){ + if(connection.getLastProtocolError() != null){ + netClient.setQuiet(); + } + + Disconnect c = new Disconnect(); + Core.app.post(() -> Net.handleClientReceived(c)); + } + + @Override + public void received(Connection connection, Object object){ + if(object instanceof FrameworkMessage) return; + + Core.app.post(() -> { + try{ + Net.handleClientReceived(object); + }catch(Exception e){ + handleException(e); + } + }); + + } + }; + + client.addListener(listener); + } + + private static boolean isLocal(InetAddress addr){ + if(addr.isAnyLocalAddress() || addr.isLoopbackAddress()) return true; + + try{ + return NetworkInterface.getByInetAddress(addr) != null; + }catch(Exception e){ + return false; + } + } + + @Override + public void connect(String ip, int port, Runnable success){ + Threads.daemon(() -> { + try{ + //just in case + client.stop(); + + Threads.daemon("Net Client", () -> { + try{ + client.run(); + }catch(Exception e){ + if(!(e instanceof ClosedSelectorException)) handleException(e); + } + }); + + client.connect(5000, ip, port, port); + success.run(); + }catch(Exception e){ + handleException(e); + } + }); + } + + @Override + public void disconnect(){ + client.close(); + } + + @Override + public void send(Object object, SendMode mode){ + try{ + if(mode == SendMode.tcp){ + client.sendTCP(object); + }else{ + client.sendUDP(object); + } + //sending things can cause an under/overflow, catch it and disconnect instead of crashing + }catch(BufferOverflowException | BufferUnderflowException e){ + Net.showError(e); + } + + Pools.free(object); + } + + @Override + public void updatePing(){ + client.updateReturnTripTime(); + } + + @Override + public int getPing(){ + return client.getReturnTripTime(); + } + + @Override + public void pingHost(String address, int port, Consumer valid, Consumer invalid){ + Threads.daemon(() -> { + try{ + DatagramSocket socket = new DatagramSocket(); + socket.send(new DatagramPacket(new byte[]{-2, 1}, 2, InetAddress.getByName(address), port)); + socket.setSoTimeout(2000); + + DatagramPacket packet = packetSupplier.get(); + socket.receive(packet); + + ByteBuffer buffer = ByteBuffer.wrap(packet.getData()); + Host host = NetworkIO.readServerData(packet.getAddress().getHostAddress(), buffer); + + Core.app.post(() -> valid.accept(host)); + }catch(Exception e){ + Core.app.post(() -> invalid.accept(e)); + } + }); + } + + @Override + public void discover(Consumer callback, Runnable done){ + Array foundAddresses = new Array<>(); + client.discoverHosts(port, multicastGroup, multicastPort, 3000, packet -> { + Core.app.post(() -> { + try{ + if(foundAddresses.contains(address -> address.equals(packet.getAddress()) || (isLocal(address) && isLocal(packet.getAddress())))){ + return; + } + ByteBuffer buffer = ByteBuffer.wrap(packet.getData()); + Host host = NetworkIO.readServerData(packet.getAddress().getHostAddress(), buffer); + callback.accept(host); + foundAddresses.add(packet.getAddress()); + }catch(Exception e){ + //don't crash when there's an error pinging a a server or parsing data + e.printStackTrace(); + } + }); + }, () -> Core.app.post(done)); + } + + @Override + public void dispose(){ + try{ + client.dispose(); + }catch(IOException e){ + throw new RuntimeException(e); + } + } + + private void handleException(Exception e){ + if(e instanceof ArcNetException){ + Core.app.post(() -> Net.showError(new IOException("mismatch"))); + }else{ + Core.app.post(() -> Net.showError(e)); + } + } + +} \ No newline at end of file diff --git a/net/src/io/anuke/mindustry/net/ArcNetServer.java b/net/src/io/anuke/mindustry/net/ArcNetServer.java new file mode 100644 index 0000000000..73002c51b2 --- /dev/null +++ b/net/src/io/anuke/mindustry/net/ArcNetServer.java @@ -0,0 +1,175 @@ +package io.anuke.mindustry.net; + +import io.anuke.arc.*; +import io.anuke.arc.net.*; +import io.anuke.arc.util.*; +import io.anuke.arc.util.async.*; +import io.anuke.mindustry.net.Net.*; +import io.anuke.mindustry.net.Packets.*; + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.util.concurrent.*; + +import static io.anuke.mindustry.Vars.*; + +public class ArcNetServer implements ServerProvider{ + final Server server; + final CopyOnWriteArrayList connections = new CopyOnWriteArrayList<>(); + Thread serverThread; + + public ArcNetServer(){ + server = new Server(4096 * 2, 4096, new PacketSerializer()); + server.setMulticast(multicastGroup, multicastPort); + server.setDiscoveryHandler((address, handler) -> { + ByteBuffer buffer = NetworkIO.writeServerData(); + buffer.position(0); + handler.respond(buffer); + }); + + NetListener listener = new NetListener(){ + + @Override + public void connected(Connection connection){ + String ip = connection.getRemoteAddressTCP().getAddress().getHostAddress(); + + ArcConnection kn = new ArcConnection(ip, connection); + + Connect c = new Connect(); + c.id = kn.id; + c.addressTCP = ip; + + Log.debug("&bRecieved connection: {0}", c.addressTCP); + + connections.add(kn); + Core.app.post(() -> Net.handleServerReceived(kn.id, c)); + } + + @Override + public void disconnected(Connection connection){ + ArcConnection k = getByKryoID(connection.getID()); + if(k == null) return; + + Disconnect c = new Disconnect(); + c.id = k.id; + + Core.app.post(() -> { + Net.handleServerReceived(k.id, c); + connections.remove(k); + }); + } + + @Override + public void received(Connection connection, Object object){ + ArcConnection k = getByKryoID(connection.getID()); + if(object instanceof FrameworkMessage || k == null) return; + + Core.app.post(() -> { + try{ + Net.handleServerReceived(k.id, object); + }catch(RuntimeException e){ + if(e.getCause() instanceof ValidateException){ + ValidateException v = (ValidateException)e.getCause(); + Log.err("Validation failed: {0} ({1})", v.player.name, v.getMessage()); + }else{ + e.printStackTrace(); + } + }catch(Exception e){ + e.printStackTrace(); + } + }); + } + }; + + server.addListener(listener); + } + + @Override + public Iterable getConnections(){ + return connections; + } + + @Override + public ArcConnection getByID(int id){ + for(int i = 0; i < connections.size(); i++){ + ArcConnection con = connections.get(i); + if(con.id == id){ + return con; + } + } + + return null; + } + + @Override + public void host(int port) throws IOException{ + connections.clear(); + server.bind(port, port); + + serverThread = new Thread(() -> { + try{ + server.run(); + }catch(Throwable e){ + if(!(e instanceof ClosedSelectorException)) Threads.throwAppException(e); + } + }, "Net Server"); + serverThread.setDaemon(true); + serverThread.start(); + } + + @Override + public void close(){ + connections.clear(); + Threads.daemon(server::stop); + } + + ArcConnection getByKryoID(int id){ + for(int i = 0; i < connections.size(); i++){ + ArcConnection con = connections.get(i); + if(con.connection != null && con.connection.getID() == id){ + return con; + } + } + + return null; + } + + class ArcConnection extends NetConnection{ + public final Connection connection; + + public ArcConnection(String address, Connection connection){ + super(address); + this.connection = connection; + } + + @Override + public boolean isConnected(){ + return connection.isConnected(); + } + + @Override + public void send(Object object, SendMode mode){ + try{ + if(mode == SendMode.tcp){ + connection.sendTCP(object); + }else{ + connection.sendUDP(object); + } + }catch(Exception e){ + Log.err(e); + Log.info("Error sending packet. Disconnecting invalid client!"); + connection.close(); + + ArcConnection k = getByKryoID(connection.getID()); + if(k != null) connections.remove(k); + } + } + + @Override + public void close(){ + if(connection.isConnected()) connection.close(); + } + } + +} \ No newline at end of file diff --git a/net/src/io/anuke/mindustry/net/MClient.java b/net/src/io/anuke/mindustry/net/MClient.java deleted file mode 100644 index af6ca3389c..0000000000 --- a/net/src/io/anuke/mindustry/net/MClient.java +++ /dev/null @@ -1,184 +0,0 @@ -package io.anuke.mindustry.net; - -import io.anuke.arc.*; -import io.anuke.arc.function.*; -import io.anuke.arc.util.async.*; -import io.anuke.arc.util.pooling.*; -import io.anuke.mindustry.game.EventType.*; -import io.anuke.mindustry.net.Net.*; -import io.anuke.mindustry.net.Packets.*; -import io.anuke.mnet.*; - -import java.io.*; -import java.net.*; -import java.nio.*; -import java.util.*; - -import static io.anuke.mindustry.Vars.*; - -public class MClient implements ClientProvider, ApplicationListener{ - MSocket socket; - - public MClient(){ - Events.on(AppLoadEvent.class, event -> Core.app.addListener(this)); - } - - public void connect(String ip, int port, Runnable success) throws IOException{ - socket = new MSocket(InetAddress.getByName(ip), port, PacketSerializer::new); - socket.addDcListener((sock, reason) -> Core.app.post(() -> Net.handleClientReceived(new Disconnect()))); - socket.connectAsync(null, 2000, response -> { - if(response.getType() == ResponseType.ACCEPTED){ - Core.app.post(() -> { - success.run(); - Connect c = new Connect(); - c.addressTCP = ip; - Net.handleClientReceived(c); - }); - }else if(response.getType() == ResponseType.WRONG_STATE){ - Core.app.post(() -> Net.showError(new IOException("alreadyconnected"))); - }else{ - Core.app.post(() -> Net.showError(new IOException("connection refused"))); - } - }); - } - - @Override - public void update(){ - if(socket == null) return; - - try{ - socket.update((sock, object) -> { - try{ - Net.handleClientReceived(object); - }catch(Exception e){ - Net.showError(e); - netClient.disconnectQuietly(); - } - }); - }catch(Exception e){ - Net.showError(e); - netClient.disconnectQuietly(); - } - } - - @Override - public void updatePing(){ - - } - - @Override - public void dispose(){ - disconnect(); - } - - public void send(Object object, SendMode mode){ - if(mode == SendMode.tcp){ - socket.send(object); - }else{ - socket.sendUnreliable(object); - } - - Pools.free(object); - } - - public int getPing(){ - return socket == null ? 0 : (int)socket.getPing(); - } - - public void disconnect(){ - if(socket != null) socket.close(); - } - - public void discover(Consumer callback, Runnable done){ - Threads.daemon(() -> { - byte[] bytes = new byte[512]; - ByteBuffer buffer = ByteBuffer.wrap(bytes); - DatagramPacket packet = new DatagramPacket(bytes, bytes.length); - ArrayList foundAddresses = new ArrayList<>(); - - try(DatagramSocket socket = new DatagramSocket()){ - broadcast(port, socket); - - socket.setSoTimeout(4000); - - outer: - while(true){ - - try{ - socket.receive(packet); - }catch(SocketTimeoutException ex){ - done.run(); - return; - } - - buffer.position(0); - - InetAddress address = ((InetSocketAddress)packet.getSocketAddress()).getAddress(); - - for(InetAddress other : foundAddresses){ - if(other.equals(address) || (isLocal(other) && isLocal(address))){ - continue outer; - } - } - - Host host = NetworkIO.readServerData(address.getHostName(), buffer); - callback.accept(host); - foundAddresses.add(address); - } - }catch(IOException ex){ - done.run(); - } - }); - } - - public void pingHost(String address, int port, Consumer valid, Consumer failed){ - Threads.daemon(() -> { - try{ - DatagramPacket packet = new DatagramPacket(new byte[512], 512); - - DatagramSocket socket = new DatagramSocket(); - socket.send(new DatagramPacket(new byte[]{-2}, 1, InetAddress.getByName(address), port)); - socket.setSoTimeout(4000); - socket.receive(packet); - - ByteBuffer buffer = ByteBuffer.wrap(packet.getData()); - Host host = NetworkIO.readServerData(packet.getAddress().getHostAddress(), buffer); - - Core.app.post(() -> valid.accept(host)); - }catch(Exception e){ - Core.app.post(() -> failed.accept(e)); - } - }); - } - private void broadcast (int udpPort, DatagramSocket socket) throws IOException{ - byte[] data = {-2}; - - for (NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())){ - for (InetAddress address : Collections.list(iface.getInetAddresses())){ - - byte[] ip = address.getAddress(); //255.255.255.255 - try{ - socket.send(new DatagramPacket(data, data.length, InetAddress.getByAddress(ip), udpPort)); - }catch (Exception ignored){} - ip[3] = -1; //255.255.255.0 - try{ - socket.send(new DatagramPacket(data, data.length, InetAddress.getByAddress(ip), udpPort)); - }catch (Exception ignored){} - ip[2] = -1; //255.255.0.0 - try{ - socket.send(new DatagramPacket(data, data.length, InetAddress.getByAddress(ip), udpPort)); - }catch (Exception ignored){} - } - } - } - - private boolean isLocal(InetAddress addr) { - if (addr.isAnyLocalAddress() || addr.isLoopbackAddress()) return true; - - try { - return NetworkInterface.getByInetAddress(addr) != null; - } catch (Exception e) { - return false; - } - } -} diff --git a/net/src/io/anuke/mindustry/net/MServer.java b/net/src/io/anuke/mindustry/net/MServer.java deleted file mode 100644 index 80c21cd285..0000000000 --- a/net/src/io/anuke/mindustry/net/MServer.java +++ /dev/null @@ -1,127 +0,0 @@ -package io.anuke.mindustry.net; - -import io.anuke.arc.*; -import io.anuke.arc.util.*; -import io.anuke.mindustry.game.EventType.*; -import io.anuke.mindustry.net.Net.*; -import io.anuke.mindustry.net.Packets.*; -import io.anuke.mnet.*; - -import java.io.*; -import java.net.*; -import java.nio.*; -import java.util.concurrent.*; - -public class MServer implements ServerProvider, ApplicationListener{ - final CopyOnWriteArrayList connections = new CopyOnWriteArrayList<>(); - MServerSocket socket; - - public MServer(){ - Events.on(AppLoadEvent.class, event -> Core.app.addListener(this)); - } - - @Override - public void update(){ - if(socket == null) return; - - socket.update(); - for(MSocket socket : socket.getSockets()){ - MConnectionImpl c = socket.getUserData(); - socket.update((s, msg) -> Core.app.post(() -> { - try{ - Net.handleServerReceived(c.id, msg); - }catch(Exception e){ - e.printStackTrace(); - } - })); - } - } - - @Override - public void host(int port) throws IOException{ - close(); - - socket = new MServerSocket(port, con -> { - MSocket sock = con.accept(null); - - MConnectionImpl kn = new MConnectionImpl(sock); - sock.setUserData(kn); - - String ip = sock.getRemoteAddress().getHostAddress(); - - Connect c = new Connect(); - c.id = kn.id; - c.addressTCP = ip; - - Log.info("&bRecieved connection: {0} / {1}", c.id, c.addressTCP); - - connections.add(kn); - Core.app.post(() -> Net.handleServerReceived(kn.id, c)); - - sock.addDcListener((socket, message) -> { - Log.info("&bLost connection {0}. Reason: {1}", kn.id, message); - - Disconnect dc = new Disconnect(); - dc.id = kn.id; - - Core.app.post(() -> { - Net.handleServerReceived(kn.id, dc); - connections.remove(kn); - }); - }); - }, PacketSerializer::new, () -> { - ByteBuffer buf = NetworkIO.writeServerData(); - byte[] bytes = buf.array(); - return new DatagramPacket(bytes, bytes.length); - }); - - connections.clear(); - } - - @Override - public void close(){ - if(socket != null){ - socket.close(); - socket = null; - } - } - - @Override - public Iterable getConnections(){ - return connections; - } - - @Override - public MConnectionImpl getByID(int id){ - for(MConnectionImpl n : connections){ - if(n.id == id){ - return n; - } - } - return null; - } - - class MConnectionImpl extends NetConnection{ - private final MSocket sock; //sock. - - public MConnectionImpl(MSocket con){ - super(con.getRemoteAddress().getHostAddress()); - this.sock = con; - } - - @Override - public void send(Object object, SendMode mode){ - if(mode == SendMode.tcp){ - sock.send(object); - }else{ - sock.sendUnreliable(object); - } - - } - - @Override - public void close(){ - sock.close(); - } - } -} diff --git a/net/src/io/anuke/mindustry/net/PacketSerializer.java b/net/src/io/anuke/mindustry/net/PacketSerializer.java index 8865551198..a101af5145 100644 --- a/net/src/io/anuke/mindustry/net/PacketSerializer.java +++ b/net/src/io/anuke/mindustry/net/PacketSerializer.java @@ -1,80 +1,87 @@ package io.anuke.mindustry.net; import io.anuke.arc.function.*; +import io.anuke.arc.net.*; +import io.anuke.arc.net.FrameworkMessage.*; import io.anuke.arc.util.pooling.*; -import io.anuke.mnet.*; import java.nio.*; -import java.util.*; @SuppressWarnings("unchecked") -public class PacketSerializer implements MSerializer{ - private ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024 * 8); +public class PacketSerializer implements NetSerializer{ + @Override public void write(ByteBuffer byteBuffer, Object o){ - if(o == null){ - byteBuffer.put((byte)-1); - return; + if(o instanceof FrameworkMessage){ + byteBuffer.put((byte)-2); //code for framework message + writeFramework(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: " + o.getClass()); + byteBuffer.put(id); + ((Packet)o).write(byteBuffer); } - - 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: " + o.getClass()); - byteBuffer.put(id); - ((Packet) o).write(byteBuffer); } + @Override public Object read(ByteBuffer byteBuffer){ byte id = byteBuffer.get(); - if(id == -1){ - return null; + if(id == -2){ + return readFramework(byteBuffer); + }else{ + Packet packet = Pools.obtain((Class)Registrator.getByID(id).type, (Supplier)Registrator.getByID(id).constructor); + packet.read(byteBuffer); + return packet; } - Packet packet = Pools.obtain((Class) Registrator.getByID(id).type, (Supplier) Registrator.getByID(id).constructor); - packet.read(byteBuffer); - return packet; } - @Override - public byte[] serialize(Object o){ - buffer.position(0); - write(buffer, o); - return Arrays.copyOfRange(buffer.array(), 0, buffer.position()); + + public static void writeFramework(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){ + buffer.put((byte)1); + }else if(message instanceof KeepAlive){ + 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); + } } - @Override - public byte[] serialize(Object o, int offset){ - buffer.position(0); - write(buffer, o); - int length = buffer.position(); - byte[] bytes = new byte[length + offset]; - System.arraycopy(buffer.array(), 0, bytes, offset, length); - return bytes; - } + public static FrameworkMessage readFramework(ByteBuffer buffer){ + byte id = buffer.get(); - @Override - public int serialize(Object o, byte[] bytes, int offset){ - buffer.position(0); - write(buffer, o); - int length = buffer.position(); - System.arraycopy(buffer.array(), 0, bytes, offset, length); - return length; - } - - @Override - public Object deserialize(byte[] bytes){ - buffer.position(0); - buffer.put(bytes); - buffer.position(0); - return read(buffer); - } - - @Override - public Object deserialize(byte[] bytes, int offset, int length){ - buffer.position(0); - buffer.put(bytes, offset, length); - buffer.position(0); - return read(buffer); + if(id == 0){ + Ping p = new Ping(); + p.id = buffer.getInt(); + p.isReply = buffer.get() == 1; + return p; + }else if(id == 1){ + return new DiscoverHost(); + }else if(id == 2){ + return new KeepAlive(); + }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!"); + } } } diff --git a/server/src/io/anuke/mindustry/server/ServerLauncher.java b/server/src/io/anuke/mindustry/server/ServerLauncher.java index fdcbd5a61b..06f842c418 100644 --- a/server/src/io/anuke/mindustry/server/ServerLauncher.java +++ b/server/src/io/anuke/mindustry/server/ServerLauncher.java @@ -8,8 +8,8 @@ public class ServerLauncher{ public static void main(String[] args){ try{ - Net.setClientProvider(new MClient()); - Net.setServerProvider(new MServer()); + Net.setClientProvider(new ArcNetClient()); + Net.setServerProvider(new ArcNetServer()); new HeadlessApplication(new MindustryServer(args), null, throwable -> CrashSender.send(throwable, f -> {})); }catch(Throwable t){ CrashSender.send(t, f -> {}); diff --git a/settings.gradle b/settings.gradle index 3254492e18..41b5080058 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,7 +26,7 @@ if(!hasProperty("release")){ use(':Arc:extensions') use(':Arc:extensions:freetype') use(':Arc:extensions:recorder') - use(':Arc:extensions:mnet') + use(':Arc:extensions:arcnet') use(':Arc:extensions:packer') use(':Arc:backends') use(':Arc:backends:backend-sdl')