1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-09-22 22:07:31 +03:00

Added rollback into the admin menu, fixed a bug where players would crash upon trying to view their own logs on relog.

This commit is contained in:
Commodore64x 2018-05-19 13:37:44 +10:00
parent 380a955e7a
commit 68af32bc9f
12 changed files with 149 additions and 58 deletions

View File

@ -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}

View File

@ -355,6 +355,19 @@ public class NetServer extends Module{
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(){

View File

@ -49,6 +49,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();
@ -160,6 +161,7 @@ public class UI extends SceneModule{
bans = new BansDialog();
admins = new AdminsDialog();
traces = new TraceDialog();
rollback = new RollbackDialog();
build.begin(scene);

View File

@ -7,6 +7,7 @@ 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;
@ -66,15 +67,61 @@ public class Administration {
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, block, rotation, action));
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, block, rotation, action));
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;

View File

@ -4,20 +4,20 @@ import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.world.Block;
public class EditLog {
public Player player;
public String playername;
public Block block;
public int rotation;
public EditAction action;
EditLog(Player player, Block block, int rotation, EditAction action) {
this.player = player;
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", player.name, block.name(), rotation, action.toString());
return String.format("Player: %s, Block: %s, Rotation: %s, Edit Action: %s", playername, block.name(), rotation, action.toString());
}
public enum EditAction {

View File

@ -186,4 +186,11 @@ public class NetEvents {
Net.send(packet, SendMode.udp);
}
public static void handleRollbackRequest(int rollbackTimes) {
RollbackRequestPacket packet = new RollbackRequestPacket();
packet.rollbackTimes = rollbackTimes;
Net.send(packet, SendMode.udp);
}
}

View File

@ -153,7 +153,8 @@ public class Packets {
buffer.putShort((short)y);
buffer.putInt(editlogs.size);
for(EditLog value : editlogs) {
buffer.putInt(value.player.id);
buffer.put((byte)value.playername.getBytes().length);
buffer.put(value.playername.getBytes());
buffer.putInt(value.block.id);
buffer.put((byte) value.rotation);
buffer.put((byte) value.action.ordinal());
@ -167,16 +168,34 @@ public class Packets {
editlogs = new Array<>();
int arraySize = buffer.getInt();
for(int a = 0; a < arraySize; a ++) {
int playerid = buffer.getInt();
byte length = buffer.get();
byte[] bytes = new byte[length];
buffer.get(bytes);
String name = new String(bytes);
int blockid = buffer.getInt();
int rotation = buffer.get();
int ordinal = buffer.get();
editlogs.add(new EditLog(Vars.playerGroup.getByID(playerid), Block.getByID(blockid), rotation, EditLog.EditAction.values()[ordinal]));
editlogs.add(new EditLog(name, Block.getByID(blockid), rotation, EditLog.EditAction.values()[ordinal]));
}
}
}
public static class RollbackRequestPacket implements Packet {
public int rollbackTimes;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(rollbackTimes);
}
@Override
public void read(ByteBuffer buffer) {
rollbackTimes = buffer.getInt();
}
}
public static class PositionPacket implements Packet{
public byte[] data;

View File

@ -18,6 +18,7 @@ public class Registrator {
BreakPacket.class,
StateSyncPacket.class,
BlockLogRequestPacket.class,
RollbackRequestPacket.class,
BlockSyncPacket.class,
BulletPacket.class,
EnemyDeathPacket.class,

View File

@ -0,0 +1,41 @@
package io.anuke.mindustry.ui.dialogs;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.ucore.scene.ui.Label;
import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Strings;
import static io.anuke.mindustry.Vars.*;
public class RollbackDialog extends FloatingDialog {
public RollbackDialog(){
super("$text.server.rollback");
setup();
shown(this::setup);
}
private void setup(){
content().clear();
buttons().clear();
if(gwt) return;
content().row();
content().add("$text.server.rollback.numberfield");
TextField field = content().addField("", t->{}).get();
field.setTextFieldFilter((f, c) -> field.getText().length() < 4);
content().add(field).size(220f, 48f);
content().row();
buttons().defaults().size(50f, 50f).left().pad(2f);
buttons().addButton("$text.cancel", this::hide);
buttons().addButton("$text.ok", () -> {
NetEvents.handleRollbackRequest(Integer.valueOf(field.getText()));
hide();
}).disabled(b -> field.getText().isEmpty() || !Strings.canParsePostiveInt(field.getText()));
}
}

View File

@ -5,11 +5,9 @@ import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.net.EditLog;
import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
@ -364,14 +362,13 @@ public class BlocksFragment implements Fragment{
d.content().add(pane).grow();
Array<EditLog> logs = Vars.currentEditLogs;
if(logs == null || logs.size == 0) {
if(currentEditLogs == null || currentEditLogs.size == 0) {
table.add("$text.block.editlogsnotfound").left();
table.row();
}
else {
for(int i = 0; i < logs.size; i++) {
EditLog log = logs.get(i);
for(int i = 0; i < currentEditLogs.size; i++) {
EditLog log = currentEditLogs.get(i);
table.add("[gold]" + (i + 1) + ". [white]" + log.info()).left();
table.row();
}

View File

@ -58,6 +58,10 @@ public class PlayerListFragment implements Fragment{
new button("$text.server.admins", () -> {
ui.admins.show();
}).padTop(-12).padBottom(-12).padRight(-12).fillY().cell.disabled(b -> Net.client());
new button("$text.server.rollback", () -> {
ui.rollback.show();
}).padTop(-12).padBottom(-12).padRight(-12).fillY().cell.disabled(b -> !player.isAdmin);
}}.pad(10f).growX().end();
}}.end();

View File

@ -743,49 +743,7 @@ public class ServerControl extends Module {
return;
}
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;
}
}
}
netServer.admins.rollbackWorld(rollbackTimes);
info("Rollback done!");
});
}