1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-09-17 11:27:35 +03:00

Modularized Kryonet handler

This commit is contained in:
Anuken 2018-01-01 13:32:18 -05:00
parent 4bf78587db
commit c7dbdd1773
8 changed files with 269 additions and 450 deletions

View File

@ -5,33 +5,19 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.utils.IntArray;
import com.esotericsoftware.kryonet.*;
import com.esotericsoftware.kryonet.util.InputStreamSender;
import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.io.PlatformFunction;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.ClientProvider;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Net.ServerProvider;
import io.anuke.mindustry.net.Packets.Connect;
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.function.Callable;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.layout.Unit;
import java.io.IOException;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class AndroidLauncher extends AndroidApplication{
@ -78,212 +64,8 @@ public class AndroidLauncher extends AndroidApplication{
config.hideStatusBar = true;
Net.setClientProvider(new ClientProvider() {
Client client;
{
client = new Client();
client.start();
client.addListener(new Listener(){
@Override
public void connected (Connection connection) {
Connect c = new Connect();
c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString();
Net.handleClientReceived(c);
}
@Override
public void disconnected (Connection connection) {
Disconnect c = new Disconnect();
Net.handleClientReceived(c);
}
@Override
public void received (Connection connection, Object object) {
if(object instanceof FrameworkMessage) return;
try{
Net.handleClientReceived(object);
}catch (Exception e){
Gdx.app.exit();
throw new RuntimeException(e);
}
}
});
register(Registrator.getClasses());
}
@Override
public void connect(String ip, int port) throws IOException {
client.connect(5000, ip, port, port);
}
@Override
public void disconnect() {
client.close();
}
@Override
public void send(Object object, SendMode mode) {
if(mode == SendMode.tcp){
client.sendTCP(object);
}else{
client.sendUDP(object);
}
}
@Override
public void updatePing() {
client.updateReturnTripTime();
}
@Override
public int getPing() {
return client.getReturnTripTime();
}
@Override
public void register(Class<?>... types) {
for(Class<?> c : types){
client.getKryo().register(c);
}
}
});
Net.setServerProvider(new ServerProvider() {
Server server;
IntArray connections = new IntArray();
{
server = new Server();
Thread thread = new Thread(server, "Kryonet Server");
thread.setDaemon(true);
thread.start();
server.addListener(new Listener(){
@Override
public void connected (Connection connection) {
Connect c = new Connect();
c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString();
Net.handleServerReceived(c, c.id);
connections.add(c.id);
}
@Override
public void disconnected (Connection connection) {
Disconnect c = new Disconnect();
c.id = connection.getID();
Net.handleServerReceived(c, c.id);
connections.removeValue(c.id);
}
@Override
public void received (Connection connection, Object object) {
if(object instanceof FrameworkMessage) return;
try{
Net.handleServerReceived(object, connection.getID());
}catch (Exception e){
Gdx.app.exit();
throw new RuntimeException(e);
}
}
});
register(Registrator.getClasses());
}
@Override
public IntArray getConnections() {
return connections;
}
@Override
public void host(int port) throws IOException {
server.bind(port, port);
}
@Override
public void 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
public void send(Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToAllTCP(object);
}else{
server.sendToAllUDP(object);
}
}
@Override
public void sendTo(int id, Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToTCP(id, object);
}else{
server.sendToUDP(id, object);
}
}
@Override
public void sendExcept(int id, Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToAllExceptTCP(id, object);
}else{
server.sendToAllExceptUDP(id, object);
}
}
@Override
public void register(Class<?>... types) {
for(Class<?> c : types){
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()));
}
});
Net.setClientProvider(new KryoClient());
Net.setServerProvider(new KryoServer());
initialize(new Mindustry(), config);
}

View File

@ -38,10 +38,10 @@ project(":desktop") {
dependencies {
compile project(":core")
compile project(":kryonet")
compile "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
compile "com.badlogicgames.gdx:gdx-controllers-lwjgl3:$gdxVersion"
compile "com.esotericsoftware:kryonet:2.22.0-RC1"
}
}
@ -70,6 +70,7 @@ project(":android") {
dependencies {
compile project(":core")
compile project(":kryonet")
compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
@ -78,7 +79,6 @@ project(":android") {
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
compile "com.badlogicgames.gdx:gdx-controllers-android:$gdxVersion"
compile "com.esotericsoftware:kryonet:2.22.0-RC1"
}
}
@ -109,6 +109,15 @@ project(":core") {
}
}
project(":kryonet") {
apply plugin: "java"
dependencies {
compile project(":core")
compile "com.esotericsoftware:kryonet:2.22.0-RC1"
}
}
tasks.eclipse.doLast {
delete ".project"
}

