Replaced ArrayLists with Arrays, overhauled requesting of logs from the server, improved rollback command and added log resetting.

This commit is contained in:
Commodore64x
2018-05-14 18:48:44 +10:00
parent 7f2c2d9d6b
commit b3adf7b331
11 changed files with 78 additions and 72 deletions

View File

@ -4,6 +4,7 @@ import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.core.*; import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.Bullet; import io.anuke.mindustry.entities.Bullet;
@ -20,7 +21,6 @@ import io.anuke.ucore.entities.EffectEntity;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
public class Vars{ public class Vars{
@ -81,8 +81,6 @@ public class Vars{
public static boolean showUI = true; public static boolean showUI = true;
//whether to show block debug //whether to show block debug
public static boolean showBlockDebug = false; public static boolean showBlockDebug = false;
public static IntMap<ArrayList<EditLog>> editLogs = new IntMap<>();
public static boolean headless = false; public static boolean headless = false;
@ -94,6 +92,8 @@ public class Vars{
//amount of drops that are left when breaking a block //amount of drops that are left when breaking a block
public static final float breakDropAmount = 0.5f; public static final float breakDropAmount = 0.5f;
public static Array<EditLog> currentEditLogs = new Array<>();
//only if smoothCamera //only if smoothCamera
public static boolean snapCamera = true; public static boolean snapCamera = true;

View File

@ -169,9 +169,9 @@ public class NetClient extends Module {
ui.hudfrag.updateItems(); ui.hudfrag.updateItems();
}); });
Net.handleClient(BlockLogSyncPacket.class, packet -> { Net.handleClient(BlockLogRequestPacket.class, packet -> {
Vars.editLogs = packet.editlogs; currentEditLogs = packet.editlogs;
}); });
Net.handleClient(PlacePacket.class, (packet) -> { Net.handleClient(PlacePacket.class, (packet) -> {
Placement.placeBlock(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, Timers.get("placeblocksound", 10)); Placement.placeBlock(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, Timers.get("placeblocksound", 10));
@ -256,6 +256,7 @@ public class NetClient extends Module {
world.getCore().entity != null){ world.getCore().entity != null){
world.getCore().entity.onDeath(true); world.getCore().entity.onDeath(true);
} }
netServer.admins.getEditLogs().clear();
kicked = true; kicked = true;
ui.restart.show(); ui.restart.show();
}); });

View File

@ -33,7 +33,6 @@ public class NetServer extends Module{
private final static int timerEntitySync = 0; private final static int timerEntitySync = 0;
private final static int timerStateSync = 1; private final static int timerStateSync = 1;
private final static int timerBlockLogSync = 2;
public final Administration admins = new Administration(); public final Administration admins = new Administration();
@ -348,6 +347,11 @@ public class NetServer extends Module{
Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name); Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name);
} }
}); });
Net.handleServer(BlockLogRequestPacket.class, (id, packet) -> {
packet.editlogs = EditLog.logsFromTile(packet.x, packet.y);
Net.sendTo(id, packet, SendMode.udp);
});
} }
public void update(){ public void update(){
@ -480,12 +484,5 @@ public class NetServer extends Module{
Net.send(packet, SendMode.udp); Net.send(packet, SendMode.udp);
} }
if(timer.get(timerBlockLogSync, serverSyncTime)) {
BlockLogSyncPacket packet = new BlockLogSyncPacket();
packet.editlogs = admins.getEditLogs();
Net.send(packet, SendMode.udp);
}
} }
} }

View File

