Fixed many network-related bugs

This commit is contained in:
Anuken
2018-01-28 17:09:21 -05:00
parent 205c4e723a
commit 3562a70669
26 changed files with 284 additions and 79 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ text.server.closing=[accent]Closing server...
text.server.kicked.kick=You have been kicked from the server! text.server.kicked.kick=You have been kicked from the server!
text.server.kicked.invalidPassword=Invalid password! text.server.kicked.invalidPassword=Invalid password!
text.server.kicked.clientOutdated=Outdated client! Update your game! text.server.kicked.clientOutdated=Outdated client! Update your game!
text.server.kicked.serverOutdated=Outdated client! Update your game! text.server.kicked.serverOutdated=Outdated server! Ask the host to update!
text.server.connected={0} has joined. text.server.connected={0} has joined.
text.server.disconnected={0} has disconnected. text.server.disconnected={0} has disconnected.
text.nohost=Can't host server on a custom map! text.nohost=Can't host server on a custom map!
+8 -2
View File
@@ -9,6 +9,8 @@ import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Shield; import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.net.ClientDebug;
import io.anuke.mindustry.net.ServerDebug;
import io.anuke.ucore.UCore; import io.anuke.ucore.UCore;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
@@ -47,8 +49,9 @@ public class Vars{
//how much the zoom changes every zoom button press //how much the zoom changes every zoom button press
public static final int zoomScale = Math.round(Unit.dp.scl(1)); public static final int zoomScale = Math.round(Unit.dp.scl(1));
//if true, player speed will be increased, massive amounts of resources will be given on start, and other debug options will be available //if true, player speed will be increased, massive amounts of resources will be given on start, and other debug options will be available
public static boolean debug = false; public static boolean debug = true;
public static boolean debugNet = false; public static boolean debugNet = true;
public static boolean console = false;
//whether the player can clip through walls //whether the player can clip through walls
public static boolean noclip = false; public static boolean noclip = false;
//whether to draw chunk borders //whether to draw chunk borders
@@ -83,6 +86,9 @@ public class Vars{
public static final GameState state = new GameState(); public static final GameState state = new GameState();
public static final ServerDebug serverDebug = new ServerDebug();
public static final ClientDebug clientDebug = new ClientDebug();
public static Control control; public static Control control;
public static Logic logic; public static Logic logic;
public static Renderer renderer; public static Renderer renderer;
@@ -4,7 +4,7 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons; import com.badlogic.gdx.Input.Buttons;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.game.DefaultKeybinds; import io.anuke.mindustry.input.DefaultKeybinds;
import io.anuke.mindustry.game.EventType.*; import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.Tutorial; import io.anuke.mindustry.game.Tutorial;
import io.anuke.mindustry.game.UpgradeInventory; import io.anuke.mindustry.game.UpgradeInventory;
@@ -266,6 +266,10 @@ public class Control extends Module{
Gdx.input = proxy; Gdx.input = proxy;
} }
if(Inputs.keyTap("console")){
console = !console;
}
if(KeyBinds.getSection("default").device.type == DeviceType.controller){ if(KeyBinds.getSection("default").device.type == DeviceType.controller){
if(Inputs.keyTap("select")){ if(Inputs.keyTap("select")){
Inputs.getProcessor().touchDown(Gdx.input.getX(), Gdx.input.getY(), 0, Buttons.LEFT); Inputs.getProcessor().touchDown(Gdx.input.getX(), Gdx.input.getY(), 0, Buttons.LEFT);
+1 -1
View File
@@ -131,7 +131,7 @@ public class Logic extends Module {
} }
} }
if(state.wavetime <= 0 || state.extrawavetime <= 0){ if(!Net.client() && (state.wavetime <= 0 || state.extrawavetime <= 0)){
runWave(); runWave();
} }
@@ -114,6 +114,8 @@ public class NetClient extends Module {
Net.handleClient(SyncPacket.class, packet -> { Net.handleClient(SyncPacket.class, packet -> {
if (!gotData) return; if (!gotData) return;
int players = 0;
int enemies = 0;
ByteBuffer data = ByteBuffer.wrap(packet.data); ByteBuffer data = ByteBuffer.wrap(packet.data);
@@ -126,9 +128,11 @@ public class NetClient extends Module {
SyncEntity entity = (SyncEntity) group.getByID(id); SyncEntity entity = (SyncEntity) group.getByID(id);
if(entity instanceof Player) players ++;
if(entity instanceof Enemy) enemies ++;
if (entity == null || id == player.id) { if (entity == null || id == player.id) {
if (id != player.id) { if (id != player.id) {
Log.info("Requesting entity {0}, group {1}.", id, group.getType().toString().replace("class io.anuke.mindustry.entities.", ""));
EntityRequestPacket req = new EntityRequestPacket(); EntityRequestPacket req = new EntityRequestPacket();
req.id = id; req.id = id;
Net.send(req, SendMode.udp); Net.send(req, SendMode.udp);
@@ -138,6 +142,10 @@ public class NetClient extends Module {
entity.read(data); entity.read(data);
} }
} }
if(debugNet){
clientDebug.setSyncDebug(players, enemies);
}
}); });
Net.handleClient(StateSyncPacket.class, packet -> { Net.handleClient(StateSyncPacket.class, packet -> {
@@ -161,6 +169,7 @@ public class NetClient extends Module {
recieved.add(spawn.id); recieved.add(spawn.id);
Enemy enemy = new Enemy(EnemyType.getByID(spawn.type)); Enemy enemy = new Enemy(EnemyType.getByID(spawn.type));
enemy.interpolator.target.set(spawn.x, spawn.y);
enemy.set(spawn.x, spawn.y); enemy.set(spawn.x, spawn.y);
enemy.tier = spawn.tier; enemy.tier = spawn.tier;
enemy.lane = spawn.lane; enemy.lane = spawn.lane;
@@ -169,6 +178,8 @@ public class NetClient extends Module {
enemy.add(); enemy.add();
Effects.effect(Fx.spawn, enemy); Effects.effect(Fx.spawn, enemy);
Log.info("Recieved enemy {0}", spawn.id);
}); });
Net.handleClient(EnemyDeathPacket.class, spawn -> { Net.handleClient(EnemyDeathPacket.class, spawn -> {
@@ -264,6 +275,8 @@ public class NetClient extends Module {
player.interpolator.target.set(player.x, player.y); player.interpolator.target.set(player.x, player.y);
player.add(); player.add();
Log.info("Recieved player {0}", packet.id);
Platform.instance.updateRPC(); Platform.instance.updateRPC();
}); });
@@ -316,6 +329,11 @@ public class NetClient extends Module {
return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name; return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
} }
public void clearRecieved(){
recieved.clear();
dead.clear();
}
void sync(){ void sync(){
if(Timers.get("syncPlayer", playerSyncTime)){ if(Timers.get("syncPlayer", playerSyncTime)){
byte[] bytes = new byte[player.getWriteSize()]; byte[] bytes = new byte[player.getWriteSize()];
@@ -157,7 +157,7 @@ public class NetServer extends Module{
Net.handleServer(WeaponSwitchPacket.class, (id, packet) -> { Net.handleServer(WeaponSwitchPacket.class, (id, packet) -> {
packet.playerid = connections.get(id).id; packet.playerid = connections.get(id).id;
Net.sendExcept(player.clientid, packet, SendMode.tcp); Net.sendExcept(id, packet, SendMode.tcp);
}); });
Net.handleServer(BlockTapPacket.class, (id, packet) -> { Net.handleServer(BlockTapPacket.class, (id, packet) -> {
@@ -194,8 +194,6 @@ public class NetServer extends Module{
e.type = enemy.type.id; e.type = enemy.type.id;
e.health = (short) enemy.health; e.health = (short) enemy.health;
Net.sendTo(dest, e, SendMode.tcp); Net.sendTo(dest, e, SendMode.tcp);
} else {
Log.err("Entity request target not found!");
} }
}); });
@@ -9,6 +9,7 @@ import io.anuke.mindustry.game.GameMode;
import io.anuke.mindustry.io.SaveIO; import io.anuke.mindustry.io.SaveIO;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.Packets.ChatPacket; import io.anuke.mindustry.net.Packets.ChatPacket;
import io.anuke.mindustry.ui.fragments.DebugFragment;
import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Map;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Sounds; import io.anuke.ucore.core.Sounds;
@@ -119,7 +120,8 @@ public class ServerControl extends Module {
if(state.is(State.menu)){ if(state.is(State.menu)){
info("&lyStatus: &rserver closed"); info("&lyStatus: &rserver closed");
}else{ }else{
info("&lyStatus: &lcPlaying on map &fi{0}&fb &lb/&lc Wave {1} &lb/&lcDifficulty {2}", Strings.capitalize(world.getMap().name), state.wave, state.difficulty.name()); info("&lyStatus: &lcPlaying on map &fi{0}&fb &lb/&lc Wave {1} &lb/&lc {2}",
Strings.capitalize(world.getMap().name), state.wave, Strings.capitalize(state.difficulty.name()));
if(playerGroup.size() > 0) { if(playerGroup.size() > 0) {
info("&lyPlayers: {0}", playerGroup.size()); info("&lyPlayers: {0}", playerGroup.size());
for (Player p : playerGroup.all()) { for (Player p : playerGroup.all()) {
@@ -138,7 +140,7 @@ public class ServerControl extends Module {
} }
netCommon.sendMessage("[pink][[Server]:[] " + arg[0]); netCommon.sendMessage("[pink][[Server]:[] " + arg[0]);
info("&ly[Server]: &lb{0}", arg[0]); info("&lyServer: &lb{0}", arg[0]);
}).mergeArgs(); }).mergeArgs();
handler.register("difficulty", "<difficulty>", "Set game difficulty.", arg -> { handler.register("difficulty", "<difficulty>", "Set game difficulty.", arg -> {
@@ -188,6 +190,10 @@ public class ServerControl extends Module {
info("Saved to slot {0}.", slot); info("Saved to slot {0}.", slot);
}); });
handler.register("info", "", "Print debug info", arg -> {
info(DebugFragment.debugInfo());
});
} }
private void readCommands(){ private void readCommands(){
+2
View File
@@ -55,6 +55,7 @@ public class UI extends SceneModule{
public final BackgroundFragment backfrag = new BackgroundFragment(); public final BackgroundFragment backfrag = new BackgroundFragment();
public final LoadingFragment loadfrag = new LoadingFragment(); public final LoadingFragment loadfrag = new LoadingFragment();
public final BlockConfigFragment configfrag = new BlockConfigFragment(); public final BlockConfigFragment configfrag = new BlockConfigFragment();
public final DebugFragment debugfrag = new DebugFragment();
private Locale lastLocale; private Locale lastLocale;
@@ -160,6 +161,7 @@ public class UI extends SceneModule{
toolfrag.build(); toolfrag.build();
chatfrag.build(); chatfrag.build();
listfrag.build(); listfrag.build();
debugfrag.build();
loadfrag.build(); loadfrag.build();
build.end(); build.end();
@@ -139,14 +139,14 @@ public class EnemyType {
} }
public void move(Enemy enemy){ public void move(Enemy enemy){
float speed = this.speed + 0.04f * enemy.tier; if(Net.client()){
float range = this.range + enemy.tier * 5;
if(Net.client() && Net.active()){
enemy.interpolate(); //TODO? better structure for interpolation enemy.interpolate(); //TODO? better structure for interpolation
return; return;
} }
float speed = this.speed + 0.04f * enemy.tier;
float range = this.range + enemy.tier * 5;
Tile core = world.getCore(); Tile core = world.getCore();
if(enemy.idletime > maxIdleLife){ if(enemy.idletime > maxIdleLife){
@@ -194,8 +194,12 @@ public class EnemyType {
enemy.move(vec.x * Timers.delta(), vec.y * Timers.delta()); enemy.move(vec.x * Timers.delta(), vec.y * Timers.delta());
updateTargeting(enemy, nearCore); updateTargeting(enemy, nearCore);
behavior(enemy);
} }
public void behavior(Enemy enemy){}
public void updateTargeting(Enemy enemy, boolean nearCore){ public void updateTargeting(Enemy enemy, boolean nearCore){
if(enemy.target != null && enemy.target instanceof TileEntity && ((TileEntity)enemy.target).dead){ if(enemy.target != null && enemy.target instanceof TileEntity && ((TileEntity)enemy.target).dead){
enemy.target = null; enemy.target = null;
@@ -1,4 +0,0 @@
package io.anuke.mindustry.entities.enemies;
public class StandardEnemy {
}
@@ -1,7 +1,6 @@
package io.anuke.mindustry.entities.enemies.types; package io.anuke.mindustry.entities.enemies.types;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
@@ -9,6 +8,8 @@ import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.entities.enemies.EnemyType;
import io.anuke.ucore.util.Tmp; import io.anuke.ucore.util.Tmp;
import static io.anuke.mindustry.Vars.tilesize;
public class BlastType extends EnemyType { public class BlastType extends EnemyType {
public BlastType() { public BlastType() {
@@ -22,8 +23,7 @@ public class BlastType extends EnemyType {
} }
@Override @Override
public void move(Enemy enemy){ public void behavior(Enemy enemy){
super.move(enemy);
float range = 10f; float range = 10f;
Vector2 offset = Tmp.v3.setZero(); Vector2 offset = Tmp.v3.setZero();
@@ -1,6 +1,5 @@
package io.anuke.mindustry.entities.enemies.types; package io.anuke.mindustry.entities.enemies.types;
import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.entities.enemies.EnemyType; import io.anuke.mindustry.entities.enemies.EnemyType;
@@ -10,6 +9,8 @@ import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import static io.anuke.mindustry.Vars.world;
public class FortressType extends EnemyType { public class FortressType extends EnemyType {
final int maxSpawn = 6; final int maxSpawn = 6;
final float spawnTime = 190; final float spawnTime = 190;
@@ -29,7 +30,7 @@ public class FortressType extends EnemyType {
} }
@Override @Override
public void move(Enemy enemy){ public void behavior(Enemy enemy){
if(enemy.distanceTo(world.getCore().worldx(), if(enemy.distanceTo(world.getCore().worldx(),
world.getCore().worldy()) <= 90f){ world.getCore().worldy()) <= 90f){
@@ -47,8 +48,6 @@ public class FortressType extends EnemyType {
enemy.spawned ++; enemy.spawned ++;
} }
}else {
super.move(enemy);
} }
} }
@@ -35,8 +35,7 @@ public class HealerType extends EnemyType {
} }
@Override @Override
public void move(Enemy enemy){ public void behavior(Enemy enemy){
super.move(enemy);
if(enemy.idletime > 60f*3){ //explode after 3 seconds of stillness if(enemy.idletime > 60f*3){ //explode after 3 seconds of stillness
explode(enemy); explode(enemy);
@@ -14,11 +14,11 @@ import io.anuke.mindustry.world.blocks.types.production.Smelter;
import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Bundles;
public enum Difficulty { public enum Difficulty {
easy(4f, 2f, new DestrutiveHeuristic(b -> b instanceof Generator)), easy(4f, 2f, 1f, new DestrutiveHeuristic(b -> b instanceof Generator)),
normal(2f, 1f, new DestrutiveHeuristic(b -> b instanceof Smelter || b instanceof Generator)), normal(2f, 1f, 1f, new DestrutiveHeuristic(b -> b instanceof Smelter || b instanceof Generator)),
hard(1.5f, 0.5f, new DestrutiveHeuristic(b -> b instanceof Turret || b instanceof Generator || b instanceof Drill || b instanceof Smelter)), hard(1.5f, 0.5f, 0.75f, new DestrutiveHeuristic(b -> b instanceof Turret || b instanceof Generator || b instanceof Drill || b instanceof Smelter)),
insane(0.5f, 0.25f, new DestrutiveHeuristic(b -> b instanceof Generator || b instanceof Drill || b instanceof Smelter || b instanceof Router)), insane(0.5f, 0.25f, 0.5f, new DestrutiveHeuristic(b -> b instanceof Generator || b instanceof Drill || b instanceof Smelter || b instanceof Router)),
purge(0.25f, 0.01f, new DestrutiveHeuristic(b -> b instanceof Generator || b instanceof Drill || b instanceof Router purge(0.25f, 0.01f, 0.25f, new DestrutiveHeuristic(b -> b instanceof Generator || b instanceof Drill || b instanceof Router
|| b instanceof Smelter || b instanceof Conveyor || b instanceof LiquidBlock || b instanceof PowerBlock)); || b instanceof Smelter || b instanceof Conveyor || b instanceof LiquidBlock || b instanceof PowerBlock));
/**The scaling of how many waves it takes for one more enemy of a type to appear. /**The scaling of how many waves it takes for one more enemy of a type to appear.
@@ -27,13 +27,16 @@ public enum Difficulty {
public final float enemyScaling; public final float enemyScaling;
/**Multiplier of the time between waves.*/ /**Multiplier of the time between waves.*/
public final float timeScaling; public final float timeScaling;
/**Scaling of max time between waves. Default time is 4 minutes.*/
public final float maxTimeScaling;
/**Pathfdining heuristic for calculating tile costs.*/ /**Pathfdining heuristic for calculating tile costs.*/
public final Heuristic<Tile> heuristic; public final Heuristic<Tile> heuristic;
Difficulty(float enemyScaling, float timeScaling, Heuristic<Tile> heuristic){ Difficulty(float enemyScaling, float timeScaling, float maxTimeScaling, Heuristic<Tile> heuristic){
this.enemyScaling = enemyScaling; this.enemyScaling = enemyScaling;
this.timeScaling = timeScaling; this.timeScaling = timeScaling;
this.heuristic = heuristic; this.heuristic = heuristic;
this.maxTimeScaling = maxTimeScaling;
} }
@Override @Override
@@ -1,4 +1,4 @@
package io.anuke.mindustry.game; package io.anuke.mindustry.input;
import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
@@ -25,6 +25,7 @@ public class DefaultKeybinds {
"rotate", new Axis(Input.SCROLL), "rotate", new Axis(Input.SCROLL),
"player_list", Input.TAB, "player_list", Input.TAB,
"chat", Input.ENTER, "chat", Input.ENTER,
"console", Input.GRAVE,
"weapon_1", Input.NUM_1, "weapon_1", Input.NUM_1,
"weapon_2", Input.NUM_2, "weapon_2", Input.NUM_2,
"weapon_3", Input.NUM_3, "weapon_3", Input.NUM_3,
@@ -51,6 +52,7 @@ public class DefaultKeybinds {
"rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B),
"player_list", Input.CONTROLLER_START, "player_list", Input.CONTROLLER_START,
"chat", Input.ENTER, "chat", Input.ENTER,
"console", Input.GRAVE,
"weapon_1", Input.NUM_1, "weapon_1", Input.NUM_1,
"weapon_2", Input.NUM_2, "weapon_2", Input.NUM_2,
"weapon_3", Input.NUM_3, "weapon_3", Input.NUM_3,
@@ -0,0 +1,51 @@
package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.OrderedMap;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.reflect.ClassReflection;
public class ClientDebug {
private OrderedMap<Class<?>, Long> last = new OrderedMap<>();
private int syncPlayers = 0;
private int syncEnemies = 0;
public void handle(Object packet){
last.put(packet.getClass(), TimeUtils.millis());
}
public void setSyncDebug(int players, int enemies){
this.syncEnemies = enemies;
this.syncPlayers = players;
}
public String getOut(){
StringBuilder build = new StringBuilder();
for(Class<?> type : last.orderedKeys()){
build.append(elapsed(type));
build.append("\n");
}
build.append("sync.players: ");
build.append(syncPlayers);
build.append("\n");
build.append("sync.enemies: ");
build.append(syncEnemies);
build.append("\n");
return build.toString();
}
private String elapsed(Class<?> type){
long t = last.get(type, -1L);
if(t == -1){
return ClassReflection.getSimpleName(type) + ": <never>";
}else{
float el = TimeUtils.timeSinceMillis(t) / 1000f;
String tu;
if(el > 1f){
tu = (int)el + "s";
}else{
tu = (int)(el * 60) + "f";
}
return ClassReflection.getSimpleName(type) + ": " + tu;
}
}
}
+6 -3
View File
@@ -16,11 +16,10 @@ import io.anuke.ucore.util.Log;
import java.io.IOException; import java.io.IOException;
import static io.anuke.mindustry.Vars.headless; import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.ui;
public class Net{ public class Net{
public static final int version = 13; public static final int version = 14;
private static boolean server; private static boolean server;
private static boolean active; private static boolean active;
@@ -141,6 +140,8 @@ public class Net{
/**Call to handle a packet being recieved for the client.*/ /**Call to handle a packet being recieved for the client.*/
public static void handleClientReceived(Object object){ public static void handleClientReceived(Object object){
if(debugNet) clientDebug.handle(object);
if(object instanceof StreamBegin) { if(object instanceof StreamBegin) {
StreamBegin b = (StreamBegin) object; StreamBegin b = (StreamBegin) object;
streams.put(b.id, new StreamBuilder(b)); streams.put(b.id, new StreamBuilder(b));
@@ -170,6 +171,8 @@ public class Net{
/**Call to handle a packet being recieved for the server.*/ /**Call to handle a packet being recieved for the server.*/
public static void handleServerReceived(int connection, Object object){ public static void handleServerReceived(int connection, Object object){
if(debugNet) serverDebug.handle(object);
if(serverListeners.get(object.getClass()) != null || listeners.get(object.getClass()) != null){ if(serverListeners.get(object.getClass()) != null || listeners.get(object.getClass()) != null){
if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object); if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object);
if(listeners.get(object.getClass()) != null) listeners.get(object.getClass()).accept(object); if(listeners.get(object.getClass()) != null) listeners.get(object.getClass()).accept(object);
@@ -0,0 +1,8 @@
package io.anuke.mindustry.net;
public class ServerDebug {
public void handle(Object packet){
}
}
@@ -0,0 +1,120 @@
package io.anuke.mindustry.ui.fragments;
import com.badlogic.gdx.Gdx;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.entities.enemies.EnemyTypes;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.scene.builders.button;
import io.anuke.ucore.scene.builders.label;
import io.anuke.ucore.scene.builders.table;
import io.anuke.ucore.scene.ui.ScrollPane;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Log.LogHandler;
import static io.anuke.mindustry.Vars.*;
public class DebugFragment implements Fragment {
private static StringBuilder log = new StringBuilder();
static{
Log.setLogger(new LogHandler(){
@Override
public void print(String text, Object... args){
super.print(text, args);
log.append(Log.format(text, args));
log.append("\n");
}
});
}
@Override
public void build(){
new table(){{
visible(() -> debug);
atop().aright();
new table("pane"){{
defaults().fillX();
new label("Debug");
row();
new button("noclip", "toggle", () -> noclip = !noclip);
row();
new button("paths", "toggle", () -> showPaths = !showPaths);
row();
new button("infammo", "toggle", () -> infiniteAmmo = !infiniteAmmo);
row();
new button("wave", () -> logic.runWave());
row();
new button("clear", () -> {
enemyGroup.clear();
state.enemies = 0;
netClient.clearRecieved();
});
row();
new button("spawn", () -> new Enemy(EnemyTypes.standard).set(player.x, player.y).add());
row();
}}.end();
row();
}}.end();
new table(){{
visible(() -> console);
atop().aleft();
new table("pane") {{
defaults().fillX();
new label(DebugFragment::debugInfo);
row();
new button("dump", () -> {
try{
Gdx.files.local("packet-dump.txt").writeString(debugInfo(), false);
}catch (Exception e){
ui.showError("Error dumping log.");
}
});
}}.end();
}}.end();
new table(){{
visible(() -> console);
atop();
Table table = new Table("pane");
table.label(() -> log.toString());
ScrollPane pane = new ScrollPane(table, "clear");
get().add(pane);
}}.end();
}
public static String debugInfo(){
return join(
"net.active: " + Net.active(),
"net.server: " + Net.server(),
"players: " + playerGroup.size(),
"enemies: " + enemyGroup.size(),
"tiles: " + tileGroup.size(),
"",
clientDebug.getOut()
);
}
private static String join(String... strings){
StringBuilder builder = new StringBuilder();
for (String string : strings) {
builder.append(string);
builder.append("\n");
}
return builder.toString();
}
}
@@ -7,7 +7,6 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.actions.Actions; import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.label; import io.anuke.ucore.scene.builders.label;
@@ -148,26 +147,6 @@ public class HudFragment implements Fragment{
}}.end(); }}.end();
}}.end(); }}.end();
//profiling table
if(debug){
new table(){{
atop();
new label("[green]density: " + Gdx.graphics.getDensity()).left();
row();
new label(() -> "[blue]requests: " + renderer.getBlocks().getRequests()).left();
row();
new label(() -> "[purple]tiles: " + tileGroup.size()).left();
row();
new label(() -> "[purple]enemies: " + enemyGroup.size()).left();
row();
new label(() -> "[orange]noclip: " + noclip).left();
row();
new label(() -> "[purple]time: " + (int)(Timers.time() / 10f) % 50).left();
row();
new label("[red]DEBUG MODE").scale(0.5f).left();
}}.end();
}
new table(){{ new table(){{
abottom(); abottom();
visible(() -> !state.is(State.menu) && control.getSaves().isSaving()); visible(() -> !state.is(State.menu) && control.getSaves().isSaving());
@@ -176,14 +155,6 @@ public class HudFragment implements Fragment{
}}.end(); }}.end();
if(debugNet) {
new table() {{
new label(() -> "players: " + playerGroup.size());
row();
new label(() -> "" + playerGroup.all());
}}.end();
}
blockfrag.build(); blockfrag.build();
} }
@@ -75,9 +75,13 @@ public class Door extends Wall{
return true; return true;
} }
} }
if(Tmp.r2.overlaps(player.hitbox.getRect(player.x, player.y))){ for(SolidEntity e : Entities.getNearby(playerGroup, x * tilesize, y * tilesize, tilesize * 2f)){
return true; Rectangle rect = e.hitbox.getRect(e.x, e.y);
if(Tmp.r2.overlaps(rect)){
return true;
}
} }
return false; return false;
@@ -13,6 +13,7 @@ import io.anuke.ucore.entities.BulletEntity;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.renderer; import static io.anuke.mindustry.Vars.renderer;
public class ShieldBlock extends PowerBlock{ public class ShieldBlock extends PowerBlock{
@@ -76,7 +77,7 @@ public class ShieldBlock extends PowerBlock{
bullet.remove(); bullet.remove();
Effects.effect(bullet.damage > 5 ? Fx.shieldhit : Fx.laserhit, bullet); Effects.effect(bullet.damage > 5 ? Fx.shieldhit : Fx.laserhit, bullet);
renderer.addShieldHit(bullet.x, bullet.y); if(!headless) renderer.addShieldHit(bullet.x, bullet.y);
entity.power -= bullet.getDamage() * powerPerDamage; entity.power -= bullet.getDamage() * powerPerDamage;
} }
@@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.world.Layer; import io.anuke.mindustry.world.Layer;
@@ -20,7 +19,7 @@ import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.graphics.Shapes; import io.anuke.ucore.graphics.Shapes;
import io.anuke.ucore.util.*; import io.anuke.ucore.util.*;
import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.*;
public class Generator extends PowerBlock{ public class Generator extends PowerBlock{
public static final int powerTime = 2; public static final int powerTime = 2;
@@ -177,7 +176,8 @@ public class Generator extends PowerBlock{
if(target != null){ if(target != null){
boolean interfering = isInterfering(target, rotation); boolean interfering = isInterfering(target, rotation);
Tmp.v1.set(Angles.translation(rotation * 90, target.block().width * tilesize / 2 + 2f + (interfering ? Vector2.dst(tile.worldx(), tile.worldy(), target.worldx(), target.worldy()) / 2f - tilesize / 2f * target.block().width - 1 : 0))); Tmp.v1.set(Angles.translation(rotation * 90, target.block().width * tilesize / 2 + 2f +
(interfering ? Vector2.dst(tile.worldx(), tile.worldy(), target.worldx(), target.worldy()) / 2f - tilesize / 2f * target.block().width + 1 : 0)));
Angles.translation(rotation * 90, width * tilesize / 2 + 2f); Angles.translation(rotation * 90, width * tilesize / 2 + 2f);
@@ -191,7 +191,7 @@ public class Generator extends PowerBlock{
} }
} }
float r = interfering ? 0.8f : 0f; float r = interfering ? 0f : 0f;
int relative = tile.relativeTo(target.x, target.y); int relative = tile.relativeTo(target.x, target.y);
@@ -13,7 +13,6 @@ import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.Connect; import io.anuke.mindustry.net.Packets.Connect;
import io.anuke.mindustry.net.Packets.Disconnect; import io.anuke.mindustry.net.Packets.Disconnect;
import io.anuke.ucore.function.Consumer; import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.util.Log;
import java.io.IOException; import java.io.IOException;
import java.net.DatagramPacket; import java.net.DatagramPacket;
@@ -43,7 +42,6 @@ public class KryoClient implements ClientProvider{
ByteBuffer buffer = ByteBuffer.wrap(datagramPacket.getData()); ByteBuffer buffer = ByteBuffer.wrap(datagramPacket.getData());
Host address = KryoRegistrator.readServerData(datagramPacket.getAddress(), buffer); Host address = KryoRegistrator.readServerData(datagramPacket.getAddress(), buffer);
addresses.put(datagramPacket.getAddress(), address); addresses.put(datagramPacket.getAddress(), address);
Log.info("Host data found: {0} bytes.", buffer.capacity());
} }
@Override @Override
@@ -51,7 +51,6 @@ public class KryoServer implements ServerProvider {
server = new Server(4096*2, 2048, connection -> new ByteSerializer()); //TODO tweak server = new Server(4096*2, 2048, connection -> new ByteSerializer()); //TODO tweak
server.setDiscoveryHandler((datagramChannel, fromAddress) -> { server.setDiscoveryHandler((datagramChannel, fromAddress) -> {
ByteBuffer buffer = KryoRegistrator.writeServerData(); ByteBuffer buffer = KryoRegistrator.writeServerData();
Log.info("Replying to discover request with buffer of size {0}.", buffer.capacity());
buffer.position(0); buffer.position(0);
datagramChannel.send(buffer, fromAddress); datagramChannel.send(buffer, fromAddress);
return true; return true;
@@ -5,6 +5,7 @@ import io.anuke.kryonet.KryoClient;
import io.anuke.kryonet.KryoServer; import io.anuke.kryonet.KryoServer;
import io.anuke.mindustry.MindustryServer; import io.anuke.mindustry.MindustryServer;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.ucore.util.Log;
public class ServerLauncher{ public class ServerLauncher{
@@ -13,6 +14,18 @@ public class ServerLauncher{
Net.setClientProvider(new KryoClient()); Net.setClientProvider(new KryoClient());
Net.setServerProvider(new KryoServer()); Net.setServerProvider(new KryoServer());
new HeadlessApplication(new MindustryServer()); new HeadlessApplication(new MindustryServer()){
@Override
public boolean executeRunnables() {
try {
return super.executeRunnables();
}catch(Throwable e) {
Log.err(e);
System.exit(-1);
return false;
}
}
};
} }
} }