diff --git a/core/assets-raw/sprites/ui/icons/icon-zoom-small.png b/core/assets-raw/sprites/ui/icons/icon-zoom-small.png new file mode 100644 index 0000000000..35c117cda3 Binary files /dev/null and b/core/assets-raw/sprites/ui/icons/icon-zoom-small.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index cd22419d6a..d2855d9762 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -38,6 +38,15 @@ text.server.refreshing=Refreshing server text.hosts.none=[lightgray]No LAN games found! text.host.invalid=[scarlet]Can't connect to host. text.server.friendlyfire=Friendly Fire +text.trace=Trace Player +text.trace.playername=Player name: [accent]{0} +text.trace.ip=IP: [accent]{0} +text.trace.modclient=Modded Client: [accent]{0} +text.trace.totalblocksbroken=Total blocks broken: [accent]{0} +text.trace.structureblocksbroken=Structure blocks broken: [accent]{0} +text.trace.lastblockbroken=Last block broken: [accent]{0} +text.trace.totalblocksplaced=Total blocks placed: [accent]{0} +text.trace.lastblockplaced=Last block placed: [accent]{0} text.server.bans=Bans text.server.bans.none=No banned players found! text.server.admins=Admins diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index d2ae5b0efd..3fecd1d35d 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -20,56 +20,56 @@ blank index: -1 blocks/blackrock1 rotate: false - xy: 722, 381 + xy: 132, 88 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackrockshadow1 rotate: false - xy: 732, 381 + xy: 844, 400 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone1 rotate: false - xy: 736, 371 + xy: 856, 405 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone2 rotate: false - xy: 736, 361 + xy: 659, 282 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone3 rotate: false - xy: 736, 351 + xy: 669, 282 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock1 rotate: false - xy: 540, 110 + xy: 679, 282 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock2 rotate: false - xy: 659, 282 + xy: 624, 233 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock3 rotate: false - xy: 669, 282 + xy: 624, 223 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -83,7 +83,7 @@ blocks/blackstoneedge index: -1 blocks/block rotate: false - xy: 250, 91 + xy: 634, 225 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -104,7 +104,7 @@ blocks/block-3x3 index: -1 blocks/block-middle rotate: false - xy: 260, 91 + xy: 634, 215 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -125,112 +125,112 @@ blocks/chainturret-icon index: -1 blocks/coal1 rotate: false - xy: 300, 95 + xy: 270, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal2 rotate: false - xy: 310, 95 + xy: 280, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal3 rotate: false - xy: 320, 95 + xy: 290, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coaldrill rotate: false - xy: 330, 95 + xy: 300, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator rotate: false - xy: 340, 95 + xy: 310, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator-top rotate: false - xy: 350, 95 + xy: 320, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalpurifier rotate: false - xy: 360, 95 + xy: 330, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/combustiongenerator rotate: false - xy: 370, 95 + xy: 340, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/compositewall rotate: false - xy: 380, 95 + xy: 350, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduit rotate: false - xy: 390, 95 + xy: 360, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitbottom rotate: false - xy: 400, 95 + xy: 370, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitliquid rotate: false - xy: 410, 95 + xy: 380, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduittop rotate: false - xy: 420, 95 + xy: 390, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyor rotate: false - xy: 430, 95 + xy: 400, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyormove rotate: false - xy: 440, 95 + xy: 410, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyortunnel rotate: false - xy: 450, 95 + xy: 420, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -244,56 +244,56 @@ blocks/core index: -1 blocks/cross rotate: false - xy: 460, 95 + xy: 430, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/crucible rotate: false - xy: 470, 95 + xy: 440, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/deepwater rotate: false - xy: 601, 187 + xy: 450, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt1 rotate: false - xy: 611, 187 + xy: 460, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt2 rotate: false - xy: 621, 189 + xy: 470, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt3 rotate: false - xy: 114, 80 + xy: 113, 71 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirtedge rotate: false - xy: 535, 211 + xy: 535, 195 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/door rotate: false - xy: 113, 70 + xy: 113, 61 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -307,7 +307,7 @@ blocks/door-large index: -1 blocks/door-large-icon rotate: false - xy: 113, 60 + xy: 113, 51 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -321,7 +321,7 @@ blocks/door-large-open index: -1 blocks/door-open rotate: false - xy: 113, 50 + xy: 132, 78 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -335,7 +335,7 @@ blocks/doubleturret index: -1 blocks/duriumwall rotate: false - xy: 132, 78 + xy: 142, 81 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, 40 + xy: 152, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/enemyspawn rotate: false - xy: 117, 30 + xy: 162, 81 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -370,245 +370,245 @@ blocks/flameturret index: -1 blocks/fluxpump rotate: false - xy: 117, 20 + xy: 117, 41 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass1 rotate: false - xy: 117, 10 + xy: 117, 31 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass2 rotate: false - xy: 865, 417 + xy: 117, 21 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass3 rotate: false - xy: 624, 233 + xy: 117, 11 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock1 rotate: false - xy: 624, 223 + xy: 117, 1 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock2 rotate: false - xy: 624, 213 + xy: 561, 203 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassedge rotate: false - xy: 535, 197 + xy: 551, 213 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/ice1 rotate: false - xy: 634, 235 + xy: 549, 194 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice2 rotate: false - xy: 634, 225 + xy: 559, 193 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice3 rotate: false - xy: 634, 215 + xy: 547, 184 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iceedge rotate: false - xy: 549, 213 + xy: 565, 213 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/icerock1 rotate: false - xy: 178, 75 + xy: 557, 183 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerock2 rotate: false - xy: 188, 75 + xy: 724, 377 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow1 rotate: false - xy: 198, 75 + xy: 724, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow1 rotate: false - xy: 198, 75 + xy: 724, 367 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow2 rotate: false - xy: 208, 75 + xy: 724, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow2 rotate: false - xy: 208, 75 + xy: 724, 357 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron1 rotate: false - xy: 238, 71 + xy: 535, 120 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron2 rotate: false - xy: 248, 71 + xy: 832, 388 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron3 rotate: false - xy: 258, 71 + xy: 300, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/irondrill rotate: false - xy: 268, 71 + xy: 310, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ironwall rotate: false - xy: 278, 71 + xy: 320, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/junction rotate: false - xy: 288, 71 + xy: 330, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/laserturret rotate: false - xy: 853, 415 + xy: 844, 410 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/lava rotate: false - xy: 537, 140 + xy: 340, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/lavaedge rotate: false - xy: 563, 213 + xy: 533, 178 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/lavasmelter rotate: false - xy: 300, 85 + xy: 350, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquiditemjunction rotate: false - xy: 310, 85 + xy: 360, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidjunction rotate: false - xy: 320, 85 + xy: 370, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidrouter rotate: false - xy: 330, 85 + xy: 380, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/machineturret rotate: false - xy: 619, 199 + xy: 856, 415 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/megarepairturret rotate: false - xy: 142, 81 + xy: 530, 106 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mortarturret rotate: false - xy: 154, 81 + xy: 736, 392 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mossblock rotate: false - xy: 340, 85 + xy: 390, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/mossstone rotate: false - xy: 340, 85 + xy: 390, 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: 350, 85 + xy: 400, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -650,336 +650,336 @@ blocks/nuclearreactor-small index: -1 blocks/oil rotate: false - xy: 360, 85 + xy: 410, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/oiledge rotate: false - xy: 577, 207 + xy: 521, 132 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/oilrefinery rotate: false - xy: 370, 85 + xy: 420, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/omnidrill rotate: false - xy: 380, 85 + xy: 430, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/plasmaturret rotate: false - xy: 166, 81 + xy: 748, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/playerspawn rotate: false - xy: 390, 85 + xy: 440, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerbooster rotate: false - xy: 400, 85 + xy: 450, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyor rotate: false - xy: 410, 85 + xy: 460, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyormove rotate: false - xy: 420, 85 + xy: 470, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaser rotate: false - xy: 430, 85 + xy: 480, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlasercorner rotate: false - xy: 440, 85 + xy: 172, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaserrouter rotate: false - xy: 450, 85 + xy: 182, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduit rotate: false - xy: 460, 85 + xy: 192, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduitbottom rotate: false - xy: 470, 85 + xy: 202, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduittop rotate: false - xy: 480, 87 + xy: 212, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pump rotate: false - xy: 298, 75 + xy: 222, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/repairturret rotate: false - xy: 178, 85 + xy: 760, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/rock1 rotate: false - xy: 308, 75 + xy: 728, 332 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rock2 rotate: false - xy: 318, 75 + xy: 728, 322 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/router rotate: false - xy: 328, 75 + xy: 728, 312 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator rotate: false - xy: 338, 75 + xy: 738, 332 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator-top rotate: false - xy: 348, 75 + xy: 738, 322 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand1 rotate: false - xy: 358, 75 + xy: 738, 312 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand2 rotate: false - xy: 368, 75 + xy: 731, 302 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand3 rotate: false - xy: 378, 75 + xy: 731, 292 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock1 rotate: false - xy: 388, 75 + xy: 741, 302 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock2 rotate: false - xy: 398, 75 + xy: 741, 292 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock3 rotate: false - xy: 408, 75 + xy: 547, 140 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandedge rotate: false - xy: 577, 193 + xy: 142, 91 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/shadow rotate: false - xy: 190, 85 + xy: 772, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shieldgenerator rotate: false - xy: 428, 75 + xy: 545, 120 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shotgunturret rotate: false - xy: 202, 85 + xy: 784, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shrub rotate: false - xy: 547, 178 + xy: 202, 77 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shrubshadow rotate: false - xy: 551, 168 + xy: 212, 77 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter rotate: false - xy: 551, 158 + xy: 222, 77 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter-middle rotate: false - xy: 551, 148 + xy: 744, 382 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sniperturret rotate: false - xy: 214, 85 + xy: 796, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/snow1 rotate: false - xy: 875, 417 + xy: 744, 372 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow2 rotate: false - xy: 885, 421 + xy: 744, 362 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow3 rotate: false - xy: 895, 421 + xy: 744, 352 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock1 rotate: false - xy: 905, 421 + xy: 744, 342 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock2 rotate: false - xy: 915, 421 + xy: 754, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock3 rotate: false - xy: 925, 421 + xy: 764, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowedge rotate: false - xy: 605, 197 + xy: 521, 118 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/sorter rotate: false - xy: 935, 421 + xy: 754, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyor rotate: false - xy: 945, 421 + xy: 774, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyormove rotate: false - xy: 955, 421 + xy: 754, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall rotate: false - xy: 965, 421 + xy: 764, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -993,98 +993,98 @@ blocks/steelwall-large index: -1 blocks/steelwall-large-icon rotate: false - xy: 975, 421 + xy: 784, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone1 rotate: false - xy: 985, 421 + xy: 754, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone2 rotate: false - xy: 995, 421 + xy: 764, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone3 rotate: false - xy: 298, 65 + xy: 774, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock1 rotate: false - xy: 308, 65 + xy: 794, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock2 rotate: false - xy: 318, 65 + xy: 754, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock3 rotate: false - xy: 328, 65 + xy: 764, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonedrill rotate: false - xy: 338, 65 + xy: 774, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneedge rotate: false - xy: 537, 150 + xy: 722, 413 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/stoneformer rotate: false - xy: 348, 65 + xy: 784, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonewall rotate: false - xy: 358, 65 + xy: 804, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter rotate: false - xy: 368, 65 + xy: 764, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter-top rotate: false - xy: 378, 65 + xy: 774, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/thermalgenerator rotate: false - xy: 388, 65 + xy: 784, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1098,56 +1098,56 @@ blocks/titancannon index: -1 blocks/titancannon-icon rotate: false - xy: 226, 85 + xy: 808, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/titanium1 rotate: false - xy: 398, 65 + xy: 794, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium2 rotate: false - xy: 408, 65 + xy: 814, 384 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium3 rotate: false - xy: 418, 65 + xy: 774, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumdrill rotate: false - xy: 428, 65 + xy: 784, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumpurifier rotate: false - xy: 438, 65 + xy: 794, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumshieldwall rotate: false - xy: 448, 65 + xy: 804, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall rotate: false - xy: 458, 65 + xy: 784, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1161,63 +1161,63 @@ blocks/titaniumwall-large index: -1 blocks/titaniumwall-large-icon rotate: false - xy: 468, 65 + xy: 794, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/turret rotate: false - xy: 528, 108 + xy: 820, 394 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/uranium1 rotate: false - xy: 577, 183 + xy: 804, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium2 rotate: false - xy: 561, 168 + xy: 814, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium3 rotate: false - xy: 561, 158 + xy: 804, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uraniumdrill rotate: false - xy: 561, 148 + xy: 814, 354 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/water rotate: false - xy: 571, 149 + xy: 748, 322 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/wateredge rotate: false - xy: 521, 132 + xy: 722, 399 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/waveturret rotate: false - xy: 533, 120 + xy: 832, 398 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1231,21 +1231,21 @@ blocks/weaponfactory index: -1 blocks/weaponfactory-icon rotate: false - xy: 547, 138 + xy: 748, 312 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 bullet rotate: false - xy: 270, 91 + xy: 240, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 chainbullet rotate: false - xy: 591, 188 + xy: 114, 81 size: 8, 7 orig: 8, 7 offset: 0, 0 @@ -1392,91 +1392,91 @@ enemies/healerenemy-t3 index: -1 enemies/mortarenemy-t1 rotate: false - xy: 981, 447 + xy: 981, 431 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t2 rotate: false - xy: 981, 431 + xy: 997, 447 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t3 rotate: false - xy: 997, 447 + xy: 997, 431 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t1 rotate: false - xy: 997, 431 + xy: 592, 211 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t2 rotate: false - xy: 592, 211 + xy: 608, 211 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t3 rotate: false - xy: 608, 211 + xy: 519, 208 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/standardenemy-t1 rotate: false - xy: 519, 208 + xy: 519, 192 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/targetenemy-t1 rotate: false - xy: 519, 208 + xy: 519, 192 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/standardenemy-t2 rotate: false - xy: 533, 178 + xy: 516, 104 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/standardenemy-t3 rotate: false - xy: 537, 164 + xy: 514, 90 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/tankenemy-t1 rotate: false - xy: 519, 192 + xy: 521, 162 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t2 rotate: false - xy: 521, 162 + xy: 521, 146 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t3 rotate: false - xy: 521, 146 + xy: 535, 209 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1504,63 +1504,63 @@ enemies/titanenemy-t3 index: -1 enemyarrow rotate: false - xy: 117, 1 + xy: 551, 204 size: 8, 7 orig: 8, 7 offset: 0, 0 index: -1 icon-coal rotate: false - xy: 218, 75 + xy: 724, 347 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 228, 75 + xy: 734, 382 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 238, 81 + xy: 734, 372 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-sand rotate: false - xy: 248, 81 + xy: 734, 362 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 258, 81 + xy: 734, 352 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 268, 81 + xy: 734, 342 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 278, 81 + xy: 537, 140 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 288, 81 + xy: 535, 130 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1588,49 +1588,49 @@ laserfull index: -1 mechs/mech-standard rotate: false - xy: 549, 199 + xy: 537, 164 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mechs/mech-standard-icon rotate: false - xy: 563, 199 + xy: 537, 150 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 mechs/ship-standard rotate: false - xy: 591, 197 + xy: 156, 91 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shell rotate: false - xy: 418, 75 + xy: 545, 130 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 458, 75 + xy: 182, 77 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 468, 75 + xy: 192, 77 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 557, 178 + xy: 804, 364 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1841,7 +1841,7 @@ ui/icons/icon-cancel index: -1 ui/icons/icon-chat rotate: false - xy: 142, 93 + xy: 579, 209 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1876,21 +1876,21 @@ ui/icons/icon-close-over index: -1 ui/icons/icon-crafting rotate: false - xy: 154, 93 + xy: 722, 387 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-cursor rotate: false - xy: 166, 93 + xy: 736, 416 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-defense rotate: false - xy: 521, 120 + xy: 736, 404 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1904,7 +1904,7 @@ ui/icons/icon-discord index: -1 ui/icons/icon-distribution rotate: false - xy: 516, 108 + xy: 748, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1974,14 +1974,14 @@ ui/icons/icon-grid index: -1 ui/icons/icon-hold rotate: false - xy: 722, 415 + xy: 760, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-holdDelete rotate: false - xy: 722, 403 + xy: 748, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2002,7 +2002,7 @@ ui/icons/icon-host index: -1 ui/icons/icon-info rotate: false - xy: 722, 391 + xy: 772, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2044,21 +2044,21 @@ ui/icons/icon-loading index: -1 ui/icons/icon-menu rotate: false - xy: 734, 416 + xy: 760, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-none rotate: false - xy: 734, 404 + xy: 784, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-pause rotate: false - xy: 734, 392 + xy: 772, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2086,7 +2086,7 @@ ui/icons/icon-pick index: -1 ui/icons/icon-play rotate: false - xy: 724, 369 + xy: 796, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2100,21 +2100,21 @@ ui/icons/icon-play-2 index: -1 ui/icons/icon-players rotate: false - xy: 724, 357 + xy: 784, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-power rotate: false - xy: 724, 345 + xy: 808, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-production rotate: false - xy: 728, 333 + xy: 796, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2205,7 +2205,7 @@ ui/icons/icon-save-map index: -1 ui/icons/icon-settings rotate: false - xy: 728, 321 + xy: 820, 418 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2226,14 +2226,14 @@ ui/icons/icon-tools index: -1 ui/icons/icon-touch rotate: false - xy: 728, 309 + xy: 808, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icons/icon-touchDelete rotate: false - xy: 731, 297 + xy: 820, 406 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2268,7 +2268,7 @@ ui/icons/icon-undo index: -1 ui/icons/icon-weapon rotate: false - xy: 731, 285 + xy: 832, 410 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2280,6 +2280,13 @@ ui/icons/icon-zoom orig: 16, 16 offset: 0, 0 index: -1 +ui/icons/icon-zoom-small + rotate: false + xy: 981, 447 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/logotext rotate: false xy: 1, 85 @@ -2346,7 +2353,7 @@ ui/scroll-knob-vertical-black index: -1 ui/selection rotate: false - xy: 865, 459 + xy: 728, 309 size: 1, 1 orig: 1, 1 offset: 0, 0 @@ -2381,7 +2388,7 @@ ui/slider-knob-over index: -1 ui/slider-vertical rotate: false - xy: 869, 427 + xy: 535, 192 size: 8, 1 orig: 8, 1 offset: 0, 0 @@ -2455,77 +2462,77 @@ weapons/beam index: -1 weapons/beam-equip rotate: false - xy: 132, 88 + xy: 170, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/blaster rotate: false - xy: 679, 282 + xy: 624, 213 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/blaster-equip rotate: false - xy: 240, 91 + xy: 634, 235 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/clustergun rotate: false - xy: 280, 91 + xy: 250, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/clustergun-equip rotate: false - xy: 290, 91 + xy: 260, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/shockgun rotate: false - xy: 438, 75 + xy: 542, 110 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/shockgun-equip rotate: false - xy: 448, 75 + xy: 172, 75 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster rotate: false - xy: 567, 189 + xy: 814, 374 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster-equip rotate: false - xy: 567, 179 + xy: 794, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/vulcan rotate: false - xy: 571, 169 + xy: 814, 344 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/vulcan-equip rotate: false - xy: 571, 159 + xy: 748, 332 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index 3068865687..3eb2c2785e 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 fb24b0e5c6..fadb2e3c78 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Mon Feb 26 10:05:40 EST 2018 +#Mon Feb 26 17:17:34 EST 2018 version=release -androidBuildCode=290 +androidBuildCode=291 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 4fe6ffbb9d..cbfa80445a 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -162,9 +162,6 @@ public class NetClient extends Module { state.wavetime = packet.countdown; state.wave = packet.wave; - //removed: messing with time isn't necessary anymore - //Timers.resetTime(packet.time + (float) (TimeUtils.timeSinceMillis(packet.timestamp) / 1000.0 * 60.0)); - ui.hudfrag.updateItems(); }); @@ -343,6 +340,11 @@ public class NetClient extends Module { player.isAdmin = packet.admin; ui.listfrag.rebuild(); }); + + Net.handleClient(TracePacket.class, packet -> { + Player player = playerGroup.getByID(packet.info.playerid); + ui.traces.show(player, packet.info); + }); } @Override diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 6fbd0f9df8..a65d1d39c8 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -64,19 +64,19 @@ public class NetServer extends Module{ if(Net.getConnection(id) == null || admins.isBanned(Net.getConnection(id).address)) return; - admins.setKnownName(Net.getConnection(id).address, packet.name); + String ip = Net.getConnection(id).address; - if(packet.version != Version.build && Version.build != -1){ - if(packet.version == -1){ - admins.banPlayer(Net.getConnection(id).address); - Net.kickConnection(id, KickReason.banned); - }else { - Net.kickConnection(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated); - } + admins.setKnownName(ip, packet.name); + if(packet.version != Version.build && Version.build != -1 && packet.version != -1){ + Net.kickConnection(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated); return; } + if(packet.version == -1){ + admins.getTrace(ip).modclient = true; + } + Log.info("Sending data to player '{0}' / {1}", packet.name, id); Player player = new Player(); @@ -90,6 +90,8 @@ public class NetServer extends Module{ player.color.set(packet.color); connections.put(id, player); + admins.getTrace(ip).playerid = player.id; + if(world.getMap().custom){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); NetworkIO.writeMap(world.getMap(), stream); @@ -164,15 +166,20 @@ public class NetServer extends Module{ Net.handleServer(PlacePacket.class, (id, packet) -> { packet.playerid = connections.get(id).id; - if(!Placement.validPlace(packet.x, packet.y, Block.getByID(packet.block))) return; + Block block = Block.getByID(packet.block); - Recipe recipe = Recipes.getByResult(Block.getByID(packet.block)); + if(!Placement.validPlace(packet.x, packet.y, block)) return; + + Recipe recipe = Recipes.getByResult(block); if(recipe == null) return; state.inventory.removeItems(recipe.requirements); - Placement.placeBlock(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, false); + Placement.placeBlock(packet.x, packet.y, block, packet.rotation, true, false); + + admins.getTrace(Net.getConnection(id).address).lastBlockPlaced = block; + admins.getTrace(Net.getConnection(id).address).totalBlocksPlaced ++; Net.send(packet, SendMode.tcp); }); @@ -182,7 +189,14 @@ public class NetServer extends Module{ if(!Placement.validBreak(packet.x, packet.y)) return; - Placement.breakBlock(packet.x, packet.y, true, false); + Block block = Placement.breakBlock(packet.x, packet.y, true, false); + + if(block != null) { + admins.getTrace(Net.getConnection(id).address).lastBlockBroken = block; + admins.getTrace(Net.getConnection(id).address).totalBlocksBroken++; + if (block.update || block.destructible) + admins.getTrace(Net.getConnection(id).address).structureBlocksBroken++; + } Net.send(packet, SendMode.tcp); }); @@ -252,18 +266,25 @@ public class NetServer extends Module{ Player other = playerGroup.getByID(packet.id); - if(other == null){ - Log.err("{0} attempted to perform admin action on nonexistant player.", player.name); + if(other == null || other.isAdmin){ + Log.err("{0} attempted to perform admin action on nonexistant or admin player.", player.name); return; } + String ip = Net.getConnection(other.clientid).address; + if(packet.action == AdminAction.ban){ - admins.banPlayer(Net.getConnection(other.clientid).address); + admins.banPlayer(ip); 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); + }else if(packet.action == AdminAction.trace){ + TracePacket trace = new TracePacket(); + trace.info = admins.getTrace(ip); + Net.sendTo(other.clientid, trace, SendMode.tcp); + Log.info("&lc{0} has requested trace info of {1}.", player.name, other.name); } }); } @@ -287,6 +308,7 @@ public class NetServer extends Module{ public void reset(){ weapons.clear(); + admins.clearTraces(); } void sync(){ diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 89a6deff52..94d0559720 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -47,6 +47,7 @@ public class UI extends SceneModule{ public LanguageDialog language; public BansDialog bans; public AdminsDialog admins; + public TraceDialog traces; public final MenuFragment menufrag = new MenuFragment(); public final ToolFragment toolfrag = new ToolFragment(); @@ -154,6 +155,7 @@ public class UI extends SceneModule{ host = new HostDialog(); bans = new BansDialog(); admins = new AdminsDialog(); + traces = new TraceDialog(); build.begin(scene); diff --git a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java index 3fb7a182b3..bc0ada5608 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java +++ b/core/src/io/anuke/mindustry/entities/enemies/EnemyType.java @@ -85,7 +85,8 @@ public class EnemyType { if(isCalculating(enemy)){ Draw.color(Color.SKY); - Lines.polySeg(20, 0, 5, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52153f); + Lines.polySeg(20, 0, 4, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52f); + Lines.polySeg(20, 0, 4, enemy.x, enemy.y, 11f, Timers.time() * 2f + enemy.id*52f + 180f); Draw.color(); } diff --git a/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java b/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java index b8e98a7b1e..822e9d5823 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java +++ b/core/src/io/anuke/mindustry/entities/enemies/types/TargetType.java @@ -56,4 +56,9 @@ public class TargetType extends EnemyType { new Enemy(EnemyTypes.target).set(enemy.x, enemy.y).add(); }); } + + @Override + public boolean isCalculating(Enemy enemy){ + return false; + } } diff --git a/core/src/io/anuke/mindustry/net/Administration.java b/core/src/io/anuke/mindustry/net/Administration.java index 82f9190098..27ebe8f1d5 100644 --- a/core/src/io/anuke/mindustry/net/Administration.java +++ b/core/src/io/anuke/mindustry/net/Administration.java @@ -10,6 +10,7 @@ public class Administration { private Array bannedIPS = new Array<>(); private Array admins = new Array<>(); private ObjectMap known = new ObjectMap<>(); + private ObjectMap traces = new ObjectMap<>(); public Administration(){ Settings.defaultList( @@ -21,6 +22,16 @@ public class Administration { load(); } + public TraceInfo getTrace(String ip){ + if(!traces.containsKey(ip)) traces.put(ip, new TraceInfo(ip)); + + return traces.get(ip); + } + + public void clearTraces(){ + traces.clear(); + } + /**Sets last known name for an IP.*/ public void setKnownName(String ip, String name){ known.put(ip, name); diff --git a/core/src/io/anuke/mindustry/net/NetEvents.java b/core/src/io/anuke/mindustry/net/NetEvents.java index 9bfe734f56..8b75515d9f 100644 --- a/core/src/io/anuke/mindustry/net/NetEvents.java +++ b/core/src/io/anuke/mindustry/net/NetEvents.java @@ -13,7 +13,7 @@ import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.entities.Entity; -import static io.anuke.mindustry.Vars.netCommon; +import static io.anuke.mindustry.Vars.*; public class NetEvents { @@ -165,4 +165,12 @@ public class NetEvents { packet.action = action; Net.send(packet, SendMode.tcp); } + + public static void handleTraceRequest(Player target){ + if(Net.client()) { + handleAdministerRequest(target, AdminAction.trace); + }else{ + ui.traces.show(target, netServer.admins.getTrace(Net.getConnection(target.clientid).address)); + } + } } diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index d6b4ff2cd2..a69072a6dc 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -8,6 +8,7 @@ import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Packet.ImportantPacket; import io.anuke.mindustry.net.Packet.UnimportantPacket; import io.anuke.mindustry.resource.Item; +import io.anuke.mindustry.world.Block; import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.EntityGroup; @@ -612,6 +613,43 @@ public class Packets { } public enum AdminAction{ - kick, ban + kick, ban, trace + } + + public static class TracePacket implements Packet{ + public TraceInfo info; + + @Override + public void write(ByteBuffer buffer) { + buffer.putInt(info.playerid); + buffer.putShort((short)info.ip.getBytes().length); + buffer.put(info.ip.getBytes()); + buffer.put(info.modclient ? (byte)1 : 0); + + buffer.putInt(info.totalBlocksBroken); + buffer.putInt(info.structureBlocksBroken); + buffer.putInt(info.lastBlockBroken.id); + + buffer.putInt(info.totalBlocksPlaced); + buffer.putInt(info.lastBlockPlaced.id); + } + + @Override + public void read(ByteBuffer buffer) { + int id = buffer.getInt(); + short iplen = buffer.getShort(); + byte[] ipb = new byte[iplen]; + buffer.get(ipb); + + info = new TraceInfo(new String(ipb)); + + info.playerid = id; + info.modclient = buffer.get() == 1; + info.totalBlocksBroken = buffer.getInt(); + info.structureBlocksBroken = buffer.getInt(); + info.lastBlockBroken = Block.getByID(buffer.getInt()); + info.totalBlocksPlaced = buffer.getInt(); + info.lastBlockPlaced = Block.getByID(buffer.getInt()); + } } } diff --git a/core/src/io/anuke/mindustry/net/Registrator.java b/core/src/io/anuke/mindustry/net/Registrator.java index 5c4b071242..8e1dfa8297 100644 --- a/core/src/io/anuke/mindustry/net/Registrator.java +++ b/core/src/io/anuke/mindustry/net/Registrator.java @@ -44,6 +44,7 @@ public class Registrator { NetErrorPacket.class, PlayerAdminPacket.class, AdministerRequestPacket.class, + TracePacket.class, }; private static ObjectIntMap> ids = new ObjectIntMap<>(); diff --git a/core/src/io/anuke/mindustry/net/TraceInfo.java b/core/src/io/anuke/mindustry/net/TraceInfo.java new file mode 100644 index 0000000000..32aa036bbd --- /dev/null +++ b/core/src/io/anuke/mindustry/net/TraceInfo.java @@ -0,0 +1,21 @@ +package io.anuke.mindustry.net; + +import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.blocks.Blocks; + +public class TraceInfo { + public int playerid; + public String ip; + public boolean modclient; + + public int totalBlocksBroken; + public int structureBlocksBroken; + public Block lastBlockBroken = Blocks.air; + + public int totalBlocksPlaced; + public Block lastBlockPlaced = Blocks.air; + + public TraceInfo(String ip){ + this.ip = ip; + } +} diff --git a/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java new file mode 100644 index 0000000000..45aaf332cb --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/dialogs/TraceDialog.java @@ -0,0 +1,53 @@ +package io.anuke.mindustry.ui.dialogs; + +import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.net.TraceInfo; +import io.anuke.ucore.scene.ui.layout.Table; +import io.anuke.ucore.util.Bundles; + +public class TraceDialog extends FloatingDialog { + + public TraceDialog(){ + super("$text.trace"); + + addCloseButton(); + } + + public void show(Player player, TraceInfo info){ + content().clear(); + + Table table = new Table("button"); + table.margin(14); + table.defaults().pad(1); + + table.defaults().left(); + table.add(Bundles.format("text.trace.playername", player.name)); + table.row(); + table.add(Bundles.format("text.trace.ip", info.ip)); + table.row(); + table.add(Bundles.format("text.trace.modclient", info.modclient)); + table.row(); + + table.add().pad(5); + table.row(); + + table.add(Bundles.format("text.trace.totalblocksbroken", info.totalBlocksBroken)); + table.row(); + table.add(Bundles.format("text.trace.structureblocksbroken", info.structureBlocksBroken)); + table.row(); + table.add(Bundles.format("text.trace.lastblockbroken", info.lastBlockBroken)); + table.row(); + + table.add().pad(5); + table.row(); + + table.add(Bundles.format("text.trace.totalblocksplaced", info.totalBlocksPlaced)); + table.row(); + table.add(Bundles.format("text.trace.lastblockplaced", info.lastBlockPlaced)); + table.row(); + + content().add(table); + + show(); + } +} diff --git a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java index bb9a692a25..a070fb1981 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/PlayerListFragment.java @@ -117,7 +117,7 @@ public class PlayerListFragment implements Fragment{ 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){ + if((Net.server() || Vars.player.isAdmin) && !player.isLocal && (!player.isAdmin || Net.server())){ button.add().growY(); float bs = (h + 14)/2f; @@ -163,8 +163,8 @@ public class PlayerListFragment implements Fragment{ }).update(b -> b.setChecked(connection != null && netServer.admins.isAdmin(connection.address))) .disabled(Net.client()); - //TODO unused? - t.addImageButton("icon-cancel", 14*2, () -> {}); + //TODO trace info for player + t.addImageButton("icon-zoom-small", 14*2, () -> NetEvents.handleTraceRequest(player)); }).padRight(12).padTop(-5).padLeft(0).padBottom(-10).size(bs + 10f, bs); diff --git a/core/src/io/anuke/mindustry/world/Placement.java b/core/src/io/anuke/mindustry/world/Placement.java index b5cd75d21c..f653cba590 100644 --- a/core/src/io/anuke/mindustry/world/Placement.java +++ b/core/src/io/anuke/mindustry/world/Placement.java @@ -21,10 +21,11 @@ import static io.anuke.mindustry.Vars.*; public class Placement { private static final Rectangle rect = new Rectangle(); - public static void breakBlock(int x, int y, boolean effect, boolean sound){ + /**Returns block type that was broken, or null if unsuccesful.*/ + public static Block breakBlock(int x, int y, boolean effect, boolean sound){ Tile tile = world.tile(x, y); - if(tile == null) return; + if(tile == null) return null; Block block = tile.isLinked() ? tile.getLinked().block() : tile.block(); Recipe result = Recipes.getByResult(block); @@ -53,6 +54,8 @@ public class Placement { if(effect) Effects.effect(Fx.breakBlock, toremove.worldx(), toremove.worldy()); } } + + return block; } public static void placeBlock(int x, int y, Block result, int rotation, boolean effects, boolean sound){ diff --git a/mindustry-maps/maps.json b/mindustry-maps/maps.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/mindustry-maps/maps.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 150a1d0487..4061240892 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -13,6 +13,7 @@ import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.net.Packets.ChatPacket; import io.anuke.mindustry.net.Packets.KickReason; +import io.anuke.mindustry.net.TraceInfo; import io.anuke.mindustry.ui.fragments.DebugFragment; import io.anuke.mindustry.world.Map; import io.anuke.mindustry.world.Tile; @@ -335,8 +336,6 @@ public class ServerControl extends Module { } }); - //assadsad - handler.register("admin", "", "Make a user admin", arg -> { if(!state.is(State.playing)) { err("Open the server first."); @@ -458,7 +457,7 @@ public class ServerControl extends Module { info(DebugFragment.debugInfo()); }); - handler.register("trace", " ", "Prints debug info about a block", arg -> { + handler.register("traceblock", " ", "Prints debug info about a block", arg -> { try{ int x = Integer.parseInt(arg[0]); int y = Integer.parseInt(arg[1]); @@ -484,6 +483,39 @@ public class ServerControl extends Module { Log.err("Invalid coordinates passed."); } }); + + handler.register("trace", "", "Trace a player's actions", arg -> { + if(!state.is(State.playing)) { + err("Open the server first."); + return; + } + + Player target = null; + + for(Player player : playerGroup.all()){ + if(player.name.equalsIgnoreCase(arg[0])){ + target = player; + break; + } + } + + if(target != null){ + TraceInfo info = netServer.admins.getTrace(Net.getConnection(target.clientid).address); + Log.info("&lcTrace info for player '{0}':", target.name); + Log.info(" &lyEntity ID: {0}", info. playerid); + Log.info(" &lyIP: {0}", info.ip); + Log.info(" &lymodded client: {0}", info.modclient); + Log.info(""); + Log.info(" &lytotal blocks broken: {0}", info.totalBlocksBroken); + Log.info(" &lystructure blocks broken: {0}", info.structureBlocksBroken); + Log.info(" &lylast block broken: {0}", info.lastBlockBroken); + Log.info(""); + Log.info(" &lytotal blocks placed: {0}", info.totalBlocksPlaced); + Log.info(" &lylast block placed: {0}", info.lastBlockPlaced); + }else{ + info("Nobody with that name could be found."); + } + }); } private void readCommands(){