Extensive network refactor

This commit is contained in:
Anuken
2019-09-07 14:11:50 -04:00
parent 38fe99f10e
commit e90c8c4d3e
48 changed files with 781 additions and 887 deletions

View File

@@ -13,6 +13,7 @@ import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.maps.*;
import io.anuke.mindustry.net.Net;
import static io.anuke.arc.Core.*;
import static io.anuke.mindustry.Vars.*;
@@ -40,6 +41,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
assets = new AssetManager();
assets.setLoader(Texture.class, "." + mapExtension, new MapPreviewLoader());
atlas = TextureAtlas.blankAtlas();
Vars.net = new Net(platform.getNet());
UI.loadSystemCursors();

View File

@@ -141,6 +141,7 @@ public class Vars implements Loadable{
/** list of all locales that can be switched to */
public static Locale[] locales;
public static Net net;
public static ContentLoader content;
public static GameState state;
public static GlobalData data;
@@ -231,7 +232,7 @@ public class Vars implements Loadable{
for(EntityGroup<?> group : entities.all()){
group.setRemoveListener(entity -> {
if(entity instanceof SyncTrait && Net.client()){
if(entity instanceof SyncTrait && net.client()){
netClient.addRemovedEntity((entity).getID());
}
});

View File

@@ -25,7 +25,7 @@ public class Pathfinder{
public Pathfinder(){
Events.on(WorldLoadEvent.class, event -> clear());
Events.on(TileChangeEvent.class, event -> {
if(Net.client()) return;
if(net.client()) return;
for(Team team : Team.all){
TeamData data = state.teams.get(team);
@@ -43,7 +43,7 @@ public class Pathfinder{
}
public void update(){
if(Net.client() || paths == null) return;
if(net.client() || paths == null) return;
for(Team team : Team.all){
if(state.teams.isActive(team)){

View File

@@ -116,7 +116,7 @@ public class WaveSpawner{
}
public boolean isSpawning(){
return spawning && !Net.client();
return spawning && !net.client();
}
private void reset(){

View File

@@ -17,7 +17,6 @@ import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.maps.Map;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.dialogs.*;
import io.anuke.mindustry.world.*;
@@ -29,6 +28,7 @@ import java.util.*;
import static io.anuke.arc.Core.*;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.net;
/**
* Control module.
@@ -67,7 +67,7 @@ public class Control implements ApplicationListener, Loadable{
Events.on(WorldLoadEvent.class, event -> {
Core.app.post(() -> Core.app.post(() -> {
if(Net.active() && player.getClosestCore() != null){
if(net.active() && player.getClosestCore() != null){
//set to closest core since that's where the player will probably respawn; prevents camera jumps
Core.camera.position.set(player.isDead() ? player.getClosestCore() : player);
}else{
@@ -99,7 +99,7 @@ public class Control implements ApplicationListener, Loadable{
Effects.shake(5, 6, Core.camera.position.x, Core.camera.position.y);
//the restart dialog can show info for any number of scenarios
Call.onGameOver(event.winner);
if(state.rules.zone != null && !Net.client()){
if(state.rules.zone != null && !net.client()){
//remove zone save on game over
if(saves.getZoneSlot() != null && !state.rules.tutorial){
saves.getZoneSlot().delete();
@@ -109,9 +109,9 @@ public class Control implements ApplicationListener, Loadable{
//autohost for pvp maps
Events.on(WorldLoadEvent.class, event -> {
if(state.rules.pvp && !Net.active()){
if(state.rules.pvp && !net.active()){
try{
Net.host(port);
net.host(port);
player.isAdmin = true;
}catch(IOException e){
ui.showError(Core.bundle.format("server.error", Strings.parseException(e, true)));
@@ -210,7 +210,7 @@ public class Control implements ApplicationListener, Loadable{
public void playZone(Zone zone){
ui.loadAnd(() -> {
logic.reset();
Net.reset();
net.reset();
world.loadGenerator(zone.generator);
zone.rules.accept(state.rules);
state.rules.zone = zone;
@@ -229,7 +229,7 @@ public class Control implements ApplicationListener, Loadable{
Zone zone = Zones.groundZero;
ui.loadAnd(() -> {
logic.reset();
Net.reset();
net.reset();
world.beginMapLoad();
@@ -284,7 +284,7 @@ public class Control implements ApplicationListener, Loadable{
@Override
public void dispose(){
content.dispose();
Net.dispose();
net.dispose();
Musics.dispose();
Sounds.dispose();
ui.editor.dispose();

View File

@@ -1,14 +1,12 @@
package io.anuke.mindustry.core;
import io.anuke.arc.Events;
import io.anuke.mindustry.entities.type.BaseUnit;
import io.anuke.mindustry.entities.type.base.BaseDrone;
import io.anuke.mindustry.game.EventType.StateChangeEvent;
import io.anuke.arc.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.entities.type.base.*;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.net.Net;
import static io.anuke.mindustry.Vars.unitGroups;
import static io.anuke.mindustry.Vars.waveTeam;
import static io.anuke.mindustry.Vars.*;
public class GameState{
/** Current wave number, can be anything in non-wave modes. */
@@ -29,7 +27,7 @@ public class GameState{
private State state = State.menu;
public int enemies(){
return Net.client() ? enemies : unitGroups[waveTeam.ordinal()].count(b -> !(b instanceof BaseDrone));
return net.client() ? enemies : unitGroups[waveTeam.ordinal()].count(b -> !(b instanceof BaseDrone));
}
public BaseUnit boss(){
@@ -46,7 +44,7 @@ public class GameState{
}
public boolean isPaused(){
return (is(State.paused) && !Net.active()) || (gameOver && !Net.active());
return (is(State.paused) && !net.active()) || (gameOver && !net.active());
}
public boolean is(State astate){

View File

@@ -190,7 +190,7 @@ public class Logic implements ApplicationListener{
}
}
if(!Net.client() && state.wavetime <= 0 && state.rules.waves){
if(!net.client() && state.wavetime <= 0 && state.rules.waves){
runWave();
}
@@ -237,7 +237,7 @@ public class Logic implements ApplicationListener{
pathfinder.update();
}
if(!Net.client() && !world.isInvalidMap() && !state.isEditor()){
if(!net.client() && !world.isInvalidMap() && !state.isEditor()){
checkGameOver();
}
}

View File

@@ -40,6 +40,7 @@ public class NetClient implements ApplicationListener{
private final static float playerSyncTime = 2;
public final static float viewScale = 2f;
private long ping;
private Interval timer = new Interval(5);
/** Whether the client is currently connecting. */
private boolean connecting = false;
@@ -60,7 +61,7 @@ public class NetClient implements ApplicationListener{
public NetClient(){
Net.handleClient(Connect.class, packet -> {
net.handleClient(Connect.class, packet -> {
Log.info("Connecting to server: {0}", packet.addressTCP);
player.isAdmin = false;
@@ -74,7 +75,7 @@ public class NetClient implements ApplicationListener{
ui.loadfrag.hide();
connecting = false;
quiet = true;
Net.disconnect();
net.disconnect();
});
ConnectPacket c = new ConnectPacket();
@@ -92,10 +93,10 @@ public class NetClient implements ApplicationListener{
return;
}
Net.send(c, SendMode.tcp);
net.send(c, SendMode.tcp);
});
Net.handleClient(Disconnect.class, packet -> {
net.handleClient(Disconnect.class, packet -> {
if(quietReset) return;
connecting = false;
@@ -120,14 +121,14 @@ public class NetClient implements ApplicationListener{
}
});
Net.handleClient(WorldStream.class, data -> {
net.handleClient(WorldStream.class, data -> {
Log.info("Recieved world data: {0} bytes.", data.stream.available());
NetworkIO.loadWorld(new InflaterInputStream(data.stream));
finishConnecting();
});
Net.handleClient(InvokePacket.class, packet -> {
net.handleClient(InvokePacket.class, packet -> {
packet.writeBuffer.position(0);
RemoteReadClient.readPacket(packet.writeBuffer, packet.type);
});
@@ -198,6 +199,16 @@ public class NetClient implements ApplicationListener{
return "[#" + player.color.toString().toUpperCase() + "]" + name;
}
@Remote(targets = Loc.client)
public static void onPing(Player player, long time){
Call.onPingResponse(player.id, time);
}
@Remote(variants = Variant.one)
public static void onPingResponse(long time){
netClient.ping = Time.timeSinceMillis(time);
}
@Remote(variants = Variant.one)
public static void onTraceInfo(Player player, TraceInfo info){
if(player != null){
@@ -233,7 +244,7 @@ public class NetClient implements ApplicationListener{
logic.reset();
ui.chatfrag.clearMessages();
Net.setClientLoaded(false);
net.setClientLoaded(false);
ui.loadfrag.show("$connecting.data");
@@ -241,7 +252,7 @@ public class NetClient implements ApplicationListener{
ui.loadfrag.hide();
netClient.connecting = false;
netClient.quiet = true;
Net.disconnect();
net.disconnect();
});
}
@@ -259,7 +270,7 @@ public class NetClient implements ApplicationListener{
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
public static void onEntitySnapshot(byte groupID, short amount, short dataLen, byte[] data){
try{
netClient.byteStream.setBytes(Net.decompressSnapshot(data, dataLen));
netClient.byteStream.setBytes(net.decompressSnapshot(data, dataLen));
DataInputStream input = netClient.dataStream;
EntityGroup group = entities.get(groupID);
@@ -315,7 +326,7 @@ public class NetClient implements ApplicationListener{
state.wave = wave;
state.enemies = enemies;
netClient.byteStream.setBytes(Net.decompressSnapshot(coreData, coreDataLen));
netClient.byteStream.setBytes(net.decompressSnapshot(coreData, coreDataLen));
DataInputStream input = netClient.dataStream;
byte cores = input.readByte();
@@ -337,12 +348,12 @@ public class NetClient implements ApplicationListener{
@Override
public void update(){
if(!Net.client()) return;
if(!net.client()) return;
if(!state.is(State.menu)){
if(!connecting) sync();
}else if(!connecting){
Net.disconnect();
net.disconnect();
}else{ //...must be connecting
timeoutTime += Time.delta();
if(timeoutTime > dataTimeout){
@@ -350,7 +361,7 @@ public class NetClient implements ApplicationListener{
ui.loadfrag.hide();
quiet = true;
ui.showError("$disconnect.data");
Net.disconnect();
net.disconnect();
timeoutTime = 0f;
}
}
@@ -360,18 +371,22 @@ public class NetClient implements ApplicationListener{
return connecting;
}
public int getPing(){
return (int)ping;
}
private void finishConnecting(){
state.set(State.playing);
connecting = false;
ui.join.hide();
Net.setClientLoaded(true);
net.setClientLoaded(true);
Core.app.post(Call::connectConfirm);
Time.runTask(40f, platform::updateRPC);
Core.app.post(() -> ui.loadfrag.hide());
}
private void reset(){
Net.setClientLoaded(false);
net.setClientLoaded(false);
removed.clear();
timeoutTime = 0f;
connecting = true;
@@ -390,13 +405,13 @@ public class NetClient implements ApplicationListener{
/** Disconnects, resetting state to the menu. */
public void disconnectQuietly(){
quiet = true;
Net.disconnect();
net.disconnect();
}
/** Disconnects, causing no further changes or reset.*/
public void disconnectNoReset(){
quiet = quietReset = true;
Net.disconnect();
net.disconnect();
}
/** When set, any disconnects will be ignored and no dialogs will be shown. */
@@ -435,7 +450,7 @@ public class NetClient implements ApplicationListener{
}
if(timer.get(1, 60)){
Net.updatePing();
Call.onPing(Time.millis());
}
}

View File

@@ -19,7 +19,6 @@ import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Administration.*;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.world.*;
@@ -41,8 +40,6 @@ public class NetServer implements ApplicationListener{
public final Administration admins = new Administration();
public final CommandHandler clientCommands = new CommandHandler("/");
/** Maps connection IDs to players. */
private IntMap<Player> connections = new IntMap<>();
private boolean closing = false;
private ByteBuffer writeBuffer = ByteBuffer.allocate(127);
@@ -54,63 +51,51 @@ public class NetServer implements ApplicationListener{
private DataOutputStream dataStream = new DataOutputStream(syncStream);
public NetServer(){
Events.on(WorldLoadEvent.class, event -> {
if(!headless){
connections.clear();
}
});
Net.handleServer(Connect.class, (id, connect) -> {
net.handleServer(Connect.class, (con, connect) -> {
if(admins.isIPBanned(connect.addressTCP)){
kick(id, KickReason.banned);
con.kick(KickReason.banned);
}
});
Net.handleServer(Disconnect.class, (id, packet) -> {
Player player = connections.get(id);
if(player != null){
net.handleServer(Disconnect.class, (con, packet) -> {
if(con.player != null){
onDisconnect(player, packet.reason);
}
connections.remove(id);
});
Net.handleServer(ConnectPacket.class, (id, packet) -> {
net.handleServer(ConnectPacket.class, (con, packet) -> {
String uuid = packet.uuid;
NetConnection connection = Net.getConnection(id);
Log.info("\n\nGET CONNECT\n\n");
if(admins.isIPBanned(con.address)) return;
if(connection == null ||
admins.isIPBanned(connection.address)) return;
if(connection.hasBegunConnecting){
kick(id, KickReason.idInUse);
if(con.hasBegunConnecting){
con.kick(KickReason.idInUse);
return;
}
connection.hasBegunConnecting = true;
PlayerInfo info = admins.getInfo(uuid);
connection.mobile = packet.mobile;
con.hasBegunConnecting = true;
con.mobile = packet.mobile;
if(admins.isIDBanned(uuid)){
kick(id, KickReason.banned);
con.kick(KickReason.banned);
return;
}
if(Time.millis() - info.lastKicked < kickDuration){
kick(id, KickReason.recentKick);
con.kick(KickReason.recentKick);
return;
}
if(admins.isIDBanned(uuid)){
kick(id, KickReason.banned);
con.kick(KickReason.banned);
return;
}
if(admins.getPlayerLimit() > 0 && playerGroup.size() >= admins.getPlayerLimit()){
kick(id, KickReason.playerLimit);
con.kick(KickReason.playerLimit);
return;
}
@@ -119,14 +104,14 @@ public class NetServer implements ApplicationListener{
info.lastName = packet.name;
info.id = packet.uuid;
admins.save();
Call.onInfoMessage(id, "You are not whitelisted here.");
Call.onInfoMessage(con.id, "You are not whitelisted here.");
Log.info("&lcDo &lywhitelist-add {0}&lc to whitelist the player &lb'{1}'", packet.uuid, packet.name);
kick(id, KickReason.whitelist);
con.kick(KickReason.whitelist);
return;
}
if(packet.versionType == null || ((packet.version == -1 || !packet.versionType.equals(Version.type)) && Version.build != -1 && !admins.allowsCustomClients())){
kick(id, !Version.type.equals(packet.versionType) ? KickReason.typeMismatch : KickReason.customClient);
con.kick(!Version.type.equals(packet.versionType) ? KickReason.typeMismatch : KickReason.customClient);
return;
}
@@ -135,12 +120,12 @@ public class NetServer implements ApplicationListener{
if(preventDuplicates){
for(Player player : playerGroup.all()){
if(player.name.trim().equalsIgnoreCase(packet.name.trim())){
kick(id, KickReason.nameInUse);
con.kick(KickReason.nameInUse);
return;
}
if(player.uuid.equals(packet.uuid) || player.usid.equals(packet.usid)){
kick(id, KickReason.idInUse);
con.kick(KickReason.idInUse);
return;
}
}
@@ -149,26 +134,26 @@ public class NetServer implements ApplicationListener{
packet.name = fixName(packet.name);
if(packet.name.trim().length() <= 0){
kick(id, KickReason.nameEmpty);
con.kick(KickReason.nameEmpty);
return;
}
String ip = Net.getConnection(id).address;
String ip = con.address;
admins.updatePlayerJoined(uuid, ip, packet.name);
if(packet.version != Version.build && Version.build != -1 && packet.version != -1){
kick(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated);
con.kick(packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated);
return;
}
if(packet.version == -1){
connection.modclient = true;
con.modclient = true;
}
Player player = new Player();
player.isAdmin = admins.isAdmin(uuid, packet.usid);
player.con = Net.getConnection(id);
player.con = con;
player.usid = packet.usid;
player.name = packet.name;
player.uuid = uuid;
@@ -183,29 +168,28 @@ public class NetServer implements ApplicationListener{
player.write(outputBuffer);
}catch(Throwable t){
t.printStackTrace();
kick(id, KickReason.nameEmpty);
con.kick(KickReason.nameEmpty);
return;
}
con.player = player;
//playing in pvp mode automatically assigns players to teams
if(state.rules.pvp){
player.setTeam(assignTeam(player, playerGroup.all()));
Log.info("Auto-assigned player {0} to team {1}.", player.name, player.getTeam());
}
connections.put(id, player);
sendWorldData(player, id);
sendWorldData(player, con.id);
platform.updateRPC();
Events.fire(new PlayerJoin(player));
});
Net.handleServer(InvokePacket.class, (id, packet) -> {
Player player = connections.get(id);
if(player == null) return;
RemoteReadServer.readPacket(packet.writeBuffer, packet.type, player);
net.handleServer(InvokePacket.class, (con, packet) -> {
if(con.player == null) return;
RemoteReadServer.readPacket(packet.writeBuffer, packet.type, con.player);
});
registerCommands();
@@ -277,7 +261,7 @@ public class NetServer implements ApplicationListener{
if(votes >= votesRequired() && target.isAdded() && target.con.isConnected()){
Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] {0}[orange] will be kicked from the server.", target.name));
admins.getInfo(target.uuid).lastKicked = Time.millis() + kickDuration*1000;
kick(target.con.id, KickReason.vote);
target.con.kick(KickReason.vote);
map[0] = null;
task.cancel();
return true;
@@ -404,7 +388,7 @@ public class NetServer implements ApplicationListener{
NetworkIO.writeWorld(player, def);
WorldStream data = new WorldStream();
data.stream = new ByteArrayInputStream(stream.toByteArray());
Net.sendStream(clientID, data);
net.sendStream(clientID, data);
Log.debug("Packed {0} compressed bytes of world data.", stream.size());
}
@@ -422,7 +406,6 @@ public class NetServer implements ApplicationListener{
Call.onPlayerDisconnect(player.id);
}
player.remove();
netServer.connections.remove(player.con.id);
Log.info("&lm[{1}] &lc{0} has disconnected. &lg&fi({2})", player.name, player.uuid, reason);
}
@@ -539,10 +522,10 @@ public class NetServer implements ApplicationListener{
state.wavetime = 0f;
}else if(action == AdminAction.ban){
netServer.admins.banPlayerIP(other.con.address);
netServer.kick(other.con.id, KickReason.banned);
other.con.kick(KickReason.banned);
Log.info("&lc{0} has banned {1}.", player.name, other.name);
}else if(action == AdminAction.kick){
netServer.kick(other.con.id, KickReason.kick);
other.con.kick(KickReason.kick);
Log.info("&lc{0} has kicked {1}.", player.name, other.name);
}else if(action == AdminAction.trace){
TraceInfo info = new TraceInfo(other.con.address, other.uuid, other.con.modclient, other.con.mobile);
@@ -580,51 +563,27 @@ public class NetServer implements ApplicationListener{
public void update(){
if(!headless && !closing && Net.server() && state.is(State.menu)){
if(!headless && !closing && net.server() && state.is(State.menu)){
closing = true;
ui.loadfrag.show("$server.closing");
Time.runTask(5f, () -> {
Net.closeServer();
net.closeServer();
ui.loadfrag.hide();
closing = false;
});
}
if(!state.is(State.menu) && Net.server()){
if(!state.is(State.menu) && net.server()){
sync();
}
}
public void kickAll(KickReason reason){
for(NetConnection con : Net.getConnections()){
kick(con.id, reason);
for(NetConnection con : net.getConnections()){
con.kick(reason);
}
}
public void kick(int connection, KickReason reason){
NetConnection con = Net.getConnection(connection);
if(con == null){
Log.err("Cannot kick unknown player!");
return;
}else{
Log.info("Kicking connection #{0} / IP: {1}. Reason: {2}", connection, con.address, reason.name());
}
Player player = connections.get(con.id);
if(player != null && (reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote) && player.uuid != null){
PlayerInfo info = admins.getInfo(player.uuid);
info.timesKicked++;
info.lastKicked = Math.max(Time.millis(), info.lastKicked);
}
Call.onKick(connection, reason);
Time.runTask(2f, con::close);
admins.save();
}
public void writeSnapshot(Player player) throws IOException{
syncStream.reset();
ObjectSet<Tile> cores = state.teams.get(player.getTeam()).cores;
@@ -640,7 +599,7 @@ public class NetServer implements ApplicationListener{
byte[] stateBytes = syncStream.toByteArray();
//write basic state data.
Call.onStateSnapshot(player.con.id, state.wavetime, state.wave, state.enemies(), (short)stateBytes.length, Net.compressSnapshot(stateBytes));
Call.onStateSnapshot(player.con.id, state.wavetime, state.wave, state.enemies(), (short)stateBytes.length, net.compressSnapshot(stateBytes));
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
@@ -671,7 +630,7 @@ public class NetServer implements ApplicationListener{
if(syncStream.size() > maxSnapshotSize){
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con.id, (byte)group.getID(), (short)sent, (short)syncBytes.length, Net.compressSnapshot(syncBytes));
Call.onEntitySnapshot(player.con.id, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
sent = 0;
syncStream.reset();
}
@@ -681,7 +640,7 @@ public class NetServer implements ApplicationListener{
dataStream.close();
byte[] syncBytes = syncStream.toByteArray();
Call.onEntitySnapshot(player.con.id, (byte)group.getID(), (short)sent, (short)syncBytes.length, Net.compressSnapshot(syncBytes));
Call.onEntitySnapshot(player.con.id, (byte)group.getID(), (short)sent, (short)syncBytes.length, net.compressSnapshot(syncBytes));
}
}
}
@@ -747,7 +706,7 @@ public class NetServer implements ApplicationListener{
NetConnection connection = player.con;
if(connection == null || !connection.isConnected() || !connections.containsKey(connection.id)){
if(connection == null || !connection.isConnected()){
//player disconnected, call d/c event
onDisconnect(player, "disappeared");
return;

View File

@@ -7,13 +7,17 @@ import io.anuke.arc.function.*;
import io.anuke.arc.math.*;
import io.anuke.arc.scene.ui.*;
import io.anuke.arc.util.serialization.*;
import io.anuke.mindustry.net.Net.*;
import io.anuke.mindustry.ui.dialogs.*;
import static io.anuke.mindustry.Vars.mobile;
public interface Platform{
/**Steam: Update lobby visibility.*/
/** Get the networking implementation.*/
NetProvider getNet();
/** Steam: Update lobby visibility.*/
default void updateLobby(){
}
@@ -41,11 +45,6 @@ public interface Platform{
});
}
/** Request external read/write perms. Run callback when complete.*/
default void requestExternalPerms(Runnable callback){
callback.run();
}
/** Update discord RPC. */
default void updateRPC(){
}

View File

@@ -40,7 +40,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait{
/** Start a fire on the tile. If there already is a file there, refreshes its lifetime. */
public static void create(Tile tile){
if(Net.client() || tile == null) return; //not clientside.
if(net.client() || tile == null) return; //not clientside.
Fire fire = map.get(tile.pos());
@@ -106,7 +106,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait{
time = Mathf.clamp(time + Time.delta(), 0, lifetime());
map.put(tile.pos(), this);
if(Net.client()){
if(net.client()){
return;
}

View File

@@ -83,7 +83,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
Puddle p = map.get(tile.pos());
if(p == null){
if(Net.client()) return; //not clientside.
if(net.client()) return; //not clientside.
Puddle puddle = Pools.obtain(Puddle.class, Puddle::new);
puddle.tile = tile;
@@ -168,7 +168,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
public void update(){
//no updating happens clientside
if(Net.client()){
if(net.client()){
amount = Mathf.lerpDelta(amount, targetAmount, 0.15f);
}else{
//update code

View File

@@ -48,7 +48,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
public static void onUnitDeath(BaseUnit unit){
if(unit == null) return;
if(Net.server() || !Net.active()){
if(net.server() || !net.active()){
UnitDrops.dropItems(unit);
}
@@ -56,7 +56,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
unit.type.deathSound.at(unit);
//visual only.
if(Net.client()){
if(net.client()){
Tile tile = world.tile(unit.spawner);
if(tile != null){
tile.block().unitRemoved(tile, unit);
@@ -255,7 +255,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
hitTime -= Time.delta();
if(Net.client()){
if(net.client()){
interpolate();
status.update(this);
return;
@@ -297,7 +297,7 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
public void removed(){
super.removed();
Tile tile = world.tile(spawner);
if(tile != null && !Net.client()){
if(tile != null && !net.client()){
tile.block().unitRemoved(tile, this);
}

View File

@@ -123,7 +123,7 @@ public abstract class FlyingUnit extends BaseUnit{
public void update(){
super.update();
if(!Net.client()){
if(!net.client()){
updateRotation();
}
wobble();
@@ -176,7 +176,7 @@ public abstract class FlyingUnit extends BaseUnit{
}
protected void wobble(){
if(Net.client()) return;
if(net.client()) return;
x += Mathf.sin(Time.time() + id * 999, 25f, 0.05f) * Time.delta();
y += Mathf.cos(Time.time() + id * 999, 25f, 0.05f) * Time.delta();

View File

@@ -1,34 +1,30 @@
package io.anuke.mindustry.entities.type;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.arc.Core;
import io.anuke.arc.collection.Queue;
import io.anuke.arc.graphics.Color;
import io.anuke.annotations.Annotations.*;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.Angles;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.*;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.pooling.Pools;
import io.anuke.mindustry.Vars;
import io.anuke.arc.util.pooling.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.input.InputHandler.PlaceDraw;
import io.anuke.mindustry.io.TypeIO;
import io.anuke.mindustry.input.InputHandler.*;
import io.anuke.mindustry.io.*;
import io.anuke.mindustry.net.Administration.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetConnection;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.*;
import java.io.*;
@@ -50,7 +46,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
public float baseRotation;
public float pointerX, pointerY;
public String name = "name";
public String uuid, usid;
public @Nullable String uuid, usid;
public boolean isAdmin, isTransferring, isShooting, isBoosting, isMobile, isTyping;
public float boostHeat, shootHeat, destructTime;
public boolean achievedFlight;
@@ -59,13 +55,13 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
public SpawnerTrait spawner, lastSpawner;
public int respawns;
public NetConnection con;
public @Nullable NetConnection con;
public boolean isLocal = false;
public Interval timer = new Interval(6);
public TargetTrait target;
public TargetTrait moveTarget;
public String lastText;
public @Nullable String lastText;
public float textFadeTime;
private float walktime, itemtime;
@@ -229,7 +225,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
@Override
public void damage(float amount){
hitTime = hitDuration;
if(!Net.client()){
if(!net.client()){
health -= calculateDamage(amount);
}
@@ -530,7 +526,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
spawner = null;
}
if(isLocal || Net.server()){
if(isLocal || net.server()){
avoidOthers();
}
@@ -561,7 +557,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
status.update(this); //status effect updating also happens with non locals for effect purposes
updateVelocityStatus(); //velocity too, for visual purposes
if(Net.server()){
if(net.server()){
updateShooting(); //server simulates player shooting
}
return;
@@ -847,7 +843,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
}else if(spawner != null && spawner.isValid()){
spawner.updateSpawning(this);
}else if(!netServer.isWaitingForPlayers()){
if(!Net.client()){
if(!net.client()){
if(lastSpawner != null && lastSpawner.isValid()){
this.spawner = lastSpawner;
}else if(getClosestCore() != null){

View File

@@ -78,7 +78,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
@Override
public void damage(float amount){
if(!Net.client()){
if(!net.client()){
super.damage(calculateDamage(amount));
}
hitTime = hitDuration;
@@ -308,7 +308,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
drownTime = Mathf.clamp(drownTime);
if(drownTime >= 0.999f && !Net.client()){
if(drownTime >= 0.999f && !net.client()){
damage(health + 1);
}
@@ -347,7 +347,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
}
public void applyEffect(StatusEffect effect, float duration){
if(dead || Net.client()) return; //effects are synced and thus not applied through clients
if(dead || net.client()) return; //effects are synced and thus not applied through clients
status.handleApply(this, effect, duration);
}

View File

@@ -123,7 +123,7 @@ public class DesktopInput extends InputHandler{
@Override
public void update(){
if(Net.active() && Core.input.keyTap(Binding.player_list)){
if(net.active() && Core.input.keyTap(Binding.player_list)){
ui.listfrag.toggle();
}

View File

@@ -49,7 +49,7 @@ public abstract class InputHandler implements InputProcessor{
@Remote(targets = Loc.client, called = Loc.server)
public static void dropItem(Player player, float angle){
if(Net.server() && player.item().amount <= 0){
if(net.server() && player.item().amount <= 0){
throw new ValidateException(player, "Player cannot drop an item.");
}
@@ -60,7 +60,7 @@ public abstract class InputHandler implements InputProcessor{
@Remote(targets = Loc.both, forward = true, called = Loc.server)
public static void transferInventory(Player player, Tile tile){
if(!player.timer.get(Player.timerTransfer, 40)) return;
if(Net.server() && (player.item().amount <= 0 || player.isTransferring)){
if(net.server() && (player.item().amount <= 0 || player.isTransferring)){
throw new ValidateException(player, "Player cannot transfer an item.");
}

View File

@@ -17,6 +17,7 @@ import java.nio.file.Files;
import java.nio.file.*;
import java.text.*;
import java.util.*;
import static io.anuke.mindustry.Vars.*;
public class CrashSender{
@@ -78,9 +79,9 @@ public class CrashSender{
//attempt to close connections, if applicable
try{
netActive = Net.active();
netServer = Net.server();
Net.dispose();
netActive = net.active();
netServer = net.server();
net.dispose();
}catch(Throwable ignored){
}

View File

@@ -17,20 +17,25 @@ import static io.anuke.mindustry.Vars.*;
@SuppressWarnings("unchecked")
public class Net{
private static boolean server;
private static boolean active;
private static boolean clientLoaded;
private static Array<Object> packetQueue = new Array<>();
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
private static ClientProvider clientProvider;
private static ServerProvider serverProvider;
private static IntMap<StreamBuilder> streams = new IntMap<>();
private static final LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
private static final LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
private boolean server;
private boolean active;
private boolean clientLoaded;
private final Array<Object> packetQueue = new Array<>();
private final ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private final ObjectMap<Class<?>, BiConsumer<NetConnection, Object>> serverListeners = new ObjectMap<>();
private final IntMap<StreamBuilder> streams = new IntMap<>();
private final NetProvider provider;
private final LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
private final LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
public Net(NetProvider provider){
this.provider = provider;
}
/** Display a network error. Call on the graphics thread. */
public static void showError(Throwable e){
public void showError(Throwable e){
if(!headless){
@@ -67,7 +72,7 @@ public class Net{
}
ui.loadfrag.hide();
if(Net.client()){
if(client()){
netClient.disconnectQuietly();
}
}
@@ -78,7 +83,7 @@ public class Net{
/**
* Sets the client loaded status, or whether it will recieve normal packets from the server.
*/
public static void setClientLoaded(boolean loaded){
public void setClientLoaded(boolean loaded){
clientLoaded = loaded;
if(loaded){
@@ -91,7 +96,7 @@ public class Net{
packetQueue.clear();
}
public static void setClientConnected(){
public void setClientConnected(){
active = true;
server = false;
}
@@ -99,10 +104,10 @@ public class Net{
/**
* Connect to an address.
*/
public static void connect(String ip, int port, Runnable success){
public void connect(String ip, int port, Runnable success){
try{
if(!active){
clientProvider.connect(ip, port, success);
provider.connectClient(ip, port, success);
active = true;
server = false;
}else{
@@ -116,8 +121,8 @@ public class Net{
/**
* Host a server at an address.
*/
public static void host(int port) throws IOException{
serverProvider.host(port);
public void host(int port) throws IOException{
provider.hostServer(port);
active = true;
server = true;
@@ -127,32 +132,32 @@ public class Net{
/**
* Closes the server.
*/
public static void closeServer(){
public void closeServer(){
for(NetConnection con : getConnections()){
Call.onKick(con.id, KickReason.serverClose);
}
serverProvider.close();
provider.closeServer();
server = false;
active = false;
}
public static void reset(){
public void reset(){
closeServer();
netClient.disconnectNoReset();
}
public static void disconnect(){
clientProvider.disconnect();
public void disconnect(){
provider.disconnectClient();
server = false;
active = false;
}
public static byte[] compressSnapshot(byte[] input){
public byte[] compressSnapshot(byte[] input){
return compressor.compress(input);
}
public static byte[] decompressSnapshot(byte[] input, int size){
public byte[] decompressSnapshot(byte[] input, int size){
return decompressor.decompress(input, size);
}
@@ -160,88 +165,74 @@ public class Net{
* Starts discovering servers on a different thread.
* Callback is run on the main libGDX thread.
*/
public static void discoverServers(Consumer<Host> cons, Runnable done){
clientProvider.discover(cons, done);
public void discoverServers(Consumer<Host> cons, Runnable done){
provider.discoverServers(cons, done);
}
/**
* Returns a list of all connections IDs.
*/
public static Iterable<NetConnection> getConnections(){
return (Iterable<NetConnection>)serverProvider.getConnections();
public Iterable<NetConnection> getConnections(){
return (Iterable<NetConnection>)provider.getConnections();
}
/**
* Returns a connection by ID
*/
public static NetConnection getConnection(int id){
return serverProvider.getByID(id);
public NetConnection getConnection(int id){
return provider.getConnection(id);
}
/**
* Send an object to all connected clients, or to the server if this is a client.
*/
public static void send(Object object, SendMode mode){
public void send(Object object, SendMode mode){
if(server){
if(serverProvider != null) serverProvider.sendServer(object, mode);
provider.sendServer(object, mode);
}else{
if(clientProvider != null) clientProvider.sendClient(object, mode);
provider.sendClient(object, mode);
}
}
/**
* Send an object to a certain client. Server-side only
*/
public static void sendTo(int id, Object object, SendMode mode){
serverProvider.sendServerTo(id, object, mode);
public void sendTo(int id, Object object, SendMode mode){
provider.sendServerTo(id, object, mode);
}
/**
* Send an object to everyone EXCEPT certain client. Server-side only
*/
public static void sendExcept(int id, Object object, SendMode mode){
serverProvider.sendServerExcept(id, object, mode);
public void sendExcept(int id, Object object, SendMode mode){
provider.sendServerExcept(id, object, mode);
}
/**
* Send a stream to a specific client. Server-side only.
*/
public static void sendStream(int id, Streamable stream){
serverProvider.sendServerStream(id, stream);
}
/**
* Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.
*/
public static void setClientProvider(ClientProvider provider){
Net.clientProvider = provider;
}
/**
* Sets the net serverProvider, e.g. what handles hosting a server.
*/
public static void setServerProvider(ServerProvider provider){
Net.serverProvider = provider;
public void sendStream(int id, Streamable stream){
provider.sendServerStream(id, stream);
}
/**
* Registers a client listener for when an object is recieved.
*/
public static <T> void handleClient(Class<T> type, Consumer<T> listener){
public <T> void handleClient(Class<T> type, Consumer<T> listener){
clientListeners.put(type, listener);
}
/**
* Registers a server listener for when an object is recieved.
*/
public static <T> void handleServer(Class<T> type, BiConsumer<Integer, T> listener){
serverListeners.put(type, (BiConsumer<Integer, Object>)listener);
public <T> void handleServer(Class<T> type, BiConsumer<NetConnection, T> listener){
serverListeners.put(type, (BiConsumer<NetConnection, Object>)listener);
}
/**
* Call to handle a packet being recieved for the client.
*/
public static void handleClientReceived(Object object){
public void handleClientReceived(Object object){
if(object instanceof StreamBegin){
StreamBegin b = (StreamBegin)object;
@@ -276,7 +267,7 @@ public class Net{
/**
* Call to handle a packet being recieved for the server.
*/
public static void handleServerReceived(int connection, Object object){
public void handleServerReceived(NetConnection connection, Object object){
if(serverListeners.get(object.getClass()) != null){
if(serverListeners.get(object.getClass()) != null)
@@ -290,50 +281,33 @@ public class Net{
/**
* Pings a host in an new thread. If an error occured, failed() should be called with the exception.
*/
public static void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed){
clientProvider.pingHost(address, port, valid, failed);
}
/**
* Update client ping.
*/
public static void updatePing(){
clientProvider.updatePing();
}
/**
* Get the client ping. Only valid after updatePing().
*/
public static int getPing(){
return server() ? 0 : clientProvider.getPing();
public void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed){
provider.pingHost(address, port, valid, failed);
}
/**
* Whether the net is active, e.g. whether this is a multiplayer game.
*/
public static boolean active(){
public boolean active(){
return active;
}
/**
* Whether this is a server or not.
*/
public static boolean server(){
public boolean server(){
return server && active;
}
/**
* Whether this is a client or not.
*/
public static boolean client(){
public boolean client(){
return !server && active;
}
public static void dispose(){
if(clientProvider != null) clientProvider.dispose();
if(serverProvider != null) serverProvider.close();
clientProvider = null;
serverProvider = null;
public void dispose(){
provider.dispose();
server = false;
active = false;
}
@@ -343,46 +317,32 @@ public class Net{
}
/** Client implementation. */
public interface ClientProvider{
public interface NetProvider{
/** Connect to a server. */
void connect(String ip, int port, Runnable success) throws IOException;
void connectClient(String ip, int port, Runnable success) throws IOException;
/** Send an object to the server. */
void sendClient(Object object, SendMode mode);
/** Update the ping. Should be done every second or so. */
void updatePing();
/** Get ping in milliseconds. Will only be valid after a call to updatePing. */
int getPing();
/** Disconnect from the server. */
void disconnect();
void disconnectClient();
/**
* Discover servers. This should run the callback regardless of whether any servers are found. Should not block.
* Callback should be run on libGDX main thread.
* @param done is the callback that should run after discovery.
*/
void discover(Consumer<Host> callback, Runnable done);
void discoverServers(Consumer<Host> callback, Runnable done);
/** Ping a host. If an error occured, failed() should be called with the exception. */
void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed);
/** Close all connections. */
default void dispose(){
disconnect();
}
}
/** Server implementation. */
public interface ServerProvider{
/** Host a server at specified port. */
void host(int port) throws IOException;
void hostServer(int port) throws IOException;
/** Sends a large stream of data to a specific client. */
default void sendServerStream(int id, Streamable stream){
NetConnection connection = getByID(id);
NetConnection connection = getConnection(id);
if(connection == null) return;
try{
int cid;
@@ -413,7 +373,7 @@ public class Net{
}
default void sendServerTo(int id, Object object, SendMode mode){
NetConnection conn = getByID(id);
NetConnection conn = getConnection(id);
if(conn == null){
Log.err("Failed to find connection with ID {0}.", id);
return;
@@ -429,13 +389,26 @@ public class Net{
}
}
/** Close the server connection. */
void close();
/** Returns a connection by ID. */
default NetConnection getConnection(int id){
for(NetConnection con : getConnections()){
if(con.id == id){
return con;
}
}
return null;
}
/** Return all connected users. */
Iterable<? extends NetConnection> getConnections();
/** Returns a connection by ID. */
NetConnection getByID(int id);
/** Close the server connection. */
void closeServer();
/** Close all connections. */
default void dispose(){
disconnectClient();
closeServer();
}
}
}

View File

@@ -1,6 +1,14 @@
package io.anuke.mindustry.net;
import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.annotations.Annotations.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.net.Administration.*;
import io.anuke.mindustry.net.Net.*;
import io.anuke.mindustry.net.Packets.*;
import static io.anuke.mindustry.Vars.netServer;
public abstract class NetConnection{
private static int lastID;
@@ -10,6 +18,7 @@ public abstract class NetConnection{
public boolean modclient;
public boolean mobile;
public @Nullable Player player;
/** ID of last recieved client snapshot. */
public int lastRecievedClientSnapshot = -1;
@@ -26,6 +35,22 @@ public abstract class NetConnection{
this.address = address;
}
public void kick(KickReason reason){
Log.info("Kicking connection #{0} / IP: {1}. Reason: {2}", this.id, address, reason.name());
if(player != null && (reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote) && player.uuid != null){
PlayerInfo info = netServer.admins.getInfo(player.uuid);
info.timesKicked++;
info.lastKicked = Math.max(Time.millis(), info.lastKicked);
}
Call.onKick(id, reason);
Time.runTask(2f, this::close);
netServer.admins.save();
}
public boolean isConnected(){
return true;
}

View File

@@ -14,8 +14,8 @@ import io.anuke.mindustry.entities.bullet.*;
import io.anuke.mindustry.entities.traits.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.gen.Sounds;
import io.anuke.mindustry.net.Net;
import static io.anuke.mindustry.Vars.net;
public class Weapon{
public final String name;
@@ -73,7 +73,7 @@ public class Weapon{
if(player == null) return;
//clients do not see their own shoot events: they are simulated completely clientside to prevent laggy visuals
//messing with the firerate or any other stats does not affect the server (take that, script kiddies!)
if(Net.client() && player == Vars.player){
if(net.client() && player == Vars.player){
return;
}
@@ -154,7 +154,7 @@ public class Weapon{
}
public void shoot(ShooterTrait p, float x, float y, float angle, boolean left){
if(Net.client()){
if(net.client()){
//call it directly, don't invoke on server
shootDirect(p, x, y, angle, left);
}else{

View File

@@ -19,7 +19,6 @@ import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.game.Saves.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.io.SaveIO.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.type.Zone.*;
import io.anuke.mindustry.ui.*;
@@ -105,7 +104,7 @@ public class DeployDialog extends FloatingDialog{
hide();
ui.loadAnd(() -> {
logic.reset();
Net.reset();
net.reset();
try{
control.saves.getZoneSlot().load();
state.set(State.playing);

View File

@@ -26,7 +26,7 @@ public class FloatingDialog extends Dialog{
hidden(() -> {
if(shouldPause && !state.is(State.menu)){
if(!wasPaused || Net.active()){
if(!wasPaused || net.active()){
state.set(State.playing);
}
}

View File

@@ -1,14 +1,12 @@
package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.scene.ui.ImageButton;
import io.anuke.arc.util.Strings;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.net.Net;
import io.anuke.arc.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.scene.ui.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.*;
import java.io.IOException;
import java.io.*;
import static io.anuke.mindustry.Vars.*;
@@ -65,7 +63,7 @@ public class HostDialog extends FloatingDialog{
ui.loadfrag.show("$hosting");
Time.runTask(5f, () -> {
try{
Net.host(Vars.port);
net.host(Vars.port);
player.isAdmin = true;
}catch(IOException e){
ui.showError(Core.bundle.format("server.error", Strings.parseException(e, true)));

View File

@@ -12,7 +12,6 @@ import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Packets.*;
@@ -68,7 +67,7 @@ public class JoinDialog extends FloatingDialog{
refreshRemote();
}
add.hide();
}).disabled(b -> Core.settings.getString("ip").isEmpty() || Net.active());
}).disabled(b -> Core.settings.getString("ip").isEmpty() || net.active());
add.shown(() -> {
add.title.setText(renaming != null ? "$server.edit" : "$server.add");
@@ -173,7 +172,7 @@ public class JoinDialog extends FloatingDialog{
server.content.clear();
server.content.label(() -> Core.bundle.get("server.refreshing") + Strings.animated(Time.time(), 4, 11, "."));
Net.pingHost(server.ip, server.port, host -> setupServer(server, host), e -> {
net.pingHost(server.ip, server.port, host -> setupServer(server, host), e -> {
server.content.clear();
server.content.add("$host.invalid");
});
@@ -276,9 +275,9 @@ public class JoinDialog extends FloatingDialog{
local.clear();
local.background((Drawable)null);
local.table("button", t -> t.label(() -> "[accent]" + Core.bundle.get("hosts.discovering.any") + Strings.animated(Time.time(), 4, 10f, ".")).pad(10f)).growX();
Net.discoverServers(this::addLocalHost, this::finishLocalHosts);
net.discoverServers(this::addLocalHost, this::finishLocalHosts);
for(String host : defaultServers){
Net.pingHost(host, port, this::addLocalHost, e -> {});
net.pingHost(host, port, this::addLocalHost, e -> {});
}
}
@@ -325,9 +324,9 @@ public class JoinDialog extends FloatingDialog{
Time.runTask(2f, () -> {
logic.reset();
Net.reset();
net.reset();
Vars.netClient.beginConnecting();
Net.connect(ip, port, () -> {
net.connect(ip, port, () -> {
hide();
add.hide();
});

View File

@@ -13,7 +13,6 @@ import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.game.Saves.*;
import io.anuke.mindustry.io.*;
import io.anuke.mindustry.io.SaveIO.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.ui.*;
import java.io.*;
@@ -193,7 +192,7 @@ public class LoadDialog extends FloatingDialog{
ui.loadAnd(() -> {
try{
Net.reset();
net.reset();
slot.load();
state.set(State.playing);
}catch(SaveException e){

View File

@@ -52,7 +52,7 @@ public class PausedDialog extends FloatingDialog{
if(!world.isZone() && !state.isEditor()){
cont.row();
cont.addButton("$savegame", save::show);
cont.addButton("$loadgame", load::show).disabled(b -> Net.active());
cont.addButton("$loadgame", load::show).disabled(b -> net.active());
}
cont.row();
@@ -63,7 +63,7 @@ public class PausedDialog extends FloatingDialog{
}else{
ui.host.show();
}
}).disabled(b -> Net.active()).colspan(2).width(dw * 2 + 20f);
}).disabled(b -> net.active()).colspan(2).width(dw * 2 + 20f);
}
cont.row();
@@ -82,12 +82,12 @@ public class PausedDialog extends FloatingDialog{
cont.row();
cont.addRowImageTextButton("$load", "icon-load", isize, load::show).disabled(b -> Net.active());
cont.addRowImageTextButton("$load", "icon-load", isize, load::show).disabled(b -> net.active());
}else{
cont.row();
}
cont.addRowImageTextButton("$hostserver.mobile", "icon-host", isize, ui.host::show).disabled(b -> Net.active());
cont.addRowImageTextButton("$hostserver.mobile", "icon-host", isize, ui.host::show).disabled(b -> net.active());
cont.addRowImageTextButton("$quit", "icon-quit", isize, this::showQuitConfirm);
}
@@ -99,8 +99,8 @@ public class PausedDialog extends FloatingDialog{
Core.settings.put("playedtutorial", true);
Core.settings.save();
}
wasClient = Net.client();
if(Net.client()) netClient.disconnectQuietly();
wasClient = net.client();
if(net.client()) netClient.disconnectQuietly();
runExitSave();
hide();
});

View File

@@ -36,7 +36,7 @@ public class SettingsMenuDialog extends SettingsDialog{
hidden(() -> {
Sounds.back.play();
if(!state.is(State.menu)){
if(!wasPaused || Net.active())
if(!wasPaused || net.active())
state.set(State.playing);
}
});

View File

@@ -1,28 +1,23 @@
package io.anuke.mindustry.ui.fragments;
import io.anuke.arc.Core;
import io.anuke.arc.Input.TextInput;
import io.anuke.arc.collection.Array;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.*;
import io.anuke.arc.Input.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.scene.Group;
import io.anuke.arc.scene.ui.Label;
import io.anuke.arc.scene.ui.Label.LabelStyle;
import io.anuke.arc.scene.ui.TextField;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.arc.scene.ui.layout.UnitScl;
import io.anuke.arc.util.Align;
import io.anuke.arc.util.Time;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.input.Binding;
import io.anuke.mindustry.net.Net;
import io.anuke.arc.math.*;
import io.anuke.arc.scene.*;
import io.anuke.arc.scene.ui.*;
import io.anuke.arc.scene.ui.Label.*;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*;
import io.anuke.mindustry.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.input.*;
import static io.anuke.arc.Core.input;
import static io.anuke.arc.Core.scene;
import static io.anuke.mindustry.Vars.maxTextLength;
import static io.anuke.mindustry.Vars.mobile;
import static io.anuke.arc.Core.*;
import static io.anuke.mindustry.Vars.net;
import static io.anuke.mindustry.Vars.*;
public class ChatFragment extends Table{
private final static int messagesShown = 10;
@@ -53,7 +48,7 @@ public class ChatFragment extends Table{
font = scene.skin.getFont("default");
visible(() -> {
if(!Net.active() && messages.size > 0){
if(!net.active() && messages.size > 0){
clearMessages();
if(chatOpen){
@@ -61,12 +56,12 @@ public class ChatFragment extends Table{
}
}
return Net.active();
return net.active();
});
update(() -> {
if(Net.active() && input.keyTap(Binding.chat)){
if(net.active() && input.keyTap(Binding.chat)){
toggle();
}

View File

@@ -23,7 +23,6 @@ import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
@@ -66,13 +65,13 @@ public class HudFragment extends Fragment{
flip = select.addImageButton("icon-arrow-up", style, iconsize, this::toggleMenus).get();
select.addImageButton("icon-pause", style, iconsize, () -> {
if(Net.active()){
if(net.active()){
ui.listfrag.toggle();
}else{
state.set(state.is(State.paused) ? State.playing : State.paused);
}
}).name("pause").update(i -> {
if(Net.active()){
if(net.active()){
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-players");
}else{
i.setDisabled(false);
@@ -81,7 +80,7 @@ public class HudFragment extends Fragment{
}).get();
select.addImageButton("icon-settings", style, iconsize, () -> {
if(Net.active() && mobile){
if(net.active() && mobile){
if(ui.chatfrag.chatOpen()){
ui.chatfrag.hide();
}else{
@@ -93,7 +92,7 @@ public class HudFragment extends Fragment{
ui.database.show();
}
}).update(i -> {
if(Net.active() && mobile){
if(net.active() && mobile){
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-chat");
}else{
i.getStyle().imageUp = Core.scene.skin.getDrawable("icon-database");
@@ -244,7 +243,7 @@ public class HudFragment extends Fragment{
info.label(() -> fps.get(Core.graphics.getFramesPerSecond())).left().style("outline");
info.row();
info.label(() -> ping.get(Net.getPing())).visible(Net::client).left().style("outline");
info.label(() -> ping.get(netClient.getPing())).visible(net::client).left().style("outline");
}).top().left();
});
@@ -542,7 +541,7 @@ public class HudFragment extends Fragment{
private boolean inLaunchWave(){
return world.isZone() &&
world.getZone().metCondition() &&
!Net.client() &&
!net.client() &&
state.wave % world.getZone().launchPeriod == 0 && !spawner.isSpawning();
}
@@ -639,12 +638,12 @@ public class HudFragment extends Fragment{
}
private boolean canSkipWave(){
return state.rules.waves && ((Net.server() || player.isAdmin) || !Net.active()) && state.enemies() == 0 && !spawner.isSpawning() && !state.rules.tutorial;
return state.rules.waves && ((net.server() || player.isAdmin) || !net.active()) && state.enemies() == 0 && !spawner.isSpawning() && !state.rules.tutorial;
}
private void addPlayButton(Table table){
table.right().addImageButton("icon-play", "right", 30f, () -> {
if(Net.client() && player.isAdmin){
if(net.client() && player.isAdmin){
Call.onAdminRequest(player, AdminAction.wave);
}else if(inLaunchWave()){
ui.showConfirm("$confirm", "$launch.skip.confirm", () -> !canSkipWave(), () -> state.wavetime = 0f);

View File

@@ -29,7 +29,7 @@ public class PlayerListFragment extends Fragment{
parent.fill(cont -> {
cont.visible(() -> visible);
cont.update(() -> {
if(!(Net.active() && !state.is(State.menu))){
if(!(net.active() && !state.is(State.menu))){
visible = false;
return;
}
@@ -52,8 +52,8 @@ public class PlayerListFragment extends Fragment{
pane.table(menu -> {
menu.defaults().growX().height(50f).fillY();
menu.addButton("$server.bans", ui.bans::show).disabled(b -> Net.client());
menu.addButton("$server.admins", ui.admins::show).disabled(b -> Net.client());
menu.addButton("$server.bans", ui.bans::show).disabled(b -> net.client());
menu.addButton("$server.admins", ui.admins::show).disabled(b -> net.client());
menu.addButton("$close", this::toggle);
}).margin(0f).pad(10f).growX();
@@ -72,7 +72,7 @@ public class PlayerListFragment extends Fragment{
playerGroup.all().each(user -> {
NetConnection connection = user.con;
if(connection == null && Net.server() && !user.isLocal) return;
if(connection == null && net.server() && !user.isLocal) return;
Table button = new Table();
button.left();
@@ -96,9 +96,9 @@ public class PlayerListFragment extends Fragment{
button.labelWrap("[#" + user.color.toString().toUpperCase() + "]" + user.name).width(170f).pad(10);
button.add().grow();
button.addImage("icon-admin").size(iconsize).visible(() -> user.isAdmin && !(!user.isLocal && Net.server())).padRight(5).get().updateVisibility();
button.addImage("icon-admin").size(iconsize).visible(() -> user.isAdmin && !(!user.isLocal && net.server())).padRight(5).get().updateVisibility();
if((Net.server() || player.isAdmin) && !user.isLocal && (!user.isAdmin || Net.server())){
if((net.server() || player.isAdmin) && !user.isLocal && (!user.isAdmin || net.server())){
button.add().growY();
float bs = (h) / 2f;
@@ -114,7 +114,7 @@ public class PlayerListFragment extends Fragment{
t.row();
t.addImageButton("icon-admin-small", "clear-toggle-partial", iconsizesmall, () -> {
if(Net.client()) return;
if(net.client()) return;
String id = user.uuid;
@@ -125,8 +125,8 @@ public class PlayerListFragment extends Fragment{
}
})
.update(b -> b.setChecked(user.isAdmin))
.disabled(b -> Net.client())
.touchable(() -> Net.client() ? Touchable.disabled : Touchable.enabled)
.disabled(b -> net.client())
.touchable(() -> net.client() ? Touchable.disabled : Touchable.enabled)
.checked(user.isAdmin);
t.addImageButton("icon-zoom-small", "clear-partial", iconsizesmall, () -> Call.onAdminRequest(user, AdminAction.trace));

View File

@@ -24,7 +24,6 @@ import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.InputHandler.*;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.world.blocks.*;
@@ -300,7 +299,7 @@ public class Block extends BlockStorage{
/** Called after the block is placed by anyone. */
@CallSuper
public void placed(Tile tile){
if(Net.client()) return;
if(net.client()) return;
if((consumesPower && !outputsPower) || (!consumesPower && outputsPower)){
int range = 10;

View File

@@ -4,10 +4,11 @@ import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.net.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.*;
import static io.anuke.mindustry.Vars.net;
public class RespawnBlock{
public static void drawRespawn(Tile tile, float heat, float progress, float time, Player player, Mech to){
@@ -64,7 +65,7 @@ public class RespawnBlock{
}
Draw.reset();
if(Net.active() && player != null){
if(net.active() && player != null){
tile.block().drawPlaceText(player.name, tile.x, tile.y - (Math.max((tile.block().size-1)/2, 0)), true);
}
}

View File

@@ -100,7 +100,7 @@ public class PowerNode extends PowerBlock{
@Override
public void placed(Tile tile){
if(Net.client()) return;
if(net.client()) return;
Predicate<Tile> valid = other -> other != null && other != tile && ((!other.block().outputsPower && other.block().consumesPower) || (other.block().outputsPower && !other.block().consumesPower) || other.block() instanceof PowerNode) && linkValid(tile, other)
&& !other.entity.proximity().contains(tile) && other.entity.power.graph != tile.entity.power.graph;

View File

@@ -94,7 +94,7 @@ public class CoreBlock extends StorageBlock{
@Override
public void handleItem(Item item, Tile tile, Tile source){
if(Net.server() || !Net.active()){
if(net.server() || !net.active()){
super.handleItem(item, tile, source);
if(state.rules.tutorial){
Events.fire(new CoreItemDeliverEvent());

View File

@@ -13,7 +13,6 @@ import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.gen.Call;
import io.anuke.mindustry.graphics.Pal;
import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.Bar;
import io.anuke.mindustry.world.Block;
@@ -23,6 +22,7 @@ import io.anuke.mindustry.world.consumers.ConsumeType;
import io.anuke.mindustry.world.meta.*;
import java.io.*;
import static io.anuke.mindustry.Vars.*;
public class UnitFactory extends Block{
protected UnitType type;
@@ -54,7 +54,7 @@ public class UnitFactory extends Block{
Effects.shake(2f, 3f, entity);
Effects.effect(Fx.producesmoke, tile.drawx(), tile.drawy());
if(!Net.client()){
if(!net.client()){
BaseUnit unit = factory.type.create(tile.getTeam());
unit.setSpawner(tile);
unit.set(tile.drawx() + Mathf.range(4), tile.drawy() + Mathf.range(4));