diff --git a/core/assets-raw/sprites/ui/icons/icon-admin-small.png b/core/assets-raw/sprites/ui/icons/icon-admin-small.png new file mode 100644 index 0000000000..c5cf9ef819 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-admin-small.png differ diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 77a8a23490..d2ae5b0efd 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -335,7 +335,7 @@ blocks/doubleturret index: -1 blocks/duriumwall rotate: false - xy: 117, 40 + xy: 132, 78 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -349,14 +349,14 @@ blocks/duriumwall-large index: -1 blocks/duriumwall-large-icon rotate: false - xy: 117, 30 + xy: 117, 40 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/enemyspawn rotate: false - xy: 117, 20 + xy: 117, 30 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -370,42 +370,42 @@ blocks/flameturret index: -1 blocks/fluxpump rotate: false - xy: 117, 10 + xy: 117, 20 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass1 rotate: false - xy: 865, 417 + xy: 117, 10 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass2 rotate: false - xy: 624, 233 + xy: 865, 417 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass3 rotate: false - xy: 624, 223 + xy: 624, 233 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock1 rotate: false - xy: 624, 213 + xy: 624, 223 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock2 rotate: false - xy: 634, 235 + xy: 624, 213 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -419,21 +419,21 @@ blocks/grassedge index: -1 blocks/ice1 rotate: false - xy: 634, 225 + xy: 634, 235 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice2 rotate: false - xy: 634, 215 + xy: 634, 225 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice3 rotate: false - xy: 178, 75 + xy: 634, 215 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -447,84 +447,84 @@ blocks/iceedge index: -1 blocks/icerock1 rotate: false - xy: 188, 75 + xy: 178, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerock2 rotate: false - xy: 198, 75 + xy: 188, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow1 rotate: false - xy: 208, 75 + xy: 198, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow1 rotate: false - xy: 208, 75 + xy: 198, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow2 rotate: false - xy: 218, 75 + xy: 208, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow2 rotate: false - xy: 218, 75 + xy: 208, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron1 rotate: false - xy: 248, 71 + xy: 238, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron2 rotate: false - xy: 258, 71 + xy: 248, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron3 rotate: false - xy: 268, 71 + xy: 258, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/irondrill rotate: false - xy: 278, 71 + xy: 268, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ironwall rotate: false - xy: 288, 71 + xy: 278, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/junction rotate: false - xy: 537, 140 + xy: 288, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -538,7 +538,7 @@ blocks/laserturret index: -1 blocks/lava rotate: false - xy: 300, 85 + xy: 537, 140 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -552,28 +552,28 @@ blocks/lavaedge index: -1 blocks/lavasmelter rotate: false - xy: 310, 85 + xy: 300, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquiditemjunction rotate: false - xy: 320, 85 + xy: 310, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidjunction rotate: false - xy: 330, 85 + xy: 320, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidrouter rotate: false - xy: 340, 85 + xy: 330, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -601,14 +601,14 @@ blocks/mortarturret index: -1 blocks/mossblock rotate: false - xy: 350, 85 + xy: 340, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/mossstone rotate: false - xy: 350, 85 + xy: 340, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -629,7 +629,7 @@ blocks/nuclearreactor-center index: -1 blocks/nuclearreactor-icon rotate: false - xy: 360, 85 + xy: 350, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -650,7 +650,7 @@ blocks/nuclearreactor-small index: -1 blocks/oil rotate: false - xy: 370, 85 + xy: 360, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -664,14 +664,14 @@ blocks/oiledge index: -1 blocks/oilrefinery rotate: false - xy: 380, 85 + xy: 370, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/omnidrill rotate: false - xy: 390, 85 + xy: 380, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -685,77 +685,77 @@ blocks/plasmaturret index: -1 blocks/playerspawn rotate: false - xy: 400, 85 + xy: 390, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerbooster rotate: false - xy: 410, 85 + xy: 400, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyor rotate: false - xy: 420, 85 + xy: 410, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyormove rotate: false - xy: 430, 85 + xy: 420, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaser rotate: false - xy: 440, 85 + xy: 430, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlasercorner rotate: false - xy: 450, 85 + xy: 440, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaserrouter rotate: false - xy: 460, 85 + xy: 450, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduit rotate: false - xy: 470, 85 + xy: 460, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduitbottom rotate: false - xy: 480, 87 + xy: 470, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduittop rotate: false - xy: 298, 75 + xy: 480, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pump rotate: false - xy: 308, 75 + xy: 298, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -769,77 +769,77 @@ blocks/repairturret index: -1 blocks/rock1 rotate: false - xy: 318, 75 + xy: 308, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rock2 rotate: false - xy: 328, 75 + xy: 318, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/router rotate: false - xy: 338, 75 + xy: 328, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator rotate: false - xy: 348, 75 + xy: 338, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator-top rotate: false - xy: 358, 75 + xy: 348, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand1 rotate: false - xy: 368, 75 + xy: 358, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand2 rotate: false - xy: 378, 75 + xy: 368, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand3 rotate: false - xy: 388, 75 + xy: 378, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock1 rotate: false - xy: 398, 75 + xy: 388, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock2 rotate: false - xy: 408, 75 + xy: 398, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock3 rotate: false - xy: 418, 75 + xy: 408, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -860,7 +860,7 @@ blocks/shadow index: -1 blocks/shieldgenerator rotate: false - xy: 438, 75 + xy: 428, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -874,28 +874,28 @@ blocks/shotgunturret index: -1 blocks/shrub rotate: false - xy: 551, 168 + xy: 547, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shrubshadow rotate: false - xy: 551, 158 + xy: 551, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter rotate: false - xy: 551, 148 + xy: 551, 158 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter-middle rotate: false - xy: 875, 417 + xy: 551, 148 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -909,42 +909,42 @@ blocks/sniperturret index: -1 blocks/snow1 rotate: false - xy: 885, 421 + xy: 875, 417 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow2 rotate: false - xy: 895, 421 + xy: 885, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow3 rotate: false - xy: 905, 421 + xy: 895, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock1 rotate: false - xy: 915, 421 + xy: 905, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock2 rotate: false - xy: 925, 421 + xy: 915, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock3 rotate: false - xy: 935, 421 + xy: 925, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -958,28 +958,28 @@ blocks/snowedge index: -1 blocks/sorter rotate: false - xy: 945, 421 + xy: 935, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyor rotate: false - xy: 955, 421 + xy: 945, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyormove rotate: false - xy: 965, 421 + xy: 955, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall rotate: false - xy: 975, 421 + xy: 965, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -993,56 +993,56 @@ blocks/steelwall-large index: -1 blocks/steelwall-large-icon rotate: false - xy: 985, 421 + xy: 975, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone1 rotate: false - xy: 995, 421 + xy: 985, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone2 rotate: false - xy: 298, 65 + xy: 995, 421 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone3 rotate: false - xy: 308, 65 + xy: 298, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock1 rotate: false - xy: 318, 65 + xy: 308, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock2 rotate: false - xy: 328, 65 + xy: 318, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock3 rotate: false - xy: 338, 65 + xy: 328, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonedrill rotate: false - xy: 348, 65 + xy: 338, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1056,35 +1056,35 @@ blocks/stoneedge index: -1 blocks/stoneformer rotate: false - xy: 358, 65 + xy: 348, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonewall rotate: false - xy: 368, 65 + xy: 358, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter rotate: false - xy: 378, 65 + xy: 368, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter-top rotate: false - xy: 388, 65 + xy: 378, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/thermalgenerator rotate: false - xy: 398, 65 + xy: 388, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1105,49 +1105,49 @@ blocks/titancannon-icon index: -1 blocks/titanium1 rotate: false - xy: 408, 65 + xy: 398, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium2 rotate: false - xy: 418, 65 + xy: 408, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium3 rotate: false - xy: 428, 65 + xy: 418, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumdrill rotate: false - xy: 438, 65 + xy: 428, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumpurifier rotate: false - xy: 448, 65 + xy: 438, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumshieldwall rotate: false - xy: 458, 65 + xy: 448, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall rotate: false - xy: 468, 65 + xy: 458, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1161,7 +1161,7 @@ blocks/titaniumwall-large index: -1 blocks/titaniumwall-large-icon rotate: false - xy: 557, 178 + xy: 468, 65 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1175,35 +1175,35 @@ blocks/turret index: -1 blocks/uranium1 rotate: false - xy: 561, 168 + xy: 577, 183 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium2 rotate: false - xy: 561, 158 + xy: 561, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium3 rotate: false - xy: 561, 148 + xy: 561, 158 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uraniumdrill rotate: false - xy: 571, 169 + xy: 561, 148 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/water rotate: false - xy: 547, 138 + xy: 571, 149 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1231,7 +1231,7 @@ blocks/weaponfactory index: -1 blocks/weaponfactory-icon rotate: false - xy: 557, 138 + xy: 547, 138 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1511,56 +1511,56 @@ enemyarrow index: -1 icon-coal rotate: false - xy: 228, 75 + xy: 218, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 238, 81 + xy: 228, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 248, 81 + xy: 238, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-sand rotate: false - xy: 258, 81 + xy: 248, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 268, 81 + xy: 258, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 278, 81 + xy: 268, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 288, 81 + xy: 278, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 238, 71 + xy: 288, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1609,28 +1609,28 @@ mechs/ship-standard index: -1 shell rotate: false - xy: 428, 75 + xy: 418, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 468, 75 + xy: 458, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 547, 178 + xy: 468, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 567, 189 + xy: 557, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1769,6 +1769,13 @@ ui/icons/icon-admin orig: 14, 14 offset: 0, 0 index: -1 +ui/icons/icon-admin-small + rotate: false + xy: 124, 82 + size: 6, 6 + orig: 6, 6 + offset: 0, 0 + index: -1 ui/icons/icon-areaDelete rotate: false xy: 93, 2 @@ -2483,42 +2490,42 @@ weapons/clustergun-equip index: -1 weapons/shockgun rotate: false - xy: 448, 75 + xy: 438, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/shockgun-equip rotate: false - xy: 458, 75 + xy: 448, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster rotate: false - xy: 567, 179 + xy: 567, 189 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster-equip rotate: false - xy: 577, 183 + xy: 567, 179 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/vulcan rotate: false - xy: 571, 159 + xy: 571, 169 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/vulcan-equip rotate: false - xy: 571, 149 + xy: 571, 159 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 05ff91f4a1..3068865687 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/assets/version.properties b/core/assets/version.properties index ce3e39f173..b8a8c88480 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Sun Feb 25 22:24:39 EST 2018 +#Sun Feb 25 23:41:37 EST 2018 version=release -androidBuildCode=282 +androidBuildCode=288 name=Mindustry code=3.3 build=custom build diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 5e53b9cd44..9e2d7344ef 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -51,6 +51,7 @@ public class NetClient extends Module { public NetClient(){ Net.handleClient(Connect.class, packet -> { + player.isAdmin = false; Net.setClientLoaded(false); recieved.clear(); @@ -331,6 +332,12 @@ public class NetClient extends Module { ui.showError(packet.message); disconnectQuietly(); }); + + Net.handleClient(PlayerAdminPacket.class, packet -> { + Player player = playerGroup.getByID(packet.id); + player.isAdmin = packet.admin; + ui.listfrag.rebuild(); + }); } @Override diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 275985e110..6fbd0f9df8 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -80,6 +80,7 @@ public class NetServer extends Module{ Log.info("Sending data to player '{0}' / {1}", packet.name, id); Player player = new Player(); + player.isAdmin = admins.isAdmin(Net.getConnection(id).address); player.clientid = id; player.name = packet.name; player.isAndroid = packet.android; @@ -109,7 +110,7 @@ public class NetServer extends Module{ Player player = connections.get(id); ByteArrayOutputStream stream = new ByteArrayOutputStream(); - NetworkIO.writeWorld(player.id, weapons.get(player.name, new ByteArray()), stream); + NetworkIO.writeWorld(player, weapons.get(player.name, new ByteArray()), stream); WorldData data = new WorldData(); data.stream = new ByteArrayInputStream(stream.toByteArray()); Net.sendStream(id, data); @@ -239,6 +240,32 @@ public class NetServer extends Module{ packet.id = connections.get(id).id; Net.sendExcept(id, packet, SendMode.tcp); }); + + Net.handleServer(AdministerRequestPacket.class, (id, packet) -> { + Player player = connections.get(id); + + if(!player.isAdmin){ + Log.err("ACCESS DENIED: Player {0} / {1} attempted to perform admin action without proper security access.", + player.name, Net.getConnection(player.clientid).address); + return; + } + + Player other = playerGroup.getByID(packet.id); + + if(other == null){ + Log.err("{0} attempted to perform admin action on nonexistant player.", player.name); + return; + } + + if(packet.action == AdminAction.ban){ + admins.banPlayer(Net.getConnection(other.clientid).address); + Net.kickConnection(other.clientid, KickReason.banned); + Log.info("&lc{0} has banned {1}.", player.name, other.name); + }else if(packet.action == AdminAction.kick){ + Net.kickConnection(other.clientid, KickReason.kick); + Log.info("&lc{0} has kicked {1}.", player.name, other.name); + } + }); } public void update(){ diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index b2064b0588..ba37bc6e2b 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -264,8 +264,14 @@ public class Renderer extends RendererModule{ Draw.color(); Draw.tcolor(player.getColor()); Draw.text(player.name, player.x, player.y + 8); - Draw.tcolor(); - } + + if(player.isAdmin){ + Draw.color(player.getColor()); + float s = 3f; + Draw.rect("icon-admin-small", player.x + layout.width/2f + 2 + 1, player.y + 7f, s, s); + } + Draw.reset(); + } } Pools.free(layout); Draw.tscl(fontscale); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index eef5a5094b..6400e6e2a2 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -34,6 +34,7 @@ public class Player extends SyncEntity{ public String name = "name"; public boolean isAndroid; + public boolean isAdmin; public Color color = new Color(); public Weapon weaponLeft = Weapon.blaster; @@ -44,7 +45,7 @@ public class Player extends SyncEntity{ public float stucktime = 0f; public boolean dashing = false; - public int clientid; + public int clientid = -1; public boolean isLocal = false; public Timer timer = new Timer(4); @@ -240,6 +241,7 @@ public class Player extends SyncEntity{ buffer.put(weaponLeft.id); buffer.put(weaponRight.id); buffer.put(isAndroid ? 1 : (byte)0); + buffer.put(isAdmin ? 1 : (byte)0); buffer.putInt(Color.rgba8888(color)); buffer.putFloat(x); buffer.putFloat(y); @@ -254,6 +256,7 @@ public class Player extends SyncEntity{ weaponLeft = (Weapon) Upgrade.getByID(buffer.get()); weaponRight = (Weapon) Upgrade.getByID(buffer.get()); isAndroid = buffer.get() == 1; + isAdmin = buffer.get() == 1; color.set(buffer.getInt()); x = buffer.getFloat(); y = buffer.getFloat(); diff --git a/core/src/io/anuke/mindustry/net/NetEvents.java b/core/src/io/anuke/mindustry/net/NetEvents.java index 332edae663..9bfe734f56 100644 --- a/core/src/io/anuke/mindustry/net/NetEvents.java +++ b/core/src/io/anuke/mindustry/net/NetEvents.java @@ -2,6 +2,7 @@ package io.anuke.mindustry.net; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.BulletType; +import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.net.Net.SendMode; @@ -149,4 +150,19 @@ public class NetEvents { packet.itemid = (byte)item.id; Net.send(packet, SendMode.udp); } + + public static void handleAdminSet(Player player, boolean admin){ + PlayerAdminPacket packet = new PlayerAdminPacket(); + packet.admin = admin; + packet.id = player.id; + player.isAdmin = admin; + Net.send(packet, SendMode.tcp); + } + + public static void handleAdministerRequest(Player target, AdminAction action){ + AdministerRequestPacket packet = new AdministerRequestPacket(); + packet.id = target.id; + packet.action = action; + Net.send(packet, SendMode.tcp); + } } diff --git a/core/src/io/anuke/mindustry/net/NetworkIO.java b/core/src/io/anuke/mindustry/net/NetworkIO.java index 298aa78522..abfd204c0e 100644 --- a/core/src/io/anuke/mindustry/net/NetworkIO.java +++ b/core/src/io/anuke/mindustry/net/NetworkIO.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.utils.ByteArray; import com.badlogic.gdx.utils.TimeUtils; +import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.game.GameMode; import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; @@ -100,7 +101,7 @@ public class NetworkIO { } } - public static void writeWorld(int playerID, ByteArray upgrades, OutputStream os){ + public static void writeWorld(Player player, ByteArray upgrades, OutputStream os){ try(DataOutputStream stream = new DataOutputStream(os)){ @@ -116,7 +117,8 @@ public class NetworkIO { stream.writeInt(state.enemies); //enemy amount stream.writeBoolean(state.friendlyFire); //friendly fire state - stream.writeInt(playerID); //player remap ID + stream.writeInt(player.id); //player remap ID + stream.writeBoolean(player.isAdmin); //--INVENTORY-- @@ -246,6 +248,7 @@ public class NetworkIO { state.friendlyFire = friendlyfire; int pid = stream.readInt(); + boolean admin = stream.readBoolean(); //inventory for(int i = 0; i < state.inventory.getItems().length; i ++){ @@ -268,6 +271,7 @@ public class NetworkIO { Entities.clear(); player.id = pid; + player.isAdmin = admin; player.add(); //map diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index fe676d4496..d6b4ff2cd2 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -576,4 +576,42 @@ public class Packets { message = new String(bytes); } } + + public static class PlayerAdminPacket implements Packet{ + public boolean admin; + public int id; + + @Override + public void write(ByteBuffer buffer) { + buffer.put(admin ? (byte)1 : 0); + buffer.putInt(id); + } + + @Override + public void read(ByteBuffer buffer) { + admin = buffer.get() == 1; + id = buffer.getInt(); + } + } + + public static class AdministerRequestPacket implements Packet{ + public AdminAction action; + public int id; + + @Override + public void write(ByteBuffer buffer) { + buffer.put((byte)action.ordinal()); + buffer.putInt(id); + } + + @Override + public void read(ByteBuffer buffer) { + action = AdminAction.values()[buffer.get()]; + id = buffer.getInt(); + } + } + + public enum AdminAction{ + kick, ban + } } diff --git a/core/src/io/anuke/mindustry/net/Registrator.java b/core/src/io/anuke/mindustry/net/Registrator.java index 05532c12e1..5c4b071242 100644 --- a/core/src/io/anuke/mindustry/net/Registrator.java +++ b/core/src/io/anuke/mindustry/net/Registrator.java @@ -42,6 +42,8 @@ public class Registrator { ItemSetPacket.class, ItemOffloadPacket.class, NetErrorPacket.class, + PlayerAdminPacket.class, + AdministerRequestPacket.class, }; private static ObjectIntMap> ids = new ObjectIntMap<>(); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java index ebc1759904..08d397c006 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/AdminsDialog.java @@ -1,10 +1,13 @@ package io.anuke.mindustry.ui.dialogs; +import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.net.NetConnection; +import io.anuke.mindustry.net.NetEvents; import io.anuke.ucore.scene.ui.ScrollPane; import io.anuke.ucore.scene.ui.layout.Table; -import static io.anuke.mindustry.Vars.netServer; -import static io.anuke.mindustry.Vars.ui; +import static io.anuke.mindustry.Vars.*; public class AdminsDialog extends FloatingDialog { @@ -40,6 +43,13 @@ public class AdminsDialog extends FloatingDialog { res.addImageButton("icon-cancel", 14*3, () -> { ui.showConfirm("$text.confirm", "$text.confirmunadmin", () -> { netServer.admins.unAdminPlayer(ip); + for(Player player : playerGroup.all()){ + NetConnection c = Net.getConnection(player.clientid); + if(c != null){ + NetEvents.handleAdminSet(player, false); + break; + } + } setup(); }); }).size(h).pad(-14f); diff --git a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java index 0c7878e8bf..52b8cf3a71 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/HostDialog.java @@ -50,6 +50,7 @@ public class HostDialog extends FloatingDialog{ Timers.runTask(5f, () -> { try{ Net.host(Vars.port); + player.isAdmin = true; }catch (IOException e){ ui.showError(Bundles.format("text.server.error", Strings.parseException(e, false))); } @@ -58,19 +59,4 @@ public class HostDialog extends FloatingDialog{ }); }).width(w).height(70f); } - - /* - showTextInput("$text.hostserver", "$text.server.port", Vars.port + "", new DigitsOnlyFilter(), text -> { - int result = Strings.parseInt(text); - if(result == Integer.MIN_VALUE || result >= 65535){ - ui.showError("$text.server.invalidport"); - }else{ - try{ - Net.host(result); - }catch (IOException e){ - ui.showError(Bundles.format("text.server.error", Strings.parseException(e, false))); - } - } - }); - */ } diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index 76a63a06bc..bb9a692a25 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -1,10 +1,12 @@ package io.anuke.mindustry.ui.fragments; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetConnection; import io.anuke.mindustry.net.NetEvents; +import io.anuke.mindustry.net.Packets.AdminAction; import io.anuke.mindustry.net.Packets.KickReason; import io.anuke.mindustry.ui.BorderImage; import io.anuke.ucore.core.Inputs; @@ -86,7 +88,7 @@ public class PlayerListFragment implements Fragment{ for(Player player : playerGroup.all()){ NetConnection connection = Net.getConnection(player.clientid); - if(connection == null && !player.isLocal) continue; + if(connection == null && Net.server() && !player.isLocal) continue; Table button = new Table("button"); button.left(); @@ -113,7 +115,9 @@ public class PlayerListFragment implements Fragment{ button.labelWrap("[#" + player.getColor().toString().toUpperCase() + "]" + player.name).width(170f).pad(10); button.add().grow(); - if(Net.server() && !player.isLocal){ + button.addImage("icon-admin").size(14*2).visible(() -> player.isAdmin && !(!player.isLocal && Net.server())).padRight(5); + + if((Net.server() || Vars.player.isAdmin) && !player.isLocal && !player.isAdmin){ button.add().growY(); float bs = (h + 14)/2f; @@ -123,30 +127,45 @@ public class PlayerListFragment implements Fragment{ t.addImageButton("icon-ban", 14*2, () -> { ui.showConfirm("$text.confirm", "$text.confirmban", () -> { - netServer.admins.banPlayer(connection.address); - Net.kickConnection(player.clientid, KickReason.banned); + if(Net.server()) { + netServer.admins.banPlayer(connection.address); + Net.kickConnection(player.clientid, KickReason.banned); + }else{ + NetEvents.handleAdministerRequest(player, AdminAction.ban); + } }); }).padBottom(-5.1f); - t.addImageButton("icon-cancel", 14*2, () -> Net.kickConnection(player.clientid, KickReason.kick)).padBottom(-5.1f); + t.addImageButton("icon-cancel", 14*2, () -> { + if(Net.server()) { + Net.kickConnection(player.clientid, KickReason.kick); + }else{ + NetEvents.handleAdministerRequest(player, AdminAction.kick); + } + }).padBottom(-5.1f); t.row(); t.addImageButton("icon-admin", "toggle", 14*2, () -> { + if(Net.client()) return; + if(netServer.admins.isAdmin(connection.address)){ ui.showConfirm("$text.confirm", "$text.confirmunadmin", () -> { netServer.admins.unAdminPlayer(connection.address); - //TODO send aproppriate packets. + NetEvents.handleAdminSet(player, false); }); }else{ ui.showConfirm("$text.confirm", "$text.confirmadmin", () -> { netServer.admins.adminPlayer(connection.address); - //TODO send aproppriate packets. + NetEvents.handleAdminSet(player, true); }); } - }).update(b -> b.setChecked(netServer.admins.isAdmin(connection.address))); + }).update(b -> b.setChecked(connection != null && netServer.admins.isAdmin(connection.address))) + .disabled(Net.client()); + + //TODO unused? + t.addImageButton("icon-cancel", 14*2, () -> {}); - t.addImageButton("icon-cancel", 14*2, () -> Net.kickConnection(player.clientid, KickReason.kick)); }).padRight(12).padTop(-5).padLeft(0).padBottom(-10).size(bs + 10f, bs); diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 9003cccc85..150a1d0487 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -355,6 +355,7 @@ public class ServerControl extends Module { if(target != null){ String ip = Net.getConnection(player.clientid).address; netServer.admins.adminPlayer(ip); + NetEvents.handleAdminSet(target, true); info("Admin-ed player by IP: {0} / {1}", ip, arg[0]); }else{ info("Nobody with that name could be found."); @@ -379,6 +380,7 @@ public class ServerControl extends Module { if(target != null){ String ip = Net.getConnection(player.clientid).address; netServer.admins.unAdminPlayer(ip); + NetEvents.handleAdminSet(target, false); info("Un-admin-ed player by IP: {0} / {1}", ip, arg[0]); }else{ info("Nobody with that name could be found.");