Skip to content

Commit

Permalink
Merge pull request #125 from hellomouse/feature-blocklogsandrollback
Browse files Browse the repository at this point in the history
Added edit logging and whole world rollback
  • Loading branch information
Anuken authored Jun 1, 2018
2 parents fcb74d4 + c79c238 commit a647efe
Show file tree
Hide file tree
Showing 17 changed files with 346 additions and 12 deletions.
4 changes: 4 additions & 0 deletions core/assets/bundles/bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ text.server.bans=Bans
text.server.bans.none=No banned players found!
text.server.admins=Admins
text.server.admins.none=No admins found!
text.server.rollback=Rollback
text.server.rollback.numberfield=Rollback Amount:
text.server.add=Add Server
text.server.delete=Are you sure you want to delete this server?
text.server.hostname=Host: {0}
Expand Down Expand Up @@ -209,6 +211,8 @@ placemode.touch.name=touch
placemode.cursor.name=cursor
text.blocks.extrainfo=[accent]extra block info:
text.blocks.blockinfo=Block Info
text.blocks.editlogs=Edit Logs
text.block.editlogsnotfound=[red]There are no edit logs for this location.
text.blocks.powercapacity=Power Capacity
text.blocks.powershot=Power/shot
text.blocks.powersecond=Power/second
Expand Down
6 changes: 5 additions & 1 deletion core/src/io/anuke/mindustry/Vars.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.effect.Shield;
import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.core.Platform;
import io.anuke.mindustry.net.EditLog;
import io.anuke.mindustry.net.ClientDebug;
import io.anuke.mindustry.net.ServerDebug;
import io.anuke.ucore.UCore;
Expand All @@ -19,7 +22,6 @@
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.OS;

import java.util.Locale;

