447 Commits

Author SHA1 Message Date
de4f32feb2 Started on implementing printer tool
All checks were successful
SteamWarCI Build successful
2025-05-20 23:19:32 +02:00
a3d2d2be1e Remove softRef construct, add onPlayerLeave cleanup
All checks were successful
SteamWarCI Build successful
2025-05-08 20:58:16 +02:00
7a000efb93 Fix
All checks were successful
SteamWarCI Build successful
2025-05-08 18:02:56 +02:00
42c9d6d612 Added cleanup of cursor
All checks were successful
SteamWarCI Build successful
2025-05-08 17:56:12 +02:00
67c679a20f Add onclick handler
All checks were successful
SteamWarCI Build successful
2025-05-08 17:33:14 +02:00
a071d8a1f2 Fix jumpy cursor
All checks were successful
SteamWarCI Build successful
2025-05-07 19:49:14 +02:00
7b25bd31fc Fix nullpointer in RCursor
All checks were successful
SteamWarCI Build successful
2025-05-05 22:46:10 +02:00
139a2c275c Fixed bugs, added block align or free render
All checks were successful
SteamWarCI Build successful
2025-04-30 12:57:39 +02:00
aa787b5a25 Implemented cursor manager for deduplicated cursor updating
All checks were successful
SteamWarCI Build successful
2025-04-30 12:17:48 +02:00
54adc12045 Started refactoring simulator cursor for reuse
All checks were successful
SteamWarCI Build successful
2025-04-29 23:25:22 +02:00
32c85b9bd5 Merge pull request 'Add error handling and logging to Techhider and TinyProtocol' (#55) from techhider-debug-nachrichten into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #55
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-04-29 18:13:00 +02:00
15bb92fbba Improve error handling and logging in Techhider and TinyProtocol
All checks were successful
SteamWarCI Build successful
Refined logging messages for clarity by replacing "Techhider" with "PacketInterceptor" where appropriate. Adjusted error handling in `TechhiderbugCommand` by removing redundant `flush` calls and properly logging exceptions during bug report generation. These changes aim to enhance maintainability and debugging.
2025-04-29 18:04:58 +02:00
d6a5caf95d Add error handling and logging to Techhider and TinyProtocol
All checks were successful
SteamWarCI Build successful
2025-04-29 17:59:22 +02:00
66d18e316b Hotfix: Schematic Download geht für nicht Supervisor Player
All checks were successful
SteamWarCI Build successful
2025-04-28 16:47:43 +02:00
5cdad8c2f4 Add Dev 1.21.5
All checks were successful
SteamWarCI Build successful
2025-04-27 02:28:39 +02:00
87a7120a6a Merge remote-tracking branch 'origin/main'
All checks were successful
SteamWarCI Build successful
2025-04-26 23:57:03 +02:00
b5a9564808 Allow next next location in JumpAndRun 2025-04-26 23:56:59 +02:00
f93362a023 LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java aktualisiert
All checks were successful
SteamWarCI Build successful
2025-04-26 23:48:33 +02:00
b1bef4ced5 Add ErrorLogging for Bugged Schematics
All checks were successful
SteamWarCI Build successful
2025-04-26 22:27:53 +02:00
e7e1e2d968 Merge remote-tracking branch 'origin/main'
All checks were successful
SteamWarCI Build successful
2025-04-26 22:17:50 +02:00
713275ba11 Add ErrorLogging for Bugged Schematics 2025-04-26 22:17:43 +02:00
e72ae3cf94 LobbySystem/src/de/steamwar/lobby/jumpandrun/JumpAndRun.java aktualisiert
All checks were successful
SteamWarCI Build successful
2025-04-26 22:13:31 +02:00
d36753dec1 Merge pull request 'Fixed meterstock' (#54) from BauSystem/fix-meterstock into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #54
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-04-26 13:37:33 +02:00
84cc292df4 Fixed meterstock
All checks were successful
SteamWarCI Build successful
2025-04-26 13:08:13 +02:00
f89c4e88f9 Fix HotbarKit
All checks were successful
SteamWarCI Build successful
Fix steamwar.devserver.gradle
Add WarGear20 to build.gradle.kts
2025-04-25 18:07:14 +02:00
a38f9222dd Merge remote-tracking branch 'origin/main'
All checks were successful
SteamWarCI Build successful
2025-04-23 20:55:30 +02:00
5ee9d3e167 Hotfix HotbarKit 2025-04-23 20:55:26 +02:00
98321de46c Merge pull request 'Replace Jukeboxes with Lodestone in panzer sklave' (#50) from BauSystem/fix-panzersklave into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #50
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-04-23 19:14:53 +02:00
239ba3f213 made more readable
All checks were successful
SteamWarCI Build successful
2025-04-23 19:14:44 +02:00
3d7dedd3ad Fix jukeboxes in panzer sklave
All checks were successful
SteamWarCI Build successful
2025-04-23 19:13:07 +02:00
ef66b8c1f1 Fix HotbarKit.onInventoryClick not resetting the cursor item
All checks were successful
SteamWarCI Build successful
2025-04-23 18:28:58 +02:00
1201b16ee4 Merge pull request 'Improve Server starter 'steamwar.devserver.gradle'' (#41) from ImprovedServerStarter into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #41
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-04-23 18:16:39 +02:00
4ddd88f540 Merge pull request 'Enable clicking 'Ready' in inventory' (#42) from FightSystem/HotbarKitInInv into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #42
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-04-23 18:12:40 +02:00
147e34c0d6 Fix TNTClickListener
All checks were successful
SteamWarCI Build successful
2025-04-21 11:47:00 +02:00
ca35ab9234 Remove code Duplication HotbarKit
All checks were successful
SteamWarCI Build successful
2025-04-20 20:41:47 +02:00
3df84a7dad Update from PR
All checks were successful
SteamWarCI Build successful
2025-04-20 20:40:19 +02:00
313b22cb44 Optimize SimulatorStabGenerator
All checks were successful
SteamWarCI Build successful
2025-04-20 18:30:30 +02:00
83c20729fa Fix RAM usage on multiple usages
All checks were successful
SteamWarCI Build successful
2025-04-20 08:27:56 +02:00
925901e40e Fix steamwar.devserver.gradle 2025-04-20 08:27:56 +02:00
059dd314d1 Fix building of DevServer 2025-04-20 08:27:56 +02:00
86ff619548 Add FightServer to configure those 2025-04-20 08:27:56 +02:00
76e00b07db Add plugins option to DevServer Task 2025-04-20 08:27:56 +02:00
4edfd32ff5 Add a check if the template exists in the user.home directory 2025-04-20 08:27:56 +02:00
5669725f9b Fix dev.py path 2025-04-20 08:27:56 +02:00
335649fa87 Fix steamwar.devserver.gradle 2025-04-20 08:27:56 +02:00
9001e83321 Add steamwar.properties 'worldName' and 'host'
Remove some options
2025-04-20 08:27:56 +02:00
32703c6659 Enable Velocity, prio Setup needed for that 2025-04-20 08:27:56 +02:00
e393aad25f Add all parameters that dev.py has 2025-04-20 08:27:56 +02:00
50543ddd4e Improve Server starter 'steamwar.devserver.gradle'
See build.gradle.kts of BauSystem
2025-04-20 08:27:56 +02:00
230ac09b61 Hotfix for disabled things
All checks were successful
SteamWarCI Build successful
2025-04-20 08:12:22 +02:00
48ea88e1a7 Merge pull request 'BauSystem/SimulatorStabGenerator' (#47) from BauSystem/SimulatorStabGenerator into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #47
2025-04-19 23:21:45 +02:00
05dc42355d Update and improve SimulatorStabGenerator
All checks were successful
SteamWarCI Build successful
2025-04-19 23:04:19 +02:00
17704487c9 Add SimulatorStabGenerator 2025-04-19 17:58:40 +02:00
76bbfd0381 Merge pull request 'Add TNTClickListener.TNT_CLICK_DETAILS as a toggle' (#46) from BauSystem/TNTClickDetails into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #46
2025-04-18 21:52:29 +02:00
ae9166528d Add TNTClickListener.TNT_CLICK_DETAILS as a toggle
All checks were successful
SteamWarCI Build successful
2025-04-18 21:49:59 +02:00
119fae4b51 Merge pull request 'Add ActiveMonths to ArenaMode for rotating modes' (#45) from VelocityCore/ActiveMonthsForRotatingGameModes into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #45
2025-04-18 18:38:41 +02:00
43621b18b4 Fix TypeMappers.arenaMapTypeMapper
All checks were successful
SteamWarCI Build successful
2025-04-18 16:57:35 +02:00
e5bdbac3c7 Change isNotActive to isActive
All checks were successful
SteamWarCI Build successful
2025-04-18 16:50:16 +02:00
fd738f539a Add 3 new PluginMessage channel
All checks were successful
SteamWarCI Build successful
2025-04-18 14:17:59 +02:00
b4c7576433 Merge pull request 'TNTLeague/BiggerCoins' (#12) from TNTLeague/BiggerCoins into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #12
Reviewed-by: Chaoscaot <max@chaoscaot.de>
2025-04-18 12:36:29 +02:00
8204e2ad21 Fix MWTeam.leave not distributing items correctly
All checks were successful
SteamWarCI Build successful
2025-04-18 12:30:22 +02:00
684a74b60d Fix SmartPlaceListener not updating Comparator or Repeater
All checks were successful
SteamWarCI Build successful
2025-04-18 12:14:43 +02:00
1f58b51af6 Fix NoteBlock turning off on redstone destroy under or up to 2 blocks beside it
All checks were successful
SteamWarCI Build successful
2025-04-18 12:07:31 +02:00
c9cfb48c4e Final fix for GlobalListener
All checks were successful
SteamWarCI Build successful
2025-04-18 10:14:08 +02:00
ace567ba33 Add chat system to TowerRun
All checks were successful
SteamWarCI Build successful
2025-04-18 10:07:42 +02:00
2094120150 Remove prefix. Cannot merge them together because of 'ChatListener.sendChat'
All checks were successful
SteamWarCI Build successful
2025-04-18 09:32:35 +02:00
e143268caa Fix DiscordBot.serverTeamChat sending to discord if received from discord!
All checks were successful
SteamWarCI Build successful
2025-04-18 09:30:26 +02:00
7802fdd7d9 Add ActiveMonths to ArenaMode for rotating modes
All checks were successful
SteamWarCI Build successful
2025-04-18 09:13:23 +02:00
7fb3d3d137 Hotfix DiscordBot.ingameChat going to broadcast instead of globalChat
All checks were successful
SteamWarCI Build successful
2025-04-17 21:38:35 +02:00
61d84492dc Merge branch 'main' into TNTLeague/BiggerCoins
All checks were successful
SteamWarCI Build successful
2025-04-17 21:18:40 +02:00
f74780d395 Hotfix IngameListener
All checks were successful
SteamWarCI Build successful
2025-04-17 16:47:23 +02:00
62dac000d4 Merge pull request 'Add general Melting of Blocks' (#43) from TowerRun/GeneralMeltingOfBlocks into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #43
2025-04-17 16:32:28 +02:00
424c80ec81 Add general Melting of Blocks
All checks were successful
SteamWarCI Build successful
2025-04-17 16:09:29 +02:00
ae7d394ae2 Enable clicking 'Ready' in inventory
All checks were successful
SteamWarCI Build successful
2025-04-17 15:45:25 +02:00
306444356c Update & Fix Spelling on Chaos Messages
All checks were successful
SteamWarCI Build successful
2025-04-17 01:28:06 +02:00
29dff8dce6 Fix PunishmentCommand sending double prefix
All checks were successful
SteamWarCI Build successful
2025-04-16 21:07:05 +02:00
cbaacd4e85 Merge pull request 'Improve and fix the discord rate limit warnings' (#37) from VelocityCore/ImproveDiscordChannel into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #37
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-04-16 20:16:52 +02:00
e24dada435 Trigger rebuild
All checks were successful
SteamWarCI Build successful
2025-04-16 18:13:58 +02:00
d04ffd5cf6 Fix some stuff for 1.21 BauSystem
Some checks failed
SteamWarCI Build failed
2025-04-16 18:12:50 +02:00
9da1de9b6c Fix MsgCommand being able to /r to offline players
All checks were successful
SteamWarCI Build successful
2025-04-16 13:42:31 +02:00
866c376ee5 Fix DevCommand not working when version switching without trying to connect in between when no server is running
All checks were successful
SteamWarCI Build successful
2025-04-16 10:20:10 +02:00
0b14a216d9 Fix SmartPlaceListener updating block under repeater/comparator
All checks were successful
SteamWarCI Build successful
2025-04-14 10:04:57 +02:00
b2853b9dec Fix RCommand being able to send offline players
All checks were successful
SteamWarCI Build successful
2025-04-14 10:01:50 +02:00
df5c363fb7 Fix FreezeListener
All checks were successful
SteamWarCI Build successful
2025-04-14 09:57:31 +02:00
5b3c3f36b4 Fix comment
All checks were successful
SteamWarCI Build successful
2025-04-14 09:16:06 +02:00
e1bcdd59ba Move 'maxNumberOfWebhooks' constructor parameter to end of list
All checks were successful
SteamWarCI Build successful
2025-04-14 09:14:04 +02:00
c9e4b57f12 Fix: Explicitly cast null to Integer in DownloadCommand
All checks were successful
SteamWarCI Build successful
2025-04-12 19:10:18 +02:00
fdcd248ba6 Merge branch 'main' of https://git.steamwar.de/SteamWar/SteamWar
Some checks failed
SteamWarCI Build failed
2025-04-12 19:04:11 +02:00
f573771355 Hotfix: Double Creation of //copy Schematics in //download command 2025-04-12 19:03:32 +02:00
80078cd8e2 Merge pull request 'Fix spectator handling' (#38) from spectator-improvements into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #38
Reviewed-by: Chaoscaot <max@chaoscaot.de>
2025-04-12 14:46:41 +02:00
76fc468d89 Merge pull request 'Refactors SchematicNode queries for efficiency' (#39) from improve-search-querry into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #39
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-04-12 14:40:34 +02:00
1304048509 Refactors SchematicNode queries for efficiency
All checks were successful
SteamWarCI Build successful
2025-04-11 00:07:53 +02:00
cf4ac95c2f Bugfix after testing
All checks were successful
SteamWarCI Build successful
2025-04-09 21:04:28 +02:00
4a816696ec Update the message limits
All checks were successful
SteamWarCI Build successful
2025-04-09 09:10:30 +02:00
038f54c3b3 Make it buildable and reduce complexity
All checks were successful
SteamWarCI Build successful
2025-04-09 09:03:07 +02:00
f2d8c9c02b Only AntiTest
All checks were successful
SteamWarCI Build successful
2025-04-08 21:34:41 +02:00
2405c5e620 Fix spectator handling
All checks were successful
SteamWarCI Build successful
2025-04-08 21:31:47 +02:00
d9493c7474 Dont show bedrock players and send an error for getting your own skull as a bedrock player
All checks were successful
SteamWarCI Build successful
2025-04-08 20:58:23 +02:00
2ccb240ef5 Merge remote-tracking branch 'origin/main'
All checks were successful
SteamWarCI Build successful
2025-04-08 20:54:54 +02:00
d1d1679c0a Add /skull shorthand for own skull 2025-04-08 20:54:48 +02:00
4c6ab2c1a0 Improve and fix the discord rate limit warnings
Some checks failed
SteamWarCI Build failed
2025-04-08 20:52:54 +02:00
62002e44d7 Merge pull request 'Add techhiderbug command.' (#36) from FightSystem/techhiderbug into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #36
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-04-07 21:22:39 +02:00
9c3f7526ff Add techhiderbug command.
All checks were successful
SteamWarCI Build successful
2025-04-07 19:37:23 +02:00
eefe17e5f7 Merge pull request 'Use combinedIds to hide in TechHider.iBlockDataHidden' (#35) from hotfix/TechHider into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #35
Reviewed-by: Chaoscaot <max@chaoscaot.de>
2025-04-05 18:12:54 +02:00
812e78d277 Make it 1.8 compatible
All checks were successful
SteamWarCI Build successful
2025-04-05 18:02:48 +02:00
fd220d7fd4 Fix maven url
All checks were successful
SteamWarCI Build successful
2025-04-04 13:57:09 +02:00
446cd5deae Fixup ChecklistChannel
All checks were successful
SteamWarCI Build successful
2025-04-04 11:23:51 +02:00
a6c46d0270 Use combinedIds to hide in TechHider.iBlockDataHidden
All checks were successful
SteamWarCI Build successful
2025-04-04 11:21:54 +02:00
2686ab285b Improve WaitTime in ChecklistChannel
All checks were successful
SteamWarCI Build successful
2025-04-04 11:16:12 +02:00
57ea1470e2 Fix for real!
All checks were successful
SteamWarCI Build successful
2025-04-04 10:54:21 +02:00
bfdc9c118a Hopefully fix it
All checks were successful
SteamWarCI Build successful
2025-04-04 10:52:37 +02:00
dafe838a8a Improve DiscordChannel on discord!
All checks were successful
SteamWarCI Build successful
2025-04-04 10:49:01 +02:00
13bd154383 Merge remote-tracking branch 'origin/main'
All checks were successful
SteamWarCI Build successful
2025-04-03 17:56:22 +02:00
9248c9fa51 Remove first second and third in master rank 2025-04-03 17:56:19 +02:00
764dec99f4 Remove display name cleansing in direct tablist handling
All checks were successful
SteamWarCI Build successful
2025-04-02 19:05:31 +02:00
c9a1528dfe Update UserElo for better distribution
All checks were successful
SteamWarCI Build successful
2025-04-02 10:21:03 +02:00
8c37466312 Revert "Add Alu-Hut"
All checks were successful
SteamWarCI Build successful
This reverts commit b37ded3a8d.
2025-04-02 08:58:42 +02:00
3b7e38aceb Revert "Fix Realtime"
This reverts commit 87f0765506.
2025-04-02 08:58:42 +02:00
e7c4c998a0 Revert "Allow edit of Lobby"
This reverts commit 1dcd2f102c.
2025-04-02 08:58:42 +02:00
5907648462 Revert "Allow edit of Lobby"
This reverts commit f62af55d39.
2025-04-02 08:58:42 +02:00
b32d6e9c69 Revert "Update difficulty"
This reverts commit 47c8cb1701.
2025-04-02 08:58:42 +02:00
f533e85007 Revert "Update difficulty"
This reverts commit 81c310c946.
2025-04-02 08:58:42 +02:00
81c310c946 Update difficulty
All checks were successful
SteamWarCI Build successful
2025-04-01 23:32:32 +02:00
47c8cb1701 Update difficulty
All checks were successful
SteamWarCI Build successful
2025-04-01 23:19:24 +02:00
f62af55d39 Allow edit of Lobby
All checks were successful
SteamWarCI Build successful
2025-04-01 20:58:10 +02:00
1dcd2f102c Allow edit of Lobby
All checks were successful
SteamWarCI Build successful
2025-04-01 20:56:33 +02:00
87f0765506 Fix Realtime
All checks were successful
SteamWarCI Build successful
2025-03-31 22:44:01 +02:00
b37ded3a8d Add Alu-Hut
All checks were successful
SteamWarCI Build successful
2025-03-31 22:37:55 +02:00
c4e9f80315 Fix leader not changeable during events
All checks were successful
SteamWarCI Build successful
2025-03-31 19:56:36 +02:00
19e14f787a Merge pull request 'feat(BauSystem): add tracer lua-lib' (#24) from BauSystem/tracer-lua-lib into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #24
Reviewed-by: Chaoscaot <max@chaoscaot.de>
Reviewed-by: Lixfel <lixfel@noreply.localhost>
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-03-30 17:33:29 +02:00
0f629a6387 Merge pull request 'Feature(BauSystem): Add example hotkey script' (#31) from BauSystem/add-example-scipt into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #31
Reviewed-by: Lixfel <lixfel@noreply.localhost>
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-03-30 17:32:42 +02:00
1a356da6e0 Trigger Rebuild
All checks were successful
SteamWarCI Build successful
2025-03-30 11:17:27 +02:00
f6a18dffcc Trigger Rebuild
All checks were successful
SteamWarCI Build successful
2025-03-30 11:14:20 +02:00
98cc09a7d3 Trigger Rebuild
All checks were successful
SteamWarCI Build successful
2025-03-30 11:11:01 +02:00
4c8a03ac9c Add 30 seconds EndCountdown for TowerRun
All checks were successful
SteamWarCI Build successful
2025-03-29 19:53:09 +01:00
16f2eaad52 fixed Script ordering
All checks were successful
SteamWarCI Build successful
2025-03-25 22:03:59 +01:00
90d2e70a6e Merge branch 'main' into BauSystem/add-example-scipt
All checks were successful
SteamWarCI Build successful
2025-03-25 21:55:04 +01:00
d22b01f5e6 Updated copyright
All checks were successful
SteamWarCI Build successful
2025-03-25 21:54:03 +01:00
0da3ebfbcc Merge pull request 'SpigotCore/RDisplay' (#23) from SpigotCore/RDisplay into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #23
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-03-23 18:30:29 +01:00
923142d0cb Merge branch 'main' into SpigotCore/RDisplay
All checks were successful
SteamWarCI Build successful
2025-03-23 18:29:09 +01:00
eca9963653 Add example hotkey script
All checks were successful
SteamWarCI Build successful
2025-03-21 18:49:49 +01:00
9467291020 Add license header to tracer lib
All checks were successful
SteamWarCI Build successful
2025-03-18 21:33:34 +01:00
e14c7321c2 Merge branch 'main' into BauSystem/tracer-lua-lib 2025-03-18 21:31:39 +01:00
50b6947312 Hotfix DiscordChatRoom
All checks were successful
SteamWarCI Build successful
2025-03-13 17:14:17 +01:00
9eca9ab990 Add DepthCommand to toggle Depth Counter
All checks were successful
SteamWarCI Build successful
2025-03-13 17:04:59 +01:00
34e4cd7060 Add click on SimulatorMaterialGui to change material
All checks were successful
SteamWarCI Build successful
2025-03-13 16:53:37 +01:00
30cb09c127 Hotfix ELO on leave
All checks were successful
SteamWarCI Build successful
2025-03-13 16:36:34 +01:00
c94d67660a Fixed doc
All checks were successful
SteamWarCI Build successful
2025-03-12 19:13:47 +01:00
522cd850a2 Add copyright and usage note!
All checks were successful
SteamWarCI Build successful
2025-03-12 08:45:01 +01:00
394591f302 First impl
All checks were successful
SteamWarCI Build successful
2025-03-11 22:58:03 +01:00
3016ad31fa Merge branch 'main' into SpigotCore/RDisplay
All checks were successful
SteamWarCI Build successful
2025-03-11 21:49:27 +01:00
1d293b446c Hotfix WhoisCommand for Developers not showing the User ID
All checks were successful
SteamWarCI Build successful
2025-03-11 18:31:31 +01:00
3b41cc4ac5 Improved tracer Lib
All checks were successful
SteamWarCI Build successful
2025-03-10 22:17:05 +01:00
a71f3f6c66 Merge pull request 'Update Bossbar of FightSystem' (#22) from FightSystem/UpdatedBossBar into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #22
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-03-09 18:27:27 +01:00
2225b811fa Update Bossbar of FightSystem
All checks were successful
SteamWarCI Build successful
2025-03-09 18:18:13 +01:00
96c25687b6 Hotfix SendCommand
All checks were successful
SteamWarCI Build successful
2025-03-08 22:16:39 +01:00
82723e4c31 Hotfix ShieldPrinting pasting AIR, it should not
All checks were successful
SteamWarCI Build successful
2025-03-08 18:34:22 +01:00
17eaefe3d0 Hotfix ShieldPrinting pasting AIR, it should not
All checks were successful
SteamWarCI Build successful
2025-03-08 17:51:41 +01:00
911a08a156 Merge remote-tracking branch 'origin/main'
All checks were successful
SteamWarCI Build successful
2025-03-08 17:44:55 +01:00
b60111e717 Hotfix ShieldPrinting pasting AIR, it should not 2025-03-08 17:44:46 +01:00
644cc9da84 Fix /arena bugs with event arenas
All checks were successful
SteamWarCI Build successful
2025-03-08 15:58:54 +01:00
29cb1cc5da Implemented first tracer lib version
All checks were successful
SteamWarCI Build successful
2025-03-08 01:11:24 +01:00
9bc1f8b328 Refactor password check and add cache clearance.
All checks were successful
SteamWarCI Build successful
2025-03-04 21:05:01 +01:00
f38b85f9cb Fix TPSSystem in 1.21 and beyond
All checks were successful
SteamWarCI Build successful
2025-03-03 11:27:46 +01:00
600c24441c Fix final things
All checks were successful
SteamWarCI Build successful
2025-03-03 10:09:54 +01:00
f3b5a45f62 Fix final things
All checks were successful
SteamWarCI Build successful
2025-03-03 10:05:08 +01:00
caee70c07e Hotfix some exceptions
All checks were successful
SteamWarCI Build successful
2025-03-03 10:01:56 +01:00
5f73395b63 Hotfix some exceptions
All checks were successful
SteamWarCI Build successful
2025-03-03 09:56:12 +01:00
b4eab65757 Hotfix xsome exceptions
All checks were successful
SteamWarCI Build successful
2025-03-03 09:42:39 +01:00
0a60654a28 Add some of the Easter Particles
All checks were successful
SteamWarCI Build successful
2025-03-03 09:35:42 +01:00
85c0db873c Final Hotfix of Send Command!
All checks were successful
SteamWarCI Build successful
2025-03-02 19:09:59 +01:00
f0beb22856 Hotfix the "to" back in
All checks were successful
SteamWarCI Build successful
2025-03-02 18:54:59 +01:00
af55c946a6 Remove player length constraint
All checks were successful
SteamWarCI Build successful
2025-03-02 18:51:01 +01:00
8b49b8a736 Add player respawn handling with custom spawn location
All checks were successful
SteamWarCI Build successful
2025-03-02 15:31:33 +01:00
6d4ae9593d Refine eventFight ID check in TNTLeagueConfig initialization.
All checks were successful
SteamWarCI Build successful
2025-03-02 15:14:10 +01:00
2fad352f62 Fix event initialization check in TNTLeagueConfig
All checks were successful
SteamWarCI Build successful
2025-03-02 15:02:11 +01:00
2d28cc6182 Fix isEvent function to correctly check eventFightId
All checks were successful
SteamWarCI Build successful
2025-03-02 14:58:26 +01:00
b0bd719627 Backend Fixes
All checks were successful
SteamWarCI Build successful
2025-03-02 09:08:49 +01:00
284c4acd4b Merge pull request 'Add event count to Team info' (#21) from VelocityCore/TeamInfoEventCount into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #21
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-03-01 21:45:06 +01:00
96a4168f37 Add event count to Team info
All checks were successful
SteamWarCI Build successful
2025-03-01 21:40:54 +01:00
c77b8f57ce Merge pull request 'Configurable techhider interaction suppression' (#19) from config-techhider-interaction-suppression into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #19
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-03-01 08:34:05 +01:00
e3c02cfb60 Revert "Update VV dependency version"
All checks were successful
SteamWarCI Build successful
This reverts commit 9f108a7cea.
2025-03-01 08:33:15 +01:00
ade9a1b5eb Allow TNT in shulker boxes
All checks were successful
SteamWarCI Build successful
2025-03-01 08:32:19 +01:00
ce907389df Refactor SQL query to remove schema qualifiers.
All checks were successful
SteamWarCI Build successful
2025-02-25 22:46:54 +01:00
d9b58d7170 Merge pull request 'Authentication v2' (#17) from Backend/new-auth into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #17
2025-02-25 22:40:09 +01:00
3db327eb84 Merge branch 'main' into Backend/new-auth
All checks were successful
SteamWarCI Build successful
2025-02-25 22:39:59 +01:00
fd82707414 Update webpassword command and clean up deprecated logic
All checks were successful
SteamWarCI Build successful
2025-02-23 17:27:29 +01:00
a2b3661605 Refactor V2 Auth
All checks were successful
SteamWarCI Build successful
2025-02-23 17:24:14 +01:00
b045f16160 Remove deprecated configureAuthRoutes function call
All checks were successful
SteamWarCI Build successful
2025-02-20 22:40:18 +01:00
dea0d33185 Refactor token generation and remove unused endpoints.
All checks were successful
SteamWarCI Build successful
2025-02-20 22:13:13 +01:00
11cf0b6c54 Merge pull request 'Add LegacyBauSystem with adaptions to current SpigotCore' (#20) from legacy-bau-system into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #20
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-02-20 06:46:06 +01:00
593ca9f0cf Merge pull request 'VelocityCore/SendCommand2.0' (#18) from VelocityCore/SendCommand2.0 into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #18
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-02-19 21:22:11 +01:00
7f5b57516e Reduce access token duration and enhance auth endpoints
All checks were successful
SteamWarCI Build successful
2025-02-17 18:28:43 +01:00
8ec12603b6 Add password reset URL generation and backend validation
All checks were successful
SteamWarCI Build successful
2025-02-17 17:48:26 +01:00
ef029eb420 Add LegacyBauSystem with adaptions to current SpigotCore
All checks were successful
SteamWarCI Build successful
2025-02-16 19:40:18 +01:00
9f108a7cea Update VV dependency version
Some checks failed
SteamWarCI Build failed
2025-02-16 17:25:18 +01:00
b516d1d569 Configurable techhider interaction suppression
All checks were successful
SteamWarCI Build successful
2025-02-16 17:14:55 +01:00
56e1abca7e Kick player on Channel injection failure
All checks were successful
SteamWarCI Build successful
2025-02-16 17:09:27 +01:00
5420c19b39 Add SCRIPT.md and sw.def.lua
All checks were successful
SteamWarCI Build successful
2025-02-14 20:34:49 +01:00
dd9467fa36 Hotfix TeamPlayer.onPlayerInteractEntity
All checks were successful
SteamWarCI Build successful
2025-02-14 16:53:26 +01:00
ccbac9f7fb Merge branch 'main' into VelocityCore/SendCommand2.0
All checks were successful
SteamWarCI Build successful
2025-02-13 20:40:16 +01:00
6aeecd444e Authentication v2
All checks were successful
SteamWarCI Build successful
2025-02-04 21:47:29 +01:00
ec43e7eba8 Trigger rebuild
All checks were successful
SteamWarCI Build successful
2025-02-02 16:29:10 +01:00
fbea45fb0f Merge pull request 'Add server shutdown if less than 2 players after 5 minutes' (#15) from TNTLeague/auto-shutdown into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #15
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-02-02 16:15:52 +01:00
abbbf7d3cb Merge branch 'main' into TNTLeague/auto-shutdown
All checks were successful
SteamWarCI Build successful
2025-02-02 16:14:25 +01:00
1dc0c0d8a8 Merge pull request 'Add ReadyCommand' (#16) from TNTLeague/add-ready-command into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #16
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-02-02 16:14:20 +01:00
25cf1ab314 Add ReadyCommand
All checks were successful
SteamWarCI Build successful
2025-02-02 16:11:02 +01:00
1715fdccdf Remove unused imports in TNTLeague classes
All checks were successful
SteamWarCI Build successful
2025-02-02 16:07:24 +01:00
e39db5978b Add server shutdown if less than 2 players after 5 minutes
All checks were successful
SteamWarCI Build successful
2025-02-02 16:06:48 +01:00
b4baef321f Trigger rebuild
All checks were successful
SteamWarCI Build successful
2025-02-02 15:28:33 +01:00
93ab1a50f3 Fix team auto-assign logic in lobby state
All checks were successful
SteamWarCI Build successful
Replaced `members.add` with `join` to correctly integrate new players into teams during the lobby phase. This ensures proper team setup and adherence to game mechanics.
2025-02-02 14:12:25 +01:00
c6a7107ec2 Merge pull request 'Make TNTLeague Event System Capable' (#13) from TNTLeague/add-event into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #13
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-02-02 13:03:02 +01:00
8ac5fe44ef Merge pull request 'Make TowerRun Event System Capable' (#14) from TowerRun/event into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #14
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-02-02 12:55:26 +01:00
414bd20eb9 Make TowerRun Event System Capable
All checks were successful
SteamWarCI Build successful
2025-02-01 22:58:49 +01:00
482282f913 Make TNTLeague Event System Capable
All checks were successful
SteamWarCI Build successful
2025-02-01 22:00:36 +01:00
3d153d49b5 Make TNTLeague Event System Capable
All checks were successful
SteamWarCI Build successful
2025-02-01 21:50:36 +01:00
20c90d9af5 Remove randomness
All checks were successful
SteamWarCI Build successful
2025-01-30 13:23:46 +01:00
c799046f43 Add bigger coins and remove TNT from spawning 2025-01-30 13:23:43 +01:00
90666e2d20 Merge pull request 'Add teamsOnSameLine for Arena Monochrome' (#5) from TNTLeague/TeamsOnSameLine into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #5
Reviewed-by: Chaoscaot <max@chaoscaot.de>
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-01-29 21:20:19 +01:00
77c6f41f1a Merge branch 'main' into TNTLeague/TeamsOnSameLine
All checks were successful
SteamWarCI Build successful
2025-01-29 21:19:35 +01:00
b3ddc04830 Fix Add Referee
All checks were successful
SteamWarCI Build successful
2025-01-29 19:12:45 +01:00
02b63687bc Fix Event Create
All checks were successful
SteamWarCI Build successful
2025-01-29 18:38:38 +01:00
dbf59df173 Fix Gitea Backend
All checks were successful
SteamWarCI Build successful
2025-01-26 10:13:36 +01:00
71362bc079 Hotfix: API Download is decompressed
All checks were successful
SteamWarCI Build successful
2025-01-26 00:22:50 +01:00
315674ebd8 Merge branch 'main' into TNTLeague/TeamsOnSameLine
All checks were successful
SteamWarCI Build successful
2025-01-24 22:44:47 +01:00
d5fb48ff3f Merge pull request 'Fix for Role Lookup in CouncilChannel' (#11) from VelocityCore/CouncilChannel into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #11
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-01-24 08:23:46 +01:00
5eaff4c492 Merge pull request 'Remove ViaVersion requirement from dev servers' (#10) from VelocityCore/DevVersion into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #10
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-01-24 08:23:30 +01:00
4db5c50b06 Fix PR stuff
All checks were successful
SteamWarCI Build successful
2025-01-24 08:21:47 +01:00
aa01fde5a0 Fix locale
All checks were successful
SteamWarCI Build successful
2025-01-23 18:21:44 +01:00
aa5fcd3811 Update CouncilChannel every hour
All checks were successful
SteamWarCI Build successful
2025-01-22 19:52:16 +01:00
de591b7a5f Update CouncilChannel
All checks were successful
SteamWarCI Build successful
2025-01-22 09:39:10 +01:00
e83878a49b Remove ViaVersion requirement from dev servers
All checks were successful
SteamWarCI Build successful
2025-01-22 09:29:20 +01:00
bbd42a769b Merge pull request 'Update CouncilChannel' (#9) from VelocityCore/CouncilChannel into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #9
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-01-22 09:22:58 +01:00
6541c34cc8 Update CouncilChannel
All checks were successful
SteamWarCI Build successful
2025-01-21 16:53:17 +01:00
364911e449 Fix CouncilChannel URL
All checks were successful
SteamWarCI Build successful
2025-01-21 08:09:11 +01:00
7f7f84a4c4 Fix CouncilChannel, unloading issues
All checks were successful
SteamWarCI Build successful
2025-01-21 00:03:39 +01:00
3fadeb7751 Disable Logs
All checks were successful
SteamWarCI Build successful
2025-01-20 19:09:29 +01:00
8da9a3cfbb Fix Schematic Upload
All checks were successful
SteamWarCI Build successful
2025-01-20 17:38:32 +01:00
0ce7429151 Fix Schematic Upload
All checks were successful
SteamWarCI Build successful
2025-01-20 17:31:20 +01:00
2848db02ab Merge pull request 'Update Links to new Website' (#8) from Website/update-links into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #8
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-01-20 17:14:42 +01:00
35e4f66c91 Merge pull request 'TNTLeague/fixes' (#7) from TNTLeague/fixes into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #7
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-01-20 17:14:05 +01:00
b4accdf0a1 Update Links to new Website
All checks were successful
SteamWarCI Build successful
2025-01-20 17:08:24 +01:00
b41eec56b9 Merge pull request 'Add bust to RatsChannel threads' (#6) from VelocityCore/RatsChannel into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #6
2025-01-20 17:03:46 +01:00
35142f108f Update Links to new Website
All checks were successful
SteamWarCI Build successful
2025-01-20 17:03:18 +01:00
af79ef544b Fixes
All checks were successful
SteamWarCI Build successful
2025-01-20 16:56:59 +01:00
ca076f9ffd Fix Schematic Download Link
All checks were successful
SteamWarCI Build successful
2025-01-20 16:56:10 +01:00
eacae09e4f Fix TNTLeague
All checks were successful
SteamWarCI Build successful
2025-01-20 16:46:53 +01:00
90ebc93b14 Add bust to RatsChannel threads
All checks were successful
SteamWarCI Build successful
2025-01-20 16:44:24 +01:00
747bb1055d Fix TNTLeague
All checks were successful
SteamWarCI Build successful
2025-01-20 16:43:56 +01:00
18418cca2a fixup! Fix TNTLeague
Some checks failed
SteamWarCI Build failed
2025-01-20 16:41:30 +01:00
a9660bd325 Fix TNTLeague 2025-01-20 16:40:45 +01:00
569d5b033e Fix setlocale command
All checks were successful
SteamWarCI Build successful
2025-01-20 16:14:44 +01:00
052e549606 Fix replay saving
All checks were successful
SteamWarCI Build successful
2025-01-20 16:09:40 +01:00
6519269d74 Add bust to RatsChannel threads
All checks were successful
SteamWarCI Build successful
2025-01-20 16:07:52 +01:00
ee705792bf Merge pull request 'File based replays' (#2) from newReplays into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #2
Reviewed-by: Chaoscaot <max@chaoscaot.de>
2025-01-20 14:55:09 +01:00
65cf84f164 Merge pull request 'Fix custom NPC Chats color codes for TheBreadBeard' (#4) from LobbySystem/NPCChats into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #4
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-01-20 12:46:02 +01:00
a13039bce4 Fix unignore message
All checks were successful
SteamWarCI Build successful
2025-01-20 12:31:27 +01:00
d721a7496e Merge pull request 'Update Schematic Download and /webpw to new Website' (#3) from Schematics/new-website into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #3
2025-01-20 12:26:54 +01:00
721723716e Fix sign
Some checks failed
SteamWarCI Build failed
2025-01-20 12:25:55 +01:00
3d2cba6a28 Fix tutorials
All checks were successful
SteamWarCI Build successful
2025-01-20 12:19:10 +01:00
3be748b92e Fix maven repo location
All checks were successful
SteamWarCI Build successful
2025-01-20 11:30:05 +01:00
898f3c785b Test CI
Some checks failed
SteamWarCI Build failed
2025-01-20 11:24:56 +01:00
2192eddb8b Test CI 2025-01-20 11:19:08 +01:00
327da139ba Merge branch 'newServer' 2025-01-20 11:04:23 +01:00
658dcd024d Add teamsOnSameLine for Arena Monochrome 2025-01-20 01:04:09 +01:00
ab4aaf782f Fix custom NPC Chats color codes for TheBreadBeard 2025-01-20 00:42:45 +01:00
21b389a993 Update Schematic Download and /webpw to new Website 2025-01-17 22:28:46 +01:00
3d78a23af1 Test CI 2025-01-17 17:44:07 +01:00
07185d0960 Test CI 2025-01-17 17:42:32 +01:00
d42da4c903 gradle.properties aktualisiert 2025-01-17 17:40:49 +01:00
afd0541039 Move Replays to File system 2025-01-17 13:46:02 +01:00
eaae2f4009 Adapt to new server, unlock old versions again 2025-01-17 13:28:57 +01:00
0c815ee1d5 Test CI
Some checks failed
SteamWarCI Build failed
2025-01-16 16:37:50 +01:00
429f938f1c Test CI
Some checks failed
SteamWarCI Build failed
2025-01-16 16:26:57 +01:00
fba7fe5008 Test CI 2025-01-16 15:23:17 +01:00
4012426e26 Test CI 2025-01-16 15:19:44 +01:00
fe4e486d41 Test CI 2025-01-16 15:07:22 +01:00
79a0fcb3aa BauSystem/build.gradle.kts aktualisiert 2025-01-15 22:20:50 +01:00
393f840507 BauSystem/build.gradle.kts aktualisiert 2025-01-15 22:14:39 +01:00
349e36fb6b CommandFramework/build.gradle.kts aktualisiert 2025-01-15 22:12:55 +01:00
6096828394 SchematicSystem/build.gradle.kts aktualisiert 2025-01-15 22:00:12 +01:00
2d84cc8ca7 KotlinCore/build.gradle.kts aktualisiert 2025-01-15 21:54:30 +01:00
ceff8e9cd5 BauSystem/build.gradle.kts aktualisiert 2025-01-15 21:51:09 +01:00
82e6aff4bb buildSrc/src/steamwar.java.gradle aktualisiert 2025-01-15 18:32:49 +01:00
8e7a6a56ca buildSrc/build.gradle aktualisiert 2025-01-15 18:23:57 +01:00
12c2ae435d CI Test 2025-01-15 18:21:44 +01:00
2564227ec7 CI Test 2025-01-15 18:18:11 +01:00
91d4a2dac3 Changes for new Server 2025-01-15 10:01:23 +01:00
f7c9c6d796 Fix tablist 2025-01-15 10:00:34 +01:00
0f1fbc4b88 Test Webhook 2025-01-14 23:44:30 +01:00
bfdf6471d2 Cleanup things and fix setting back to default
Some checks failed
SteamWarCI Build failed
2025-01-08 16:52:24 +01:00
e418109ab7 Reduce spawn packets to 0 if everything is default 2025-01-08 16:27:18 +01:00
06010ae27c Merge pull request 'Fix Schem Upload' (#100) from Schematics/fix-upload into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/100
Reviewed-by: Lixfel <lixfel@steamwar.de>
2025-01-08 13:27:07 +01:00
a39f172a34 Fix Schem Upload 2025-01-08 12:56:51 +01:00
82c73f9367 Fix packet count to at most 2 for the display entities at spawn 2025-01-08 12:24:17 +01:00
1350be9b80 Add new roughlyenoughitems plugin channel 2025-01-08 12:02:11 +01:00
1f65121c68 Fixup postSpawn because of NPE/Not Initialized Exception 2025-01-07 18:41:50 +01:00
3c848389c9 Update structure 2025-01-07 18:41:50 +01:00
33f41869b6 Fix packets 2025-01-07 18:41:50 +01:00
3c1d46398d Add RDisplay, RBlockDisplay, RItemDisplay, RTextDisplay 2025-01-07 18:41:50 +01:00
8e51db3e5b Fix tablist 2025-01-07 17:15:34 +01:00
fdd25b11a2 Merge pull request 'Fix invisible players' (#98) from FightSystem/FixInvisiblePlayers into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/98
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2025-01-07 17:12:15 +01:00
b6d5f8dcba Merge branch 'main' into FightSystem/FixInvisiblePlayers
# Conflicts:
#	FightSystem/FightSystem_18/src/de/steamwar/fightsystem/utils/BlockIdWrapper18.java
2025-01-07 17:11:06 +01:00
604a1db218 Fix Array reflection 2025-01-07 17:06:02 +01:00
01da293680 Fix Array reflection 2025-01-07 17:05:36 +01:00
e26e590e18 Merge pull request 'Potential fix for true IP for floodgate players' (#97) from VelocityCore/floodgateIPs into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/97
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2025-01-07 16:59:31 +01:00
26bc341c4d Fix 1.15- reflections 2025-01-07 16:57:06 +01:00
46fed25da4 Fix renaming for class name duplications 2025-01-07 16:38:40 +01:00
d3fbbb9768 Merge pull request 'Mojang map reflections' (#89) from MojMapReflections into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/89
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2025-01-07 16:27:02 +01:00
9a8cb543e9 Update SendCommand
Some checks failed
SteamWarCI Build failed
2025-01-07 14:27:57 +01:00
ed16de900e Merge pull request 'Fix /schem changetype schem type normal' (#99) from SchematicSystem/changetypenormal into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/99
Reviewed-by: Chaoscaot <chaos@chaoscaot.de>
2025-01-06 20:12:19 +01:00
66f4efb27f Fix /schem changetype schem type normal 2025-01-06 19:24:15 +01:00
053bd06342 Fix invisible players 2025-01-06 19:18:47 +01:00
9888700273 Migrate reflections to mojang mapped by default 2025-01-06 16:44:10 +01:00
94a1ed3569 More robust version detection. 2025-01-06 10:25:19 +01:00
da148c0e9f Replace {nms} and {obc} tags 2025-01-06 10:15:48 +01:00
ab34d86da4 Merge branch 'main' into MojMapReflections
# Conflicts:
#	SpigotCore/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java
#	SpigotCore/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java
#	SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/PartialChunkFixer.java
2025-01-06 10:06:28 +01:00
088965df59 Potential fix for true IP for floodgate players 2025-01-04 21:25:32 +01:00
a3490b801e Fix server transfer failure after checkpoint restoration 2025-01-03 12:55:59 +01:00
856c79661b Merge pull request 'Move ViaVersion to Proxy' (#87) from ViaOnProxy into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/87
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2025-01-03 07:33:45 +01:00
9f0f11adeb Fix entity orientation 2025-01-02 17:24:37 +01:00
6b7825ead9 Fix version matching 2025-01-02 11:05:07 +01:00
025ec2a850 Hotfix: 1.20 Schematic Reader 2025-01-01 14:12:38 +01:00
d7d6c2df7b Merge pull request 'VelocityCore/PrivateTicketLog' (#61) from VelocityCore/PrivateTicketLog into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/61
Reviewed-by: Lixfel <lixfel@steamwar.de>
2025-01-01 13:00:44 +01:00
55c3579e5c Merge pull request 'Add custom NPC Chats for specific players' (#93) from LobbySystem/NPCChats into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/93
Reviewed-by: Lixfel <lixfel@steamwar.de>
2025-01-01 12:58:12 +01:00
d64e32eaa5 Cleanup code 2025-01-01 12:56:49 +01:00
abb8ab2204 Merge pull request 'Fix Schematics Readers' (#72) from Schematics/1.21 into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/72
Reviewed-by: Lixfel <lixfel@steamwar.de>
2025-01-01 12:42:01 +01:00
c1dbce4648 Fix EventListener.onPlayerQuit 2024-12-31 18:56:42 +01:00
7dc5686389 Fixes... 2024-12-31 11:25:00 +01:00
f52cec0448 Add custom NPC Chats for TheBreadBeard 2024-12-28 22:58:35 +01:00
add43b2f54 Merge pull request 'Remove anti pickaxe drop code' (#94) from TNTLeague/RemovePickaxeDropCode into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/94
Reviewed-by: Chaoscaot <chaos@chaoscaot.de>
2024-12-28 22:28:20 +01:00
ca0f82897e Remove anti pickaxe drop code 2024-12-28 18:26:04 +01:00
f111d55200 Add custom NPC Chats for specific players 2024-12-28 17:36:40 +01:00
7eba9231d5 Fix build issues 2024-12-28 17:15:57 +01:00
e9ac198fcb Remove deop on TNTLeague join (mit Lixfel abgesprochen) 2024-12-26 22:42:07 +01:00
3a47e348d0 Merge pull request 'Add LastOnline to WhoisCommand' (#90) from VelocityCore/LastOnlineTime into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/90
Reviewed-by: Lixfel <lixfel@steamwar.de>
2024-12-26 22:23:01 +01:00
a16e1e8cee Add LastOnline to WhoisCommand 2024-12-26 21:44:40 +01:00
0f73939bf0 Move and rename Reflection fields 2024-12-26 19:11:01 +01:00
30ac38ef53 Merge pull request 'Remove /leader command, allow for Leader promotion' (#86) from FightSystem/Leader into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/86
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-12-26 10:53:07 +01:00
22a8ca4aea Move ViaVersion to Proxy 2024-12-24 14:55:27 +01:00
bd87221198 Add subcommand to reload gamemodes without full softreload 2024-12-23 13:12:57 +01:00
fb0a653b0e Remove /leader command, allow for Leader promotion 2024-12-23 13:05:00 +01:00
9154077104 Fix TNT League Stage Names 2024-12-23 12:50:38 +01:00
55adb1a052 Improve SendCommand 2024-12-22 23:16:19 +01:00
4448eab877 Hotfix: Rework Pickaxe 2024-12-22 22:54:46 +01:00
180fb685bd Hotfix: SubMessage 2024-12-22 22:49:06 +01:00
df1ec88f6c Hotfix: SubMessage 2024-12-22 22:46:00 +01:00
655b6cd15f Merge pull request 'Add Some Fixes and Improvements' (#83) from TNTLeague/fixes-and-improvements into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/83
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-12-22 22:38:03 +01:00
867091d210 Merge remote-tracking branch 'origin/TNTLeague/fixes-and-improvements' into TNTLeague/fixes-and-improvements 2024-12-22 22:27:45 +01:00
2f34369756 Fix SubMessage class 2024-12-22 22:27:30 +01:00
89fe401b03 Cleanup DealerInventory and TNTLeagueConfig 2024-12-22 22:22:42 +01:00
aaa808f90f Add Some Fixes and Improvements 2024-12-22 21:57:54 +01:00
1ea6bd61f8 Fix concurrent cipher usage 2024-12-22 16:17:58 +01:00
026b7bcc0e Fix SpectatePort 2024-12-22 16:02:52 +01:00
4da2307d50 Merge pull request 'TechHider refactoring, simple Blocktagging' (#82) from blocktagger into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/82
Reviewed-by: Chaoscaot <chaos@chaoscaot.de>
2024-12-22 07:18:41 +01:00
7d9996529e Add orientation pattern 2024-12-21 21:19:40 +01:00
a2710628a5 Update TechHiderWrapper and add orientation pattern 2024-12-21 19:47:40 +01:00
ec5382316a Fixes 2024-12-21 19:33:23 +01:00
51fd5faa4d Merge branch 'main' into Schematics/1.21
# Conflicts:
#	VelocityCore/build.gradle.kts
2024-12-21 19:29:46 +01:00
acbc5c5fd3 Cryptographically secure signature 2024-12-21 18:46:33 +01:00
793fc31b5c TechHider refactoring, simple Blocktagging 2024-12-21 16:53:49 +01:00
1b47700c19 Fix Event 2024-12-21 16:16:54 +01:00
06b0af5a16 Hotfix API EventFight Create 2024-12-21 15:42:27 +01:00
d08ccc3a98 Fix Everything 2024-12-21 12:30:39 +01:00
336915dd96 Fix Schem Upload 2024-12-21 12:03:43 +01:00
8fac9cd37e Merge pull request 'Partial diagonal HullHider uncovering, performance improvement' (#79) from FIghtSystem/partialSides into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/79
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-12-21 11:21:45 +01:00
3b2ee668b2 Merge pull request 'Additional Pluginmessage classifications, Lunar refactoring' (#80) from VelocityCore/PluginMessages into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/80
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-12-21 11:21:21 +01:00
c479d21cd2 Additional Pluginmessage classifications, Lunar refactoring 2024-12-21 11:09:16 +01:00
10e016c850 Partial diagonal HullHider uncovering, performance improvement 2024-12-21 10:52:41 +01:00
0e43c2a615 Hotfix: SW Survival 2024-12-17 20:02:12 +01:00
9eab15bfd5 Hotfix: Groups 2024-12-15 17:18:40 +01:00
2436340765 Fixes and Balances 2024-12-13 19:13:14 +01:00
7d9b3cd098 Merge remote-tracking branch 'origin/main' 2024-12-13 13:08:34 +01:00
85c6dcdc1e Add TNTLeague Auto-Stop 2024-12-13 13:08:28 +01:00
997a800c85 Fix Hullhider 1.15-, improve performance. 2024-12-13 11:26:19 +01:00
a5ffddad66 Add AdminReplay line of sight tools. 2024-12-13 10:42:44 +01:00
61e8ba14ca Fixes 2024-12-13 10:22:01 +01:00
56c66b33b7 Fix Locations 2024-12-13 09:43:18 +01:00
b90884ee1d Fix Locations 2024-12-13 09:31:15 +01:00
e1d3e47845 Fixes and De-Spagetti Code 2024-12-12 16:09:25 +01:00
b12846d011 Merge remote-tracking branch 'origin/main' 2024-12-11 15:05:02 +01:00
7488a4d063 Remove Stats 2024-12-11 15:04:54 +01:00
429e2f86aa Fix Hullhider. 2024-12-11 15:03:32 +01:00
c308a06e6b Test if broadcasting apollo:json acceptance triggers ModList sending. 2024-12-11 14:48:32 +01:00
68c7cfed73 Hotfix: Allow ReplayMod on Devservers 2024-12-11 14:34:31 +01:00
c3c4b94e3b Fix TNTLeague Sound 2024-12-11 14:20:38 +01:00
f61c27804a Fix TNTLeague Sound 2024-12-11 14:11:39 +01:00
b36c974f86 Fix TNTLeague Sound 2024-12-11 14:08:33 +01:00
ae4d498694 Fix TNTLeague Sound 2024-12-11 14:04:06 +01:00
e9f6b284eb Test if broadcasting apollo:json acceptance triggers ModList sending. 2024-12-11 13:26:12 +01:00
454cfecc0e Merge pull request 'Better Hull Hider Algorithm' (#76) from FightSystem/HullHiderAlgo_v2 into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/76
Reviewed-by: Chaoscaot <chaos@chaoscaot.de>
2024-12-11 13:16:39 +01:00
bc217c16dd Merge pull request 'Finish TNTLeague' (#53) from TNTLeague/finish into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/53
Reviewed-by: Lixfel <lixfel@steamwar.de>
2024-12-11 10:53:39 +01:00
d3f6075686 Add to CI 2024-12-11 10:53:17 +01:00
a1e77e571b Fix entity hider. 2024-12-11 09:52:05 +01:00
b31bd58e1a Handle additional recorded plugin channels. 2024-12-10 12:58:19 +01:00
f81b95e39f Fix direction id. 2024-12-10 12:57:21 +01:00
7ce5e319b5 Reduce unnecessary branch propagation by early abort with primary direction visibility. 2024-12-10 11:08:44 +01:00
c50bb64516 Performance improvements 2024-12-10 01:59:16 +01:00
b1c0e36cee Remove diagonal diagonals, branch only in enemy direction 2024-12-10 00:44:26 +01:00
be653754a7 Better Hull Hider Algorithm
Cardinal visibility with diagonal branching.
2024-12-10 00:01:47 +01:00
9c055ee929 Merge pull request 'Fix Schematic Punishment Messages' (#75) from SchematicSystem/fix-punishment into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/75
Reviewed-by: Lixfel <lixfel@steamwar.de>
2024-12-09 19:06:00 +01:00
80ab0eeda0 Fix 2024-12-09 19:05:36 +01:00
257f70cc6a Merge pull request 'Limit maximum number of sent in Schematics' (#74) from SchematicSystem/no-more-than-three into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/74
Reviewed-by: Lixfel <lixfel@steamwar.de>
2024-12-09 19:02:46 +01:00
970780b855 Reduce PluginMessage spam 2024-12-09 16:26:48 +01:00
c0d9b9f89b Fix /historic hover 2024-12-09 16:20:21 +01:00
6d0fa6527e Fix Schematic Punishment Messages 2024-12-08 23:40:50 +01:00
df4cd12d2a Unused Import 2024-12-08 23:29:57 +01:00
60dc00fd92 Limit maximum number of sent in Schematics 2024-12-08 23:29:13 +01:00
06eec10660 Fixes... 2024-12-08 23:18:32 +01:00
e1010f79e9 Merge pull request 'Fix color region reset' (#73) from BauSystem/resetColor into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/73
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-12-06 21:04:49 +01:00
e93683842b Language 2024-12-06 18:36:59 +01:00
cd17e625ca Remove debug output 2024-12-06 13:39:08 +01:00
d21e50dadd Test fix DiscordAlert 2024-12-06 13:36:13 +01:00
19ea605784 Debug DiscordAlert 2024-12-06 13:32:37 +01:00
4c12148552 Fix color region reset 2024-12-06 13:22:02 +01:00
da672a7506 Fix tablist after softreload 2024-12-06 13:07:21 +01:00
2f50c7acae Add debug output for DiscordAlert malfunction, add plugin messages 2024-12-06 12:50:09 +01:00
ed276bf4ce Fix for delayed interaction replys, add plugin messages 2024-12-06 11:41:29 +01:00
f5f8b3bd06 Test fix for delayed interaction replys 2024-12-06 11:23:54 +01:00
f01f869479 Fix logging of WARN level in Exception table 2024-12-05 21:48:52 +01:00
3ce958778a Fix NPE 2024-12-05 16:03:21 +01:00
c4849657df Deploy api backend 2024-12-05 13:28:46 +01:00
9a6dec6679 Merge pull request 'SubserverSystem-Refactoring' (#71) from SubserverSystem-Refactoring into main
Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/71
Reviewed-by: Chaoscaot <chaos@chaoscaot.de>
2024-12-04 11:43:27 +01:00
0134ef1f61 Maybe, Fix Schematics Readers 2024-12-03 22:43:14 +01:00
19a4d0e93a Fixes 2024-12-03 17:17:29 +01:00
677eb4137a Merge branch 'main' into TNTLeague/finish 2024-12-03 17:07:56 +01:00
7b55e99be0 Fix arena start condition 2024-12-03 17:05:53 +01:00
3abba4ae35 Add /build stop command 2024-12-03 15:50:32 +01:00
d2650ad97f Remove Servertype enum, fix starting multiple servers at once, 2024-12-03 15:42:57 +01:00
b3cd8d843f Add private ticket log 2024-11-27 19:34:19 +01:00
3e270643e8 Add private ticket log 2024-11-27 19:18:41 +01:00
8bb2be52f2 Language Fixes 2024-11-24 22:38:01 +01:00
d30fb5f949 Merge remote-tracking branch 'origin/main' into TNTLeague/finish 2024-11-24 22:20:41 +01:00
5e74aaad2c Merge branch 'main' into TNTLeague/finish 2024-11-24 22:13:01 +01:00
ec990cb52a Remove Component Messages 2024-11-24 21:35:13 +01:00
9415a3f217 Nits 2024-11-18 18:02:15 +01:00
4bb1bc0cbd Fixes, changes and Refactors 2024-11-17 12:04:07 +01:00
78853c70f8 Fixes and Update Copyright 2024-11-15 23:42:08 +01:00
5ac327409b Merge branch 'SpigotCore/1.21' into TNTLeague/finish 2024-11-15 23:13:44 +01:00
2e9dbfe8b8 Fixes... 2024-11-15 21:35:10 +01:00
27bd7be776 Fix Translations 2024-11-14 22:55:03 +01:00
9dff1f5884 Revert "Update Message"
This reverts commit ac9197c554.
2024-11-14 22:18:34 +01:00
26f15304a2 Merge branch 'KotlinCore/message-update' into TNTLeague/finish 2024-11-14 22:16:14 +01:00
d115975403 Add ComponentMessage, for TranslatableComponents in Paper >1.20 2024-11-14 22:08:06 +01:00
ac9197c554 Update Message 2024-11-14 19:31:17 +01:00
9d87ac6747 Merge branch 'main' into TNTLeague/finish 2024-11-10 16:47:14 +01:00
4edc59ba66 Add translations 2024-08-29 22:33:54 +02:00
424 changed files with 16031 additions and 3267 deletions

View File

@ -109,7 +109,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
@Override
public void setSelection(Player p, Point minPoint, Point maxPoint) {
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, toBlockVector3(minPoint), toBlockVector3(maxPoint)));
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3()));
}
@Override
@ -178,9 +178,9 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
pastePoint.set(v);
if (pasteBuilder.isReset()) {
e.setBlocks(new CuboidRegion(toBlockVector3(pasteBuilder.getMinPoint()), toBlockVector3(pasteBuilder.getMaxPoint())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
if (pasteBuilder.getWaterLevel() != 0) {
e.setBlocks(new CuboidRegion(toBlockVector3(pasteBuilder.getMinPoint()), toBlockVector3(pasteBuilder.getMaxPoint()).withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
}
}
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
@ -193,7 +193,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
@Override
public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) {
BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0));
CuboidRegion region = new CuboidRegion(bukkitWorld, toBlockVector3(minPoint), toBlockVector3(maxPoint));
CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3());
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) {
ForwardExtentCopy copy = new ForwardExtentCopy(
@ -204,7 +204,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
copy.setCopyingBiomes(false);
Operations.complete(copy);
clipboard.setOrigin(toBlockVector3(copyPoint));
clipboard.setOrigin(copyPoint.toBlockVector3());
return clipboard;
} catch (WorldEditException e) {
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
@ -224,10 +224,6 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
}
}
private BlockVector3 toBlockVector3(Point point) {
return BlockVector3.at(point.getX(), point.getY(), point.getZ());
}
@Override
public boolean inWater(org.bukkit.World world, Vector tntPosition) {
Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ());

View File

@ -19,27 +19,21 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.bausystem.features.util.NoClipCommand;
import net.minecraft.server.v1_15_R1.*;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.function.LongSupplier;
public class NMSWrapper15 implements NMSWrapper {
private static final Reflection.FieldAccessor<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
@Override
@SuppressWarnings("deprecation")
@ -63,7 +57,7 @@ public class NMSWrapper15 implements NMSWrapper {
player.updateInventory();
}
private static final Reflection.FieldAccessor<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
private static final Reflection.Field<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
@Override
public void setGameStateChangeReason(Object packet) {
@ -120,12 +114,12 @@ public class NMSWrapper15 implements NMSWrapper {
return invalid;
}
private final Class<?> explosionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion");
private final Reflection.FieldAccessor<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.FieldAccessor<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.FieldAccessor<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.FieldAccessor<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.FieldAccessor<List> e = Reflection.getField(explosionPacket, List.class, 0);
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
@Override
public Object resetExplosionKnockback(Object packet) {

View File

@ -19,12 +19,9 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
import de.steamwar.Reflection;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.PacketPlayInFlying;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntity;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityTeleport;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;

View File

@ -19,36 +19,26 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection;
import de.steamwar.bausystem.features.util.NoClipCommand;
import net.minecraft.SystemUtils;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.server.level.PlayerInteractManager;
import net.minecraft.world.level.EnumGamemode;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.function.LongSupplier;
public class NMSWrapper18 implements NMSWrapper {
private static final Reflection.FieldAccessor<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
@Override
@SuppressWarnings("deprecation")
@ -73,7 +63,7 @@ public class NMSWrapper18 implements NMSWrapper {
player.updateInventory();
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override
public void setGameStateChangeReason(Object packet) {
@ -130,12 +120,12 @@ public class NMSWrapper18 implements NMSWrapper {
return invalid;
}
private final Class<?> explosionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion");
private final Reflection.FieldAccessor<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.FieldAccessor<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.FieldAccessor<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.FieldAccessor<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.FieldAccessor<List> e = Reflection.getField(explosionPacket, List.class, 0);
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
@Override
public Object resetExplosionKnockback(Object packet) {

View File

@ -19,8 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
import de.steamwar.Reflection;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.server.level.EntityPlayer;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;

View File

@ -19,37 +19,26 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection;
import de.steamwar.bausystem.features.util.NoClipCommand;
import net.minecraft.SystemUtils;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.server.level.PlayerInteractManager;
import net.minecraft.world.level.EnumGamemode;
import net.minecraft.world.phys.Vec3D;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.function.LongSupplier;
public class NMSWrapper19 implements NMSWrapper {
private static final Reflection.FieldAccessor<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
@Override
@SuppressWarnings("deprecation")
@ -73,7 +62,7 @@ public class NMSWrapper19 implements NMSWrapper {
player.updateInventory();
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override
public void setGameStateChangeReason(Object packet) {
@ -130,12 +119,12 @@ public class NMSWrapper19 implements NMSWrapper {
return invalid;
}
private final Class<?> explosionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion");
private final Reflection.FieldAccessor<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.FieldAccessor<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.FieldAccessor<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.FieldAccessor<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.FieldAccessor<List> e = Reflection.getField(explosionPacket, List.class, 0);
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
@Override
public Object resetExplosionKnockback(Object packet) {

View File

@ -19,17 +19,12 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.server.level.EntityPlayer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
@Override

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.bausystem.features.util.NoClipCommand;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
@ -40,7 +40,7 @@ import java.util.List;
public class NMSWrapper20 implements NMSWrapper {
private static final Reflection.FieldAccessor<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
@Override
@SuppressWarnings("deprecation")
@ -64,7 +64,7 @@ public class NMSWrapper20 implements NMSWrapper {
player.updateInventory();
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override
public void setGameStateChangeReason(Object packet) {
@ -121,12 +121,12 @@ public class NMSWrapper20 implements NMSWrapper {
return invalid;
}
private final Class<?> explosionPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion");
private final Reflection.FieldAccessor<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.FieldAccessor<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.FieldAccessor<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.FieldAccessor<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.FieldAccessor<List> e = Reflection.getField(explosionPacket, List.class, 0);
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
@Override
public Object resetExplosionKnockback(Object packet) {

View File

@ -19,18 +19,12 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import net.minecraft.network.protocol.game.PacketPlayInFlying;
import net.minecraft.network.protocol.game.PacketPlayOutEntityTeleport;
import net.minecraft.server.level.EntityPlayer;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class PlayerMovementWrapper20 implements PlayerMovementWrapper {
@Override

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.bausystem.features.util.NoClipCommand;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTBase;
@ -45,7 +45,7 @@ import java.util.Optional;
public class NMSWrapper21 implements NMSWrapper {
private static final Reflection.FieldAccessor<PlayerInteractManager> playerInteractManager = Reflection.getField(EntityPlayer.class, null, PlayerInteractManager.class);
private static final Reflection.Field<PlayerInteractManager> playerInteractManager = Reflection.getField(EntityPlayer.class, null, PlayerInteractManager.class);
@Override
public void setInternalGameMode(Player player, GameMode gameMode) {
@ -68,14 +68,14 @@ public class NMSWrapper21 implements NMSWrapper {
player.updateInventory();
}
private static final Reflection.FieldAccessor<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
@Override
public void setGameStateChangeReason(Object packet) {
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
}
private static final Reflection.FieldAccessor<PlayerAbilities> playerAbilities = Reflection.getField(EntityHuman.class, null, PlayerAbilities.class);
private static final Reflection.Field<PlayerAbilities> playerAbilities = Reflection.getField(EntityHuman.class, null, PlayerAbilities.class);
@Override
public void setPlayerBuildAbilities(Player player) {

View File

@ -38,7 +38,6 @@ dependencies {
compileOnly(libs.spigotapi)
compileOnly(libs.axiom)
compileOnly(libs.authlib)
compileOnly(libs.viaapi)
compileOnly(libs.fawe18)

View File

@ -406,6 +406,8 @@ BLOCK_COUNTER_MESSAGE_SECOND=§7Damage §8> §e{0} §7Blocks §e{1} §7TNT §e
BLOCK_COUNTER_ENABLE=§7BlockCounter activated
BLOCK_COUNTER_DISABLE=§7BlockCounter deactivated
# DepthCounter
DEPTH_COUNTER_DISABLE=§7Depth Counter disabled
DEPTH_COUNTER_ENABLE=§7Depth Counter enabled
DEPTH_COUNTER_MESSAGE=§7Depth §8> §7
DEPTH_COUNTER_COUNT={0}{1}§8×{2}{3}§8×{4}{5}
DEPTH_COUNTER_HOVER=§7X§8×§7Y§8×§7Z
@ -945,6 +947,9 @@ SPEED_TAB_NAME=Input speed
WORLDEDIT_WAND=WorldEdit Wand
WORLDEDIT_LEFTCLICK=Left click: select pos #1
WORLDEDIT_RIGHTCLICK=Right click: select pos #2
TNT_DETAILS_COMMAND=§8/§etntdetails §8-§7 Toggle information printed after clicking on a TNT
TNT_DETAILS_ON = §eTNTDetails §aactivated
TNT_DETAILS_OFF = §eTNTDetails §cdeactivated
TNT_CLICK_HEADER=§8---=== §eTNT §8===---
TNT_CLICK_ORDER=§eEntity Order§8: §e{0}
TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0}
@ -1014,5 +1019,3 @@ COLORREPLACE_HELP=§8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §
TYPEREPLACE_HELP=§8//§etypereplace §8[§7type§8] §8[§7type§8] §8- §7Replace all blocks of one type with another
# Schematic
SCHEMATIC_GUI_ITEM=§eSchematics
#VersionAnnouncer
SERVER_VERSION=§7This server runs on Minecraft version §e{0}

View File

@ -369,6 +369,8 @@ BLOCK_COUNTER_MESSAGE_SECOND=§7Schaden §8> §e{0} §7Blöcke §e{1} §7TNT
BLOCK_COUNTER_ENABLE=§7BlockCounter angemacht
BLOCK_COUNTER_DISABLE=§7BlockCounter ausgemacht
# DepthCounter
DEPTH_COUNTER_DISABLE=§7Depth Counter deaktiviert
DEPTH_COUNTER_ENABLE=§7Depth Counter aktiviert
DEPTH_COUNTER_MESSAGE=§7Tiefe §8> §7
# TPSLimit
TPSLIMIT_FREEZE_HELP=§8/§etpslimit 0 §8-§7 Friere TPS ein
@ -887,6 +889,9 @@ SPEED_TAB_NAME=Geschwindigkeit eingeben
WORLDEDIT_WAND=WorldEdit Wand
WORLDEDIT_LEFTCLICK=Left click: select pos #1
WORLDEDIT_RIGHTCLICK=Right click: select pos #2
TNT_DETAILS_COMMAND=§8/§etntdetails §8-§7 Aktiviert/Deaktiviert das senden von Details beim Klick auf TNT
TNT_DETAILS_ON = §eTNTDetails §aaktiviert
TNT_DETAILS_OFF = §eTNTDetails §cdeaktiviert
TNT_CLICK_HEADER=§8---=== §eTNT §8===---
TNT_CLICK_ORDER=§eEntity Order§8: §e{0}
TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0}
@ -955,5 +960,3 @@ COLORREPLACE_HELP=§8//§ecolorreplace §8[§7color§8] §8[§7color§8] §8- §
TYPEREPLACE_HELP=§8//§etyreplace §8[§7type§8] §8[§7type§8] §8- §7Ersetzt einen Blockgruppe mit einer anderen
# Schematics
SCHEMATIC_GUI_ITEM=§eSchematics
#VersionAnnouncer
SERVER_VERSION=§7Dieser Server läuft auf Minecraft-Version §e{0}

View File

@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.cannon.depth;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
@ -65,7 +66,9 @@ public class Depth {
dimensions.setZ(Math.abs(dimensions.getZ()));
RegionUtils.message(region, player -> {
if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount));
}
});
}

View File

@ -0,0 +1,45 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.cannon.depth;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@Linked
public class DepthCommand extends SWCommand {
public DepthCommand() {
super("depth");
}
@Register
public void toggle(Player player) {
if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
Config.getInstance().get(player).put("depth_message", false);
BauSystem.MESSAGE.send("DEPTH_COUNTER_DISABLE", player);
} else {
Config.getInstance().get(player).put("depth_message", true);
BauSystem.MESSAGE.send("DEPTH_COUNTER_ENABLE", player);
}
}
}

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.observer;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.bausystem.region.Point;
import org.bukkit.Location;
import org.bukkit.Material;
@ -170,7 +170,7 @@ public class ObserverTracer {
}
}
private static final Class<?> craftPoweredRail = Reflection.getClass("{obc}.block.impl.CraftPoweredRail");
private static final Class<?> craftPoweredRail = Reflection.getClass("org.bukkit.craftbukkit.block.impl.CraftPoweredRail");
private boolean checkAllowed(Block block, BlockData blockData) {
if (checkMaterial(block)) return true;
if (block.getType() == Material.BELL) {

View File

@ -0,0 +1,37 @@
package de.steamwar.bausystem.features.printerTool;
import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@Linked
public class PrinterToolItem implements Listener {
public static ItemStack getItem(Player p) {
ItemStack itemStack = new SWItem(Material.WOODEN_PICKAXE, "Printer Tool").getItemStack();
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setCustomModelData(1);
itemStack.setItemMeta(itemMeta);
ItemUtils.setItem(itemStack, "printer_tool");
return itemStack;
}
public static boolean isItem(ItemStack itemStack) {
return itemStack != null && ItemUtils.isItem(itemStack, "printer_tool");
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
ItemStack item = event.getItem();
if(PrinterToolItem.isItem(item)) {
}
}
}

View File

@ -11,8 +11,9 @@ import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.type.NoteBlock;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -60,6 +61,24 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
public void onPhysicsEvent(BlockPhysicsEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
if (e.getSourceBlock().getType() == Material.NOTE_BLOCK) {
BlockState state = e.getSourceBlock().getState();
NoteBlock noteBlock = (NoteBlock) state.getBlockData();
if (noteBlock.isPowered()) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
state.update(true, false);
}, 1);
}
}
if (e.getBlock().getType() == Material.NOTE_BLOCK) {
BlockState state = e.getBlock().getState();
NoteBlock noteBlock = (NoteBlock) state.getBlockData();
if (noteBlock.isPowered()) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
state.update(true, false);
}, 1);
}
}
e.setCancelled(true);
}
}
@ -71,6 +90,105 @@ public class FreezeListener implements Listener, ScoreboardElement {
}
}
@EventHandler
public void onNotePlay(NotePlayEvent event) {
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=45, z=98},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=44, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=97},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=97},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=96},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-108, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=45, z=98},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-104, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=49, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
////[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=102},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-108, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-104, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
}
@EventHandler
public void onPistonRetract(BlockPistonRetractEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
@ -108,13 +226,13 @@ public class FreezeListener implements Listener, ScoreboardElement {
}
}
@EventHandler(priority = EventPriority.MONITOR)
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent e) {
if (Core.getVersion() < 19) return;
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
if (e.isCancelled()) return;
e.setCancelled(true);
e.getBlock().setType(Material.BARRIER, false);
e.getBlock().setType(Material.AIR, false);
}
}

View File

@ -20,7 +20,6 @@
package de.steamwar.bausystem.features.region;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.config.BauServer;
import de.steamwar.bausystem.region.GlobalRegion;
import de.steamwar.bausystem.region.Region;
@ -31,7 +30,6 @@ import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.sql.Punishment;
@ -40,7 +38,6 @@ import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.io.IOException;
import java.util.logging.Level;
@Linked
@ -61,7 +58,7 @@ public class ResetCommand extends SWCommand {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getResetFile(RegionType.NORMAL)))
.color(region.getPlain(Flag.COLOR, ColorMode.class).getColor());
region.reset(pasteBuilder, RegionType.NORMAL, RegionExtensionType.NORMAL);
for (Flag value : Flag.values()) {
for (Flag value : Flag.getResetFlags()) {
region.set(value, value.getDefaultValue());
}
RegionUtils.message(region, "REGION_RESET_RESETED");

View File

@ -24,7 +24,6 @@ import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.features.script.ScriptRunner;
import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
@ -32,7 +31,6 @@ import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -72,10 +70,11 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerQuit(PlayerQuitEvent event) {
StorageLib.removePlayer(event.getPlayer());
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(Permission.BUILD.hasPermission(event.getPlayer())) {
ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event);
}
StorageLib.removePlayer(event.getPlayer());
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {

View File

@ -51,7 +51,7 @@ public class TpsLib implements LuaLib {
tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
tpsLib.set("current", getter(TPSWatcher::getTPS));
tpsLib.set("limit", getter(tpsSystem::getCurrentTPSLimit));
tpsLib.set("limit", getter(TPSSystem::getCurrentTPSLimit));
return tpsLib;
}
}

View File

@ -0,0 +1,113 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.script.lua.libs;
import de.steamwar.bausystem.features.tracer.TNTPoint;
import de.steamwar.bausystem.features.tracer.Trace;
import de.steamwar.bausystem.features.tracer.TraceManager;
import de.steamwar.linkage.Linked;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.ZeroArgFunction;
@Linked
public class TracerLib implements LuaLib {
@Override
public String name() {
return "tracer";
}
private static LuaTable convertTrace(Trace trace) {
LuaTable luaTrace = new LuaTable();
luaTrace.set("getRecords", new ZeroArgFunction() {
@Override
public LuaValue call() {
return LuaValue.listOf(
trace.getHistories()
.stream()
.map((history) -> LuaValue.listOf(history
.stream()
.map(TracerLib::convertTntPoint)
.toArray(LuaValue[]::new)))
.toArray(LuaValue[]::new));
}
});
luaTrace.set("getId", new ZeroArgFunction() {
@Override
public LuaValue call() {
return LuaValue.valueOf(trace.getUuid().toString());
}
});
return luaTrace;
}
private static LuaTable convertTntPoint(TNTPoint tntPoint) {
Location pointPos = tntPoint.getLocation();
LuaTable luaPos = LuaValue.tableOf(new LuaValue[]{
LuaValue.valueOf("x"), LuaValue.valueOf(pointPos.getX()),
LuaValue.valueOf("y"), LuaValue.valueOf(pointPos.getY()),
LuaValue.valueOf("z"), LuaValue.valueOf(pointPos.getZ()),
});
Vector pointVel = tntPoint.getVelocity();
LuaTable luaVel = LuaValue.tableOf(new LuaValue[]{
LuaValue.valueOf("x"), LuaValue.valueOf(pointVel.getX()),
LuaValue.valueOf("y"), LuaValue.valueOf(pointVel.getY()),
LuaValue.valueOf("z"), LuaValue.valueOf(pointVel.getZ()),
});
return LuaValue.tableOf(new LuaValue[]{
LuaValue.valueOf("pos"), luaPos,
LuaValue.valueOf("vel"), luaVel,
LuaValue.valueOf("ticksSinceStart"), LuaValue.valueOf(tntPoint.getTicksSinceStart()),
LuaValue.valueOf("fuse"), LuaValue.valueOf(tntPoint.getFuse()),
LuaValue.valueOf("isExplosion"), LuaValue.valueOf(tntPoint.isExplosion()),
LuaValue.valueOf("isInWater"), LuaValue.valueOf(tntPoint.isInWater()),
LuaValue.valueOf("hasDestroyedBuild"), LuaValue.valueOf(tntPoint.isDestroyedBuildArea()),
LuaValue.valueOf("hasDestroyedTestblock"), LuaValue.valueOf(tntPoint.isDestroyedTestBlock())
});
}
@Override
public LuaTable get(Player player) {
LuaTable rootTable = LuaValue.tableOf();
rootTable.set("getTraces", new ZeroArgFunction() {
@Override
public LuaValue call() {
return LuaValue.listOf(TraceManager.instance.getAll()
.stream()
.map(TracerLib::convertTrace)
.toArray(LuaValue[]::new));
}
}
);
return rootTable;
}
}

View File

@ -160,6 +160,11 @@ public class ShieldPrinting implements Listener {
private void paste(Map<Material, BlockDataConfiguration<?>[]> stateConfiguration) {
for (Map.Entry<Vector, BlockData> entry : shieldData.entrySet()) {
BlockData copied = entry.getValue();
if (copied.getMaterial().isAir()) {
continue;
}
Block block = entry.getKey().toLocation(WORLD).getBlock();
if (entry.getValue().getMaterial() != block.getType()) {
block.setBlockData(entry.getValue(), false);
@ -171,12 +176,11 @@ public class ShieldPrinting implements Listener {
BlockDataConfiguration[] stateConfigurations = stateConfiguration.get(entry.getValue().getMaterial());
if (stateConfigurations == null) {
block.setBlockData(entry.getValue(), false);
continue;
}
BlockData worldOriginal = block.getBlockData();
BlockData copied = entry.getValue().clone();
copied = copied.clone();
for (BlockDataConfiguration blockDataConfiguration : stateConfigurations) {
if (blockDataConfiguration == null) continue;
blockDataConfiguration.apply(copied, worldOriginal);

View File

@ -76,7 +76,7 @@ public class SimulatorCommand extends SWCommand {
@Register(value = "start", description = "SIMULATOR_START_HELP")
public void start(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) {
SimulatorExecutor.run(simulator);
SimulatorExecutor.run(simulator, () -> {});
}
@Register(value = "rename", description = "SIMULATOR_RENAME_HELP")

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.simulator;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
@ -72,9 +72,9 @@ import java.util.stream.Collectors;
public class SimulatorCursor implements Listener {
private final World WORLD = Bukkit.getWorlds().get(0);
private Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
private Class<?> look = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInLook");
private Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
private Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
private Class<?> look = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
private Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
private Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
private Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
@ -168,9 +168,19 @@ public class SimulatorCursor implements Listener {
}
return;
}
Simulator simulator = SimulatorStorage.getSimulator(player);
SimulatorWatcher.show(simulator, player);
Simulator simulator = SimulatorStorage.getSimulator(player);
if (simulator != null && simulator.getStabGenerator() != null) {
removeCursor(player);
SimulatorWatcher.show(null, player);
SWUtils.sendToActionbar(player, "§cGenerating Stab");
synchronized (calculating) {
calculating.remove(player);
}
return;
}
SimulatorWatcher.show(simulator, player);
List<REntity> entities = SimulatorWatcher.getEntitiesOfSimulator(simulator);
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities);
if (rayTraceResult == null) {
@ -357,7 +367,7 @@ public class SimulatorCursor implements Listener {
if (simulator == null) {
return;
}
SimulatorExecutor.run(simulator);
SimulatorExecutor.run(simulator, () -> {});
return;
}

View File

@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.simulator.data;
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator;
import de.steamwar.inventory.InvCallback;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
@ -30,13 +31,13 @@ import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
@Getter
@Setter
@RequiredArgsConstructor
public final class Simulator {
private SimulatorStabGenerator stabGenerator = null;
private Material material = Material.BARREL;
private final String name;
private boolean autoTrace = false;

View File

@ -60,6 +60,7 @@ public final class TNTPhase extends SimulatorPhase {
@Override
public void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
if (count <= 0) return;
tickStart.accept(tickOffset, new SimulatorAction(order, count) {
@Override
public void accept(World world) {

View File

@ -0,0 +1,34 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import lombok.AllArgsConstructor;
import org.bukkit.util.Vector;
import java.util.function.Function;
@AllArgsConstructor
public enum Direction {
X(Vector::getBlockX),
Y(Vector::getBlockY),
Z(Vector::getBlockZ);
public final Function<Vector, Integer> component;
}

View File

@ -46,7 +46,7 @@ public class SimulatorExecutor implements Listener {
private static Map<Long, Map<Integer, List<SimulatorAction>>> tickStartActions = new HashMap<>();
private static Map<Long, List<SimulatorAction>> tickEndActions = new HashMap<>();
public static boolean run(Simulator simulator) {
public static boolean run(Simulator simulator, Runnable onEnd) {
if (currentlyRunning.contains(simulator)) return false;
currentlyRunning.add(simulator);
@ -69,7 +69,7 @@ public class SimulatorExecutor implements Listener {
public void accept(World world) {
currentlyRunning.remove(simulator);
if (simulator.isAutoTrace()) {
if (simulator.isAutoTrace() && onEnd == null) {
simulator.getGroups()
.stream()
.map(SimulatorGroup::getElements)
@ -82,10 +82,12 @@ public class SimulatorExecutor implements Listener {
TraceRecorder.instance.stopRecording(region);
});
}
onEnd.run();
}
});
if (simulator.isAutoTrace()) {
if (simulator.isAutoTrace() && onEnd == null) {
simulator.getGroups()
.stream()
.map(SimulatorGroup::getElements)

View File

@ -0,0 +1,45 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class SimulatorStabGenerator {
private final StabData stabData;
public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) {
stabData = new StabData(region, simulator, tntElement, tntElement.getPhases(), depthLimit);
new StabSetup(stabData);
}
public void cancel() {
stabData.cancel = true;
stabData.simulator.setStabGenerator(null);
for (Player player : Bukkit.getOnlinePlayers()) {
BossBarService.instance.remove(player, stabData.region, "simulator_stab_generator");
}
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.region.Region;
import lombok.RequiredArgsConstructor;
import java.util.List;
import java.util.logging.Level;
@RequiredArgsConstructor
public class StabData {
protected static final int MAX_RECORDINGS = 5;
protected static final int MAX_TICK_DIFFERENCE = 3;
protected static final Level LEVEL = Level.INFO;
protected static final int TNT_INCREASE = 10;
protected static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20;
protected final Region region;
protected final Simulator simulator;
protected final TNTElement tntElement;
protected final List<TNTPhase> phases;
protected final int depthLimit;
protected Clipboard clipboard;
protected boolean cancel = false;
protected Direction direction = null;
protected int currentDepth = 0;
}

View File

@ -0,0 +1,103 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
import de.steamwar.bausystem.features.tracer.TNTPoint;
import de.steamwar.bausystem.features.tracer.Trace;
import de.steamwar.bausystem.features.tracer.TraceManager;
import de.steamwar.bausystem.features.tracer.TraceRecorder;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import org.bukkit.Bukkit;
import org.bukkit.util.Vector;
import java.util.List;
import java.util.Objects;
public class StabDirection extends StabStep {
public StabDirection(StabData data) {
super(data);
}
@Override
protected void start() {
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(data.region.getMinPointTestblockExtension().toBlockVector3(), data.region.getMaxPointTestblockExtension().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
}
Trace trace = TraceRecorder.instance.startRecording(data.region);
runSimulator(() -> {
TraceRecorder.instance.stopRecording(data.region);
calculateDirection(trace);
});
}
private void calculateDirection(Trace trace) {
long tickSinceStart = -1;
List<TNTPoint> points = null;
for (List<TNTPoint> current : trace.getHistories()) {
long ticks = current.get(0).getTicksSinceStart();
if (points == null || ticks > tickSinceStart) {
tickSinceStart = ticks;
points = current;
} else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) {
points = current;
}
}
TraceManager.instance.remove(trace);
if (points == null) {
stop();
return;
}
TNTPoint current = points.getLast();
Vector velocity = current.getVelocity();
if (velocity.getX() < 0) velocity.setX(-velocity.getX());
if (velocity.getY() < 0) velocity.setY(-velocity.getY());
if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ());
if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) {
data.direction = Direction.X;
} else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) {
data.direction = Direction.Y;
} else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) {
data.direction = Direction.Z;
} else {
stop();
return;
}
Bukkit.getLogger().log(StabData.LEVEL, "Direction: {0}", data.direction);
data.phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT);
data.phases.getFirst().setCount(StabData.TNT_INCREASE);
new StabGenerator(data);
}
@Override
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
bossbar.setProgress(0);
bossbar.setTitle("§eCalculating Stab Direction");
}
}

View File

@ -0,0 +1,61 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import de.steamwar.bausystem.features.tracer.Trace;
import de.steamwar.bausystem.features.tracer.TraceRecorder;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
public class StabFinalizer extends StabStep {
public StabFinalizer(StabData data) {
super(data);
}
@Override
protected void start() {
try {
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
.color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor());
data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
} catch (SecurityException e) {
stop();
throw e;
}
TraceRecorder.instance.startRecording(data.region);
runSimulator(() -> {
TraceRecorder.instance.stopRecording(data.region);
stop();
});
}
@Override
protected void bossbar(BauSystemBossbar bossbar, boolean stopped) {
bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0));
bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit);
}
}

View File

@ -0,0 +1,250 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.region.utils.RegionType;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import java.util.*;
import java.util.stream.Collectors;
import static de.steamwar.bausystem.features.simulator.execute.Direction.Y;
public class StabGenerator extends StabStep implements Listener {
private int recordings = 0;
private List<Integer> currentDepths = new ArrayList<>();
private int lastDepth = 0;
private int retries = 0;
private final Map<Integer, Set<Location>> destroyedBlocksPerSlice = new HashMap<>();
private Set<Integer> gabStart = new HashSet<>();
private Set<TNTPhase> failedAtLeastOnce = new HashSet<>();
@EventHandler
public void onEntityExplode(EntityExplodeEvent event) {
if (Region.getRegion(event.getEntity().getLocation()) == data.region) {
event.blockList().forEach(block -> {
if (!data.region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
int component = data.direction.component.apply(block.getLocation().toVector());
destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>())
.add(block.getLocation());
});
}
}
public StabGenerator(StabData data) {
super(data);
}
@Override
protected void start() {
try {
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
.color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor());
data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
} catch (SecurityException e) {
stop();
throw e;
}
if (data.cancel) {
HandlerList.unregisterAll(this);
return;
}
runSimulator(this::calculateStab);
}
private void calculateStab() {
TNTPhase lastPhase = data.phases.getLast();
List<Map.Entry<Integer, Set<Location>>> locations = destroyedBlocksPerSlice.entrySet()
.stream()
.sorted(Comparator.comparingInt(Map.Entry::getKey))
.collect(Collectors.toList());
int depth = 0;
for (int i = 0; i < locations.size(); i++) {
if (data.direction != Y && i > 0 && Math.abs(locations.get(i - 1).getKey() - locations.get(i).getKey()) > 3) {
if (gabStart.add(locations.get(i).getKey())) {
Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0} because of gap", StabData.TNT_INCREASE);
lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE);
recordings = 0;
currentDepths.clear();
run();
return;
}
}
if (i == 0 || i == locations.size() - 1) {
if (locations.get(i).getValue().size() > StabData.MIN_BLOCK_TO_COUNT_AS_DEPTH) {
depth++;
}
} else {
depth++;
}
}
if (depth > 0) {
Bukkit.getLogger().log(StabData.LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())});
destroyedBlocksPerSlice.clear();
currentDepths.add(depth);
} else {
destroyedBlocksPerSlice.clear();
lastPhase.setTickOffset(lastPhase.getTickOffset() + 1);
Bukkit.getLogger().log(StabData.LEVEL, "No dimension - Increasing tickOffset to: {0}", lastPhase.getTickOffset());
lastPhase.setOrder(0);
if (lastPhase.getTickOffset() > 80) {
stop();
} else {
run();
}
return;
}
int minDepth = currentDepths.stream().min(Integer::compareTo).orElse(0);
int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0);
data.currentDepth = maxDepth;
int countWithoutLast = 0;
for (int i = 0; i < data.phases.size() - 1; i++) {
countWithoutLast += data.phases.get(i).getCount();
}
countWithoutLast -= gabStart.size();
boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5;
if (moreTNTNeeded) {
Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0}", StabData.TNT_INCREASE);
lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE);
recordings = 0;
currentDepths.clear();
run();
return;
}
if (recordings++ < StabData.MAX_RECORDINGS) {
run();
return;
}
recordings = 0;
currentDepths.clear();
if (maxDepth - minDepth > lastPhase.getCount()) {
Bukkit.getLogger().log(StabData.LEVEL, "Stab failed at least once. Adding one tnt to {0}", minDepth - 3);
int current = 0;
TNTPhase last = null;
for (TNTPhase phase : data.phases) {
if (current < minDepth - 3) {
current += phase.getCount();
last = phase;
continue;
}
if (failedAtLeastOnce.add(last)) {
last = null;
break;
}
if (last != null) {
last.setCount(last.getCount() + 1);
Bukkit.getLogger().log(StabData.LEVEL, "Added to phase {0} now has {1} tnt", new Object[]{data.phases.indexOf(last), last.getCount()});
}
break;
}
if (last != null) {
run();
return;
}
}
Bukkit.getLogger().log(StabData.LEVEL, "No more TNT needed on phase adjusting - {0} new count; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()});
lastPhase.setCount(maxDepth - countWithoutLast);
if (lastPhase.getCount() <= 0) {
Bukkit.getLogger().log(StabData.LEVEL, "Count was 0 or negative - removing last phase");
data.phases.removeLast();
}
if (maxDepth > data.depthLimit) {
Bukkit.getLogger().log(StabData.LEVEL, "Depth is greater than {0} - finished", data.depthLimit);
new StabFinalizer(data);
return;
}
if (maxDepth <= lastDepth) {
if (lastPhase.getCount() <= 0) {
retries++;
}
if (lastPhase.getCount() > 0 || retries > StabData.MAX_TICK_DIFFERENCE) {
Bukkit.getLogger().log(StabData.LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth);
new StabFinalizer(data);
return;
}
}
lastDepth = maxDepth;
newPhase(data, lastPhase);
run();
}
public static void newPhase(StabData data, TNTPhase lastPhase) {
Bukkit.getLogger().log(StabData.LEVEL, "Adding new phase in next tick");
TNTPhase nextPhase = new TNTPhase();
nextPhase.setCount(StabData.TNT_INCREASE);
nextPhase.setTickOffset(lastPhase.getTickOffset() + 1);
nextPhase.setXJump(lastPhase.isXJump());
nextPhase.setYJump(lastPhase.isYJump());
nextPhase.setZJump(lastPhase.isZJump());
data.phases.add(nextPhase);
}
@Override
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0));
if (finished) {
bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit);
return;
}
StringBuilder st = new StringBuilder();
st.append("§7Direction §e").append(data.direction);
st.append(" §e").append(data.currentDepth).append("§8/§7").append(data.depthLimit);
if (recordings > 0) {
st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(StabData.MAX_RECORDINGS);
}
bossbar.setTitle(st.toString());
}
}

View File

@ -0,0 +1,85 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.tracer.TraceRecorder;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class StabSetup extends StabStep {
public StabSetup(StabData data) {
super(data);
}
@Override
protected void start() {
TNTPhase tntPhase = data.simulator.getGroups().stream()
.filter(simulatorGroup -> !simulatorGroup.isDisabled())
.map(SimulatorGroup::getElements)
.flatMap(List::stream)
.filter(TNTElement.class::isInstance)
.map(TNTElement.class::cast)
.filter(tntElement -> !tntElement.isDisabled())
.filter(tntElement -> data.tntElement != tntElement)
.map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset)))
.filter(Optional::isPresent)
.map(Optional::get)
.peek(phase -> {
if (phase.getOrder() > TNTPhase.ORDER_LIMIT) {
phase.setOrder(TNTPhase.ORDER_LIMIT);
}
})
.filter(phase -> phase != data.phases.get(0))
.max(Comparator.comparingInt(TNTPhase::getTickOffset))
.orElse(null);
if (tntPhase == null) {
throw new SecurityException("");
}
TNTPhase phase = data.phases.get(0);
data.phases.clear();
data.phases.add(phase);
phase.setCount(1);
phase.setTickOffset(tntPhase.getTickOffset());
phase.setOrder(100);
TraceRecorder.instance.stopRecording(data.region);
if (TraceRecorder.instance.isAutoTraceEnabledInRegion(data.region)) {
TraceRecorder.instance.removeAutoTraceRegion(data.region);
}
data.clipboard = FlatteningWrapper.impl.copy(data.region.getMinPointTestblockExtension(), data.region.getMaxPointTestblockExtension(), data.region.getTestBlockPoint());
new StabDirection(data);
}
@Override
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
bossbar.setProgress(0);
bossbar.setTitle("§eSetting up Simulator");
}
}

View File

@ -0,0 +1,95 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.simulator.execute;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
import de.steamwar.bausystem.utils.bossbar.BossBarService;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
public abstract class StabStep {
protected final StabData data;
protected StabStep(StabData data) {
this.data = data;
run();
}
protected final void run() {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
for (Player player : Bukkit.getOnlinePlayers()) {
BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator");
bossbar.setColor(BarColor.GREEN);
bossbar.setStyle(BarStyle.SEGMENTED_10);
bossbar(bossbar, false);
}
}, 1);
if (this instanceof Listener) {
Bukkit.getPluginManager().registerEvents((Listener) this, BauSystem.getInstance());
}
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::start, 20);
}
protected abstract void start();
protected final void runSimulator(Runnable onFinish) {
SimulatorExecutor.run(data.simulator, () -> {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
if (this instanceof Listener) {
HandlerList.unregisterAll((Listener) this);
}
onFinish.run();
}, 20);
});
}
protected abstract void bossbar(BauSystemBossbar bossbar, boolean stopped);
protected final void stop() {
data.simulator.setStabGenerator(null);
SimulatorWatcher.update(data.simulator);
for (Player player : Bukkit.getOnlinePlayers()) {
BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator");
bossbar.setColor(BarColor.GREEN);
bossbar.setStyle(BarStyle.SEGMENTED_10);
bossbar(bossbar, true);
}
new Thread(() -> {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
for (Player player : Bukkit.getOnlinePlayers()) {
BossBarService.instance.remove(player, data.region, "simulator_stab_generator");
}
}
}).start();
}
}

View File

@ -53,6 +53,16 @@ public class SimulatorMaterialGui extends SimulatorPageGui<Material> {
this.back = back;
}
@Override
public boolean shouldOpen() {
if (player.getItemOnCursor().getType().isAir()) {
return true;
}
change.accept(player.getItemOnCursor().getType());
SimulatorWatcher.update(simulator);
return false;
}
@Override
public String baseTitle() {
return "Material";

View File

@ -24,8 +24,11 @@ import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui;
import de.steamwar.bausystem.region.Region;
import de.steamwar.inventory.SWItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -97,6 +100,14 @@ public class SimulatorTNTGui extends SimulatorScrollGui<TNTPhase> {
tnt.setDisabled(!tnt.isDisabled());
SimulatorWatcher.update(simulator);
}));
inventory.setItem(49, new SWItem(Material.CALIBRATED_SCULK_SENSOR, "§eCreate Stab", click -> {
new SimulatorAnvilGui<>(player, "Depth Limit", "", Integer::parseInt, depthLimit -> {
if (depthLimit <= 0) return false;
simulator.setStabGenerator(new SimulatorStabGenerator(Region.getRegion(player.getLocation()), simulator, tnt, depthLimit));
SimulatorWatcher.update(simulator);
return true;
}, null).open();
}));
inventory.setItem(50, new SWItem(Material.CHEST, parent.getElements().size() == 1 ? "§eMake Group" : "§eAdd another TNT to Group", clickType -> {
TNTElement tntElement = new TNTElement(tnt.getPosition().clone());
tntElement.add(new TNTPhase());

View File

@ -44,7 +44,7 @@ public class SimulatorAnvilGui<T extends Number> {
if (error.get()) {
anvilInv.open();
} else {
back.open();
if (back != null) back.open();
}
error.set(false);
}, 0);

View File

@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.simulator.gui.base;
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
import de.steamwar.bausystem.features.simulator.data.Simulator;
import de.steamwar.core.Core;
import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import org.bukkit.Bukkit;
@ -46,6 +45,8 @@ public abstract class SimulatorBaseGui {
}
public final void open() {
if (!shouldOpen()) return;
String newTitle = title();
String originalTitle = player.getOpenInventory().getTitle();
@ -62,7 +63,11 @@ public abstract class SimulatorBaseGui {
if (Core.getVersion() > 19) {
player.getOpenInventory().setTitle(title());
}
if (simulator != null && simulator.getStabGenerator() != null) {
populateStabGenerator();
} else {
populate();
}
if (player.getOpenInventory().getTopInventory() == inv) {
inventory.open();
SimulatorWatcher.watch(player, simulator, this::open);
@ -82,10 +87,25 @@ public abstract class SimulatorBaseGui {
});
SimulatorWatcher.watch(player, simulator, this::open);
if (simulator != null && simulator.getStabGenerator() != null) {
populateStabGenerator();
} else {
populate();
}
inventory.open();
}
private void populateStabGenerator() {
inventory.setItem(22, new SWItem(Material.BARRIER, "§cCancel Stab Generator", click -> {
simulator.getStabGenerator().cancel();
SimulatorWatcher.update(simulator);
}));
}
public boolean shouldOpen() {
return true;
}
private void setup() {
for (int i = 0; i < 9; i++) {
inventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8", clickType -> {

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.bausystem.utils.WorldEditUtils;
import de.steamwar.core.Core;
import lombok.Getter;
import lombok.SneakyThrows;
import org.bukkit.Location;
@ -56,7 +57,7 @@ public class Panzern {
private BaseBlock blockType;
private BaseBlock slabType;
private static final BaseBlock jukeboxType = BlockTypes.JUKEBOX.getDefaultState().toBaseBlock();
private static final BaseBlock jukeboxType = (Core.getVersion() > 19 ? BlockTypes.get("lodestone"): BlockTypes.get("jukebox")).getDefaultState().toBaseBlock();
private static final BaseBlock cobwebType = BlockTypes.COBWEB.getDefaultState().toBaseBlock();
private static final BaseBlock airType = BlockTypes.AIR.getDefaultState().toBaseBlock();

View File

@ -19,8 +19,8 @@
package de.steamwar.bausystem.features.smartplace;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
@ -81,7 +81,7 @@ public class SmartPlaceListener implements Listener {
IGNORED.remove(Material.BARRIER);
}
private static final Class<?> useItem = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem");
private static final Class<?> useItem = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket");
private static final Set<Player> SMART_PLACING = new HashSet<>();
private static final Set<Player> WAS_EXECUTED = new HashSet<>();
@ -223,7 +223,7 @@ public class SmartPlaceListener implements Listener {
Block block = event.getBlock().getRelative(BlockFace.DOWN);
BlockState old = block.getState();
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
block.setType(Material.GLASS);
block.setType(Material.GLASS, true);
old.update(true, false);
}, 1);
}

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.tpslimit;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.ChatWrapper;
@ -45,18 +45,18 @@ class PacketCache {
private static Set<Entity> entities = new HashSet<>();
private static BukkitTask task = null;
private static Class<?> vec3dClass = Reflection.getClass("{nms.world.phys}.Vec3D");
private static Reflection.FieldAccessor<Object> zeroVec3d = (Reflection.FieldAccessor<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
private static Class<?> vec3dClass = Reflection.getClass("net.minecraft.world.phys.Vec3");
private static Reflection.Field<Object> zeroVec3d = (Reflection.Field<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
private static Object ZERO_VEC3D = zeroVec3d.get(null);
private static Class<?> velocityPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityVelocity");
private static Reflection.ConstructorInvoker velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
private static Class<?> velocityPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket");
private static Reflection.Constructor velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
private static Class<?> teleportPacketClass = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityTeleport");
private static Class<?> entityClass = Reflection.getClass("{nms.world.entity}.Entity");
private static Reflection.ConstructorInvoker teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
private static Class<?> teleportPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket");
private static Class<?> entityClass = Reflection.getClass("net.minecraft.world.entity.Entity");
private static Reflection.Constructor teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
private static Class<?> craftEntityClass = Reflection.getClass("{obc}.entity.CraftEntity");
private static Reflection.MethodInvoker getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
private static Class<?> craftEntityClass = Reflection.getClass("org.bukkit.craftbukkit.entity.CraftEntity");
private static Reflection.Method getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
private static Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
private static Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);

View File

@ -42,16 +42,16 @@ public class TPSCommand extends SWCommand {
public void genericCommand(Player p, String... args) {
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_HEAD", p);
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_MESSAGE", p,
TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND),
TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS),
TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE),
TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES),
TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND),
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.TEN_SECONDS),
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_MINUTE),
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.FIVE_MINUTES),
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.TEN_MINUTES)
);
}
@Register
public void genericCommand(Player p, TPSWatcher.TPSType type) {
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, tpsSystem.getTPS(type));
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, TPSWatcher.getTPSUnlimited(type));
}
}

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.tpslimit;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
@ -28,11 +28,11 @@ import org.bukkit.World;
@UtilityClass
public class TPSFreezeUtils {
private static Reflection.FieldAccessor<Boolean> fieldAccessor;
private static Reflection.Field<Boolean> fieldAccessor;
@Getter
private static final boolean canFreeze;
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", null);
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.CraftWorld"), "getHandle", null);
@Getter
private static boolean frozen = false;
@ -40,9 +40,9 @@ public class TPSFreezeUtils {
private static final World world = Bukkit.getWorlds().get(0);
static {
Reflection.FieldAccessor<Boolean> fieldAccessor;
Reflection.Field<Boolean> fieldAccessor;
try {
fieldAccessor = Reflection.getField(Reflection.getClass("{nms.server.level}.WorldServer"), "freezed", boolean.class);
fieldAccessor = Reflection.getField(Reflection.getClass("net.minecraft.server.level.ServerLevel"), "freezed", boolean.class);
} catch (IllegalArgumentException e) {
fieldAccessor = null;
}

View File

@ -19,15 +19,12 @@
package de.steamwar.bausystem.features.tpslimit;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
import de.steamwar.core.Core;
import de.steamwar.core.TPSWatcher;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
@ -104,8 +101,8 @@ public class TPSLimitUtils {
}
*/
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
static {
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
if (tpsLimiter != null) {

View File

@ -38,6 +38,7 @@ import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.linkage.MaxVersion;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@ -51,14 +52,11 @@ import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
@Linked
@MaxVersion(20) // Hotfix for 1.21 tps limit! -> Backport coming later
public class TPSSystem implements Listener {
@Getter
private double currentTPSLimit = 20;
public double getTPS(TPSWatcher.TPSType tpsType) {
return TPSWatcher.getTPSUnlimited(tpsType);
}
private static double currentTPSLimit = 20;
public TPSSystem() {
if (TPSFreezeUtils.isCanFreeze()) {
@ -336,26 +334,26 @@ public class TPSSystem implements Listener {
} else if (TPSFreezeUtils.frozen()) {
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + BauSystem.MESSAGE.parse("SCOREBOARD_TPS_FROZEN", p);
} else {
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + tpsSystem.getTPS(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit();
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit();
}
}
private String tpsColor() {
double tps = tpsSystem.getTPS(TPSWatcher.TPSType.ONE_SECOND);
if (tps > tpsSystem.getCurrentTPSLimit() * 0.9) {
double tps = TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND);
if (tps > TPSSystem.getCurrentTPSLimit() * 0.9) {
return "§a";
}
if (tps > tpsSystem.getCurrentTPSLimit() * 0.5) {
if (tps > TPSSystem.getCurrentTPSLimit() * 0.5) {
return "§e";
}
return "§c";
}
private String tpsLimit() {
if (tpsSystem.getCurrentTPSLimit() == 20) {
if (TPSSystem.getCurrentTPSLimit() == 20) {
return "";
}
return "§8/§7" + tpsSystem.getCurrentTPSLimit();
return "§8/§7" + TPSSystem.getCurrentTPSLimit();
}
}

View File

@ -102,11 +102,14 @@ public class TraceRecorder implements Listener {
*
* @param region region to be recorded
*/
public void startRecording(Region region) {
if (activeTraces.containsKey(region)) return;
public Trace startRecording(Region region) {
if (activeTraces.containsKey(region)) {
return activeTraces.get(region).getTrace();
}
TraceRecordingWrapper wrappedTrace = new TraceRecordingWrapper(region);
activeTraces.put(region, wrappedTrace);
return wrappedTrace.getTrace();
}
/**

View File

@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.tracer.rendering;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.bausystem.features.tracer.TNTPoint;
import de.steamwar.bausystem.features.tracer.Trace;
import de.steamwar.bausystem.features.tracer.TraceManager;
@ -30,10 +31,13 @@ import net.md_5.bungee.api.chat.ClickEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import yapion.hierarchy.types.YAPIONValue;
import java.util.List;
import java.util.stream.Collectors;
import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DETAILS;
/**
* Wrapper for the rendering of a record bundle
*/
@ -66,6 +70,7 @@ public class TraceEntity extends RFallingBlockEntity {
* @param player the player the message should be printed for
*/
public void printIntoChat(Player player) {
if (!Config.getInstance().get(player).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return;
TNTPoint representative = records.get(0);
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player);

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.util;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.mojang.authlib.GameProfile;
import de.steamwar.bausystem.BauSystem;
@ -49,15 +49,15 @@ import java.util.function.BiFunction;
@Linked
public class NoClipCommand extends SWCommand implements Listener {
public static final Class<?> gameStateChange = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutGameStateChange");
private static final Reflection.FieldAccessor<Float> floatFieldAccessor = Reflection.getField(gameStateChange, float.class, 0);
public static final Class<?> gameStateChange = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundGameEventPacket");
private static final Reflection.Field<Float> floatFieldAccessor = Reflection.getField(gameStateChange, float.class, 0);
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
private static final Class<?> useItem = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem");
private static final Class<?> blockDig = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig");
private static final Class<?> windowClick = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInWindowClick");
private static final Class<?> setSlotStack = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInSetCreativeSlot");
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
private static final Class<?> useItem = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket");
private static final Class<?> blockDig = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundPlayerActionPacket");
private static final Class<?> windowClick = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundContainerClickPacket");
private static final Class<?> setSlotStack = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket");
@Getter
private static final List<Player> NOCLIPS = new ArrayList<>();

View File

@ -42,6 +42,15 @@ public class SkullCommand extends SWCommand {
super("skull", "head");
}
@Register
public void giveCommand(@Validator Player p) {
if (p.getName().startsWith(".")) {
BauSystem.MESSAGE.send("SKULL_INVALID", p);
return;
}
giveCommand(p, p.getName());
}
@Register(description = "SKULL_HELP")
public void giveCommand(@Validator Player p, @Mapper("player") @ErrorMessage("SKULL_INVALID") String skull) {
ItemStack is = SWItem.getPlayerSkull(skull).getItemStack();
@ -63,7 +72,7 @@ public class SkullCommand extends SWCommand {
@Override
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.endsWith("")).collect(Collectors.toList());
return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.startsWith(".")).collect(Collectors.toList());
}
};
}

View File

@ -21,22 +21,46 @@ package de.steamwar.bausystem.features.util;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.configplayer.Config;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import yapion.hierarchy.types.YAPIONObject;
import yapion.hierarchy.types.YAPIONValue;
@Linked
public class TNTClickListener implements Listener {
public class TNTClickListener extends SWCommand implements Listener {
public static final String TNT_CLICK_DETAILS = "tnt_click_details";
public TNTClickListener() {
super("tntdetails");
}
@Register(description = "TNT_DETAILS_COMMAND")
public void toggle(Player player) {
YAPIONObject yapionObject = Config.getInstance().get(player);
if (yapionObject.getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) {
yapionObject.put(TNT_CLICK_DETAILS, false);
BauSystem.MESSAGE.send("TNT_DETAILS_OFF", player);
} else {
yapionObject.put(TNT_CLICK_DETAILS, true);
BauSystem.MESSAGE.send("TNT_DETAILS_ON", player);
}
}
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (event.getHand() != EquipmentSlot.HAND) return;
if (!Config.getInstance().get(event.getPlayer()).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return;
Entity entity = event.getRightClicked();
if (event.getRightClicked() instanceof TNTPrimed) {

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.world;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.linkage.Linked;
@ -32,7 +32,7 @@ public class AntiCursorReCentering implements Enable {
@Override
public void enable() {
Class<?> closeWindow = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutCloseWindow");
Class<?> closeWindow = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundContainerClosePacket");
TinyProtocol.instance.addFilter(closeWindow, (player, object) -> {
if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CRAFTING) {
return object;

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.world;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.linkage.Linked;
@ -29,7 +29,7 @@ import org.bukkit.GameMode;
public class NoCreativeKnockback {
public NoCreativeKnockback() {
TinyProtocol.instance.addFilter(Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion"), (player, o) -> {
TinyProtocol.instance.addFilter(Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket"), (player, o) -> {
if (player.getGameMode() != GameMode.CREATIVE) return o;
return NMSWrapper.impl.resetExplosionKnockback(o);
});

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.world;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
@ -48,21 +48,21 @@ import org.bukkit.util.Vector;
@MinVersion(20)
public class SignEditFrom20 implements Listener {
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private static final Class<?> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
private static final Class<?> craftWorld = Reflection.getClass("{obc}.CraftWorld");
private static final Class<?> generatorAccess = Reflection.getClass("{nms.world.level}.GeneratorAccess");
private static final Reflection.MethodInvoker getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
private static final Reflection.MethodInvoker at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock");
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
private static final Class<?> generatorAccess = Reflection.getClass("net.minecraft.world.level.LevelAccessor");
private static final Reflection.Method getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
private static final Reflection.Method at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
private static final Class<?> openSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutOpenSignEditor");
private static final Reflection.FieldAccessor<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
private static final Reflection.FieldAccessor<?> sideFieldAccessor = Reflection.getField(openSign, boolean.class, 0);
private static final Class<?> openSign = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket");
private static final Reflection.Field<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
private static final Reflection.Field<?> sideFieldAccessor = Reflection.getField(openSign, boolean.class, 0);
private static final Class<?> updateSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUpdateSign");
private static final Reflection.FieldAccessor<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
private static final Reflection.FieldAccessor<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
private static final Class<?> updateSign = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSignUpdatePacket");
private static final Reflection.Field<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
private static final Reflection.Field<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
@EventHandler
public void editSign(PlayerInteractEvent event) {

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.world;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
@ -40,20 +40,20 @@ import org.bukkit.event.player.PlayerInteractEvent;
@MaxVersion(19)
public class SignEditUntil19 implements Listener {
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private static final Class<?> craftBlock = Reflection.getClass("{obc}.block.CraftBlock");
private static final Class<?> craftWorld = Reflection.getClass("{obc}.CraftWorld");
private static final Class<?> generatorAccess = Reflection.getClass("{nms.world.level}.GeneratorAccess");
private static final Reflection.MethodInvoker getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
private static final Reflection.MethodInvoker at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock");
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
private static final Class<?> generatorAccess = Reflection.getClass("net.minecraft.world.level.LevelAccessor");
private static final Reflection.Method getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
private static final Reflection.Method at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
private static final Class<?> openSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutOpenSignEditor");
private static final Reflection.FieldAccessor<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
private static final Class<?> openSign = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket");
private static final Reflection.Field<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
private static final Class<?> updateSign = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUpdateSign");
private static final Reflection.FieldAccessor<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
private static final Reflection.FieldAccessor<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
private static final Class<?> updateSign = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSignUpdatePacket");
private static final Reflection.Field<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
private static final Reflection.Field<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
@EventHandler
public void editSign(PlayerInteractEvent event) {

View File

@ -179,7 +179,12 @@ public class SpectatorListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
if (event.getMessage().startsWith("/schem save") || event.getMessage().startsWith("//schem save") || event.getMessage().startsWith("/schematic save") || event.getMessage().startsWith("//schematic save")) {
if (event.getMessage().startsWith("/schem save") ||
event.getMessage().startsWith("//schem save") ||
event.getMessage().startsWith("/schematic save") ||
event.getMessage().startsWith("//schematic save") ||
event.getMessage().startsWith("/download") ||
event.getMessage().startsWith("//download")) {
if (!Permission.SUPERVISOR.hasPermission(event.getPlayer())) {
event.setCancelled(true);
event.setMessage("/");

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.features.xray;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.techhider.TechHiderCommand;
@ -108,8 +108,8 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
});
}
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
{
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {

View File

@ -73,4 +73,8 @@ public class Point {
public Location toLocation(Player player, double dx, double dy, double dz) {
return new Location(player.getWorld(), x + dx, y + dy, z + dz, player.getLocation().getYaw(), player.getLocation().getPitch());
}
public BlockVector3 toBlockVector3() {
return BlockVector3.at(this.x, this.y, this.z);
}
}

View File

@ -21,41 +21,40 @@ package de.steamwar.bausystem.region.flags;
import de.steamwar.bausystem.region.flags.flagvalues.*;
import de.steamwar.bausystem.shared.EnumDisplay;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.EnumSet;
import java.util.Set;
import java.util.stream.Collectors;
@Getter
@AllArgsConstructor
public enum Flag implements EnumDisplay {
COLOR("FLAG_COLOR", ColorMode.class, ColorMode.YELLOW),
TNT("FLAG_TNT", TNTMode.class, TNTMode.ONLY_TB),
FIRE("FLAG_FIRE", FireMode.class, FireMode.ALLOW),
FREEZE("FLAG_FREEZE", FreezeMode.class, FreezeMode.INACTIVE),
PROTECT("FLAG_PROTECT", ProtectMode.class, ProtectMode.ACTIVE),
ITEMS("FLAG_ITEMS", ItemMode.class, ItemMode.INACTIVE),
NO_GRAVITY("FLAG_NO_GRAVITY", NoGravityMode.class, NoGravityMode.INACTIVE),
COLOR("FLAG_COLOR", ColorMode.class, ColorMode.YELLOW, false),
TNT("FLAG_TNT", TNTMode.class, TNTMode.ONLY_TB, true),
FIRE("FLAG_FIRE", FireMode.class, FireMode.ALLOW, true),
FREEZE("FLAG_FREEZE", FreezeMode.class, FreezeMode.INACTIVE, true),
PROTECT("FLAG_PROTECT", ProtectMode.class, ProtectMode.ACTIVE, true),
ITEMS("FLAG_ITEMS", ItemMode.class, ItemMode.INACTIVE, true),
NO_GRAVITY("FLAG_NO_GRAVITY", NoGravityMode.class, NoGravityMode.INACTIVE, true),
;
@Getter
private static final Set<Flag> flags;
@Getter
private static final Set<Flag> resetFlags;
static {
flags = EnumSet.allOf(Flag.class);
resetFlags = flags.stream().filter(flag -> flag.reset).collect(Collectors.toUnmodifiableSet());
}
private final String chatValue;
private final Class<? extends Value<?>> valueType;
private final Flag.Value<?> defaultValue;
private final Value<?>[] values;
<T extends Enum<T> & Value<T>> Flag(String chatValue, final Class<? extends Value<T>> valueType, final Flag.Value<T> defaultValue) {
this.chatValue = chatValue;
this.valueType = valueType;
this.defaultValue = defaultValue;
this.values = defaultValue.getValues();
}
private final boolean reset;
public Value<?> getFlagValueOf(final String name) {
return this.defaultValue.getValueOf(name);

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.UtilityClass;
@ -81,12 +81,12 @@ public class PlaceItemUtils {
.collect(Collectors.toSet());
}
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private static final Reflection.ConstructorInvoker blockPositionConstructor = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
private static final Class<?> craftBlock = Reflection.getClass("{obc}.block.CraftBlockState");
private static final Class<?> craftWorld = Reflection.getClass("{obc}.CraftWorld");
private static final Reflection.FieldAccessor<?> positionAccessor = Reflection.getField(craftBlock, blockPosition, 0);
private static final Reflection.FieldAccessor<?> worldAccessor = Reflection.getField(craftBlock, craftWorld, 0);
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
private static final Reflection.Constructor blockPositionConstructor = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlockState");
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
private static final Reflection.Field<?> positionAccessor = Reflection.getField(craftBlock, blockPosition, 0);
private static final Reflection.Field<?> worldAccessor = Reflection.getField(craftBlock, craftWorld, 0);
/**
* Attempt to place an {@link ItemStack} the {@link Player} is holding against a {@link Block} inside the World.

View File

@ -19,17 +19,16 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.core.BountifulWrapper;
import de.steamwar.core.Core;
import de.steamwar.core.VersionDependent;
import de.steamwar.entity.REntity;
import org.bukkit.entity.Player;
public interface PlayerMovementWrapper {
Class<?> teleportPacket = REntity.teleportPacket;
Reflection.FieldAccessor<Integer> teleportEntity = REntity.teleportEntity;
Reflection.Field<Integer> teleportEntity = REntity.teleportEntity;
BountifulWrapper.PositionSetter teleportPosition = REntity.teleportPosition;
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());

View File

@ -1,49 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.utils;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.ViaAPI;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.linkage.Linked;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@Linked
public class VersionAnnouncer implements Listener {
private final String versionString = Bukkit.getBukkitVersion().split("-", 2)[0];
@SuppressWarnings("unchecked")
private final ViaAPI<Player> via = Via.getAPI();
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if(via.getServerVersion().supportedVersions().contains(via.getPlayerVersion(player)))
return;
BauSystem.MESSAGE.sendPrefixless("SERVER_VERSION", player, ChatMessageType.ACTION_BAR, versionString);
}
}

View File

@ -19,7 +19,7 @@
package de.steamwar.bausystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
@ -100,7 +100,7 @@ public class WorldEditUtils {
.getSessionManager()
.get(BukkitAdapter.adapt(player));
Reflection.ConstructorInvoker constructorInvoker = Reflection.getConstructor(clazz, com.sk89q.worldedit.world.World.class);
Reflection.Constructor constructorInvoker = Reflection.getConstructor(clazz, com.sk89q.worldedit.world.World.class);
RegionSelector regionSelector = (RegionSelector) constructorInvoker.invoke(BukkitAdapter.adapt(player.getWorld()));
localSession.setRegionSelector(BukkitAdapter.adapt(player.getWorld()), regionSelector);

View File

@ -0,0 +1,204 @@
package de.steamwar.bausystem.utils.cursor;
import de.steamwar.bausystem.utils.RayTraceUtils;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action;
import org.bukkit.util.Vector;
import yapion.hierarchy.types.YAPIONType;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@Getter
public class RCursor {
private final World WORLD = Bukkit.getWorlds().get(0);
private final REntityServer targetServer;
private final REntityServer cursorServer;
private final Player owner;
private final Material highlightMaterial;
private final ClickHandler onClickHandler;
private RFallingBlockEntity cursorEntity;
private Location cursorLocation;
private boolean isHittingEntity = false;
@Setter
private Material cursorMaterial;
@Setter
private CursorMode cursorMode;
private boolean visible = true;
public RCursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, CursorMode cursorMode, ClickHandler onClickHandler) {
this.targetServer = targetServer;
this.owner = owner;
this.highlightMaterial = highlightMaterial;
this.cursorMaterial = cursorMaterial;
this.cursorMode = cursorMode;
this.onClickHandler = onClickHandler;
cursorServer = new REntityServer();
cursorServer.addPlayer(owner);
RCursorManager.getInstance().registerCursor(this);
}
public void render() {
if (!visible) return;
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(owner, owner.getLocation(), targetServer.getEntities());
if (rayTraceResult == null) {
if(cursorEntity != null) cursorEntity.die();
cursorEntity = null;
return;
}
REntity hitEntity = rayTraceResult.getHitEntity() == cursorEntity ? null : rayTraceResult.getHitEntity();
Material activeCursorMaterial = hitEntity == null ? cursorMaterial : highlightMaterial;
Location activeCursorLocation = hitEntity == null ? cursorMode.positionTransform.apply(owner, rayTraceResult).toLocation(WORLD)
: new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD);
cursorLocation = activeCursorLocation;
isHittingEntity = hitEntity != null;
if (cursorEntity == null) {
cursorEntity = new RFallingBlockEntity(cursorServer, activeCursorLocation, activeCursorMaterial);
cursorEntity.setNoGravity(true);
} if (cursorEntity.getMaterial() == activeCursorMaterial) {
cursorEntity.move(activeCursorLocation);
} else {
cursorEntity.die();
cursorEntity = new RFallingBlockEntity(cursorServer, activeCursorLocation, activeCursorMaterial);
cursorEntity.setNoGravity(true);
if(activeCursorMaterial == highlightMaterial) {
cursorEntity.setGlowing(true);
}
}
}
public void hide() {
visible = false;
if (cursorEntity != null) {
cursorEntity.die();
cursorEntity = null;
}
}
public void show() {
visible = true;
}
void handleClick(Action action) {
if(!visible || cursorLocation == null) return;
onClickHandler.handle(cursorLocation, isHittingEntity, action);
}
public void close() {
cursorServer.close();
RCursorManager.getInstance().unregisterCursor(this);
}
@AllArgsConstructor
public enum CursorMode {
FREE((player, rayTraceResult) -> {
Vector pos = rayTraceResult.getHitPosition();
BlockFace face = rayTraceResult.getHitBlockFace();
if (face != null) {
switch (face) {
case DOWN:
pos.setY(pos.getY() - 0.98);
break;
case EAST:
pos.setX(pos.getX() + 0.49);
break;
case WEST:
pos.setX(pos.getX() - 0.49);
break;
case NORTH:
pos.setZ(pos.getZ() - 0.49);
break;
case SOUTH:
pos.setZ(pos.getZ() + 0.49);
break;
default:
break;
}
if (face.getModY() == 0 && player.isSneaking()) {
pos.setY(pos.getY() - 0.49);
}
}
if (!player.isSneaking()) {
pos.setX(pos.getBlockX() + 0.5);
if (face == null || face.getModY() == 0)
pos.setY(pos.getBlockY() + 0.0);
pos.setZ(pos.getBlockZ() + 0.5);
}
return pos;
}),
BLOCK_ALIGNED((player, rayTraceResult) -> {
Vector pos = rayTraceResult.getHitPosition();
BlockFace face = rayTraceResult.getHitBlockFace();
if (face != null) {
switch (face) {
case DOWN:
pos.setY(pos.getY() - 0.98);
break;
case EAST:
pos.setX(pos.getX() + 0.49);
break;
case WEST:
pos.setX(pos.getX() - 0.49);
break;
case NORTH:
pos.setZ(pos.getZ() - 0.49);
break;
case SOUTH:
pos.setZ(pos.getZ() + 0.49);
break;
default:
break;
}
}
pos.setX(pos.getBlockX() + 0.5);
if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) {
pos.setY(pos.getBlockY() + 1.0);
} else {
pos.setY(pos.getBlockY());
}
pos.setZ(pos.getBlockZ() + 0.5);
return pos;
});
private final BiFunction<Player, RayTraceUtils.RRayTraceResult, Vector> positionTransform;
}
public interface ClickHandler{
public void handle(Location cursorLocation, boolean didHitEntity, Action action);
}
}

View File

@ -0,0 +1,112 @@
package de.steamwar.bausystem.utils.cursor;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.linkage.Linked;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
@Linked
public class RCursorManager implements Listener {
@Getter
private static RCursorManager instance;
private final Set<Player> calculationActive = new HashSet<>();
private final Map<Player, RCursor> activeCursors = new HashMap<>();
public RCursorManager() {
if (instance == null) {
instance = this;
}
BiFunction<Player, Object, Object> function = (player, object) -> {
updateCursor(player);
return object;
};
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
Set<Player> playersWithActiveCursor = activeCursors.keySet();
playersWithActiveCursor.forEach(this::updateCursor);
}, 0);
Class<?> positionPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
Class<?> lookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
Class<?> positionLookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
TinyProtocol.instance.addFilter(positionPacketClass, function);
TinyProtocol.instance.addFilter(lookPacketClass, function);
TinyProtocol.instance.addFilter(positionLookPacketClass, function);
}
void registerCursor(RCursor cursor) {
closeCursorOf(cursor.getOwner());
activeCursors.put(cursor.getOwner(), cursor);
}
void unregisterCursor(RCursor cursor) {
activeCursors.remove(cursor.getOwner());
}
private void closeCursorOf(Player player) {
RCursor currentPlayerCursor = activeCursors.get(player);
if(currentPlayerCursor != null) {
currentPlayerCursor.close();
};
}
private void updateCursor(Player player) {
if (!activeCursors.containsKey(player)) {
return;
}
synchronized (calculationActive) {
if (calculationActive.contains(player)) {
return;
} else {
calculationActive.add(player);
}
}
RCursor cursor = activeCursors.get(player);
if (cursor != null) {
cursor.render();
}
synchronized (calculationActive) {
calculationActive.remove(player);
}
}
@EventHandler
private void handlePlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
RCursor cursorOfPlayer = activeCursors.get(player);
cursorOfPlayer.handleClick(event.getAction());
}
@EventHandler
private void handlePlayerQuit(PlayerQuitEvent event) {
closeCursorOf(event.getPlayer());
}
}

View File

@ -2,8 +2,6 @@ name: BauSystem
authors: [ Lixfel, YoyoNow, Chaoscaot, Zeanon, D4rkr34lm ]
version: "2.0"
depend: [ WorldEdit, SpigotCore ]
softdepend:
- ViaVersion
load: POSTWORLD
main: de.steamwar.bausystem.BauSystem
api-version: "1.13"

419
BauSystem/SCRIPT.md Normal file
View File

@ -0,0 +1,419 @@
# SteamWar.de - Script System
---
<!-- TOC -->
* [SteamWar.de - Script System](#steamwarde---script-system)
* [Einleitung](#einleitung)
* [Nutzung mit einer IDE](#nutzung-mit-einer-ide)
* [Basis-Apis](#basis-apis)
* [SteamWar.de-Api](#steamwarde-api)
* [player](#player)
* [random](#random)
* [region](#region)
* [tnt](#tnt)
* [trace](#trace)
* [server](#server)
* [tps](#tps)
* [storage](#storage)
* [inventory](#inventory)
* [SteamWar.de-Global-Api](#steamwarde-global-api)
* [Commands](#commands)
* [Hotkeys](#hotkeys)
* [Eventtypen](#eventtypen)
* [BlockEvent](#blockevent)
* [InteractEvent](#interactevent)
* [Position](#position)
* [Instabile APIs](#instabile-apis)
* [_worldedit](#worldedit)
* [Beispiele](#beispiele)
* [Hello, World!](#hello-world)
* [Code](#code)
* [Ausgabe](#ausgabe)
* [BauGUI on DoubleSwap](#baugui-on-doubleswap)
* [Code](#code-1)
* [SL Command](#sl-command)
* [Code](#code-2)
* [Paste Hotkey](#paste-hotkey)
* [Code](#code-3)
* [Inventory](#inventory-1)
* [Code](#code-4)
<!-- TOC -->
## Einleitung
Das Script System auf SteamWar.de basiert auf [Lua](https://www.lua.org/docs.html).
Der Code wird einfach in ein Minecraft Buch geschrieben und kann mit einem Links-Klick ausgeführt werden.
## Nutzung mit einer IDE
Im Repository liegen [Lua-Definitionen](sw.def.lua) für [Luanalysis](https://plugins.jetbrains.com/plugin/14698-luanalysis).
Diese können in der IDE genutzt werden, um die APIs zu nutzen.
Einfach die `sw.def.lua` in denselben Ordner wie das Script legen und die IDE sollte die APIs erkennen.
# Basis-Apis
Es werden folgende Standard-Apis zur Verfügung gestellt:
- [`math`](https://www.lua.org/manual/5.4/manual.html#6.7)
- [`string`](https://www.lua.org/manual/5.4/manual.html#6.4)
- [`table`](https://www.lua.org/manual/5.4/manual.html#6.6)
- [`bit32`](https://www.lua.org/manual/5.2/manual.html#6.7)
# SteamWar.de-Api
APIs, die mit einem `_` beginnen sind noch nicht stabil und können sich jederzeit ändern.
Sie sollten daher nicht verwendet werden, da sie sich noch in der Entwicklung befinden.
Diese können auch undokumentierte Funktionen enthalten, die nicht in der Dokumentation aufgeführt sind.
In den Scripten gibt es dazu noch folgende globale Variablen:
- [`player`](#player)
- [`random`](#random)
- [`region`](#region)
- [`server`](#server)
- [`storage`](#storage)
- [`inventory`](#inventory)
- `_worldedit`
Ohne eine Kategorie sind folgende Funktionen verfügbar, die nicht allgemein sind:
| Name | Signature | Beschreibung |
|-----------|-----------------------------------|-------------------------------------------------------------------------------------------------------------------|
| `print` | print(String...) | @see chat(String...) |
| `input` | input(String, Function\<String>) | Fragt den User nach einer Eingabe mit der Nachricht und called die zugehörige Funktion nach dieser |
| `delayed` | delayed(Number, Function\<Void>) | Wartet die angegebene Anzahl an Ticks und führt danach die zugehörige Funktion aus |
| `pos` | pos(Number, Number, Number) | Erstellt aus drei Zahlen eine Position-Table. Die Koordinaten sind unter den Namen `x`, `y` und `z` abgespeichert |
| `exec` | exec(String...) | Führt den angegebenen Befehl als Spieler aus |
| `length` | length(Any): Int | Gibt die Länge des Objekts zurück |
| `join` | length(String, String...): String | Füge die Texte mit den ersten Parameter zusammen |
### player
Das `player`-Modul stellt Funktionen zur Verfügung, die den Spieler betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|------------------|--------------------------------|---------------------------------------------------------------------------------------------------------------------------|
| `name` | name(): String | Gibt den `displayName` des Spielers zurück |
| `chat` | chat(String...) | Sendet den Text in den Chat des Spielers |
| `actionbar` | actionbar(String...) | Sendet den Text in die ActionBar des Spielers |
| `x` | x(Number), x(): Number | Setzt oder gibt die X-Koordinate des Spielers |
| `y` | y(Number), y(): Number | Setzt oder gibt die Y-Koordinate des Spielers |
| `z` | z(Number), z(): Number | Setzt oder gibt die Z-Koordinate des Spielers |
| `yaw` | yaw(Number), yaw(): Number | Setzt oder gibt die Gierung des Spielers |
| `pitch` | pitch(Number), pitch(): Number | Setzt oder gibt die Steigung des Spielers |
| `sneaking` | sneaking(): Boolean | Wahr, wenn der Spieler am Sneaken ist |
| `sprinting` | sprinting(): Boolean | Wahr, wenn der Spieler am Sprinten ist |
| `slot` | slot(Number), slot(): Number | Setzt oder gibt den Slot des gehaltenden Items des Spielers [(Wiki)](https://minecraft.fandom.com/wiki/Slot#Java_Edition) |
| `item` | item(): String | Gibt den Itemtyp der Main-Hand zurück |
| `offHandItem` | offHandItem(): String | Gibt den Itemtyp der Off-Hand zurück |
| `closeInventory` | closeInventory() | Schließe das aktuell geöffnete Inventar des Spielers |
### random
Das `random`-Modul stellt Funktionen zur Verfügung, die Zufallszahlen betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|------------|------------------------------------|-------------------------------------------------------------------------------|
| nextInt | nextInt(): Int | Gibt eine Zufallszahl zurück zwischen Integer.MIN_VALUE und Integer.MAX_VALUE |
| -"- | nextInt(Int): Int | Gibt eine Zufallszahl zurück zischen 0 und dem Argument |
| -"- | nextInt(Int, Int): Int | Gibt eine Zufallszahl zurück zwischen dem ersten und zweiten Argument |
| nextDouble | nextDouble(): Double | Gibt eine Zufallszahl zurück zwischen 0 und 1 |
| -"- | nextDouble(Double): Double | Gibt eine Zufallszahl zurück zwischen 0 und dem Argument |
| -"- | nextDouble(Double, Double): Double | Gibt eine Zufallszahl zurück zwischen ersten und zweiten Argument |
| nextBool | nextBool(): Boolean | Gibt true oder false zurück |
### region
Das `region`-Modul stellt Funktion zur Verfügung, die die Region des Spielers betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|-----------|---------------------|------------------------------------------------------------------------------------------------------------|
| `name` | name(): String | Gibt den Regionsnamen |
| `type` | type(): String | Gibt den Regionstyp |
| `fire` | fire(): Boolean | Gibt den Fire-Modus der Region zurück |
| `freeze` | freeze(): Boolean | Gibt den Freeze-Modus der Region zurück |
| `protect` | protect(): Boolean | Gibt den Protect-Modus der Region zurück |
| `loader` | loader(): String | Gibt den Status des Loaders des Spielers zurück, die Werte sind: `OFF`, `SETUP`, `RUNNING`, `PAUSE`, `END` |
| `get` | get(String): Region | Gibt die Region mit dem Namen zurück. Die Region ist gleich aufgebaut wie das Regions-Modul |
| `list` | list(): Region[] | Gibt alle Region zurück. Die Region ist gleich aufgebaut wie das Regions-Modul |
Es gibt folgende weitere Module:
| Name | Beschreibung |
|---------|-----------------|
| `tnt` | [tnt](#tnt) |
| `trace` | [trace](#trace) |
#### tnt
Das `tnt`-Modul stellt Funktionen zur Verfügung, die den TNT-Modus in der Region des Spielers betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|-------------|----------------------|-------------------------------------------------------------------------------------|
| `mode` | mode(): String | Gibt den Aktuellen TNT-Modus zurück, die werte sind: `ALLOW`, `DENY` oder `ONLY_TB` |
| `enabled` | enabled(): Boolean | Gibt zurück, ob der TNT-Modus in der Region des Spielers aktiviert ist oder nicht |
| `onlyTb` | onlyTb(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Tb ist |
| `onlyBuild` | onlyBuild(): Boolean | Gibt zurück, ob der TNT-Modus auf Only-Build ist |
#### trace
Das `trace`-Modul stellt Funktionen zur Verfügung, die den Status des Tracers der Region betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|----------|-------------------|--------------------------------------------------------------------------------|
| `active` | active(): Boolean | Gibt zurück, ob der Tracer in der Region des Spielers aktiviert ist oder nicht |
| `auto` | auto(): Boolean | Gibt zurück, ob der Tracer in der Region ein Auto-Tracer ist |
| `status` | status(): String | Gibt den Status des Tracers zurück |
| `time` | time(): String | Gibt die Zeit des Tracers zurück |
## server
Das `server`-Modul stellt Funktionen zur Verfügung, die den Server betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|--------------|-------------------------|---------------------------------------------------------------------|
| `time` | time(): String | Gibt die aktuelle Zeit im Format `HH:mm:ss` zurück |
| `ticks` | ticks(): Number | Gibt die Ticks seit start des Serverstarts zurück |
| `getBlockAt` | getBlockAt(Pos): String | Gibt das Material an der Position zurück |
| `setBlockAt` | setBlockAt(Pos, String) | Setzt das Material an der angegebenen Stelle (z.B. Stein = `STONE`) |
Es gibt folgende weitere Module:
| Name | Beschreibung |
|-------|--------------|
| `tps` | [tps](#tps) |
#### tps
Das `tps`-Modul stellt Funktionen zur Verfügung, die die TPS des Servers betreffen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|--------------|----------------------|-------------------------------------------------------------------|
| `current` | current(): Number | Gibt die aktuelle TPS zurück (Das selbe wie `oneSecound()`) |
| `oneSecond` | oneSecond(): Number | Gibt die durchschnittliche TPS über die letzte Sekunde zurück |
| `tenSecond` | tenSecond(): Number | Gibt die durchschnittliche TPS über die letzte 10 Sekunden zurück |
| `oneMinute` | oneMinute(): Number | Gibt die durchschnittliche TPS über die letzte Minute zurück |
| `fiveMinute` | fiveMinute(): Number | Gibt die durchschnittliche TPS über die letzte 5 Minuten zurück |
| `tenMinute` | tenMinute(): Number | Gibt die durchschnittliche TPS über die letzte 10 Minuten zurück |
| `limit` | limit(): Number | Gibt das TPS-Limit zurück |
## storage
Das `storage`-Modul stellt Funktionen zur Verfügung, mit welchen man Werte speichern kann.
Es gibt folgende Module:
| Name | Beschreibung |
|----------|---------------------|
| `player` | Spieler abhängig |
| `region` | Region des Spielers |
| `global` | Alle Skripte |
Alle Module haben folgende Funktionen:
| Name | Signature | Beschreibung |
|------------|----------------------------|--------------------------------------------------------|
| `get` | get(String): Any | Gibt den Wert des Schlüssels zurück |
| `set` | set(String, Any) | Setzt den Wert des Schlüssels auf den angegebenen Wert |
| `has` | has(String): Boolean | Prüft ob ein Wert vorhanden ist |
| `remove` | remove(String) | Löscht den Schlüssel |
| `accessor` | accessor(String): Accessor | Gibt einen Accessor zurück |
Ein Accessor ist ein Objekt, womit du direkt auf einen Wert zugreifen kannst und es ändern kannst.
Es geht wie folgt:
```lua
keyAccessor = storage.player.accessor("key")
keyAccessor("Hello World") -- Setzt den Wert auf "Hello World"
print(keyAccessor()) -- Gibt den Wert zurück
```
## inventory
Das `inventory`-Modul stellt Funktionen zur Verfügung, um ein Inventar zu öffnen.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|----------|-----------------------------------|-------------------------------------------------------------------|
| `create` | create(String, Number): Inventory | Erstellt ein Inventar mit dem Title und der Anzahl an Zeilen |
Das `Inventory`-Objekt hat folgende Funktionen:
| Name | Signature | Beschreibung |
|-------------------|--------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `item` | item(Number, String, String, Function\<String>) | Setze ein Item mit dem Typen des ersten Strings an den Slot (Startet bei 0) mit dem Namen des zweiten Strings mit einem Klick-Handler der den Klick-Typen rein gibt (z.B. `LEFT`, `SHIFT_LEFT`, `RIGHT`, `SHIFT_RIGHT`) |
| -"- | item(Number, String, String, Function\<String>, List<String>) | Füge eine Lore an das Item hinzu |
| -"- | item(Number, String, String, Function\<String>, List<String>, Boolean) | Gebe an, ob das Item enchanted sein soll |
| -"- | item(Number, String, String, Function\<String>, List<String>, Boolean, Number) | Gebe die Anzahl der Items an |
| `setCloseHandler` | setCloseHandler(Function\<Void>) | Gebe einen Handler an, der beim schließen des Inventares ausgeführt wird |
| `open` | open() | Öffne das Inventar |
Siehe auch: [Inventory Beispiel](#inventory-1)
Siehe auch: [Liste an Materials](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html)
```
⚠️⚠️⚠️
Wenn eine Barrier statt des richtigen Items angezeigt wird, dann ist das angegebene Material nicht gültig.
⚠️⚠️⚠️
```
# SteamWar.de-Global-Api
Mit `/script` kann man Script-Bücher global abspeichern. Diese haben dann zugrif auf die `global`-Api.
Die `global`-Api stellt Funktionen zur Verfügung um auf Events, Commands und Hotkeys mit einem Script zu reagieren.
Es gibt folgende Funktionen:
| Name | Signature | Beschreibung |
|-----------|-----------------------------------|-----------------------------------------------------------------------------|
| `event` | event(EventType, Function(Any)) | Registriere einen Event Listener |
| `command` | command(String, Function(Args)) | Registriere einen Befehl |
| `hotkey` | hotkey(String, Function(Boolean)) | Registriere einen Hotkey, the function gets a boolean if the key is pressed |
Es gibt folgende Variablen:
| Name | Beschreibung |
|----------|----------------------------------|
| `events` | Siehe: [Event Type](#eventtypen) |
## Commands
Der Command Handler kriegt eine Liste aller angegeben argumenten. Die Argumente sind vom Typ `String`. Mit dem Wert gespeichert unter `args.alias` oder `args["alias"]` erhältst du, welcher command eingegeben wurde. Wenn ein handler für mehrere Befehle registriert wurde kannst du es hiermit erkennen.
Du kannst `args.hasShortFlag(String)` um herauszufinden ob eine Flag angegeben wurde wie zum Beispiel `-f`. Mit `args.removeShortFlag(String)` kannst du die Flag entfernen und erhältst ob sie angegeben wurde.
## Hotkeys
Hotkeys werden im folgenden Format angegeben: `MODIFIER+KEY`. Bei den Hotkey erstellung ist die Großschreibung egal. Es gibt folgende Modifier:
- `ctrl`
- `shift`
- `alt`
- `meta`
Es können auch mehrere Modifier angegeben werden, z.B. `ctrl+shift+alt+c`. Die Reihenfolge der Modifier und des Keys ist egal.
## Eventtypen
Einige Events sind auch abbrechbar, dazu muss die Funktion `setCancelled()` aufgerufen werden.
| Name | Wenn | Parameter | Abbrechbar |
|---------------------|-----------------------------------------------------|---------------------------------|------------|
| `DoubleSwap` | Beim Doppelten Drücken der Swap-Hands taste | NIL | false |
| `PlaceBlock` | Beim Platzieren von Blöcken | [BlockEvent](#blockevent) | true |
| `BreakBlock` | Beim Zerstören von Blöcken | [BlockEvent](#blockevent) | true |
| `RightClick` | Beim Rechtsklick | [InteractEvent](#interactevent) | true |
| `LeftClick` | Beim Linksklick | [InteractEvent](#interactevent) | true |
| `TNTSpawn` | Wenn ein TNT in der aktuellen Region spawnt | NIL | false |
| `TNTExplode` | Wenn ein TNT in der aktuellen Region explodiert | [Position](#position) | true |
| `TNTExplodeInBuild` | Wenn ein TNT in der aktuellen Bau Region explodiert | [Position](#position) | true |
| `SelfJoin` | Wenn man selbst den Server betritt | NIL | false |
| `SelfLeave` | Wenn man den Server verlässt | NIL | false |
| `DropItem` | Wenn man ein Item droppt | (type: Material) | true |
| `EntityDeath` | Wenn ein Entity stirbt | (type: Entity Type) | false |
### BlockEvent
Das übergebene Objekt an den Handler hat folgende Variablen:
| Name | Beschreibung |
|--------|-----------------------------|
| `x` | Die X-Koordinate des Blocks |
| `y` | Die Y-Koordinate des Blocks |
| `z` | Die Z-Koordinate des Blocks |
| `type` | Das Material des Blocks |
### InteractEvent
Das übergebene Objekt an den Handler hat folgende Variablen:
| Name | Beschreibung |
|------------|-------------------------------------------------------------------------------------------------------------------------------|
| `action` | Die Action die ausgeführt wurde, Mögliche Werte: `RIGHT_CLICK_BLOCK`, `RIGHT_CLICK_AIR`, `LEFT_CLICK_BLOCK`, `LEFT_CLICK_AIR` |
| `hand` | Die Hand die zum ausführen genutzt wird, Mögliche Werte: `HAND`, `OFF_HAND`, `null` |
| `block` | Der Typ des Items mit dem geklickt wurde |
| `hasBlock` | Wahr, wenn auf einen Block geklickt wurde |
Wenn `hasBlock` wahr ist, gibt es folgende Variablen:
| Name | Beschreibung |
|-------------|-----------------------------------------|
| `blockX` | Die X-Koordinate des Blocks |
| `blockY` | Die Y-Koordinate des Blocks |
| `blockZ` | Die Z-Koordinate des Blocks |
| `blockFace` | Die Seite des Blocks die geklickt wurde |
### Position
Die Position ist ein Objekt mit folgenden Variablen:
| Name | Beschreibung |
|------|------------------|
| `x` | Die X-Koordinate |
| `y` | Die Y-Koordinate |
| `z` | Die Z-Koordinate |
# Instabile APIs
Hier sind einige APIs aufgelistet, die nicht stabil sind und sich jederzeit ändern können.
## _worldedit
| Name | Signatur | Beschreibung |
|-------------|-----------------------------------------------------------|-----------------------------------|
| `selection` | selection(Liste\<Pos>), selection(): {min: Pos, max: Pos} | Die aktuelle auswahl des Spielers |
# Beispiele
## Hello, World!
Ein einfaches Hello, World!-Script.
#### Code
```lua
print("Hello, World!")
```
#### Ausgabe
```
Hello, World!
```
## BauGUI on DoubleSwap
Das Standardskript für das Öffnen des BauGUIs
#### Code
```lua
function handler(event)
exec("gui")
end
event(events.DoubleSwap, handler)
```
## SL Command
Ein einfacher Command Redefiner.
#### Code
```lua
function handler(args)
exec("stoplag")
end
command("sl", handler)
```
## Paste Hotkey
Ein Hotkey zum Pasten des Clipboard-Inhalts.
#### Code
```lua
function handler(pressed)
if pressed then
exec("/paste -o")
end
end
hotkey("ctrl+v", handler)
```
## Inventory
Ein Beispiel für ein Inventar.
#### Code
```lua
inv = inventory.create("Test Inv", 3)
inv.item(13, "STONE", "Ich bin ein Stein", function(e) player.chat(e) end, {"Die Lore", "Die Zweite Zeile"}, true)
inv.open()
```

View File

@ -34,3 +34,19 @@ dependencies {
implementation(project(":BauSystem:BauSystem_20"))
implementation(project(":BauSystem:BauSystem_21"))
}
tasks.register<DevServer>("DevBau20") {
group = "run"
description = "Run a 1.20 Dev Bau"
dependsOn(":SpigotCore:shadowJar")
dependsOn(":BauSystem:shadowJar")
template = "Bau20"
}
tasks.register<DevServer>("DevBau21") {
group = "run"
description = "Run a 1.21 Dev Bau"
dependsOn(":SpigotCore:shadowJar")
dependsOn(":BauSystem:shadowJar")
template = "Bau21"
}

87
BauSystem/hotkeys.lua Normal file
View File

@ -0,0 +1,87 @@
-- This file is a part of the SteamWar software.
--
-- Copyright (C) 2025 SteamWar.de-Serverteam
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
---
--- This serves both as an example and a quick start to the Stewamwar Script Api
---
function hotkeys_freeze(pressed)
if pressed then
exec("/freeze")
end
end
function hotkeys_rgc(pressed)
if pressed then
exec("/rgc")
end
end
function hotkeys_rgp(pressed)
if pressed then
exec("/rgp")
end
end
trace_cycle_counter = 0;
function hotkeys_cycle_trace_view(pressed)
if not pressed then
return
end
trace_cycle = (trace_cycle + 1) % 3
trace_commands = {"trace hide", "trace show", "trace show -e -c"}
exec(trace_commands[trace_cycle + 1])
end
function hotkeys_tick_step(pressed)
if pressed then
exec("tick step")
end
end
function hotkeys_tpslimit(pressed)
if not pressed then
return
end
if tps.limit() == 20 then
exec("tpslimit 200")
else
exec("tpslimit 20")
end
end
function hotkeys_tb(pressed)
if pressed then
exec("tb -e")
end
end
function hotkeys_trace_delete(pressed)
if pressed then
exec("trace delete")
end
end
hotkey("ctrl+g", hotkeys_freeze)
hotkey("ctrl+c", hotkeys_rgc)
hotkey("ctrl+v", hotkeys_rgp)
hotkey("ctrl+x", hotkeys_tick_step)
hotkey("shift+x", hotkeys_cycle_trace_view)
hotkey("ctrl+y", hotkeys_tb)
hotkey("ctrl+alt", hotkeys_trace_delete)
hotkey("ctrl+h", hotkeys_trace_delete)

432
BauSystem/sw.def.lua Normal file
View File

@ -0,0 +1,432 @@
-- This file is a part of the SteamWar software.
--
-- Copyright (C) 2021 SteamWar.de-Serverteam
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
---
--- This file contains the definitions for the SteamWar.de script API.
--- It is used by the IDE to provide code completion and type checking.
--- Created by Chaoscaot
---
inventory = {}
---@param title string
---@param size number
---@return Inventory
function inventory.create(title, size) return nil end
---@alias InventoryClick 'LEFT' | 'SHIFT_LEFT' | 'RIGHT' | 'SHIFT_RIGHT' | 'MIDDLE' | 'NUMBER_KEY'
---@class Inventory
local Inventory = {}
---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick)): void
---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick), lore: string[]): void
---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick), lore: string[], enchanted: boolean): void
---@param slot number
---@param material string
---@param name string
---@param handler fun(click: InventoryClick): void
---@param lore string[]
---@param enchanted boolean
---@param amount number
---@return void
function Inventory.item(slot, material, name, handler, lore, enchanted, amount) end
---@param handler fun(): void
---@return void
function Inventory.setCloseHandler(handler) end
---@return void
function Inventory.open() end
player = {}
---@return string
---Get the name of the player.
function player.name() return "" end
---@return void
function player.chat(...) end
---@return void
---Send a message to the actionbar of the player.
function player.actionbar(...) end
---@overload fun(): number
---@param newX number
function player.x(newX) end
---@overload fun(): number
---@param newY number
function player.y(newY) end
---@overload fun(): number
---@param newZ number
function player.z(newZ) end
---@overload fun(): number
---@param newYaw number
function player.yaw(newYaw) end
---@overload fun(): number
---@param newPitch number
function player.pitch(newPitch) end
---@return boolean
function player.sneaking() return nil end
---@return boolean
function player.sprinting() return nil end
---@overload fun(): number
---@param newSlot number
function player.slot(newSlot) end
---@return string
function player.item() return nil end
---@return string
function player.offHandItem() return nil end
---@return void
function player.closeInventory() end
---@field nextBool fun(): boolean
random = {}
---@overload fun(): number
---@overload fun(bound: number): number
---@param origin number
---@param bound number
---@return number
function random.nextInt(origin, bound) return nil end
---@overload fun(): number
---@overload fun(bound: number): number
---@param origin number
---@param bound number
---@return number
function random.nextDouble(origin, bound) return nil end
---@return boolean
function random.nextBool() return nil end
---@alias RegionType 'wg' | 'mwg' | 'as' | 'ws' | 'ws_inner' | 'ws_rumpf' | 'ws_rahmen' | 'spawn'
---@class iregion
---@field tnt tnt
---@field trace trace
local iregion = {}
---@class region: iregion
region = {}
---@return string
function iregion.name() return nil end
---@return RegionType
function iregion.type() return nil end
---@return boolean
function iregion.fire() return nil end
---@return boolean
function iregion.freeze() return nil end
---@return boolean
function iregion.protect() return nil end
---@return string
function iregion.loader() return nil end
---@return Position
function iregion.copyPoint() return nil end
---@return Position
function iregion.minPointBuild() return nil end
---@return Position
function iregion.maxPointBuild() return nil end
---@return Position
function iregion.minPointBuildExtension() return nil end
---@return Position
function iregion.maxPointBuildExtension() return nil end
---@return Position
function iregion.testblockPoint() return nil end
---@return Position
function iregion.minPointTestblock() return nil end
---@return Position
function iregion.maxPointTestblock() return nil end
---@return Position
function iregion.minPointTestblockExtension() return nil end
---@return Position
function iregion.maxPointTestblockExtension() return nil end
---@alias TNTMode 'ALLOW' | 'DENY' | 'ONLY_TB'
---@class tnt
local tnt = {}
---@return TNTMode
function tnt.mode() return nil end
---@return boolean
function tnt.enabled() return nil end
---@return boolean
function tnt.onlyTb() return nil end
---@return boolean
function tnt.onlyBuild() return nil end
---@param name string
---@return iregion
function region.get(name) return nil end
---@return iregion[]
function region.list() return nil end
---@class tracerLib
tracer = {}
---@class TraceRecord
---@field pos Position
---@field vel Position
---@field ticksSinceStart number
---@field fuse number
---@field isExplosion boolean
---@field isInWater boolean
---@field hasDestroyedBuild boolean
---@field hasDestroyedTestblock boolean
---@class Tracer
---@field getId fun(): string
---@field getRecords fun(): {[number]: {[number]: TraceRecord}}
function tracer.getTraces() return nil end
---@class Position
---@field x number
---@field y number
---@field z number
---@class server
---@field tps tps
server = {}
---@return string
function server.time() return nil end
---@return number
function server.ticks() return nil end
---@param position Position
---@return string
function getBlockAt(position) return nil end
---@param position Position
---@param material string
---@return void
function setBlockAt(position, material) return nil end
---@class tps
local tps = {}
---@return number
function tps.oneSecond() return nil end
---@return number
function tps.tenSecond() return nil end
---@return number
function tps.oneMinute() return nil end
---@return number
function tps.fiveMinute() return nil end
---@return number
function tps.tenMinute() return nil end
---@return number
function tps.current() return nil end
---@return number
function tps.limit() return nil end
---@class storage
---@field global storageLib
---@field player storageLib
---@field region storageLib
storage = {}
---@class storageLib
---Any Primitive, Array or Table will be saved across restarts, everything else will be discarded
local storageLib = {}
---@param key string
---@return any
function storageLib.get(key) return nil end
---@param key string
---@param value any
---@return void
function storageLib.set(key, value) end
---@param key string
---@return boolean
function storageLib.has(key) return nil end
---@param key string
---@return void
function storageLib.remove(key) end
---@param key string
---@return Accessor
function storageLib.accessor(key) return nil end
---@class Accessor
---@overload fun(): any
---@overload fun(value: any)
---@class Selection
---@field max Position
---@field min Position
---@class _worldedit
_worldedit = {}
---@overload fun(pos: Position[]): void
---@return Selection
function _worldedit.selection() return nil end
---@param msg string
---@param callback fun(value: string): void
---@return void
function input(msg, callback) end
---@param ticks number
---@param callback fun(): void
---@return void
function delayed(ticks, callback) end
---@param x number
---@param y number
---@param z number
---@return Position
function pos(x, y, z) return nil end
---@return void
function exec(...) end
---@param obj any
---@return number
function length(obj) return 0 end
---@param separator string
---@param table any[]
---@return string
function join(separator, table) return "" end
---@class EventType
---@class events
---@field DoubleSwap EventType
---@field PlaceBlock EventType
---@field BreakBlock EventType
---@field RightClick EventType
---@field LeftClick EventType
---@field TNTSpawn EventType
---@field TNTExplode EventType
---@field TNTExplodeInBuild EventType
---@field SelfJoin EventType
---@field SelfLeave EventType
---@field DropItem EventType
---@field EntityDeath EventType
events = {}
---@param id EventType
---@param handler fun(params: any): void
---@return void
function event(id, handler) end
---@param command string
---@param handler fun(params: string[]): void
---@return void
function command(command, handler) end
---@param trigger string
---@param handler fun(pressed: boolean): void
---@return void
function hotkey(trigger, handler) end
---@class bossbar
bossbar = {}
---@alias BossBarColor 'PINK' | 'BLUE' | 'RED' | 'GREEN' | 'YELLOW' | 'PURPLE' | 'WHITE'
---@alias BossBarStyle 'SEGMENTED_6' | 'SEGMENTED_10' | 'SEGMENTED_12' | 'SEGMENTED_20' | 'SOLID'
---@alias BossBarFlag 'DARKEN_SKY' | 'PLAY_BOSS_MUSIC' | 'CREATE_FOG'
---@class BossBar
local BossBar = {}
---@param title string
---@param color BossBarColor
---@param style BossBarStyle
---@return BossBar
function bossbar.create(title, color, style) return nil end
---@return string
---@overload fun(title: string): void
function BossBar.title() end
---@return BossBarColor
---@overload fun(color: BossBarColor): void
function BossBar.color() end
---@return BossBarStyle
---@overload fun(style: BossBarStyle): void
function BossBar.style() end
---@return number
---@overload fun(progress: number): void
function BossBar.progress() end
---@return boolean
---@overload fun(visible: boolean): void
function BossBar.visible() end
---@return boolean
---@param flag BossBarFlag
function BossBar.hasFlag(flag) return nil end
---@return void
---@param flag BossBarFlag
function BossBar.addFlag(flag) end
---@return boolean
---@param flag BossBarFlag
function BossBar.removeFlag(flag) return nil end
---@return void
function BossBar.destroy() end

View File

@ -64,7 +64,7 @@ public class Event {
}
public static Event create(String eventName, Timestamp start, Timestamp end){
return get(create.insertGetKey(eventName, start, start, end, 5, false, false));
return get(create.insertGetKey(eventName, start, start, end, 5, false));
}
public static Event get(int eventID){

View File

@ -43,7 +43,7 @@ public class EventFight implements Comparable<EventFight> {
private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis");
private static final Statement setFight = table.update(Table.PRIMARY, "Fight");
private static final Statement create = table.insertAll(true);
private static final Statement create = table.insertFields(true, "eventID", "startTime", "spielmodus", "map", "teamBlue", "teamRed", "spectatePort");
private static final Statement update = table.update(Table.PRIMARY, "startTime", "spielModus", "map", "teamBlue", "teamRed", "spectatePort");
private static final Statement delete = table.delete(Table.PRIMARY);

View File

@ -35,8 +35,9 @@ import java.util.stream.Collectors;
public class Fight {
private static final Table<Fight> table = new Table<>(Fight.class);
private static final SelectStatement<Fight> getPage = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.AllowReplay) AND (r.NodeId IS NULL OR r.AllowReplay) AS ReplayAllowed, (SELECT COUNT(1) FROM Replay WHERE Replay.FightID = f.FightID) as ReplayAvailable FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
private static final SelectStatement<Fight> getPage = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.AllowReplay) AND (r.NodeId IS NULL OR r.AllowReplay) AS ReplayAllowed FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition");
private static final Statement updateReplayAvailable = table.update(Table.PRIMARY, "ReplayAvailable");
public static List<Fight> getPage(int page, int elementsPerPage) {
List<Fight> fights = getPage.listSelect(page * elementsPerPage, elementsPerPage);
@ -54,6 +55,10 @@ public class Fight {
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition);
}
public static void markReplayAvailable(int fightID) {
updateReplayAvailable.update(true, fightID);
}
@Getter
@Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int fightID;
@ -80,10 +85,10 @@ public class Fight {
private final int win;
@Field
private final String wincondition;
@Field
private final boolean replayAvailable;
@Field // Virtual field for easy select
private final boolean replayAllowed;
@Field // Virtual field for easy select
private final boolean replayAvailable;
@Getter
private final List<FightPlayer> bluePlayers = new ArrayList<>();

View File

@ -28,12 +28,14 @@ import java.sql.PreparedStatement;
import java.util.zip.GZIPInputStream;
@AllArgsConstructor
@Getter
public class NodeData {
static {
new SqlTypeMapper<>(PipedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("PipedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
new SqlTypeMapper<>(ByteArrayInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("ByteArrayInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
new SqlTypeMapper<>(BufferedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("BufferedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
SqlTypeMapper.ordinalEnumMapper(SchematicFormat.class);
}
private static final Table<NodeData> table = new Table<>(NodeData.class);
@ -48,21 +50,24 @@ public class NodeData {
throw new IllegalArgumentException("Node is a directory");
return get.select(rs -> {
if(rs.next()) {
return new NodeData(node.getId(), rs.getBoolean("NodeFormat"));
return new NodeData(node.getId(), SchematicFormat.values()[rs.getInt("NodeFormat")]);
} else {
return new NodeData(node.getId(), false);
return new NodeData(node.getId(), SchematicFormat.MCEDIT);
}
}, node);
}
@Getter
@Field(keys = {Table.PRIMARY})
private final int nodeId;
@Field
private boolean nodeFormat;
private SchematicFormat nodeFormat;
public InputStream schemData() throws IOException {
return schemData(true);
}
public InputStream schemData(boolean decompress) throws IOException {
try {
return selSchemData.select(rs -> {
rs.next();
@ -71,7 +76,11 @@ public class NodeData {
if(rs.wasNull() || schemData.available() == 0) {
throw new SecurityException("SchemData is null");
}
if (decompress) {
return new GZIPInputStream(schemData);
} else {
return schemData;
}
} catch (IOException e) {
throw new SecurityException("SchemData is wrong", e);
}
@ -81,12 +90,18 @@ public class NodeData {
}
}
public void saveFromStream(InputStream blob, boolean newFormat) {
public void saveFromStream(InputStream blob, SchematicFormat newFormat) {
updateDatabase.update(nodeId, newFormat, blob);
nodeFormat = newFormat;
}
public boolean getNodeFormat() {
return nodeFormat;
@AllArgsConstructor
@Getter
public enum SchematicFormat {
MCEDIT(".schematic"),
SPONGE_V2(".schem"),
SPONGE_V3(".schem");
private final String fileEnding;
}
}

View File

@ -1,7 +1,7 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
* Copyright (C) 2025 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@ -35,7 +35,7 @@ import java.time.Instant;
public class NodeDownload {
private static final char[] HEX = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static final String LINK_BASE = "https://steamwar.de/download.php?schem=";
private static final String LINK_BASE = "https://api.steamwar.de/download/";
private static final Table<NodeDownload> table = new Table<>(NodeDownload.class);
private static final Statement insert = table.insertFields("NodeId", "Link");

View File

@ -1,74 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.sql;
import de.steamwar.sql.internal.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.sql.SQLException;
@AllArgsConstructor
public class Replay {
static {
new SqlTypeMapper<>(File.class, "BLOB", (rs, identifier) -> {
try {
File file = File.createTempFile("replay", ".replay");
file.deleteOnExit();
Files.copy(rs.getBinaryStream(identifier), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
return file;
} catch (IOException e) {
throw new SQLException(e);
}
}, (st, index, value) -> {
try {
st.setBinaryStream(index, new FileInputStream(value));
} catch (FileNotFoundException e) {
throw new SQLException(e);
}
});
}
private static final Table<Replay> table = new Table<>(Replay.class);
private static final SelectStatement<Replay> get = table.select(Table.PRIMARY);
public static final Statement insert = table.insertAll();
public static Replay get(int fightID) {
return get.select(fightID);
}
public static void save(int fightID, File file) {
insert.update(fightID, file);
}
@Field(keys = {Table.PRIMARY})
private final int fightID;
@Getter
@Field
private final File replay;
}

View File

@ -31,10 +31,13 @@ public class SchematicNode {
static {
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> {
throw new SecurityException("SchematicNode cannot be used as type (recursive select)");
}, (st, index, value) -> st.setInt(index, value.nodeId));
}
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
public static void clear() {
TAB_CACHE.clear();
}
@ -42,24 +45,45 @@ public class SchematicNode {
private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode ";
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem",
"NodeType");
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem",
"NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
private static final Statement delete = table.delete(Table.PRIMARY);
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?");
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table,
nodeSelector + "WHERE NodeId = ?");
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table,
nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table,
nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector
+ "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table,
nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table,
nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table,
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId");
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table,
"SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId "
+ Statement.NULL_SAFE_EQUALS
+ "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table,
"SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId "
+ Statement.NULL_SAFE_EQUALS
+ "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table,
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeId = ?");
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table,
"WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId"
+ Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table,
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table,
"SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table,
"WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
static {
NodeMember.init();
@ -102,8 +126,7 @@ public class SchematicNode {
SchematicType nodeType,
int nodeRank,
boolean replaceColor,
boolean allowReplay
) {
boolean allowReplay) {
this.nodeId = nodeId;
this.nodeOwner = nodeOwner;
this.effectiveOwner = effectiveOwner;
@ -118,7 +141,7 @@ public class SchematicNode {
}
public static List<SchematicNode> getAll(SteamwarUser user) {
return all.listSelect(user);
return all.listSelect(user, user, user);
}
public static Map<Integer, List<SchematicNode>> getAllMap(SteamwarUser user) {
@ -130,7 +153,8 @@ public class SchematicNode {
}
public static SchematicNode byParentName(SteamwarUser user, Integer schematicId, String name) {
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId, name);
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId,
name);
}
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
@ -142,10 +166,11 @@ public class SchematicNode {
}
public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) {
return schematicAccessibleForUser.select(user, schematicId) != null;
return schematicAccessibleForUser.select(user, user, user, schematicId) != null;
}
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type,
Integer parentId) {
return accessibleByUserTypeInParent.listSelect(user, user, type, user, parentId);
}
@ -160,7 +185,8 @@ public class SchematicNode {
private static Map<Integer, List<SchematicNode>> map(List<SchematicNode> in) {
Map<Integer, List<SchematicNode>> map = new HashMap<>();
for (SchematicNode effectiveSchematicNode : in) {
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode);
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>())
.add(effectiveSchematicNode);
}
return map;
}
@ -218,7 +244,8 @@ public class SchematicNode {
return byId.select(id);
}
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType,
Integer parent) {
return accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent);
}
@ -283,10 +310,12 @@ public class SchematicNode {
}
if (s.contains("/")) {
String[] layers = s.split("/");
Optional<SchematicNode> currentNode = Optional.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
Optional<SchematicNode> currentNode = Optional
.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
for (int i = 1; i < layers.length; i++) {
int finalI = i;
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode
.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
if (!node.isPresent()) {
return null;
} else {
@ -375,11 +404,10 @@ public class SchematicNode {
return nodeType == null;
}
@Deprecated
public boolean getSchemFormat() {
public String getFileEnding() {
if (isDir())
throw new SecurityException("Node is Directory");
return NodeData.get(this).getNodeFormat();
return NodeData.get(this).getNodeFormat().getFileEnding();
}
public int getRank() {
@ -435,7 +463,8 @@ public class SchematicNode {
}
public SchematicNode getParentNode() {
if(parentNode == null) return null;
if (parentNode == null)
return null;
return SchematicNode.getSchematicNode(parentNode);
}
@ -500,7 +529,11 @@ public class SchematicNode {
builder.append(split);
}
while (currentNode.isPresent()) {
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
currentNode = currentNode
.flatMap(schematicNode -> Optional
.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner))
.map(NodeMember::getParent).orElse(schematicNode.getOptionalParent()))
.map(SchematicNode::getSchematicNode);
currentNode.ifPresent(node -> builder.insert(0, split).insert(0, node.getName()));
}
return builder.toString();
@ -513,13 +546,18 @@ public class SchematicNode {
map.add(new AbstractMap.SimpleEntry<>(getName(), getId()));
}
while (currentNode.isPresent()) {
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
currentNode = currentNode
.flatMap(schematicNode -> Optional
.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner))
.map(NodeMember::getParent).orElse(schematicNode.getOptionalParent()))
.map(SchematicNode::getSchematicNode);
currentNode.ifPresent(node -> map.add(0, new AbstractMap.SimpleEntry<>(node.getName(), node.getId())));
}
return map;
}
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
public static boolean invalidSchemName(String[] layers) {
for (String layer : layers) {
if (layer.isEmpty()) {
@ -557,7 +595,8 @@ public class SchematicNode {
if (s.contains("/")) {
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
if (pa == null) return new ArrayList<>();
if (pa == null)
return new ArrayList<>();
List<SchematicNode> nodes = SchematicNode.list(user, pa.getId());
String br = pa.generateBreadcrumbs();
nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : "")));

View File

@ -29,7 +29,6 @@ import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.sql.Timestamp;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.stream.Collectors;
@ -73,6 +72,7 @@ public class SteamwarUser {
private static final Statement getPlaytime = new Statement("SELECT SUM(UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime)) as Playtime FROM Session WHERE UserID = ?");
private static final Statement getFirstjoin = new Statement("SELECT MIN(StartTime) AS FirstJoin FROM Session WHERE UserID = ?");
private static final Statement getLastonline = new Statement("SELECT MAX(EndTime) AS LastOnline FROM Session WHERE UserID = ?");
private static final Map<Integer, SteamwarUser> usersById = new HashMap<>();
private static final Map<UUID, SteamwarUser> usersByUUID = new HashMap<>();
@ -121,13 +121,12 @@ public class SteamwarUser {
return byDiscord.select(discordId);
}
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer) {
SteamwarUser user = get(uuid);
if (user != null) {
if (!user.userName.equals(name)) {
updateName.update(name, user.id);
nameUpdate.accept(user.userName, name);
user.userName = name;
}
@ -276,6 +275,14 @@ public class SteamwarUser {
}, id);
}
public Timestamp getLastOnline() {
return getLastonline.select(rs -> {
if (rs.next())
return rs.getTimestamp("LastOnline");
return null;
}, id);
}
public void punish(Punishment.PunishmentType punishment, Timestamp time, String banReason, int from, boolean perma) {
initPunishments();
punishments.remove(punishment);
@ -328,7 +335,7 @@ public class SteamwarUser {
public boolean verifyPassword(String password) {
try {
if (this.password == null) {
if (!hasPassword()) {
return false;
}
@ -350,6 +357,10 @@ public class SteamwarUser {
}
}
public boolean hasPassword() {
return this.password != null;
}
private byte[] generateHash(String password, byte[] salt)
throws InvalidKeySpecException {
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512);

View File

@ -75,15 +75,7 @@ public class UserElo {
public static void setElo(int userId, String gameMode, int elo) {
emblemCache.remove(userId);
int oldPlacement = getPlacement(getElo(userId, gameMode).orElse(0), gameMode);
int newPlacement = getPlacement(elo, gameMode);
gameModeUserEloCache.getOrDefault(gameMode, Collections.emptyMap()).remove(userId);
if (oldPlacement <= 3 || newPlacement <= 3) {
emblemCache.clear();
}
setElo.update(Season.getSeason(), gameMode, userId, elo);
}
@ -112,27 +104,17 @@ public class UserElo {
public static String getEmblemProgression(String gameMode, int userId) {
switch (getProgression(userId, gameMode)) {
case -1:
return "§f/ §8 ∧ ❂ III II I";
return "§8❱❱❱❱ ❂";
case 0:
return "§8/ §6 §8∧ ∧ ❂ III II I";
return "§e❱§8❱❱❱ ❂";
case 1:
return "§8/ §6∧ §8 ∧ ❂ III II I";
return "§e❱❱§8❱❱ ❂";
case 2:
return "§8/ ∧ §7 §8∧ ∧ ❂ III II I";
return "§e❱❱❱§8❱ ❂";
case 3:
return "§8/ §7∧ §8 ∧ ❂ III II I";
return "§e❱❱❱❱§8 ❂";
case 4:
return "§8/ ∧ §e §8∧ ❂ III II I";
case 5:
return "§8/ §e∧ §8❂ III II I";
case 6:
return "§8/ ∧ §5❂ §8III II I";
case 7:
return "§8/ ∧ ❂ §5III §8II I";
case 8:
return "§8/ ∧ ❂ III §5II §8I";
case 9:
return "§8/ ∧ ❂ III II §5I";
return "§8❱❱❱❱ §5❂";
default:
throw new SecurityException("Progression is not in range");
}
@ -142,19 +124,11 @@ public class UserElo {
int elo = getElo(userId, gameMode).orElse(-1);
if (elo < 0) return -1;
if (elo <= 100) return 0;
if (elo <= 200) return 1;
if (elo <= 400) return 2;
if (elo <= 600) return 3;
if (elo <= 900) return 4;
if (elo <= 1200) return 5;
int placement = getPlacement(elo, gameMode);
if (placement == 1) return 9;
if (placement == 2) return 8;
if (placement == 3) return 7;
return 6;
if (elo < 150) return 0;
if (elo < 350) return 1;
if (elo < 600) return 2;
if (elo < 900) return 3;
return 4;
}
public static String toEmblem(int progression) {
@ -162,25 +136,15 @@ public class UserElo {
case -1:
return "";
case 0:
return "§6 ";
return "§e❱ ";
case 1:
return "§6∧ ";
return "§e❱❱ ";
case 2:
return "§7 ";
return "§e❱❱❱ ";
case 3:
return "§7∧ ";
return "§e❱❱❱❱ ";
case 4:
return "§e ";
case 5:
return "§e∧ ";
case 6:
return "§5❂ ";
case 7:
return "§5III ";
case 8:
return "§5II ";
case 9:
return "§5I ";
default:
throw new SecurityException("Progression out of range");
}

View File

@ -62,7 +62,7 @@ public class Statement implements AutoCloseable {
String user = properties.getProperty("user");
String password = properties.getProperty("password");
PRODUCTION_DATABASE = "core".equals(properties.getProperty("database"));
PRODUCTION_DATABASE = "production".equals(properties.getProperty("database"));
MAX_CONNECTIONS = SQLConfig.impl.maxConnections();
conProvider = () -> {
try {

View File

@ -19,45 +19,46 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.Config;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.Map;
public class BlockIdWrapper14 implements BlockIdWrapper {
private static final Class<?> chunkProviderServer = Reflection.getClass("{nms.server.level}.ChunkProviderServer");
private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
private static final Class<?> playerChunkMap = Reflection.getClass("{nms.server.level}.PlayerChunkMap");
private static final Reflection.FieldAccessor<?> getPlayerChunkMap = Reflection.getField(chunkProviderServer, playerChunkMap, 0);
private static final Reflection.FieldAccessor<? extends Map> entityTrackers = Core.getVersion() > 15 ? Reflection.getField(playerChunkMap, Int2ObjectMap.class, 0) : Reflection.getField(playerChunkMap, org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap.class, 0);
private static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
private static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private static final Class<?> chunkProviderServer = Reflection.getClass("net.minecraft.server.level.ServerChunkCache");
private static final Reflection.Method getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
private static final Class<?> playerChunkMap = Reflection.getClass("net.minecraft.server.level.ChunkMap");
private static final Reflection.Field<?> getPlayerChunkMap = Reflection.getField(chunkProviderServer, playerChunkMap, 0);
private static final Reflection.Field<? extends Map> entityTrackers = Core.getVersion() > 15 ? Reflection.getField(playerChunkMap, Int2ObjectMap.class, 0) : Reflection.getField(playerChunkMap, org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap.class, 0);
private static final Class<?> block = Reflection.getClass("net.minecraft.world.level.block.Block");
private static final Class<?> iBlockData = Reflection.getClass("net.minecraft.world.level.block.state.BlockState");
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
private final Map trackers;
public BlockIdWrapper14() {
trackers = entityTrackers.get(getPlayerChunkMap.get(getChunkProvider.invoke(getWorldHandle.invoke(Config.world))));
}
private static final Reflection.MethodInvoker getCombinedId = Reflection.getTypedMethod(block, null, int.class, iBlockData);
private static final Reflection.MethodInvoker getNMS = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.CraftBlock"), "getNMS", iBlockData);
private static final Reflection.Method getCombinedId = Reflection.getTypedMethod(block, null, int.class, iBlockData);
private static final Reflection.Method getNMS = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock"), "getNMS", iBlockData);
@Override
public int blockToId(Block block) {
return (int) getCombinedId.invoke(null, getNMS.invoke(block));
}
private static final Reflection.MethodInvoker getByCombinedId = Reflection.getTypedMethod(block, null, iBlockData, int.class);
private static final Reflection.ConstructorInvoker newBlockPosition = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
private static final Reflection.MethodInvoker getTypeAndData = Reflection.getMethod(worldServer, null, blockPosition, iBlockData, int.class);
private static final Reflection.MethodInvoker removeTileEntity = Reflection.getMethod(worldServer, Core.getVersion() > 15 ? "m" : "removeTileEntity", blockPosition);
private static final Reflection.MethodInvoker flagDirty = Reflection.getMethod(chunkProviderServer, null, blockPosition);
private static final Reflection.Method getByCombinedId = Reflection.getTypedMethod(block, null, iBlockData, int.class);
private static final Reflection.Constructor newBlockPosition = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
private static final Reflection.Method getTypeAndData = Reflection.getMethod(worldServer, null, blockPosition, iBlockData, int.class);
private static final Reflection.Method removeTileEntity = Reflection.getMethod(worldServer, Core.getVersion() > 15 ? "m" : "removeTileEntity", blockPosition);
private static final Reflection.Method flagDirty = Reflection.getMethod(chunkProviderServer, null, blockPosition);
@Override
public void setBlock(World world, int x, int y, int z, int blockState) {
Object blockData = getByCombinedId.invoke(null, blockState);
@ -69,25 +70,25 @@ public class BlockIdWrapper14 implements BlockIdWrapper {
flagDirty.invoke(getChunkProvider.invoke(nworld), pos);
}
private static final Class<?> entityTracker = Reflection.getClass("{nms.server.level}.PlayerChunkMap$EntityTracker");
private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "b" : "updatePlayer", entityPlayer);
private static final Class<?> entityTracker = Reflection.getClass("net.minecraft.server.level.ChunkMap$TrackedEntity");
private static final Reflection.Method updatePlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "b" : "updatePlayer", entityPlayer);
@Override
public void trackEntity(Player player, int entity) {
Object tracker = trackers.get(entity);
public void trackEntity(Player player, Entity entity) {
Object tracker = trackers.get(entity.getEntityId());
if(tracker != null)
updatePlayer.invoke(tracker, getPlayer.invoke(player));
}
private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "a" : "clear", entityPlayer);
private static final Reflection.Method clearPlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "a" : "clear", entityPlayer);
@Override
public void untrackEntity(Player player, int entity) {
Object tracker = trackers.get(entity);
public void untrackEntity(Player player, Entity entity) {
Object tracker = trackers.get(entity.getEntityId());
if(tracker != null)
clearPlayer.invoke(tracker, getPlayer.invoke(player));
}
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(Reflection.getClass("{obc}.util.CraftMagicNumbers"), "getMaterial", Material.class, block);
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
private static final Reflection.Method getMaterialByBlock = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.util.CraftMagicNumbers"), "getMaterial", Material.class, block);
private static final Reflection.Method getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
@Override
public Material idToMaterial(int blockState) {
return (Material)getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(getByCombinedId.invoke(null, blockState)));

View File

@ -42,6 +42,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.sql.NodeData;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import org.bukkit.DyeColor;
@ -144,6 +145,6 @@ public class WorldeditWrapper14 implements WorldeditWrapper {
throw new SecurityException(e);
}
new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), true);
new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), NodeData.SchematicFormat.SPONGE_V2);
}
}

View File

@ -24,11 +24,13 @@ plugins {
dependencies {
compileOnly(project(":SpigotCore", "default"))
compileOnly(project(":FightSystem:FightSystem_Core", "default"))
compileOnly(project(":FightSystem:FightSystem_14", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.nms18)
compileOnly(libs.fawe18)
compileOnly(libs.authlib)
compileOnly(libs.fastutil)
}

View File

@ -0,0 +1,47 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.mojang.authlib.GameProfile;
import de.steamwar.core.ProtocolWrapper;
import de.steamwar.fightsystem.FightSystem;
import org.bukkit.GameMode;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public class BlockIdWrapper18 extends BlockIdWrapper14 {
@Override
public void trackEntity(Player player, Entity entity) {
if(entity instanceof Player)
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.REMOVE, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE));
player.showEntity(FightSystem.getPlugin(), entity);
}
@Override
public void untrackEntity(Player player, Entity entity) {
player.hideEntity(FightSystem.getPlugin(), entity);
if(entity instanceof Player)
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.ADD, new GameProfile(entity.getUniqueId(), entity.getName()), GameMode.CREATIVE));
}
}

View File

@ -19,7 +19,7 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.Config;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.level.chunk.Chunk;
@ -33,9 +33,9 @@ import java.util.stream.StreamSupport;
public class CraftbukkitWrapper18 implements CraftbukkitWrapper {
private static final Reflection.MethodInvoker getWorld = Reflection.getMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle");
private static final Reflection.MethodInvoker getChunk = Reflection.getTypedMethod(net.minecraft.world.level.World.class, null, Chunk.class, int.class, int.class);
private static final Reflection.MethodInvoker getChunkSections = Reflection.getTypedMethod(Chunk.class, null, ChunkSection[].class);
private static final Reflection.Method getWorld = Reflection.getMethod(Reflection.getClass("org.bukkit.craftbukkit.CraftWorld"), "getHandle");
private static final Reflection.Method getChunk = Reflection.getTypedMethod(net.minecraft.world.level.World.class, null, Chunk.class, int.class, int.class);
private static final Reflection.Method getChunkSections = Reflection.getTypedMethod(Chunk.class, null, ChunkSection[].class);
private ChunkSection[] getChunkSections(World world, int x, int z) {
return (ChunkSection[]) getChunkSections.invoke(getChunk.invoke(getWorld.invoke(world), x, z));
}
@ -46,7 +46,7 @@ public class CraftbukkitWrapper18 implements CraftbukkitWrapper {
System.arraycopy(getChunkSections(backup, x, z), 0, sections, 0, sections.length);
}
private static final Reflection.MethodInvoker getEntity = Reflection.getTypedMethod(Reflection.getClass("{obc}.entity.CraftEntity"), "getHandle", net.minecraft.world.entity.Entity.class);
private static final Reflection.Method getEntity = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.entity.CraftEntity"), "getHandle", net.minecraft.world.entity.Entity.class);
protected net.minecraft.world.entity.Entity getEntity(Entity e) {
return (net.minecraft.world.entity.Entity) getEntity.invoke(e);
}
@ -56,8 +56,8 @@ public class CraftbukkitWrapper18 implements CraftbukkitWrapper {
return getEntity(e).ce();
}
private static final Reflection.MethodInvoker getWorldEntities = Reflection.getTypedMethod(WorldServer.class, null, LevelEntityGetter.class);
private static final Reflection.MethodInvoker getIterable = Reflection.getTypedMethod(LevelEntityGetter.class, null, Iterable.class);
private static final Reflection.Method getWorldEntities = Reflection.getTypedMethod(WorldServer.class, null, LevelEntityGetter.class);
private static final Reflection.Method getIterable = Reflection.getTypedMethod(LevelEntityGetter.class, null, Iterable.class);
@Override
public Stream<?> entityIterator() {
return StreamSupport.stream(((Iterable<?>) getIterable.invoke(getWorldEntities.invoke(getWorld.invoke(Config.world)))).spliterator(), false);

View File

@ -19,7 +19,7 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.Config;
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
import net.minecraft.core.BlockPosition;
@ -27,31 +27,22 @@ import net.minecraft.core.SectionPosition;
import net.minecraft.network.protocol.game.PacketPlayOutBlockChange;
import net.minecraft.network.protocol.game.PacketPlayOutMultiBlockChange;
import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.List;
public class HullHiderWrapper18 implements HullHiderWrapper {
private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", IBlockData.class);
private static final Reflection.Method getState = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.block.data.CraftBlockData"), "getState", IBlockData.class);
@Override
public Object generateBlockChangePacket(List<Hull.IntVector> changes) {
List<Object> blockdata = new ArrayList<>(changes.size());
Object[] blockdata = new Object[changes.size()];
for(int i = 0; i < blockdata.length; i++) {
Hull.IntVector change = changes.get(i);
blockdata[i] = getState.invoke(Config.world.getBlockData(change.getX(), change.getY(), change.getZ()));
}
changes.removeIf(change -> {
BlockData data = Config.world.getBlockData(change.getX(), change.getY(), change.getZ());
boolean unchanged = data.getMaterial() == Config.ObfuscateWith || Config.HiddenBlocks.contains(data.getMaterial());
if(!unchanged)
blockdata.add(getState.invoke(data));
return unchanged;
});
if(changes.isEmpty())
return null;
return generateBlockChangePacket(changes, blockdata.toArray());
return generateBlockChangePacket(changes, blockdata);
}
private Object generateBlockChangePacket(List<Hull.IntVector> changes, Object[] blockdata) {

View File

@ -19,19 +19,20 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.Config;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public class BlockIdWrapper8 implements BlockIdWrapper {
private static final Class<?> entityTracker = Reflection.getClass("{nms}.EntityTracker");
private static final Reflection.FieldAccessor<?> getEntityTracker = Reflection.getField(worldServer, entityTracker, 0);
private static final Class<?> intHashMap = Reflection.getClass("{nms}.IntHashMap");
private static final Reflection.FieldAccessor<?> getTrackedEntities = Reflection.getField(entityTracker, intHashMap, 0);
private static final Class<?> entityTracker = Reflection.getClass("net.minecraft.EntityTracker");
private static final Reflection.Field<?> getEntityTracker = Reflection.getField(worldServer, entityTracker, 0);
private static final Class<?> intHashMap = Reflection.getClass("net.minecraft.IntHashMap");
private static final Reflection.Field<?> getTrackedEntities = Reflection.getField(entityTracker, intHashMap, 0);
private final Object trackers;
public BlockIdWrapper8() {
@ -53,20 +54,20 @@ public class BlockIdWrapper8 implements BlockIdWrapper {
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
}
private static final Class<?> entityTrackerEntry = Reflection.getClass("{nms}.EntityTrackerEntry");
private static final Reflection.MethodInvoker get = Reflection.getTypedMethod(intHashMap, "get", Object.class, int.class);
private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTrackerEntry, "updatePlayer", entityPlayer);
private static final Class<?> entityTrackerEntry = Reflection.getClass("net.minecraft.EntityTrackerEntry");
private static final Reflection.Method get = Reflection.getTypedMethod(intHashMap, "get", Object.class, int.class);
private static final Reflection.Method updatePlayer = Reflection.getMethod(entityTrackerEntry, "updatePlayer", entityPlayer);
@Override
public void trackEntity(Player player, int entity) {
Object tracker = get.invoke(trackers, entity);
public void trackEntity(Player player, Entity entity) {
Object tracker = get.invoke(trackers, entity.getEntityId());
if(tracker != null)
updatePlayer.invoke(tracker, getPlayer.invoke(player));
}
private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTrackerEntry, "a", entityPlayer);
private static final Reflection.Method clearPlayer = Reflection.getMethod(entityTrackerEntry, "a", entityPlayer);
@Override
public void untrackEntity(Player player, int entity) {
Object tracker = get.invoke(trackers, entity);
public void untrackEntity(Player player, Entity entity) {
Object tracker = get.invoke(trackers, entity.getEntityId());
if(tracker != null)
clearPlayer.invoke(tracker, getPlayer.invoke(player));
}

View File

@ -19,26 +19,17 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.Config;
import org.bukkit.Material;
import java.util.List;
public class HullHiderWrapper8 implements HullHiderWrapper {
private static final Reflection.ConstructorInvoker newMultiBlockChange = Reflection.getConstructor("{nms}.PacketPlayOutMultiBlockChange", int.class, short[].class, Reflection.getClass("{nms}.Chunk"));
private static final Reflection.MethodInvoker getHandle = Reflection.getMethod("{obc}.CraftChunk", "getHandle");
private static final Reflection.Constructor newMultiBlockChange = Reflection.getConstructor("net.minecraft.PacketPlayOutMultiBlockChange", int.class, short[].class, Reflection.getClass("net.minecraft.Chunk"));
private static final Reflection.Method getHandle = Reflection.getMethod("org.bukkit.craftbukkit.CraftChunk", "getHandle");
@Override
public Object generateBlockChangePacket(List<Hull.IntVector> changes) {
changes.removeIf(change -> {
Material material = Config.world.getBlockAt(change.getX(), change.getY(), change.getZ()).getType();
return material == Config.ObfuscateWith || Config.HiddenBlocks.contains(material);
});
if(changes.isEmpty())
return null;
Hull.IntVector chunk = changes.get(0);
chunk = new Hull.IntVector(chunk.getX() >> 4, chunk.getY() >> 4, chunk.getZ() >> 4);
int xOffset = 16*chunk.getX();

View File

@ -39,6 +39,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.world.World;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.sql.NodeData;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import org.bukkit.DyeColor;
@ -142,6 +143,6 @@ public class WorldeditWrapper8 implements WorldeditWrapper {
throw new SecurityException(e);
}
new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), false);
new SchematicData(schem).saveFromBytes(outputStream.toByteArray(), NodeData.SchematicFormat.MCEDIT);
}
}

View File

@ -19,7 +19,7 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.listener.Recording;
@ -43,9 +43,9 @@ import java.util.Map;
public class BountifulWrapper9 implements BountifulWrapper {
private static final Class<?> enumHand = Reflection.getClass("{nms.world}.EnumHand");
private static final Class<?> enumHand = Reflection.getClass("net.minecraft.world.InteractionHand");
private static final Object mainHand = enumHand.getEnumConstants()[0];
private static final Reflection.FieldAccessor<?> blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0);
private static final Reflection.Field<?> blockPlaceHand = Reflection.getField(Recording.blockPlacePacket, enumHand, 0);
@Override
public boolean mainHand(Object packet) {

View File

@ -29,4 +29,5 @@ dependencies {
compileOnly(libs.worldedit15)
compileOnly(libs.fastutil)
compileOnly(libs.authlib)
compileOnly(libs.netty)
}

View File

@ -344,7 +344,7 @@ public class Config {
EventTeamBlueID = team1.getTeamId();
EventTeamRedID = team2.getTeamId();
BothTeamsPublic = EventTeamRedID == 0 && EventTeamBlueID == 0;
SpectatePort = EventKampf.getSpectatePort();
SpectatePort = EventKampf.getSpectatePort() == null ? 0 : EventKampf.getSpectatePort();
LiveReplay = SpectatePort != 0;
Referees = Referee.get(Config.EventKampf.getEventID());

View File

@ -97,6 +97,7 @@ public class FightSystem extends JavaPlugin {
new PrepareSchem();
new TestJoin();
new NormalJoin();
new Spectator();
new RunningWorldInteraction();
new PersonalKitCreator();
new ArrowStopper();
@ -153,10 +154,10 @@ public class FightSystem extends JavaPlugin {
new GamemodeCommand();
new ReadyCommand();
new AkCommand();
new LeaderCommand();
new LockschemCommand();
new StateCommand();
new SkipCommand();
new TechhiderbugCommand();
new TPSWarpCommand();
new UnrankCommand();
new WinCommand();

View File

@ -34,9 +34,6 @@ GAMEMODE_NOT_ALLOWED=§cChanging gamemode is not permitted
GAMEMODE_UNKNOWN=§cUnknown gamemode {0}
GAMEMODE_HELP=§8/§7gm §8[§egamemode§8]
LEADER_FULL=§cAll teams already have a leader
ALREADY_IN_TEAM=§cYou are already in a team
LOCKSCHEM_HELP=§8/§7lockschem §8[§eteam§8]
UNKNOWN_TEAM=§cThis team does not exist
LOCKSCHEM_LOCKED=§7Schematic locked
@ -65,7 +62,9 @@ STATE_RUNNING=§eFighting phase
STATE_SPECTATE_WIN=§7Victory {0}
STATE_SPECTATE_TIE=§7Draw
REMOVE_TITLE=Kick player
MANAGE_TITLE=Manage players
MANAGE_LORE1=§eLeft §7click§8: §ekick
MANAGE_LORE2=§eRight §7click§8: §epromote
KIT_SELECTION_TITLE=Kit selection
KIT_NO_KITS=§cNo kits found
@ -113,7 +112,7 @@ SKIP_NOT_READY=§c§mSkipping to next event
TEAM_CHAT={0}{1}§8» {0}{2}
CHOOSE_KIT=§eChoose kit
RESPAWN=§eRespawn
REMOVE_PLAYERS=§cKick player
MANAGE_PLAYERS=§cManage players
CHOOSE_SCHEMATIC=§eChoose {0}
SCHEMATIC_REQUIRED=§cChoose a schematic first
ADD_AI=§eAdd AI
@ -141,7 +140,6 @@ NO_TELEPORT=§cYou are not allowed to use this teleport function
OPEN_INVENTORY_TO_CUSTOMIZE=§eOpen inventory to customize your kit
NO_ENTERN=§cYou may not board
NO_TEAMAREA=§cYou are not allowed in the team area
TEST_BECOME_LEADER=§7Become a team leader with §8/§eleader
PREPARE_SCHEM_DELETED=§cApparently the schematic to be submitted was deleted. submission aborted.
PREPARE_SCHEM_EXISTS=§cThere is already a schematic with the suffix -prepared, please rename or delete it, submission aborted.
PREPARE_ACTIVE_PISTON=§cMoving pistons were found in the team area, submission aborted.

View File

@ -32,9 +32,6 @@ GAMEMODE_NOT_ALLOWED=§cSpielmodusänderung verboten
GAMEMODE_UNKNOWN=§cUnbekannter Spielmodus {0}
GAMEMODE_HELP=§8/§7gm §8[§eSpielmodus§8]
LEADER_FULL=§cAlle Teams haben bereits einen Leader
ALREADY_IN_TEAM=§cDu bist bereits in einem Team
LOCKSCHEM_HELP=§8/§7lockschem §8[§eTeam§8]
UNKNOWN_TEAM=§cDieses Team existiert nicht
LOCKSCHEM_LOCKED=§7Schematic gesperrt
@ -59,7 +56,9 @@ STATE_RUNNING=§eKampfphase
STATE_SPECTATE_WIN=§7Sieg {0}
STATE_SPECTATE_TIE=§7Unentschieden
REMOVE_TITLE=Spieler rauswerfen
MANAGE_TITLE=Mitspieler verwalten
MANAGE_LORE1=§eLinksklick§8: §eRauswurf
MANAGE_LORE2=§eRechtsklick§8: §eBefördern
KIT_SELECTION_TITLE=Kitauswahl
KIT_NO_KITS=§cKeine Kits gefunden
@ -106,7 +105,7 @@ SKIP_READY=§aBeschleunigung zum nächsten Event
SKIP_NOT_READY=§c§mBeschleunigung zum nächsten Event
CHOOSE_KIT=§eKit wählen
RESPAWN=§eRespawn
REMOVE_PLAYERS=§cSpieler rauswerfen
MANAGE_PLAYERS=§cMitspieler verwalten
CHOOSE_SCHEMATIC=§e{0} wählen
SCHEMATIC_REQUIRED=§cZuerst muss eine Schematic gewählt sein
ADD_AI=§eKI hinzufügen
@ -134,7 +133,6 @@ NO_TELEPORT=§cDu darfst diese Teleportfunktion nicht benutzen
OPEN_INVENTORY_TO_CUSTOMIZE=§eInventar zum Anpassen des Kits öffnen
NO_ENTERN=§cDu darfst nicht entern
NO_TEAMAREA=§cDu darfst nicht zu den Teams
TEST_BECOME_LEADER=§7Werde zum Teamleader mit §8/§eleader
PREPARE_SCHEM_DELETED=§cAnscheinend wurde die auszufahrende Schematic gelöscht, Einsenden wird abgebrochen.
PREPARE_SCHEM_EXISTS=§cEs existiert bereits eine Schem mit Namenszusatz -prepared, diese bitte umbenennen oder löschen, Einsenden wird abgebrochen.
PREPARE_ACTIVE_PISTON=§cIm Teambereich wurden sich noch bewegende Pistons gefunden, Einsenden wird abgebrochen.

View File

@ -19,7 +19,7 @@
package de.steamwar.fightsystem.ai;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.FightTeam;

View File

@ -19,7 +19,7 @@
package de.steamwar.fightsystem.commands;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.Reflection;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
@ -39,7 +39,7 @@ import org.bukkit.entity.Player;
@UtilityClass
public class Commands {
private static final Reflection.FieldAccessor<SimpleCommandMap> commandMap = Reflection.getField("{obc}.CraftServer", "commandMap", SimpleCommandMap.class);
private static final Reflection.Field<SimpleCommandMap> commandMap = Reflection.getField("org.bukkit.craftbukkit.CraftServer", "commandMap", SimpleCommandMap.class);
public static void injectCommand(Command cmd) {
commandMap.get(Bukkit.getServer()).register("FightSystem", cmd);
}

View File

@ -36,6 +36,7 @@ import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@ -53,6 +54,10 @@ public class GUI {
String name = team.getLeader() != null ? team.getLeader().getEntity().getName() : team.getName();
inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColor() + name), click -> {
p.closeInventory();
if(ArenaMode.ManualTeams.contains(Config.mode) && team.canbeLeader(p))
team.addMember(p);
else
JoinRequest.forPlayer(p, team);
});
}
@ -117,14 +122,21 @@ public class GUI {
inv.open();
}
public static void chooseRemove(Player p){
public static void managePlayers(Player p){
List<SWListInv.SWListEntry<UUID>> players = SWListInv.createPlayerList(p.getUniqueId());
FightTeam team = Fight.getPlayerTeam(p);
if(team == null)
return;
players.removeIf(swItemUUIDPair -> !team.equals(Fight.getPlayerTeam(Bukkit.getPlayer(swItemUUIDPair.getObject()))));
SWListInv<UUID> inv = new SWListInv<>(p, msg.parse("REMOVE_TITLE", p), players, (ClickType click, UUID player) -> {
players.removeIf(listEntry -> !team.equals(Fight.getPlayerTeam(Bukkit.getPlayer(listEntry.getObject()))));
players.forEach(listEntry -> listEntry.getItem().setLore(msg.parse("MANAGE_LORE1", p), msg.parse("MANAGE_LORE2", p)));
SWListInv<UUID> inv = new SWListInv<>(p, msg.parse("MANAGE_TITLE", p), players, (ClickType click, UUID player) -> {
if(click.isLeftClick()) {
Commands.kick(p, SteamwarUser.get(player).getUserName());
} else if(click.isRightClick()) {
LivingEntity target = (LivingEntity) Bukkit.getEntity(player);
if(target != null)
team.setLeader(team.getFightPlayer(target), false);
}
p.closeInventory();
});
inv.setCallback(-999, (ClickType click) -> p.closeInventory());

View File

@ -1,60 +0,0 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class LeaderCommand implements CommandExecutor {
public LeaderCommand() {
new StateDependentCommand(ArenaMode.ManualTeams, FightState.Setup, "leader", this);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(!(sender instanceof Player))
return false;
Player player = (Player) sender;
if(Fight.getFightPlayer(player) != null) {
FightSystem.getMessage().sendPrefixless("ALREADY_IN_TEAM", player, ChatMessageType.ACTION_BAR);
return false;
}
for(FightTeam team : Fight.teams()) {
if(team.canbeLeader(player)) {
team.addMember(player);
return false;
}
}
FightSystem.getMessage().sendPrefixless("LEADER_FULL", player, ChatMessageType.ACTION_BAR);
return false;
}
}

Some files were not shown because too many files have changed in this diff Show More