Extensive network refactor
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -116,7 +116,7 @@ public class WaveSpawner{
|
||||
}
|
||||
|
||||
public boolean isSpawning(){
|
||||
return spawning && !Net.client();
|
||||
return spawning && !net.client();
|
||||
}
|
||||
|
||||
private void reset(){
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(){
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
|
||||
@@ -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){
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user