public class Vars{
Expand Down Expand Up @@ -96,6 +98,8 @@ public class Vars{
//amount of drops that are left when breaking a block
public static final float breakDropAmount = 0.5f;

public static Array<EditLog> currentEditLogs = new Array<>();

//only if smoothCamera
public static boolean snapCamera = true;

Expand Down
5 changes: 5 additions & 0 deletions core/src/io/anuke/mindustry/core/NetClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType;
Expand Down Expand Up @@ -166,6 +167,10 @@ public NetClient(){

ui.hudfrag.updateItems();
});

Net.handleClient(BlockLogRequestPacket.class, packet -> {
currentEditLogs = packet.editlogs;
});

Net.handleClient(PlacePacket.class, (packet) -> {
Placement.placeBlock(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, Timers.get("placeblocksound", 10));
Expand Down
30 changes: 26 additions & 4 deletions core/src/io/anuke/mindustry/core/NetServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;

import static io.anuke.mindustry.Vars.*;

public class NetServer extends Module{
Expand All @@ -44,7 +43,10 @@ public class NetServer extends Module{

public NetServer(){

Events.on(GameOverEvent.class, () -> weapons.clear());
Events.on(GameOverEvent.class, () -> {
weapons.clear();
admins.getEditLogs().clear();
});

Net.handleServer(Connect.class, (id, connect) -> {
if(admins.isIPBanned(connect.addressTCP)){
Expand Down Expand Up @@ -211,6 +213,7 @@ public NetServer(){

Placement.placeBlock(packet.x, packet.y, block, packet.rotation, true, false);

admins.logEdit(packet.x, packet.y, connections.get(id), block, packet.rotation, EditLog.EditAction.PLACE);
admins.getTrace(Net.getConnection(id).address).lastBlockPlaced = block;
admins.getTrace(Net.getConnection(id).address).totalBlocksPlaced ++;
admins.getInfo(admins.getTrace(Net.getConnection(id).address).uuid).totalBlockPlaced ++;
Expand All @@ -235,6 +238,7 @@ public NetServer(){
Block block = Placement.breakBlock(packet.x, packet.y, true, false);

if(block != null) {
admins.logEdit(packet.x, packet.y, connections.get(id), block, tile.getRotation(), EditLog.EditAction.BREAK);
admins.getTrace(Net.getConnection(id).address).lastBlockBroken = block;
admins.getTrace(Net.getConnection(id).address).totalBlocksBroken++;
admins.getInfo(admins.getTrace(Net.getConnection(id).address).uuid).totalBlocksBroken ++;
Expand Down Expand Up @@ -312,7 +316,7 @@ public NetServer(){
packet.id = connections.get(id).id;
Net.sendExcept(id, packet, SendMode.tcp);
});

Net.handleServer(AdministerRequestPacket.class, (id, packet) -> {
Player player = connections.get(id);

Expand Down Expand Up @@ -345,6 +349,24 @@ public NetServer(){
Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name);
}
});

Net.handleServer(BlockLogRequestPacket.class, (id, packet) -> {
packet.editlogs = admins.getEditLogs().get(packet.x + packet.y * world.width(), new Array<>());
Net.sendTo(id, packet, SendMode.udp);
});

Net.handleServer(RollbackRequestPacket.class, (id, packet) -> {
Player player = connections.get(id);

if(!player.isAdmin){
Log.err("ACCESS DENIED: Player {0} / {1} attempted to perform a rollback without proper security access.",
player.name, Net.getConnection(player.clientid).address);
return;
}

admins.rollbackWorld(packet.rollbackTimes);
Log.info("&lc{0} has rolled back the world {1} times.", player.name, packet.rollbackTimes);
});
}

public void update(){
Expand Down Expand Up @@ -474,7 +496,7 @@ void sync(){
packet.wave = state.wave;
packet.time = Timers.time();
packet.timestamp = TimeUtils.millis();

Net.send(packet, SendMode.udp);
}
}
Expand Down
6 changes: 6 additions & 0 deletions core/src/io/anuke/mindustry/core/Renderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,12 @@ void drawOverlay(){
Lines.crect(target.drawx(), target.drawy(), target.block().width * tilesize, target.block().height * tilesize);
Draw.color();
}

if(Inputs.keyDown("block_logs")){
Draw.color(Colors.get("accent"));
Lines.crect(target.drawx(), target.drawy(), target.block().width * tilesize, target.block().height * tilesize);
Draw.color();
}

if(target.entity != null) {
int bot = 0, top = 0;
Expand Down
2 changes: 2 additions & 0 deletions core/src/io/anuke/mindustry/core/UI.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class UI extends SceneModule{
public BansDialog bans;
public AdminsDialog admins;
public TraceDialog traces;
public RollbackDialog rollback;
public ChangelogDialog changelog;

public final MenuFragment menufrag = new MenuFragment();
Expand Down Expand Up @@ -159,6 +160,7 @@ public void init(){
bans = new BansDialog();
admins = new AdminsDialog();
traces = new TraceDialog();
rollback = new RollbackDialog();

build.begin(scene);

Expand Down
1 change: 1 addition & 0 deletions core/src/io/anuke/mindustry/input/DefaultKeybinds.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public static void load(){
"rotate", new Axis(Input.SCROLL),
"toggle_menus", Input.C,
"block_info", Input.CONTROL_LEFT,
"block_logs", Input.I,
"player_list", Input.TAB,
"chat", Input.ENTER,
"chat_history_prev", Input.UP,
Expand Down
11 changes: 11 additions & 0 deletions core/src/io/anuke/mindustry/input/DesktopInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ public void update(){
Cursors.restoreCursor();
}
}

if(recipe == null && !ui.hasMouse() && Inputs.keyDown("block_logs")) {
showCursor = true;
if(Inputs.keyTap("select")){
NetEvents.handleBlockLogRequest(getBlockX(), getBlockY());
Timers.runTask(20f, () -> {
ui.hudfrag.blockfrag.showBlockLogs(getBlockX(), getBlockY());
Cursors.restoreCursor();
});
}
}

if(target != null && target.block().isConfigurable(target)){
showCursor = true;
Expand Down
74 changes: 74 additions & 0 deletions core/src/io/anuke/mindustry/net/Administration.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package io.anuke.mindustry.net;

import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Placement;
import io.anuke.mindustry.world.blocks.types.BlockPart;
import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.mindustry.world.blocks.types.Rock;
import io.anuke.mindustry.world.blocks.types.StaticBlock;
import io.anuke.ucore.core.Settings;
import static io.anuke.mindustry.Vars.world;

public class Administration {
public static final int defaultMaxBrokenBlocks = 15;
Expand All @@ -15,6 +24,9 @@ public class Administration {
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
/**Maps UUIDs to trace infos. This is wiped when a player logs off.*/
private ObjectMap<String, TraceInfo> traceInfo = new ObjectMap<>();
/**Maps packed coordinates to logs for that coordinate */
private IntMap<Array<EditLog>> editLogs = new IntMap<>();

private Array<String> bannedIPs = new Array<>();

public Administration(){
Expand Down Expand Up @@ -48,6 +60,68 @@ public void setAntiGriefParams(int maxBreak, int cooldown){
Settings.save();
}

public IntMap<Array<EditLog>> getEditLogs() {
return editLogs;
}

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(editLogs.containsKey(x + y * world.width())) {
editLogs.get(x + y * world.width()).add(new EditLog(player.name, block, rotation, action));
}
else {
Array<EditLog> logs = new Array<>();
logs.add(new EditLog(player.name, block, rotation, action));
editLogs.put(x + y * world.width(), logs);
}
}

public void rollbackWorld(int rollbackTimes) {
for(IntMap.Entry<Array<EditLog>> editLog : editLogs.entries()) {
int coords = editLog.key;
Array<EditLog> logs = editLog.value;

for(int i = 0; i < rollbackTimes; i++) {

EditLog log = logs.get(logs.size - 1);

int x = coords % world.width();
int y = coords / world.width();
Block result = log.block;
int rotation = log.rotation;

if(log.action == EditLog.EditAction.PLACE) {
Placement.breakBlock(x, y, false, false);

Packets.BreakPacket packet = new Packets.BreakPacket();
packet.x = (short) x;
packet.y = (short) y;
packet.playerid = 0;

Net.send(packet, Net.SendMode.tcp);
}
else if(log.action == EditLog.EditAction.BREAK) {
Placement.placeBlock(x, y, result, rotation, false, false);

Packets.PlacePacket packet = new Packets.PlacePacket();
packet.x = (short) x;
packet.y = (short) y;
packet.rotation = (byte) rotation;
packet.playerid = 0;
packet.block = result.id;

Net.send(packet, Net.SendMode.tcp);
}

logs.removeIndex(logs.size - 1);
if(logs.size == 0) {
editLogs.remove(coords);
break;
}
}
}
}

public boolean validateBreak(String id, String ip){
if(!isAntiGrief() || isAdmin(id, ip)) return true;

Expand Down
26 changes: 26 additions & 0 deletions core/src/io/anuke/mindustry/net/EditLog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.anuke.mindustry.net;

import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.world.Block;

public class EditLog {
public String playername;
public Block block;
public int rotation;
public EditAction action;

EditLog(String playername, Block block, int rotation, EditAction action) {
this.playername = playername;
this.block = block;
this.rotation = rotation;
this.action = action;
}

public String info() {
return String.format("Player: %s, Block: %s, Rotation: %s, Edit Action: %s", playername, block.name(), rotation, action.toString());
}

public enum EditAction {
PLACE, BREAK;
}
}
16 changes: 16 additions & 0 deletions core/src/io/anuke/mindustry/net/NetEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,20 @@ public static void handleTraceRequest(Player target){
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);
}

public static void handleRollbackRequest(int rollbackTimes) {
RollbackRequestPacket packet = new RollbackRequestPacket();
packet.rollbackTimes = rollbackTimes;

Net.send(packet, SendMode.udp);
}
}
Loading

0 comments on commit a647efe

Please sign in to comment.