Minor admin bugfixes, made players wait 30 seconds after being kicked

This commit is contained in:
Anuken
2018-03-20 18:27:19 -04:00
parent ba7be0293c
commit 216b3969ed
9 changed files with 88 additions and 76 deletions

View File

@@ -38,6 +38,7 @@ 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 server! Ask the host to update! text.server.kicked.serverOutdated=Outdated server! Ask the host to update!
text.server.kicked.banned=You are banned on this server. text.server.kicked.banned=You are banned on this server.
text.server.kicked.recentKick=You have been kicked recently.\nWait before connecting again.
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!

View File

@@ -1,7 +1,7 @@
#Autogenerated file. Do not modify. #Autogenerated file. Do not modify.
#Mon Mar 19 20:53:58 EDT 2018 #Tue Mar 20 18:24:58 EDT 2018
version=release version=release
androidBuildCode=450 androidBuildCode=452
name=Mindustry name=Mindustry
code=3.4 code=3.4
build=custom build build=custom build

View File

@@ -7,12 +7,10 @@ import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.game.EventType.GameOverEvent; import io.anuke.mindustry.game.EventType.GameOverEvent;
import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.io.Version; import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.net.Administration; import io.anuke.mindustry.net.*;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Administration.PlayerInfo;
import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.NetworkIO;
import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.TraceInfo;
import io.anuke.mindustry.resource.*; import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Placement; import io.anuke.mindustry.world.Placement;
@@ -31,7 +29,7 @@ import java.nio.ByteBuffer;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
public class NetServer extends Module{ public class NetServer extends Module{
private final static float serverSyncTime = 4, itemSyncTime = 10; private final static float serverSyncTime = 4, itemSyncTime = 10, kickDuration = 30 * 1000;
private final static int timerEntitySync = 0; private final static int timerEntitySync = 0;
private final static int timerStateSync = 1; private final static int timerStateSync = 1;
@@ -50,39 +48,48 @@ public class NetServer extends Module{
Net.handleServer(Connect.class, (id, connect) -> { Net.handleServer(Connect.class, (id, connect) -> {
if(admins.isIPBanned(connect.addressTCP)){ if(admins.isIPBanned(connect.addressTCP)){
Net.kickConnection(id, KickReason.banned); kick(id, KickReason.banned);
} }
}); });
Net.handleServer(ConnectPacket.class, (id, packet) -> { Net.handleServer(ConnectPacket.class, (id, packet) -> {
String uuid = new String(Base64Coder.encode(packet.uuid)); String uuid = new String(Base64Coder.encode(packet.uuid));
if(Net.getConnection(id) == null || if(Net.getConnection(id) == null ||
admins.isIPBanned(Net.getConnection(id).address)) return; admins.isIPBanned(Net.getConnection(id).address)) return;
TraceInfo trace = admins.getTrace(Net.getConnection(id).address);
PlayerInfo info = admins.getInfo(uuid);
if(admins.isIDBanned(uuid)){ if(admins.isIDBanned(uuid)){
Net.kickConnection(id, KickReason.banned); kick(id, KickReason.banned);
return;
}
if(TimeUtils.millis() - info.lastKicked < kickDuration){
kick(id, KickReason.recentKick);
return; return;
} }
String ip = Net.getConnection(id).address; String ip = Net.getConnection(id).address;
admins.updatePlayerJoined(uuid, ip, packet.name); admins.updatePlayerJoined(uuid, ip, packet.name);
admins.getTrace(ip).uuid = uuid; trace.uuid = uuid;
admins.getTrace(ip).android = packet.android; trace.android = packet.android;
if(packet.version != Version.build && Version.build != -1 && packet.version != -1){ if(packet.version != Version.build && Version.build != -1 && packet.version != -1){
Net.kickConnection(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated); kick(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated);
return; return;
} }
if(packet.version == -1){ if(packet.version == -1){
admins.getTrace(ip).modclient = true; trace.modclient = true;
} }
Log.info("Sending data to player '{0}' / {1}", packet.name, id); Log.info("Sending data to player '{0}' / {1}", packet.name, id);
Player player = new Player(); Player player = new Player();
player.isAdmin = admins.isAdmin(Net.getConnection(id).address); player.isAdmin = admins.isAdmin(uuid, ip);
player.clientid = id; player.clientid = id;
player.name = packet.name; player.name = packet.name;
player.isAndroid = packet.android; player.isAndroid = packet.android;
@@ -92,7 +99,7 @@ public class NetServer extends Module{
player.color.set(packet.color); player.color.set(packet.color);
connections.put(id, player); connections.put(id, player);
admins.getTrace(ip).playerid = player.id; trace.playerid = player.id;
if(world.getMap().custom){ if(world.getMap().custom){
ByteArrayOutputStream stream = new ByteArrayOutputStream(); ByteArrayOutputStream stream = new ByteArrayOutputStream();
@@ -165,14 +172,14 @@ public class NetServer extends Module{
TraceInfo info = admins.getTrace(Net.getConnection(id).address); TraceInfo info = admins.getTrace(Net.getConnection(id).address);
Weapon weapon = (Weapon)Upgrade.getByID(packet.weaponid); Weapon weapon = (Weapon)Upgrade.getByID(packet.weaponid);
float wtrc = 45f; float wtrc = 40f;
if(!Timers.get(info.ip + "-weapontrace", wtrc)){ if(!Timers.get(info.ip + "-weapontrace", wtrc)){
info.fastShots ++; info.fastShots ++;
}else{ }else{
if(info.fastShots - 2 > (int)(wtrc / (weapon.getReload() / 2f))){ if(info.fastShots - 2 > (int)(wtrc / (weapon.getReload() / 2f))){
Net.kickConnection(id, KickReason.kick); kick(id, KickReason.kick);
} }
info.fastShots = 0; info.fastShots = 0;
@@ -296,10 +303,10 @@ public class NetServer extends Module{
if(packet.action == AdminAction.ban){ if(packet.action == AdminAction.ban){
admins.banPlayerIP(ip); admins.banPlayerIP(ip);
Net.kickConnection(other.clientid, KickReason.banned); kick(other.clientid, KickReason.banned);
Log.info("&lc{0} has banned {1}.", player.name, other.name); Log.info("&lc{0} has banned {1}.", player.name, other.name);
}else if(packet.action == AdminAction.kick){ }else if(packet.action == AdminAction.kick){
Net.kickConnection(other.clientid, KickReason.kick); kick(other.clientid, KickReason.kick);
Log.info("&lc{0} has kicked {1}.", player.name, other.name); Log.info("&lc{0} has kicked {1}.", player.name, other.name);
}else if(packet.action == AdminAction.trace){ }else if(packet.action == AdminAction.trace){
TracePacket trace = new TracePacket(); TracePacket trace = new TracePacket();
@@ -332,6 +339,31 @@ public class NetServer extends Module{
admins.clearTraces(); admins.clearTraces();
} }
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);
}
PlayerInfo info = admins.getInfo(admins.getTrace(con.address).uuid);
if(reason == KickReason.kick || reason == KickReason.banned){
info.timesKicked ++;
info.lastKicked = TimeUtils.millis();
}
KickPacket p = new KickPacket();
p.reason = reason;
con.send(p, SendMode.tcp);
Timers.runTask(2f, con::close);
admins.save();
}
void sync(){ void sync(){
if(timer.get(timerEntitySync, serverSyncTime)){ if(timer.get(timerEntitySync, serverSyncTime)){

View File

@@ -133,12 +133,13 @@ public class Administration {
} }
/**Makes a player an admin. Returns whether this player was already an admin.*/ /**Makes a player an admin. Returns whether this player was already an admin.*/
public boolean adminPlayer(String id){ public boolean adminPlayer(String id, String ip){
PlayerInfo info = getCreateInfo(id); PlayerInfo info = getCreateInfo(id);
if(info.admin) if(info.admin)
return false; return false;
info.validAdminIP = ip;
info.admin = true; info.admin = true;
save(); save();
@@ -166,8 +167,9 @@ public class Administration {
return getCreateInfo(uuid).banned; return getCreateInfo(uuid).banned;
} }
public boolean isAdmin(String id){ public boolean isAdmin(String id, String ip){
return getCreateInfo(id).admin; PlayerInfo info = getCreateInfo(id);
return info.admin && ip.equals(info.validAdminIP);
} }
public PlayerInfo getInfo(String id){ public PlayerInfo getInfo(String id){
@@ -212,6 +214,7 @@ public class Administration {
public static class PlayerInfo{ public static class PlayerInfo{
public String id; public String id;
public String lastName = "<unknown>", lastIP = "<unknown>"; public String lastName = "<unknown>", lastIP = "<unknown>";
public String validAdminIP;
public Array<String> ips = new Array<>(); public Array<String> ips = new Array<>();
public Array<String> names = new Array<>(); public Array<String> names = new Array<>();
public int timesKicked; //TODO not implemented! public int timesKicked; //TODO not implemented!
@@ -219,6 +222,7 @@ public class Administration {
public int totalBlockPlaced; public int totalBlockPlaced;
public int totalBlocksBroken; public int totalBlocksBroken;
public boolean banned, admin; public boolean banned, admin;
public long lastKicked; //last kicked timestamp
PlayerInfo(String id){ PlayerInfo(String id){
this.id = id; this.id = id;

View File

@@ -12,7 +12,6 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.io.Platform; import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.net.Packet.ImportantPacket; import io.anuke.mindustry.net.Packet.ImportantPacket;
import io.anuke.mindustry.net.Packet.UnimportantPacket; import io.anuke.mindustry.net.Packet.UnimportantPacket;
import io.anuke.mindustry.net.Packets.KickReason;
import io.anuke.mindustry.net.Streamable.StreamBegin; import io.anuke.mindustry.net.Streamable.StreamBegin;
import io.anuke.mindustry.net.Streamable.StreamBuilder; import io.anuke.mindustry.net.Streamable.StreamBuilder;
import io.anuke.mindustry.net.Streamable.StreamChunk; import io.anuke.mindustry.net.Streamable.StreamChunk;
@@ -101,11 +100,6 @@ public class Net{
clientProvider.discover(cons); clientProvider.discover(cons);
} }
/**Kick a specified connection from the server.*/
public static void kickConnection(int id, KickReason reason){
serverProvider.kick(id, reason);
}
/**Returns a list of all connections IDs.*/ /**Returns a list of all connections IDs.*/
public static Array<NetConnection> getConnections(){ public static Array<NetConnection> getConnections(){
return (Array<NetConnection>)serverProvider.getConnections(); return (Array<NetConnection>)serverProvider.getConnections();
@@ -307,10 +301,6 @@ public class Net{
Array<? extends NetConnection> getConnections(); Array<? extends NetConnection> getConnections();
/**Returns a connection by ID.*/ /**Returns a connection by ID.*/
NetConnection getByID(int id); NetConnection getByID(int id);
/**Kick a certain connection.*/
void kick(int connection, KickReason reason);
/**Returns the ping for a certain connection.*/
int getPingFor(NetConnection connection);
/**Close all connections.*/ /**Close all connections.*/
void dispose(); void dispose();
} }

View File

@@ -377,7 +377,7 @@ public class Packets {
} }
public enum KickReason{ public enum KickReason{
kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true); kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick;
public final boolean quiet; public final boolean quiet;
KickReason(){ quiet = false; } KickReason(){ quiet = false; }

View File

@@ -130,7 +130,7 @@ public class PlayerListFragment implements Fragment{
ui.showConfirm("$text.confirm", "$text.confirmban", () -> { ui.showConfirm("$text.confirm", "$text.confirmban", () -> {
if(Net.server()) { if(Net.server()) {
netServer.admins.banPlayerIP(connection.address); netServer.admins.banPlayerIP(connection.address);
Net.kickConnection(player.clientid, KickReason.banned); netServer.kick(player.clientid, KickReason.banned);
}else{ }else{
NetEvents.handleAdministerRequest(player, AdminAction.ban); NetEvents.handleAdministerRequest(player, AdminAction.ban);
} }
@@ -139,7 +139,7 @@ public class PlayerListFragment implements Fragment{
t.addImageButton("icon-cancel", 14*2, () -> { t.addImageButton("icon-cancel", 14*2, () -> {
if(Net.server()) { if(Net.server()) {
Net.kickConnection(player.clientid, KickReason.kick); netServer.kick(player.clientid, KickReason.kick);
}else{ }else{
NetEvents.handleAdministerRequest(player, AdminAction.kick); NetEvents.handleAdministerRequest(player, AdminAction.kick);
} }
@@ -150,14 +150,16 @@ public class PlayerListFragment implements Fragment{
t.addImageButton("icon-admin", "toggle", 14*2, () -> { t.addImageButton("icon-admin", "toggle", 14*2, () -> {
if(Net.client()) return; if(Net.client()) return;
if(netServer.admins.isAdmin(connection.address)){ String id = netServer.admins.getTrace(connection.address).uuid;
if(netServer.admins.isAdmin(id, connection.address)){
ui.showConfirm("$text.confirm", "$text.confirmunadmin", () -> { ui.showConfirm("$text.confirm", "$text.confirmunadmin", () -> {
netServer.admins.unAdminPlayer(connection.address); netServer.admins.unAdminPlayer(id);
NetEvents.handleAdminSet(player, false); NetEvents.handleAdminSet(player, false);
}); });
}else{ }else{
ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> { ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> {
netServer.admins.adminPlayer(connection.address); netServer.admins.adminPlayer(id, connection.address);
NetEvents.handleAdminSet(player, true); NetEvents.handleAdminSet(player, true);
}); });
} }

View File

@@ -134,23 +134,6 @@ public class KryoServer implements ServerProvider {
return null; return null;
} }
@Override
public void kick(int connection, KickReason reason) {
KryoConnection con = getByID(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);
}
KickPacket p = new KickPacket();
p.reason = reason;
con.send(p, SendMode.tcp);
Timers.runTask(2f, con::close);
}
@Override @Override
public void host(int port) throws IOException { public void host(int port) throws IOException {
lastconnection = 0; lastconnection = 0;
@@ -278,12 +261,6 @@ public class KryoServer implements ServerProvider {
} }
} }
@Override
public int getPingFor(NetConnection con) {
KryoConnection k = (KryoConnection)con;
return k.connection == null ? 0 : k.connection.getReturnTripTime();
}
@Override @Override
public void dispose(){ public void dispose(){
close(); close();

View File

@@ -78,7 +78,7 @@ public class ServerControl extends Module {
info("Game over!"); info("Game over!");
for(NetConnection connection : Net.getConnections()){ for(NetConnection connection : Net.getConnections()){
Net.kickConnection(connection.id, KickReason.gameover); netServer.kick(connection.id, KickReason.gameover);
} }
if (mode != ShuffleMode.off) { if (mode != ShuffleMode.off) {
@@ -127,22 +127,28 @@ public class ServerControl extends Module {
Log.info("Stopped server."); Log.info("Stopped server.");
}); });
handler.register("host", "<mapname> [mode]", "Open the server with a specific map.", arg -> { handler.register("host", "[mapname] [mode]", "Open the server with a specific map.", arg -> {
if(state.is(State.playing)){ if(state.is(State.playing)){
err("Already hosting. Type 'stop' to stop hosting first."); err("Already hosting. Type 'stop' to stop hosting first.");
return; return;
} }
String search = arg[0];
Map result = null; Map result = null;
for(Map map : world.maps().list()){
if(map.name.equalsIgnoreCase(search))
result = map;
}
if(result == null){ if(arg.length > 0) {
err("No map with name &y'{0}'&lr found.", search); String search = arg[0];
return; for (Map map : world.maps().list()) {
if (map.name.equalsIgnoreCase(search))
result = map;
}
if(result == null){
err("No map with name &y'{0}'&lr found.", search);
return;
}
}else{
while(result == null || result.visible)
result = world.maps().getAllMaps().random();
} }
GameMode mode = null; GameMode mode = null;
@@ -273,7 +279,7 @@ public class ServerControl extends Module {
} }
if(target != null){ if(target != null){
Net.kickConnection(target.clientid, KickReason.kick); netServer.kick(target.clientid, KickReason.kick);
info("It is done."); info("It is done.");
}else{ }else{
info("Nobody with that name could be found..."); info("Nobody with that name could be found...");
@@ -299,7 +305,7 @@ public class ServerControl extends Module {
String ip = Net.getConnection(target.clientid).address; String ip = Net.getConnection(target.clientid).address;
netServer.admins.banPlayerIP(ip); netServer.admins.banPlayerIP(ip);
netServer.admins.banPlayerID(netServer.admins.getTrace(ip).uuid); netServer.admins.banPlayerID(netServer.admins.getTrace(ip).uuid);
Net.kickConnection(target.clientid, KickReason.banned); netServer.kick(target.clientid, KickReason.banned);
info("Banned player by IP and ID: {0} / {1}", ip, netServer.admins.getTrace(ip).uuid); info("Banned player by IP and ID: {0} / {1}", ip, netServer.admins.getTrace(ip).uuid);
}else{ }else{
info("Nobody with that name could be found."); info("Nobody with that name could be found.");
@@ -337,7 +343,7 @@ public class ServerControl extends Module {
for(Player player : playerGroup.all()){ for(Player player : playerGroup.all()){
if(Net.getConnection(player.clientid).address.equals(arg[0])){ if(Net.getConnection(player.clientid).address.equals(arg[0])){
Net.kickConnection(player.clientid, KickReason.banned); netServer.kick(player.clientid, KickReason.banned);
break; break;
} }
} }
@@ -352,7 +358,7 @@ public class ServerControl extends Module {
for(Player player : playerGroup.all()){ for(Player player : playerGroup.all()){
if(netServer.admins.getTrace(Net.getConnection(player.clientid).address).uuid.equals(arg[0])){ if(netServer.admins.getTrace(Net.getConnection(player.clientid).address).uuid.equals(arg[0])){
Net.kickConnection(player.clientid, KickReason.banned); netServer.kick(player.clientid, KickReason.banned);
break; break;
} }
} }
@@ -394,7 +400,7 @@ public class ServerControl extends Module {
if(target != null){ if(target != null){
String id = netServer.admins.getTrace(Net.getConnection(target.clientid).address).uuid; String id = netServer.admins.getTrace(Net.getConnection(target.clientid).address).uuid;
netServer.admins.adminPlayer(id); netServer.admins.adminPlayer(id, Net.getConnection(target.clientid).address);
NetEvents.handleAdminSet(target, true); NetEvents.handleAdminSet(target, true);
info("Admin-ed player by ID: {0} / {1}", id, arg[0]); info("Admin-ed player by ID: {0} / {1}", id, arg[0]);
}else{ }else{