View File

@ -75,7 +75,7 @@ public class NetClient extends Module {
Net.handle(EntityDataPacket.class, data -> {
Gdx.app.postRunnable(() -> {
Timers.run(10f, () -> { //TODO hack
Timers.run(10f, () -> { //TODO hack. should only run once world data is recieved
Vars.control.playerGroup.remap(Vars.player, data.playerid);
for (Player player : data.players) {

View File

@ -1,27 +1,15 @@
package io.anuke.mindustry.desktop;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntArray;
import com.esotericsoftware.kryonet.*;
import com.esotericsoftware.kryonet.util.InputStreamSender;
import com.esotericsoftware.minlog.Log;
import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.Mindustry;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.io.PlatformFunction;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.ClientProvider;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Net.ServerProvider;
import io.anuke.mindustry.net.Packets.Connect;
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 java.awt.*;
@ -30,7 +18,6 @@ import java.net.URI;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class DesktopLauncher {
@ -67,221 +54,15 @@ public class DesktopLauncher {
}
@Override
public void addDialog(TextField field){
}
public void addDialog(TextField field){ }
};
Mindustry.args = Array.with(arg);
Log.set(Log.LEVEL_DEBUG);
Net.setClientProvider(new ClientProvider() {
Client client;
{
client = new Client();
client.start();
client.addListener(new Listener(){
@Override
public void connected (Connection connection) {
Connect c = new Connect();
c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString();
Net.handleClientReceived(c);
}
@Override
public void disconnected (Connection connection) {
Disconnect c = new Disconnect();
Net.handleClientReceived(c);
}
@Override
public void received (Connection connection, Object object) {
if(object instanceof FrameworkMessage) return;
try{
Net.handleClientReceived(object);
}catch (Exception e){
Gdx.app.exit();
throw new RuntimeException(e);
}
}
});
register(Registrator.getClasses());
}
@Override
public void connect(String ip, int port) throws IOException {
client.connect(5000, ip, port, port);
}
@Override
public void disconnect() {
client.close();
}
@Override
public void send(Object object, SendMode mode) {
if(mode == SendMode.tcp){
client.sendTCP(object);
}else{
client.sendUDP(object);
}
}
@Override
public void updatePing() {
client.updateReturnTripTime();
}
@Override
public int getPing() {
return client.getReturnTripTime();
}
@Override
public void register(Class<?>... types) {
for(Class<?> c : types){
client.getKryo().register(c);
}
}
});
Net.setServerProvider(new ServerProvider() {
Server server;
IntArray connections = new IntArray();
{
server = new Server();
Thread thread = new Thread(server, "Kryonet Server");
thread.setDaemon(true);
thread.start();
server.addListener(new Listener(){
@Override
public void connected (Connection connection) {
Connect c = new Connect();
c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString();
Net.handleServerReceived(c, c.id);
connections.add(c.id);
}
@Override
public void disconnected (Connection connection) {
Disconnect c = new Disconnect();
c.id = connection.getID();
Net.handleServerReceived(c, c.id);
connections.removeValue(c.id);
}
@Override
public void received (Connection connection, Object object) {
if(object instanceof FrameworkMessage) return;
try{
Net.handleServerReceived(object, connection.getID());
}catch (Exception e){
Gdx.app.exit();
throw new RuntimeException(e);
}
}
});
register(Registrator.getClasses());
}
@Override
public IntArray getConnections() {
return connections;
}
@Override
public void host(int port) throws IOException {
server.bind(port, port);
}
@Override
public void 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
public void send(Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToAllTCP(object);
}else{
server.sendToAllUDP(object);
}
}
@Override
public void sendTo(int id, Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToTCP(id, object);
}else{
server.sendToUDP(id, object);
}
}
@Override
public void sendExcept(int id, Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToAllExceptTCP(id, object);
}else{
server.sendToAllExceptUDP(id, object);
}
}
@Override
public void register(Class<?>... types) {
for(Class<?> c : types){
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()));
}
});
Net.setClientProvider(new KryoClient());
Net.setServerProvider(new KryoServer());
new Lwjgl3Application(new Mindustry(), config);
}

4
kryonet/build.gradle Normal file
View File

@ -0,0 +1,4 @@
apply plugin: "java"
sourceCompatibility = 1.8
sourceSets.main.java.srcDirs = [ "src/" ]

View File

@ -0,0 +1,90 @@
package io.anuke.kryonet;
import com.badlogic.gdx.Gdx;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.FrameworkMessage;
import com.esotericsoftware.kryonet.Listener;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.ClientProvider;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.Connect;
import io.anuke.mindustry.net.Packets.Disconnect;
import io.anuke.mindustry.net.Registrator;
import java.io.IOException;
public class KryoClient implements ClientProvider{
Client client;
public KryoClient(){
client = new Client();
client.start();
client.addListener(new Listener(){
@Override
public void connected (Connection connection) {
Connect c = new Connect();
c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString();
Net.handleClientReceived(c);
}
@Override
public void disconnected (Connection connection) {
Disconnect c = new Disconnect();
Net.handleClientReceived(c);
}
@Override
public void received (Connection connection, Object object) {
if(object instanceof FrameworkMessage) return;
try{
Net.handleClientReceived(object);
}catch (Exception e){
Gdx.app.exit();
throw new RuntimeException(e);
}
}
});
register(Registrator.getClasses());
}
@Override
public void connect(String ip, int port) throws IOException {
client.connect(5000, ip, port, port);
}
@Override
public void disconnect() {
client.close();
}
@Override
public void send(Object object, SendMode mode) {
if(mode == SendMode.tcp){
client.sendTCP(object);
}else{
client.sendUDP(object);
}
}
@Override
public void updatePing() {
client.updateReturnTripTime();
}
@Override
public int getPing() {
return client.getReturnTripTime();
}
@Override
public void register(Class<?>... types) {
for(Class<?> c : types){
client.getKryo().register(c);
}
}
}

View File

@ -0,0 +1,153 @@
package io.anuke.kryonet;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.IntArray;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.FrameworkMessage;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.kryonet.util.InputStreamSender;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Net.ServerProvider;
import io.anuke.mindustry.net.Packets.Connect;
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 java.io.IOException;
import java.util.Arrays;
public class KryoServer implements ServerProvider {
Server server;
IntArray connections = new IntArray();
public KryoServer(){
server = new Server();
Thread thread = new Thread(server, "Kryonet Server");
thread.setDaemon(true);
thread.start();
server.addListener(new Listener(){
@Override
public void connected (Connection connection) {
Connect c = new Connect();
c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString();
Net.handleServerReceived(c, c.id);
connections.add(c.id);
}
@Override
public void disconnected (Connection connection) {
Disconnect c = new Disconnect();
c.id = connection.getID();
Net.handleServerReceived(c, c.id);
connections.removeValue(c.id);
}
@Override
public void received (Connection connection, Object object) {
if(object instanceof FrameworkMessage) return;
try{
Net.handleServerReceived(object, connection.getID());
}catch (Exception e){
Gdx.app.exit();
throw new RuntimeException(e);
}
}
});
register(Registrator.getClasses());
}
@Override
public IntArray getConnections() {
return connections;
}
@Override
public void host(int port) throws IOException {
server.bind(port, port);
}
@Override
public void 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
public void send(Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToAllTCP(object);
}else{
server.sendToAllUDP(object);
}
}
@Override
public void sendTo(int id, Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToTCP(id, object);
}else{
server.sendToUDP(id, object);
}
}
@Override
public void sendExcept(int id, Object object, SendMode mode) {
if(mode == SendMode.tcp){
server.sendToAllExceptTCP(id, object);
}else{
server.sendToAllExceptUDP(id, object);
}
}
@Override
public void register(Class<?>... types) {
for(Class<?> c : types){
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()));
}
}

View File

@ -1,4 +1,4 @@
include 'desktop', 'html', 'core', 'android'
include 'desktop', 'html', 'core', 'android', 'kryonet'
if(System.properties["release"] == null || System.properties["release"].equals("false")){
if (new File(settingsDir, '../uCore').exists()) {