Implemented LAN discovery
This commit is contained in:
@@ -16,6 +16,9 @@ text.server.connected=A player has joined.
|
|||||||
text.server.disconnected={0} has disconnected.
|
text.server.disconnected={0} has disconnected.
|
||||||
text.hostserver=Host Server
|
text.hostserver=Host Server
|
||||||
text.host=Host
|
text.host=Host
|
||||||
|
text.hosts.discovering=Discovering LAN games
|
||||||
|
text.hosts.none=[lightgray]No hosts found!
|
||||||
|
text.joingame.byip=Join by IP...
|
||||||
text.joingame.title=Join Game
|
text.joingame.title=Join Game
|
||||||
text.joingame.ip=IP:
|
text.joingame.ip=IP:
|
||||||
text.disconnect=Disconnected.
|
text.disconnect=Disconnected.
|
||||||
|
|||||||
@@ -188,6 +188,11 @@ public class Control extends Module{
|
|||||||
Settings.defaults("save-" + i + "-data", "empty");
|
Settings.defaults("save-" + i + "-data", "empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Settings.defaultList(
|
||||||
|
"ip", "localhost",
|
||||||
|
"port", Vars.port+""
|
||||||
|
);
|
||||||
|
|
||||||
Settings.loadAll("io.anuke.moment");
|
Settings.loadAll("io.anuke.moment");
|
||||||
|
|
||||||
for(Map map : Vars.world.maps().list()){
|
for(Map map : Vars.world.maps().list()){
|
||||||
|
|||||||
@@ -179,29 +179,6 @@ public class UI extends SceneModule{
|
|||||||
editorDialog = new MapEditorDialog(editor);
|
editorDialog = new MapEditorDialog(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
join = new FloatingDialog("$text.joingame.title");
|
|
||||||
join.content().add("$text.joingame.ip").left();
|
|
||||||
Mindustry.platforms.addDialog(join.content().addField("localhost", text -> lastip = text).size(180f, 54f).get());
|
|
||||||
join.content().row();
|
|
||||||
join.content().add("$text.server.port").left();
|
|
||||||
Mindustry.platforms.addDialog(join.content()
|
|
||||||
.addField(Vars.port + "", new DigitsOnlyFilter(), text -> lastport = Strings.parseInt(text))
|
|
||||||
.size(180f, 54f).get());
|
|
||||||
join.buttons().defaults().size(140f, 60f).pad(4f);
|
|
||||||
join.buttons().addButton("$text.cancel", join::hide);
|
|
||||||
join.buttons().addButton("$text.ok", () -> {
|
|
||||||
showLoading("$text.connecting");
|
|
||||||
|
|
||||||
Timers.runTask(2f, () -> {
|
|
||||||
try{
|
|
||||||
Net.connect(lastip, lastport);
|
|
||||||
}catch (IOException e) {
|
|
||||||
showError(Bundles.format("text.connectfail", Strings.parseException(e, false)));
|
|
||||||
hideLoading();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).disabled(b -> lastip.isEmpty() || lastport == Integer.MIN_VALUE);
|
|
||||||
|
|
||||||
settingserror = new Dialog("Warning", "dialog");
|
settingserror = new Dialog("Warning", "dialog");
|
||||||
settingserror.content().add("[crimson]Failed to access local storage.\nSettings will not be saved.");
|
settingserror.content().add("[crimson]Failed to access local storage.\nSettings will not be saved.");
|
||||||
settingserror.content().margin(10f);
|
settingserror.content().margin(10f);
|
||||||
@@ -211,6 +188,8 @@ public class UI extends SceneModule{
|
|||||||
gameerror.content().labelWrap("$text.error.crashmessage").width(600f).pad(10f);
|
gameerror.content().labelWrap("$text.error.crashmessage").width(600f).pad(10f);
|
||||||
gameerror.buttons().addButton("#text.ok", gameerror::hide).size(200f, 50);
|
gameerror.buttons().addButton("#text.ok", gameerror::hide).size(200f, 50);
|
||||||
|
|
||||||
|
join = new JoinDialog();
|
||||||
|
|
||||||
discord = new Dialog("Discord", "dialog");
|
discord = new Dialog("Discord", "dialog");
|
||||||
discord.content().margin(12f);
|
discord.content().margin(12f);
|
||||||
discord.content().add("$text.discord");
|
discord.content().add("$text.discord");
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class Net{
|
|||||||
|
|
||||||
/**Starts discovering servers on a different thread. Does not work with GWT.
|
/**Starts discovering servers on a different thread. Does not work with GWT.
|
||||||
* Callback is run on the main libGDX thread.*/
|
* Callback is run on the main libGDX thread.*/
|
||||||
public void discoverServers(Consumer<Array<Address>> cons){
|
public static void discoverServers(Consumer<Array<Address>> cons){
|
||||||
executor.submit(() -> {
|
executor.submit(() -> {
|
||||||
Array<Address> arr = clientProvider.discover();
|
Array<Address> arr = clientProvider.discover();
|
||||||
Gdx.app.postRunnable(() -> {
|
Gdx.app.postRunnable(() -> {
|
||||||
|
|||||||
@@ -1,12 +1,103 @@
|
|||||||
package io.anuke.mindustry.ui;
|
package io.anuke.mindustry.ui;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import io.anuke.mindustry.Mindustry;
|
||||||
|
import io.anuke.mindustry.Vars;
|
||||||
|
import io.anuke.mindustry.net.Address;
|
||||||
|
import io.anuke.mindustry.net.Net;
|
||||||
|
import io.anuke.ucore.core.Settings;
|
||||||
|
import io.anuke.ucore.core.Timers;
|
||||||
|
import io.anuke.ucore.scene.style.Drawable;
|
||||||
|
import io.anuke.ucore.scene.ui.Dialog;
|
||||||
|
import io.anuke.ucore.scene.ui.TextButton;
|
||||||
|
import io.anuke.ucore.scene.ui.TextField.TextFieldFilter.DigitsOnlyFilter;
|
||||||
|
import io.anuke.ucore.scene.ui.layout.Table;
|
||||||
|
import io.anuke.ucore.util.Bundles;
|
||||||
|
import io.anuke.ucore.util.Strings;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class JoinDialog extends FloatingDialog {
|
public class JoinDialog extends FloatingDialog {
|
||||||
|
Dialog join;
|
||||||
|
Table hosts = new Table();
|
||||||
|
float w = 400;
|
||||||
|
|
||||||
public JoinDialog(){
|
public JoinDialog(){
|
||||||
super("$text.joingame");
|
super("$text.joingame");
|
||||||
|
|
||||||
|
addCloseButton();
|
||||||
|
|
||||||
|
join = new FloatingDialog("$text.joingame.title");
|
||||||
|
join.content().add("$text.joingame.ip").left();
|
||||||
|
Mindustry.platforms.addDialog(join.content().addField(Settings.getString("ip"),text ->{
|
||||||
|
Settings.putString("ip", text);
|
||||||
|
Settings.save();
|
||||||
|
}).size(180f, 54f).get());
|
||||||
|
|
||||||
|
join.content().row();
|
||||||
|
join.content().add("$text.server.port").left();
|
||||||
|
Mindustry.platforms.addDialog(join.content()
|
||||||
|
.addField(Settings.getString("port"), new DigitsOnlyFilter(), text ->{
|
||||||
|
Settings.putString("port", text);
|
||||||
|
Settings.save();
|
||||||
|
})
|
||||||
|
.size(180f, 54f).get());
|
||||||
|
join.buttons().defaults().size(140f, 60f).pad(4f);
|
||||||
|
join.buttons().addButton("$text.cancel", join::hide);
|
||||||
|
join.buttons().addButton("$text.ok", () ->
|
||||||
|
connect(Settings.getString("port"), Integer.parseInt(Settings.getString("port")))
|
||||||
|
).disabled(b -> Settings.getString("ip").isEmpty() || Integer.parseInt(Settings.getString("port")) == Integer.MIN_VALUE);
|
||||||
|
|
||||||
|
setup();
|
||||||
|
|
||||||
|
shown(() -> {
|
||||||
|
hosts.clear();
|
||||||
|
hosts.background("button");
|
||||||
|
hosts.label(() -> "[accent]" + Bundles.get("text.hosts.discovering") + new String(new char[(int)(Timers.time() / 10) % 4]).replace("\0", ".")).pad(10f);
|
||||||
|
Net.discoverServers(list -> {
|
||||||
|
addHosts(list);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
|
hosts.background("button");
|
||||||
content().clear();
|
content().clear();
|
||||||
|
content().add(hosts).width(w).pad(0);
|
||||||
|
content().row();
|
||||||
|
content().addButton("$text.joingame.byip", "clear", join::show).width(w).height(80f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addHosts(Array<Address> array){
|
||||||
|
hosts.clear();
|
||||||
|
|
||||||
|
if(array.size == 0){
|
||||||
|
hosts.add("$text.hosts.none").pad(20f);
|
||||||
|
}else {
|
||||||
|
for (Address a : array) {
|
||||||
|
TextButton button = hosts.addButton("[accent]"+a.name, "clear", () -> {
|
||||||
|
connect(a.address, Vars.port);
|
||||||
|
}).width(w).height(80f).pad(4f).get();
|
||||||
|
button.left();
|
||||||
|
button.row();
|
||||||
|
button.add("[lightgray]" + a.address + " / " + Vars.port).pad(4).left();
|
||||||
|
|
||||||
|
hosts.row();
|
||||||
|
hosts.background((Drawable) null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void connect(String ip, int port){
|
||||||
|
Vars.ui.showLoading("$text.connecting");
|
||||||
|
|
||||||
|
Timers.runTask(2f, () -> {
|
||||||
|
try{
|
||||||
|
Net.connect(ip, port);
|
||||||
|
}catch (IOException e) {
|
||||||
|
Vars.ui.showError(Bundles.format("text.connectfail", Strings.parseException(e, false)));
|
||||||
|
Vars.ui.hideLoading();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,17 +44,15 @@ public class MenuDialog extends FloatingDialog{
|
|||||||
ui.showPrefs();
|
ui.showPrefs();
|
||||||
});
|
});
|
||||||
|
|
||||||
//if(!Vars.gwt){
|
content().row();
|
||||||
content().row();
|
content().addButton("$text.savegame", () -> {
|
||||||
content().addButton("$text.savegame", () -> {
|
save.show();
|
||||||
save.show();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
content().row();
|
content().row();
|
||||||
content().addButton("$text.loadgame", () -> {
|
content().addButton("$text.loadgame", () -> {
|
||||||
load.show();
|
load.show();
|
||||||
});
|
});
|
||||||
//}
|
|
||||||
|
|
||||||
content().row();
|
content().row();
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public class MenuFragment implements Fragment{
|
|||||||
row();
|
row();
|
||||||
|
|
||||||
if(!gwt){
|
if(!gwt){
|
||||||
|
|
||||||
add(new MenuButton("$text.editor", group, ui::showEditor));
|
add(new MenuButton("$text.editor", group, ui::showEditor));
|
||||||
row();
|
row();
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -2,6 +2,7 @@ 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.badlogic.gdx.utils.ObjectSet;
|
||||||
import com.esotericsoftware.kryonet.Client;
|
import com.esotericsoftware.kryonet.Client;
|
||||||
import com.esotericsoftware.kryonet.Connection;
|
import com.esotericsoftware.kryonet.Connection;
|
||||||
import com.esotericsoftware.kryonet.FrameworkMessage;
|
import com.esotericsoftware.kryonet.FrameworkMessage;
|
||||||
@@ -101,10 +102,13 @@ public class KryoClient implements ClientProvider{
|
|||||||
@Override
|
@Override
|
||||||
public Array<Address> discover(){
|
public Array<Address> discover(){
|
||||||
List<InetAddress> list = client.discoverHosts(Vars.port, 5000);
|
List<InetAddress> list = client.discoverHosts(Vars.port, 5000);
|
||||||
|
ObjectSet<String> hostnames = new ObjectSet<>();
|
||||||
Array<Address> result = new Array<>();
|
Array<Address> result = new Array<>();
|
||||||
|
|
||||||
for(InetAddress a : list){
|
for(InetAddress a : list){
|
||||||
result.add(new Address(a.getHostName(), a.getHostAddress()));
|
if(!hostnames.contains(a.getHostName()))
|
||||||
|
result.add(new Address(a.getCanonicalHostName(), a.getHostAddress()));
|
||||||
|
hostnames.add(a.getHostName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user