Non-blocking connect / Localized connect error messages
This commit is contained in:
@@ -77,7 +77,6 @@ text.unlocked = New Block Unlocked\!
|
|||||||
text.unlocked.plural = New Blocks Unlocked\!
|
text.unlocked.plural = New Blocks Unlocked\!
|
||||||
text.players = {0} players online
|
text.players = {0} players online
|
||||||
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.closing = [accent]Closing server...
|
text.server.closing = [accent]Closing server...
|
||||||
text.server.kicked.kick = You have been kicked from the server\!
|
text.server.kicked.kick = You have been kicked from the server\!
|
||||||
text.server.kicked.serverClose = Server closed.
|
text.server.kicked.serverClose = Server closed.
|
||||||
@@ -137,7 +136,6 @@ text.disconnect = Disconnected.
|
|||||||
text.disconnect.data = Failed to load world data\!
|
text.disconnect.data = Failed to load world data\!
|
||||||
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.server.port = Port\:
|
text.server.port = Port\:
|
||||||
text.server.addressinuse = Address already in use\!
|
text.server.addressinuse = Address already in use\!
|
||||||
text.server.invalidport = Invalid port number\!
|
text.server.invalidport = Invalid port number\!
|
||||||
@@ -262,6 +260,14 @@ text.tutorial = Tutorial
|
|||||||
text.editor = Editor
|
text.editor = Editor
|
||||||
text.mapeditor = Map Editor
|
text.mapeditor = Map Editor
|
||||||
text.donate = Donate
|
text.donate = Donate
|
||||||
|
|
||||||
|
text.connectfail = [crimson]Failed to connect to server\:\n\n[accent]{0}
|
||||||
|
text.error.unreachable = Server unreachable.
|
||||||
|
text.error.invalidaddress = Invalid address.
|
||||||
|
text.error.timedout = Timed out!\nMake sure the host has port forwarding set up, and that the address is correct!
|
||||||
|
text.error.mismatch = Packet error:\npossible client/server version mismatch.\nMake sure you and the host have the latest version of Mindustry!
|
||||||
|
text.error.any = Unkown network error.
|
||||||
|
|
||||||
text.settings.language = Language
|
text.settings.language = Language
|
||||||
text.settings.reset = Reset to Defaults
|
text.settings.reset = Reset to Defaults
|
||||||
text.settings.rebind = Rebind
|
text.settings.rebind = Rebind
|
||||||
|
|||||||
@@ -269,10 +269,9 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void notifyPlaced(BuildEntity entity, boolean isBreaking){
|
private void notifyPlaced(BuildEntity entity, boolean isBreaking){
|
||||||
float timeToBuild = entity.buildCost;
|
|
||||||
float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0);
|
float dist = Math.min(entity.distanceTo(x, y) - placeDistance, 0);
|
||||||
|
|
||||||
if(!state.is(build) && dist / type.maxVelocity < timeToBuild * 0.9f){
|
if(!state.is(build) && dist / type.maxVelocity < entity.buildCost * 0.9f){
|
||||||
target = entity;
|
target = entity;
|
||||||
this.isBreaking = isBreaking;
|
this.isBreaking = isBreaking;
|
||||||
setState(build);
|
setState(build);
|
||||||
|
|||||||
@@ -17,13 +17,14 @@ import io.anuke.mindustry.net.Streamable.StreamBuilder;
|
|||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.function.BiConsumer;
|
import io.anuke.ucore.function.BiConsumer;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
|
import io.anuke.ucore.util.Bundles;
|
||||||
import io.anuke.ucore.util.Log;
|
import io.anuke.ucore.util.Log;
|
||||||
import io.anuke.ucore.util.Pooling;
|
import io.anuke.ucore.util.Pooling;
|
||||||
|
import io.anuke.ucore.util.Threads;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.headless;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
import static io.anuke.mindustry.Vars.ui;
|
|
||||||
|
|
||||||
public class Net{
|
public class Net{
|
||||||
private static boolean server;
|
private static boolean server;
|
||||||
@@ -46,15 +47,41 @@ public class Net{
|
|||||||
return serverProvider != null;
|
return serverProvider != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**Display a network error. Call on the graphics thread.*/
|
||||||
* Display a network error.
|
public static void showError(Throwable e){
|
||||||
*/
|
|
||||||
public static void showError(String text){
|
|
||||||
if(!headless){
|
if(!headless){
|
||||||
ui.showError(text);
|
Threads.assertGraphics();
|
||||||
}else{
|
|
||||||
Log.err(text);
|
Throwable t = e;
|
||||||
|
while(t.getCause() != null){
|
||||||
|
t = t.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
|
||||||
|
String type = error.getClass().toString().toLowerCase();
|
||||||
|
|
||||||
|
if(error.equals("mismatch")){
|
||||||
|
error = Bundles.get("text.error.mismatch");
|
||||||
|
}else if(error.contains("port out of range") || error.contains("invalid argument") || (error.contains("invalid") && error.contains("address"))){
|
||||||
|
error = Bundles.get("text.error.invalidaddress");
|
||||||
|
}else if(error.contains("connection refused") || error.contains("route to host") || type.contains("unknownhost")){
|
||||||
|
error = Bundles.get("text.error.unreachable");
|
||||||
|
}else if(type.contains("timeout")){
|
||||||
|
error = Bundles.get("text.error.timeout");
|
||||||
|
}else if(!error.isEmpty()){
|
||||||
|
error = Bundles.get("text.error.any");
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.showText("", Bundles.format("text.connectfail", error));
|
||||||
|
ui.loadfrag.hide();
|
||||||
|
|
||||||
|
if(Net.client()){
|
||||||
|
netClient.disconnectQuietly();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,14 +104,18 @@ public class Net{
|
|||||||
/**
|
/**
|
||||||
* 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, Runnable success){
|
||||||
lastIP = ip + ":" + port;
|
try{
|
||||||
if(!active){
|
lastIP = ip + ":" + port;
|
||||||
clientProvider.connect(ip, port);
|
if(!active){
|
||||||
active = true;
|
clientProvider.connect(ip, port, success);
|
||||||
server = false;
|
active = true;
|
||||||
}else{
|
server = false;
|
||||||
throw new IOException("Already connected!");
|
}else{
|
||||||
|
throw new IOException("Already connected!");
|
||||||
|
}
|
||||||
|
}catch(IOException e){
|
||||||
|
showError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +377,7 @@ public class Net{
|
|||||||
/**Client implementation.*/
|
/**Client implementation.*/
|
||||||
public interface ClientProvider{
|
public interface ClientProvider{
|
||||||
/**Connect to a server.*/
|
/**Connect to a server.*/
|
||||||
void connect(String ip, int port) throws IOException;
|
void connect(String ip, int port, Runnable success) throws IOException;
|
||||||
|
|
||||||
/**Send an object to the server.*/
|
/**Send an object to the server.*/
|
||||||
void send(Object object, SendMode mode);
|
void send(Object object, SendMode mode);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import io.anuke.ucore.scene.ui.layout.Cell;
|
|||||||
import io.anuke.ucore.scene.ui.layout.Table;
|
import io.anuke.ucore.scene.ui.layout.Table;
|
||||||
import io.anuke.ucore.scene.utils.UIUtils;
|
import io.anuke.ucore.scene.utils.UIUtils;
|
||||||
import io.anuke.ucore.util.Bundles;
|
import io.anuke.ucore.util.Bundles;
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
import io.anuke.ucore.util.Strings;
|
import io.anuke.ucore.util.Strings;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
@@ -300,34 +299,11 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
});
|
});
|
||||||
|
|
||||||
Timers.runTask(2f, () -> {
|
Timers.runTask(2f, () -> {
|
||||||
try{
|
Vars.netClient.beginConnecting();
|
||||||
Vars.netClient.beginConnecting();
|
Net.connect(ip, port, () -> {
|
||||||
Net.connect(ip, port);
|
|
||||||
hide();
|
hide();
|
||||||
add.hide();
|
add.hide();
|
||||||
}catch(Exception e){
|
});
|
||||||
Throwable t = e;
|
|
||||||
while(t.getCause() != null){
|
|
||||||
t = t.getCause();
|
|
||||||
}
|
|
||||||
//TODO localize
|
|
||||||
String error = t.getMessage() == null ? "" : t.getMessage().toLowerCase();
|
|
||||||
if(error.contains("connection refused")){
|
|
||||||
error = "connection refused";
|
|
||||||
}else if(error.contains("port out of range")){
|
|
||||||
error = "invalid port!";
|
|
||||||
}else if(error.contains("invalid argument")){
|
|
||||||
error = "invalid IP or port!";
|
|
||||||
}else if(t.getClass().toString().toLowerCase().contains("sockettimeout")){
|
|
||||||
error = "timed out!\nmake sure the host has port forwarding set up,\nand that the address is correct!";
|
|
||||||
}else{
|
|
||||||
error = Strings.parseException(e, false);
|
|
||||||
}
|
|
||||||
ui.showError(Bundles.format("text.connectfail", error));
|
|
||||||
ui.loadfrag.hide();
|
|
||||||
|
|
||||||
Log.err(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package io.anuke.kryonet;
|
|||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.esotericsoftware.kryonet.*;
|
import com.esotericsoftware.kryonet.*;
|
||||||
import com.esotericsoftware.minlog.Log;
|
|
||||||
import io.anuke.mindustry.net.Host;
|
import io.anuke.mindustry.net.Host;
|
||||||
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;
|
||||||
@@ -13,12 +12,14 @@ import io.anuke.mindustry.net.Packets.Connect;
|
|||||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
import io.anuke.mindustry.net.Packets.Disconnect;
|
||||||
import io.anuke.ucore.function.Consumer;
|
import io.anuke.ucore.function.Consumer;
|
||||||
import io.anuke.ucore.util.Pooling;
|
import io.anuke.ucore.util.Pooling;
|
||||||
import io.anuke.ucore.util.Strings;
|
|
||||||
import net.jpountz.lz4.LZ4Factory;
|
import net.jpountz.lz4.LZ4Factory;
|
||||||
import net.jpountz.lz4.LZ4FastDecompressor;
|
import net.jpountz.lz4.LZ4FastDecompressor;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ClosedSelectorException;
|
import java.nio.channels.ClosedSelectorException;
|
||||||
|
|
||||||
@@ -75,10 +76,12 @@ public class KryoClient implements ClientProvider{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnected (Connection connection) {
|
public void disconnected (Connection connection) {
|
||||||
Disconnect c = new Disconnect();
|
if(connection.getLastProtocolError() != null){
|
||||||
|
netClient.setQuiet();
|
||||||
|
}
|
||||||
|
|
||||||
|
Disconnect c = new Disconnect();
|
||||||
threads.runDelay(() -> Net.handleClientReceived(c));
|
threads.runDelay(() -> Net.handleClientReceived(c));
|
||||||
if(connection.getLastProtocolError() != null) Log.error("\n\n\n\nProtocol error: " + connection.getLastProtocolError() + "\n\n\n\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -89,13 +92,7 @@ public class KryoClient implements ClientProvider{
|
|||||||
try{
|
try{
|
||||||
Net.handleClientReceived(object);
|
Net.handleClientReceived(object);
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
e.printStackTrace();
|
handleException(e);
|
||||||
if(e instanceof KryoNetException && e.getMessage() != null && e.getMessage().toLowerCase().contains("incorrect")) {
|
|
||||||
Net.showError("$text.server.mismatch");
|
|
||||||
netClient.disconnectQuietly();
|
|
||||||
}else{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -128,21 +125,28 @@ public class KryoClient implements ClientProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connect(String ip, int port) throws IOException {
|
public void connect(String ip, int port, Runnable success){
|
||||||
//just in case
|
runAsync(() -> {
|
||||||
client.stop();
|
|
||||||
|
|
||||||
Thread updateThread = new Thread(() -> {
|
|
||||||
try{
|
try{
|
||||||
client.run();
|
//just in case
|
||||||
}catch (Exception e){
|
client.stop();
|
||||||
if(!(e instanceof ClosedSelectorException)) handleException(e);
|
|
||||||
}
|
|
||||||
}, "Kryonet Client");
|
|
||||||
updateThread.setDaemon(true);
|
|
||||||
updateThread.start();
|
|
||||||
|
|
||||||
client.connect(5000, ip, port, port);
|
Thread updateThread = new Thread(() -> {
|
||||||
|
try{
|
||||||
|
client.run();
|
||||||
|
}catch(Exception e){
|
||||||
|
if(!(e instanceof ClosedSelectorException)) handleException(e);
|
||||||
|
}
|
||||||
|
}, "Kryonet Client");
|
||||||
|
updateThread.setDaemon(true);
|
||||||
|
updateThread.start();
|
||||||
|
|
||||||
|
client.connect(5000, ip, port, port);
|
||||||
|
success.run();
|
||||||
|
}catch(Exception e){
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -222,12 +226,10 @@ public class KryoClient implements ClientProvider{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleException(Exception e){
|
private void handleException(Exception e){
|
||||||
e.printStackTrace();
|
|
||||||
if(e instanceof KryoNetException){
|
if(e instanceof KryoNetException){
|
||||||
Gdx.app.postRunnable(() -> Net.showError("$text.server.mismatch"));
|
Gdx.app.postRunnable(() -> Net.showError(new IOException("mismatch")));
|
||||||
}else{
|
}else{
|
||||||
Net.showError(Strings.parseException(e, true));
|
Gdx.app.postRunnable(() -> Net.showError(e));
|
||||||
disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user