@ -111,6 +111,7 @@ public class DesktopInput extends InputHandler{
if(recipe == null && !ui.hasMouse() && Inputs.keyDown("block_logs")) { if(recipe == null && !ui.hasMouse() && Inputs.keyDown("block_logs")) {
showCursor = true; showCursor = true;
if(Inputs.keyTap("select")){ if(Inputs.keyTap("select")){
NetEvents.handleBlockLogRequest(getBlockX(), getBlockY());
Timers.runTask(20f, () -> { Timers.runTask(20f, () -> {
ui.hudfrag.blockfrag.showBlockLogs(getBlockX(), getBlockY()); ui.hudfrag.blockfrag.showBlockLogs(getBlockX(), getBlockY());
Cursors.restoreCursor(); Cursors.restoreCursor();

View File

@ -12,7 +12,6 @@ import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.mindustry.world.blocks.types.Rock; import io.anuke.mindustry.world.blocks.types.Rock;
import io.anuke.mindustry.world.blocks.types.StaticBlock; import io.anuke.mindustry.world.blocks.types.StaticBlock;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import java.util.ArrayList;
import static io.anuke.mindustry.Vars.world; import static io.anuke.mindustry.Vars.world;
public class Administration { public class Administration {
@ -25,7 +24,7 @@ public class Administration {
/**Maps UUIDs to trace infos. This is wiped when a player logs off.*/ /**Maps UUIDs to trace infos. This is wiped when a player logs off.*/
private ObjectMap<String, TraceInfo> traceInfo = new ObjectMap<>(); private ObjectMap<String, TraceInfo> traceInfo = new ObjectMap<>();
/**Maps packed coordinates to logs for that coordinate */ /**Maps packed coordinates to logs for that coordinate */
private IntMap<ArrayList<EditLog>> editLogs = new IntMap<>(); private IntMap<Array<EditLog>> editLogs = new IntMap<>();
private Array<String> bannedIPs = new Array<>(); private Array<String> bannedIPs = new Array<>();
@ -60,17 +59,21 @@ public class Administration {
Settings.save(); Settings.save();
} }
public IntMap<ArrayList<EditLog>> getEditLogs() { public IntMap<Array<EditLog>> getEditLogs() {
return editLogs; return editLogs;
} }
public void setEditLogs(IntMap<Array<EditLog>> editLogs) {
this.editLogs = editLogs;
}
public void logEdit(int x, int y, Player player, Block block, int rotation, EditLog.EditAction action) { public void logEdit(int x, int y, Player player, Block block, int rotation, EditLog.EditAction action) {
if(block instanceof BlockPart || block instanceof Rock || block instanceof Floor || block instanceof StaticBlock) return; if(block instanceof BlockPart || block instanceof Rock || block instanceof Floor || block instanceof StaticBlock) return;
if(editLogs.containsKey(x + y * world.width())) { if(editLogs.containsKey(x + y * world.width())) {
editLogs.get(x + y * world.width()).add(new EditLog(player, block, rotation, action)); editLogs.get(x + y * world.width()).add(new EditLog(player, block, rotation, action));
} }
else { else {
ArrayList<EditLog> logs = new ArrayList<>(); Array<EditLog> logs = new Array<>();
logs.add(new EditLog(player, block, rotation, action)); logs.add(new EditLog(player, block, rotation, action));
editLogs.put(x + y * world.width(), logs); editLogs.put(x + y * world.width(), logs);
} }

View File

@ -1,8 +1,12 @@
package io.anuke.mindustry.net; package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import static io.anuke.mindustry.Vars.netServer;
import static io.anuke.mindustry.Vars.playerGroup; import static io.anuke.mindustry.Vars.playerGroup;
import static io.anuke.mindustry.Vars.world;
public class EditLog { public class EditLog {
@ -30,6 +34,15 @@ public class EditLog {
EditAction.valueOf(parts[3])); EditAction.valueOf(parts[3]));
} }
public static Array<EditLog> logsFromTile(int x, int y) {
for(IntMap.Entry<Array<EditLog>> editLog : netServer.admins.getEditLogs().entries()) {
if(editLog.key == (x + y * world.width())) {
return editLog.value;
}
}
return new Array<>();
}
public String toString() { public String toString() {
return String.format("%s:%s:%s:%s", player.id, block.id, rotation, action.toString()); return String.format("%s:%s:%s:%s", player.id, block.id, rotation, action.toString());
} }

View File

@ -177,4 +177,13 @@ public class NetEvents {
ui.traces.show(target, netServer.admins.getTrace(Net.getConnection(target.clientid).address)); ui.traces.show(target, netServer.admins.getTrace(Net.getConnection(target.clientid).address));
} }
} }
public static void handleBlockLogRequest(int x, int y) {
BlockLogRequestPacket packet = new BlockLogRequestPacket();
packet.x = x;
packet.y = y;
packet.editlogs = Vars.currentEditLogs;
Net.send(packet, SendMode.udp);
}
} }

View File

@ -1,5 +1,6 @@
package io.anuke.mindustry.net; package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Base64Coder; import com.badlogic.gdx.utils.Base64Coder;
import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ClassReflection;
@ -14,7 +15,6 @@ import io.anuke.mindustry.world.Block;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList;
/**Class for storing all packets.*/ /**Class for storing all packets.*/
public class Packets { public class Packets {
@ -140,51 +140,36 @@ public class Packets {
timestamp = buffer.getLong(); timestamp = buffer.getLong();
} }
} }
public static class BlockLogSyncPacket implements Packet {
public IntMap<ArrayList<EditLog>> editlogs;
public static class BlockLogRequestPacket implements Packet {
public int x;
public int y;
public Array<EditLog> editlogs;
@Override @Override
public void write(ByteBuffer buffer) { public void write(ByteBuffer buffer) {
int size = editlogs.size; buffer.putInt(x);
buffer.putInt(size); buffer.putInt(y);
for(IntMap.Entry<ArrayList<EditLog>> editlog :editlogs.entries()) { buffer.putInt(editlogs.size);
for(EditLog value : editlogs) {
String key = String.valueOf(editlog.key); String rawValue = value.toString();
buffer.put((byte) key.getBytes().length); buffer.put((byte) rawValue.getBytes().length);
buffer.put(key.getBytes()); buffer.put(rawValue.getBytes());
ArrayList<EditLog> values = editlog.value;
buffer.putInt(values.size());
for(EditLog value : values) {
String rawValue = value.toString();
buffer.put((byte) rawValue.getBytes().length);
buffer.put(rawValue.getBytes());
}
} }
} }
@Override @Override
public void read(ByteBuffer buffer) { public void read(ByteBuffer buffer) {
editlogs = new IntMap<>(); x = buffer.getInt();
int logssize = buffer.getInt(); y = buffer.getInt();
for(int i = 0; i < logssize; i ++){ editlogs = new Array<>();
int arraySize = buffer.getInt();
byte length = buffer.get(); for(int a = 0; a < arraySize; a ++) {
byte[] bytes = new byte[length];
buffer.get(bytes);
Integer key = Integer.valueOf(new String(bytes));
ArrayList<EditLog> list = new ArrayList<>();
int arraySize = buffer.getInt();
for(int a = 0; a < arraySize; a ++) {
byte[] arraybytes = new byte[buffer.get()]; byte[] arraybytes = new byte[buffer.get()];
buffer.get(arraybytes); buffer.get(arraybytes);
list.add(EditLog.valueOf(new String(arraybytes))); editlogs.add(EditLog.valueOf(new String(arraybytes)));
}
editlogs.put(key, list);
} }
} }
} }

View File

@ -17,7 +17,7 @@ public class Registrator {
PlacePacket.class, PlacePacket.class,
BreakPacket.class, BreakPacket.class,
StateSyncPacket.class, StateSyncPacket.class,
BlockLogSyncPacket.class, BlockLogRequestPacket.class,
BlockSyncPacket.class, BlockSyncPacket.class,
BulletPacket.class, BulletPacket.class,
EnemyDeathPacket.class, EnemyDeathPacket.class,

View File

@ -9,6 +9,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.input.InputHandler; import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.net.EditLog; import io.anuke.mindustry.net.EditLog;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.*; import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.ui.dialogs.FloatingDialog; import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@ -26,7 +27,6 @@ import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Bundles; import io.anuke.ucore.util.Bundles;
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 java.util.ArrayList;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
public class BlocksFragment implements Fragment{ public class BlocksFragment implements Fragment{
@ -364,13 +364,13 @@ public class BlocksFragment implements Fragment{
d.content().add(pane).grow(); d.content().add(pane).grow();
ArrayList<EditLog> logs = Vars.editLogs.get(x + y * world.width()); Array<EditLog> logs = Vars.currentEditLogs;
if(logs == null || logs.isEmpty()) { if(logs == null || logs.size == 0) {
table.add("$text.block.editlogsnotfound").left(); table.add("$text.block.editlogsnotfound").left();
table.row(); table.row();
} }
else { else {
for(int i = 0; i < logs.size(); i++) { for(int i = 0; i < logs.size; i++) {
EditLog log = logs.get(i); EditLog log = logs.get(i);
table.add("[gold]" + (i + 1) + ". [white]" + log.info()).left(); table.add("[gold]" + (i + 1) + ". [white]" + log.info()).left();
table.row(); table.row();

View File

@ -30,15 +30,11 @@ import io.anuke.ucore.util.Log;
import io.anuke.ucore.util.Strings; import io.anuke.ucore.util.Strings;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner; import java.util.Scanner;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.util.Log.*; import static io.anuke.ucore.util.Log.*;
;
public class ServerControl extends Module { public class ServerControl extends Module {
private final CommandHandler handler = new CommandHandler(""); private final CommandHandler handler = new CommandHandler("");
private ShuffleMode mode; private ShuffleMode mode;
@ -734,25 +730,26 @@ public class ServerControl extends Module {
err("Open the server first."); err("Open the server first.");
return; return;
} }
if(arg[0] == null) {
err("Please specify the amount of block edit cycles to rollback"); if(!Strings.canParsePostiveInt(arg[0])) {
err("Please input a valid, positive, number of times to rollback");
return; return;
} }
int rollbackTimes = Integer.valueOf(arg[0]); int rollbackTimes = Integer.valueOf(arg[0]);
IntMap<ArrayList<EditLog>> editLogs = netServer.admins.getEditLogs(); IntMap<Array<EditLog>> editLogs = netServer.admins.getEditLogs();
if(editLogs.size == 0){ if(editLogs.size == 0){
err("Nothing to rollback!"); err("Nothing to rollback!");
return; return;
} }
for(IntMap.Entry<ArrayList<EditLog>> editLog : editLogs.entries()) { for(IntMap.Entry<Array<EditLog>> editLog : editLogs.entries()) {
int coords = editLog.key; int coords = editLog.key;
ArrayList<EditLog> logs = editLog.value; Array<EditLog> logs = editLog.value;
for(int i = 0; i < rollbackTimes; i++) { for(int i = 0; i < rollbackTimes; i++) {
EditLog log = logs.get(logs.size() - 1); EditLog log = logs.get(logs.size - 1);
int x = coords % world.width(); int x = coords % world.width();
int y = coords / world.width(); int y = coords / world.width();
@ -782,8 +779,8 @@ public class ServerControl extends Module {
Net.send(packet, Net.SendMode.tcp); Net.send(packet, Net.SendMode.tcp);
} }
logs.remove(logs.size() - 1); logs.removeIndex(logs.size - 1);
if(logs.isEmpty()) { if(logs.size == 0) {
editLogs.remove(coords); editLogs.remove(coords);
break; break;
} }