diff --git a/BauSystem_15/build.gradle b/BauSystem_15/build.gradle index 87ae1928..d0acd9b2 100644 --- a/BauSystem_15/build.gradle +++ b/BauSystem_15/build.gradle @@ -27,8 +27,8 @@ version '1.0' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 17 +targetCompatibility = 17 sourceSets { main { diff --git a/BauSystem_15/src/de/steamwar/bausystem/utils/TickListener15.java b/BauSystem_15/src/de/steamwar/bausystem/utils/TickListener15.java new file mode 100644 index 00000000..f2b604ac --- /dev/null +++ b/BauSystem_15/src/de/steamwar/bausystem/utils/TickListener15.java @@ -0,0 +1,23 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.utils; + +public class TickListener15 implements TickListener { +} diff --git a/BauSystem_18/build.gradle b/BauSystem_18/build.gradle index 8deb57fd..4ac724e0 100644 --- a/BauSystem_18/build.gradle +++ b/BauSystem_18/build.gradle @@ -27,8 +27,8 @@ version '1.0' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 17 +targetCompatibility = 17 sourceSets { main { diff --git a/BauSystem_19/build.gradle b/BauSystem_19/build.gradle index fb86e3ac..7973f1b0 100644 --- a/BauSystem_19/build.gradle +++ b/BauSystem_19/build.gradle @@ -27,8 +27,8 @@ version '1.0' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 17 +targetCompatibility = 17 sourceSets { main { @@ -51,6 +51,7 @@ dependencies { implementation project(":BauSystem_Main") compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT' + compileOnly 'io.papermc.paper:paper-api:1.19.2-R0.1-SNAPSHOT' compileOnly 'it.unimi.dsi:fastutil:8.5.6' compileOnly 'com.mojang:datafixerupper:4.0.26' compileOnly 'io.netty:netty-all:4.1.68.Final' diff --git a/BauSystem_19/src/de/steamwar/bausystem/utils/TickListener19.java b/BauSystem_19/src/de/steamwar/bausystem/utils/TickListener19.java new file mode 100644 index 00000000..5191b38b --- /dev/null +++ b/BauSystem_19/src/de/steamwar/bausystem/utils/TickListener19.java @@ -0,0 +1,51 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.utils; + +import com.destroystokyo.paper.event.server.ServerTickEndEvent; +import com.destroystokyo.paper.event.server.ServerTickStartEvent; +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class TickListener19 implements TickListener, Listener { + + private boolean tickStartRan = false; + + public TickListener19() { + Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance()); + } + + @EventHandler + public void onServerTickStart(ServerTickStartEvent event) { + if (TPSFreezeUtils.isFrozen()) return; + Bukkit.getPluginManager().callEvent(new TickStartEvent()); + tickStartRan = true; + } + + @EventHandler + public void onServerTickEnd(ServerTickEndEvent event) { + if (!tickStartRan) return; + Bukkit.getPluginManager().callEvent(new TickEndEvent()); + tickStartRan = false; + } +} diff --git a/BauSystem_20/build.gradle b/BauSystem_20/build.gradle index bfb7c724..17121b8d 100644 --- a/BauSystem_20/build.gradle +++ b/BauSystem_20/build.gradle @@ -27,8 +27,8 @@ version '1.0' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 17 +targetCompatibility = 17 sourceSets { main { diff --git a/BauSystem_Linkage/build.gradle b/BauSystem_Linkage/build.gradle index 2169557f..7b54641a 100644 --- a/BauSystem_Linkage/build.gradle +++ b/BauSystem_Linkage/build.gradle @@ -27,8 +27,8 @@ version '1.0' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 17 +targetCompatibility = 17 sourceSets { main { diff --git a/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java b/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java index 01e29833..ffd6382f 100644 --- a/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java +++ b/BauSystem_Linkage/src/de/steamwar/linkage/types/ScoreboardElement_GENERIC.java @@ -35,6 +35,6 @@ public class ScoreboardElement_GENERIC implements LinkageType { @Override public void generateCode(BuildPlan buildPlan, MethodBuilder methodBuilder, String s, TypeElement typeElement) { buildPlan.addImport("de.steamwar.bausystem.features.world.BauScoreboard"); - methodBuilder.addLine("BauScoreboard.ELEMENTS.add(" + s + ");"); + methodBuilder.addLine("BauScoreboard.addElement(" + s + ");"); } } diff --git a/BauSystem_Main/build.gradle b/BauSystem_Main/build.gradle index 62d604cf..38432993 100644 --- a/BauSystem_Main/build.gradle +++ b/BauSystem_Main/build.gradle @@ -27,8 +27,8 @@ version '1.0' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +sourceCompatibility = 17 +targetCompatibility = 17 sourceSets { main { diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties index 20b50b0b..98f1ea7a 100644 --- a/BauSystem_Main/src/BauSystem.properties +++ b/BauSystem_Main/src/BauSystem.properties @@ -27,6 +27,10 @@ PAGE_LIST=§e Page ({0}/{1}) »» LIST_PREVIOUS_PAGE=§ePrevious page LIST_NEXT_PAGE=§eNext page +# Permissions +NO_PERMISSION = You are not allowed to use that here +SPECTATOR = §fSpectator + # Scoreboard SCOREBOARD_TIME = Time SCOREBOARD_REGION = Region @@ -40,6 +44,11 @@ SCOREBOARD_TRACE_TICKS = Ticks SCOREBOARD_TECHHIDER = TechHider§8: §aOn SCOREBOARD_XRAY = XRay§8: §aOn +SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam +SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server) Team +SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServer Team +SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNobody + # Flags FLAG_COLOR = Color FLAG_TNT = TNT @@ -116,7 +125,6 @@ BACKUP_HELP_LOAD=§8/§ebackup load §8[§7BackupName§8] §8- §7Load a region BACKUP_HELP_LIST=§8/§ebackup list §8- §7List all region backups BACKUP_HELP_GUI=§8/§ebackup gui §8- §7Open the backup GUI BACKUP_REGION_NO_REGION=§cYou are not inside any region -BACKUP_NO_PERMS=§You do not have permission to use the backup system BACKUP_CREATE_SUCCESS=§7Backup created BACKUP_CREATE_FAILURE=§cBackup failed BACKUP_CREATE_NO_CHANGE=§7No changes to save @@ -130,11 +138,6 @@ BACKUP_LORE=§eClick to load # Bau BAU_COMMAND_HELP_INFO = §8/§ebau info §8- §7Alias for §8/§ebauinfo -BAU_COMMAND_HELP_TOGGLEWE = §8/§ebau togglewe §8[§7Player§8] §8- §7Edit the WorldEdit permissions of a player -BAU_COMMAND_HELP_TOGGLEWORLD = §8/§ebau toggleworld §8[§7Player§8] §8- §7Edit the World permissions of a player -BAU_UNKNOWN_PLAYER = §cUnknown Player -BAU_NO_PLAYER = §cThe player is no member of your world! -BAU_NO_WORLD = §cThis is not your world! BAU_INFO_ITEM_NAME = §eBau-Management ## This is used in BauInfoBauGuiItem.java @@ -147,12 +150,7 @@ BAU_INFO_ITEM_LORE_ITEMS = §7Items§8: §e{0} BAU_INFO_COMMAND_HELP = §8/§ebauinfo §8- §7Information regarding this build server BAU_INFO_COMMAND_OWNER = §7Owner§8: §e{0} -BAU_INFO_COMMAND_MEMBER = §7Member §8[§7{0}§8]§8: §e -BAU_INFO_MEMBER_INFO = §e{0}§8[{1}§8,{2}§8] §8 -BAU_INFO_MEMBER_WE_ALLOW = §aWE -BAU_INFO_MEMBER_WE_DISALLOW = §cWE -BAU_INFO_MEMBER_WORLD_ALLOW = §aW -BAU_INFO_MEMBER_WORLD_DISALLOW = §cW +BAU_INFO_COMMAND_MEMBER = §7{0} §8[§7{1}§8]§8: §e{2} BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1} BAU_INFO_COMMAND_TPS = §7TPS§8:§e @@ -211,11 +209,6 @@ HOTBAR_INVENTORY=Standard hotbar # GUI GUI_EDITOR_ITEM_NAME=§eGui editor GUI_NAME=Bau GUI -GUI_NO_PERMISSION=§cYou do not have enough permissions for this -GUI_NO_OWNER=§cYou are not the owner of this World -GUI_NO_WORLD=§cYou do not have permissions to change the World -GUI_NO_WORLDEDIT=§cYou do not have permissions to use WorldEdit -GUI_NO_MEMBER=§cYou need to be a member of this World GUI_ITEM_LORE1=§7Use this item to open the bau gui GUI_ITEM_LORE2=§7or press swap hands twice. GUI_EDITOR_TITLE=Bau GUI Editor @@ -266,7 +259,6 @@ SHIELD_PRINTING_HELP_STEP_7 = §87. §7Apply the shield printing with §8/§eshi SHIELD_PRINTING_NO_REGION = §cYou are not in a region. SHIELD_PRINTING_NOT_RUNNING = §cThe shield printing is not running. -SHIELD_PRINTING_DISALLOWED = §cYou are not allowed to use shield printing here. SHIELD_PRINTING_BOSSBAR = §fMovements: {0} SHIELD_PRINTING_BOSSBAR_COPIED = §fMovements: {0} Copied: {1} @@ -303,7 +295,6 @@ SIMULATOR_CHANGE_HELP = §8/§esimulator change §8-§7 Change your simulator wa SIMULATOR_DELETE_HELP = §8/§esimulator delete §8[§7name§8] §8-§7 Deletes the simulator SIMULATOR_START_HELP = §8/§esimulator start §8[§7name§8] §8-§7 Starts the simulator SIMULATOR_COPY_HELP = §8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Copy the simulator -SIMULATOR_NO_PERMS = §cYou are not allowed to use the simulator here SIMULATOR_GUI_ITEM_NAME = §eTNT Simulator @@ -313,6 +304,7 @@ SIMULATOR_GUI_CREATE_SIM = §eCreate simulator SIMULATOR_GUI_CREATE_SIM_GUI = Create simulator SIMULATOR_NAME_ALREADY_EXISTS = §cSimulator already exists SIMULATOR_NAME_INVALID = §cInvalid name +SIMULATOR_ERROR_COPY = §cCopy failed SIMULATOR_NOT_EXISTS = §cSimulator does not exist SIMULATOR_CREATE = §aSimulator created SIMULATOR_EDIT_LOCATION = §7Edit position @@ -328,7 +320,7 @@ SIMULATOR_WAND_LORE_1 = §eRight click §8- §7Adds a position SIMULATOR_WAND_LORE_2 = §eSneaking §8- §7Free movement SIMULATOR_WAND_LORE_3 = §eLeft click §8- §7Start the simulation SIMULATOR_WAND_LORE_4 = §eRight click in air §8- §7Opens the gui -SIMULATOR_WAND_LORE_5 = §eOffhand §8- §7Simulator preview +SIMULATOR_WAND_LORE_5 = §eDouble Sneak §8- §7Swap between TNT and Redstone Block SIMULATOR_REGION_FROZEN = §cSimulator cannot be used inside frozen regions @@ -481,7 +473,6 @@ TPSLIMIT_GUI_ITEM_NAME = §eTPS limiter TPSLIMIT_GUI_ITEM_LORE = §7Currently: §e{0} TPSLIMIT_ANVIL_GUI = New TPS limit TPSLIMIT_CURRENT = §7Current TPS limit§8: §e{0} -TPSLIMIT_NO_PERMS = §cYou are not allowed to use the TPS-Limiter here TPSLIMIT_SET = §eSet TPS limit to {0} TPSLIMIT_FROZEN = §eTPS frozen @@ -573,7 +564,6 @@ LOADER_PAUSED=§7The Loader is now paused. LOADER_SMALL_TIME=§cThe wait time is too small LOADER_NEW_TIME=§7The wait time is now: {0} LOADER_NEW_LOAD_TIME=§7The action wait time is now: {0} -LOADER_PERMS=§cYou are not allowed to use the Loader here LOADER_NOTHING_RECORDED=§cYou have not recorded anything yet! LOADER_GUI_TITLE=Loader GUI @@ -693,7 +683,6 @@ OTHER_CLEAR_HELP_PLAYER=§8/§eclear §8[§7Player§8] §8- §7Clears a player i OTHER_CLEAR_CLEARED=Your inventory was cleared. OTHER_CLEAR_FROM=Your invetnory was cleared by {0}. OTHER_CLEAR_TO=The inventory of {0} §7was cleared. -OTHER_CLEAR_NO_PERMS=§cYou are not allowed to clear other's inventory here. OTHER_DECLUTTER_HELP=§8/§edeclutter §8- §7Organise your inventory OTHER_DECLUTTER_DONE=§aYour inventory was organised. OTHER_GAMEMODE_UNKNOWN=§cUnknown gamemode. @@ -709,7 +698,6 @@ OTHER_TELEPORT_SELF_2=§cBlocks left to travel: 0; ETA: 0:00 OTHER_TELEPORT_SELF_3=§cA little Movement is important. OTHER_TELEPORT_SELF_4=§cFor such a distance? OTHER_TIME_HELP=§8/§etime §8<§7Time 0=Morining§8, §76000=Midday§8, §718000=Midnight§8> - §7Sets the time on the Build -OTHER_TIME_NO_PERM=§cYou are not allowed to change the time here OTHER_TIME_INVALID=§cPlease input a time between 0 and 24000 OTHER_TIME_RESULT=§7§oWhooosh OTHER_TPS_HEAD = §7TPS: 1s 10s 1m 5m 10m @@ -775,17 +763,6 @@ MATERIAL_FLAMMABLE=§8- §eFlammable block MATERIAL_BURNABLE=§8- §eBurnable block MATERIAL_WATERLOGGABLE=§8- §eWaterloggable block MATERIAL_UNMOVABLE=§8- §eUnmovable block -# Redstonetester -RT_HELP=§8/§eredstonetester §8-§7 Gives you the redstone tester -RT_GIVEN=§7Measure the time between activation of components -RT_ITEM_NAME=§eRedstonetester -RT_ITEM_LORE_1=§eLeftclick block §8-§7 Sets the 1. Position -RT_ITEM_LORE_2=§eRightclick block §8-§7 Sets the 2. Position -RT_ITEM_LORE_3=§eShift-rightclick in air §8-§7 Reset -RT_LOC=§8: §e{0} {1} {2} -RT_INVALID_LOC=§cUnknown Position -RT_RESULT=§7Difference§8: §e{0}§7 Ticks §8,§7 R-Ticks §e{1} -RT_ACTIVATE=§7Positions deleted§8. # Region Items REGION_ITEM_COLOR=§7Color: §e{0} REGION_ITEM_COLOR_CHOOSE=Choose color @@ -811,24 +788,18 @@ REGION_COLOR_HELP_COLOR=§8/§ecolor §8[§7Color§8] §8- §7Sets the color of REGION_COLOR_HELP_COLOR_TYPE=§8/§ecolor §8[§7Color§8] §8[§7Type§8] §8- §7Sets the color of the region or globally REGION_COLOR_GLOBAL=§7All regions color set to §e{0} REGION_COLOR_NO_REGION=§cYou are currently not in any region -REGION_COLOR_NO_PERMS=§cThis is not your world! REGION_FIRE_HELP=§8/§efire §8- §7Toggle fire damage -REGION_FIRE_NO_PERMS=§cYou are not allowed to toggle fire damage here REGION_FIRE_ENABLED=§cFire damage deactivated in this region REGION_FIRE_DISABLED=§aFire damage activated in this region REGION_FREEZE_HELP=§8/§efreeze §8- §7Toggle Freeze -REGION_FREEZE_NO_PERMS=§cYou are not allowed to freeze this world REGION_FREEZE_ENABLED=§cRegion frozen REGION_FREEZE_DISABLED=§aRegion thawed REGION_ITEMS_HELP=§8/§eitems §8- §7Toggle Items -REGION_ITEMS_NO_PERMS=§cYou are not allowed to toggle items in this world REGION_ITEMS_ENABLED=§aItems enabled in this region -REGION_ITEMS_DISABLED_GLOBAL=§cItems disabled in this world REGION_ITEMS_DISABLED=§cItems disabled in this region REGION_PROTECT_HELP=§8/§eprotect §8- §7Protect the region REGION_PROTECT_DISABLE=§cProtection disabled REGION_PROTECT_ENABLE=§aProtection enabled -REGION_PROTECT_NO_PERMS=§cYou are not allowed to protect the floor here REGION_PROTECT_FALSE_REGION=§cYou are not currently in a (M)WG-region REGION_REGION_HELP_UNDO=§8/§eregion undo §8- §7undo the last 20 /testblock or /reset REGION_REGION_HELP_REDO=§8/§eregion redo §8- §7redo the last 20 §8/§7rg undo @@ -836,8 +807,6 @@ REGION_REGION_HELP_RESTORE=§8/§eregion restore §8- §7Resets the region, with REGION_REGION_HELP_RESTORE_SCHEMATIC=§8/§eregion restore §8[§7Schematic§8] §8- §7Resets the region, withoout removing your builds REGION_REGION_HELP_COPYPOINT=§8/§eregion copypoint §8- §7Teleport to the regions copy point REGION_REGION_HELP_TESTBLOCKPOINT=§8/§eregion testblockpoint §8- §7Teleport to the regions dummy point -REGION_REGION_HELP_CHANGETYPE_INFO=§8/§eregion changetype §8- §7Returns the region type -REGION_REGION_HELP_CHANGETYPE=§8/§eregion changetype §8[§7Type§8] §8- §8Sets the region type REGION_REGION_HELP_CHANGESKIN_INFO=§8/§eregion changeskin §8- §7Returns the region skin REGION_REGION_HELP_CHANGESKIN=§8/§eregion changeskin §8[§7Skin§8] §8- §8Sets the region skin REGION_REGION_NOTHING_UNDO=§cNothing left to undo @@ -853,13 +822,6 @@ REGION_REGION_TP_COPY=§7Teleported to the copy point REGION_REGION_TP_TEST_BLOCK=§7Teleported to the tesblock REGION_REGION_TP_UNKNOWN=§cUndefined teleport point REGION_REGION_NO_REGION=§cYou are not inside any region -REGION_REGION_NO_PERMS=§cYou are not allowed to change the region -REGION_REGION_CHANGETYPE_INFO=§7RRegion type is §e{0} -REGION_REGION_CHANGETYPE_UNKNOWN=§cRegion type is invalid -REGION_REGION_CHANGETYPE_INVALID=§cRegion type is not allowed here -REGION_REGION_CHANGETYPE_CHANGE=§7Region type changed to §e{0} -REGION_REGION_CHANGETYPE_CHANGE_UPDATE=§7Click §e§lHERE §7to change the region type -REGION_REGION_CHANGETYPE_CHANGE_UPDATE_HOVER=§8/§ereset REGION_REGION_CHANGESKIN_INFO=§7Region skin is §e{0} REGION_REGION_CHANGESKIN_INFO_CREATOR=§7Skin created by §e{0} REGION_REGION_CHANGESKIN_UNKNOWN=§cRegion skin is invalid @@ -871,7 +833,6 @@ REGION_RESET_HELP_RESET=§8/§ereset §8- §7Resets the region REGION_RESET_HELP_SCHEMATIC=§8/§ereset §8[§7Schematic§8] §8- §7Resets the region using a schematic REGION_RESET_RESETED=§7Region reset REGION_RESET_ERROR=§cError reseting the region -REGION_RESET_NO_PERMS=§cYou are not allowed to reset the region here REGION_RESET_NO_REGION=§cYou are currently not in any region REGION_TB_HELP_RESET=§8/§etestblock §8- §7Reset the dummy REGION_TB_HELP_RESET_EXTENSION=§8/§etestblock §8[§7ExtensionType§8] §8- §7Reset the dummy @@ -879,7 +840,6 @@ REGION_TB_HELP_SCHEMATIC=§8/§etestblock §8[§7Schematic§8] §8- §7Reset the REGION_TB_HELP_SCHEMATIC_EXTENSION=§8/§etestblock §8[§7Schematic§8] §8[§7ExtensionType§8] §8- §7Reset the dummy using a schematic REGION_TB_DONE=§7Dummy reset REGION_TB_ERROR=§cError resetting the dummy -REGION_TB_NO_PERMS=§cYou are not allowed to reset the dummy here REGION_TB_NO_REGION=§cYou are currently not in any region REGION_TB_NO_SCHEMSHARING=§cYou currently cannot share schematics until {0}. REGION_TB_NO_SCHEMRECEIVING=§cThe Owner of this build server cannot receive any schematics until {0}. @@ -889,11 +849,10 @@ REGION_TNT_ON=§aTNT-Damage activated REGION_TNT_OFF=§cTNT-Damage deactivated REGION_TNT_TB=§aTNT-Damage activated outside the building area REGION_TNT_BUILD=§aTNT-Damage activated outside the testblok area -REGION_TNT_NO_PERMS=§cYou are not allowed to toggle tnt damage here REGION_TNT_BUILD_DESTROY=§cAn explosion would have destroyed blocks in the building area REGION_TNT_TB_DESTROY=§cAn explosion would have destroyed blocks in the testblock area -AFK_KICK_MESSAGE=§cNothing happened on this server for 5 minutes. +AFK_KICK_MESSAGE=§cNothing happened on this server for 15 minutes. AFK_WARNING_MESSAGE=§cThis server will stop in one minute if you remain inactive SKIN_HELP = §8/§eskin §8[§7Shortform§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Creates the skin schematic. Use 'public' as creator to have no creator, then copy the message to YoyoNow by clicking @@ -908,7 +867,6 @@ PANZERN_PREPARE1 = §71. Check, if barrels reach until border of armor. PANZERN_PREPARE2 = §72. Carpet on the floor in walkways helps with armoring. PANZERN_PREPARE3 = §73. Shieldtechnology should be encased. PANZERN_PREPARE4 = §74. Standing in the region that is being armored can improve armoring. -PANZERN_NO_PERM = §cYou are not allowed to use the armoring system here PANZERN_NO_WORLDEDIT = §cYou have no WorldEdit selcetion PANZERN_PROGRESS = §e{0} §7Blocks left, §e{1} §7Blocks per second, §e{2} §7block delta PANZERN_DONE = §aDone @@ -918,7 +876,6 @@ LAUFBAU_HELP = §8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7B LAUFBAU_HELP_SETTINGS = §8/§elaufbau settings §8- §7Opens the settings GUI LAUFBAU_PREPARE1 = §71. Trace the cannons as often as necessary, in all modes. LAUFBAU_PREPARE2 = §72. Try to delete all fails from the traces. -LAUFBAU_NO_PERM = §cYou are not allowed to use the barrel building system here LAUFBAU_NO_WORLDEDIT = §cYou don't have a WorldEdit selection LAUFBAU_STATE_FILTERING_TRACES = Filtering traces LAUFBAU_STATE_PROCESSING_TRACES = Connnecting traces @@ -1030,7 +987,6 @@ LAUFBAU_TILT_PARTIAL = §8-§7 Tilt partial # UTILS SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Select a region type SELECT_EXTENSION_HELP = §8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Select a region type with or without extension -SELECT_NO_PERMS = §cYou are not allowed to use the slection tool here SELECT_GLOBAL_REGION = §cThe global region cannot be selected SELECT_NO_TYPE = §cThis region has no {0} SELECT_NO_EXTENSION = §cThis region has no extension @@ -1084,7 +1040,6 @@ PISTON_HELP_3 = §7Count is yellow, if too many blocks are present. PISTON_INFO = §7Moved Blocks {0}{1}§8/§712 # Warp -WARP_DISALLOWED = §cYou are not allowed to use the warp here WARP_LOC_X = §7X§8: §e{0} WARP_LOC_Y = §7Y§8: §e{0} WARP_LOC_Z = §7Z§8: §e{0} @@ -1110,12 +1065,9 @@ WARP_HELP_LIST=§8/§ewarp list §8- §7List all warps # WORLD STOP_HELP = §8/§estop §8- §7Stops the server -STOP_NO_PERMS = §cYou do not have the permission to stop the server STOP_MESSAGE = §eServer is stopping -WORLD_EDIT_NO_PERMS = §cYou do not have the permission to use WorldEdit KICKALL_HELP = §8/§ekickall §8- §7Kick all players from the server except the owner -KICKALL_NO_PERM = §cThis is not your world! # Techhider TECHHIDER_HELP = §8/§etechhider §8- §7Toggle Techhider diff --git a/BauSystem_Main/src/BauSystem_de.properties b/BauSystem_Main/src/BauSystem_de.properties index af268de5..ca651035 100644 --- a/BauSystem_Main/src/BauSystem_de.properties +++ b/BauSystem_Main/src/BauSystem_de.properties @@ -27,6 +27,10 @@ PAGE_LIST=§e Seite ({0}/{1}) »» LIST_PREVIOUS_PAGE=§eVorherige Seite LIST_NEXT_PAGE=§eNächste Seite +# Permission +NO_PERMISSION = Du darfst dies hier nicht nutzen +SPECTATOR = §fZuschauer + # Scoreboard SCOREBOARD_TIME = Uhrzeit SCOREBOARD_REGION = Region @@ -40,6 +44,11 @@ SCOREBOARD_TRACE_TICKS = Ticks SCOREBOARD_TECHHIDER = TechHider§8: §aAn SCOREBOARD_XRAY = XRay§8: §aAn +SCOREBOARD_LOCK_TEAM = Bau Lock§8: §eTeam +SCOREBOARD_LOCK_TEAM_AND_SERVERTEAM = Bau Lock§8: §e(Server-) Team +SCOREBOARD_LOCK_SERVERTEAM = Bau Lock§8: §eServerteam +SCOREBOARD_LOCK_NOBODY = Bau Lock§8: §cNiemand + # Flags FLAG_COLOR = Color FLAG_TNT = TNT @@ -115,7 +124,6 @@ BACKUP_HELP_LOAD=§8/§ebackup load §8[§7BackupName§8] §8- §7 Lade ein Back BACKUP_HELP_LIST=§8/§ebackup list §8- §7Liste alle Backups der Region auf BACKUP_HELP_GUI=§8/§ebackup gui §8- §7Öffne die Backups in einer GUI BACKUP_REGION_NO_REGION=§cDu bist in keiner Region -BACKUP_NO_PERMS=§cDu darfst hier nicht das Backup System verwenden BACKUP_CREATE_SUCCESS=§7Das Backup wurde erstellt BACKUP_CREATE_FAILURE=§cDas Backup erstellen ist schiefgegangen BACKUP_CREATE_NO_CHANGE=§7Die Region hat keine Veränderung @@ -129,11 +137,6 @@ BACKUP_LORE=§eKlicken zum Laden # Bau BAU_COMMAND_HELP_INFO = §8/§ebau info §8- §7Alias für §8/§ebauinfo -BAU_COMMAND_HELP_TOGGLEWE = §8/§ebau togglewe §8[§7Player§8] §8- §7Editiere die WorldEdit Rechte eines Spielers -BAU_COMMAND_HELP_TOGGLEWORLD = §8/§ebau toggleworld §8[§7Player§8] §8- §7Editiere die Welt Rechte eines Spielers -BAU_UNKNOWN_PLAYER = §cUnbekannter Spieler -BAU_NO_PLAYER = §cDer Spieler ist kein Mitglied deiner Welt! -BAU_NO_WORLD = §cDies ist nicht deine Welt! BAU_INFO_ITEM_NAME = §eBau-Management ## This is used in BauInfoBauGuiItem.java @@ -146,12 +149,7 @@ BAU_INFO_ITEM_LORE_PROTECT = §7Protect§8: §e{0} BAU_INFO_COMMAND_HELP = §8/§ebauinfo §8- §7Gibt Informationen über den Bau BAU_INFO_COMMAND_OWNER = §7Besitzer§8: §e{0} -BAU_INFO_COMMAND_MEMBER = §7Mitglieder §8[§7{0}§8]§8: §e -BAU_INFO_MEMBER_INFO = §e{0}§8[{1}§8,{2}§8] §8 -BAU_INFO_MEMBER_WE_ALLOW = §aWE -BAU_INFO_MEMBER_WE_DISALLOW = §cWE -BAU_INFO_MEMBER_WORLD_ALLOW = §aW -BAU_INFO_MEMBER_WORLD_DISALLOW = §cW +BAU_INFO_COMMAND_MEMBER = §7{0} §8[§7{1}§8]§8: §e{2} BAU_INFO_COMMAND_FLAG = §7{0}§8: §7{1} BAU_INFO_COMMAND_TPS = §7TPS§8:§e @@ -210,11 +208,6 @@ HOTBAR_INVENTORY=Standard Hotbar # GUI GUI_EDITOR_ITEM_NAME=§eGui Editor GUI_NAME=Bau GUI -GUI_NO_PERMISSION=§cDu hast nicht genug Rechte um dies zu tun -GUI_NO_OWNER=§cDas ist nicht deine Bauwelt -GUI_NO_WORLD=§cDu darfst hier die Welt nicht einstellen -GUI_NO_WORLDEDIT=§cDu darfst hier kein Worldedit benutzen -GUI_NO_MEMBER=§cDu musst ein Member der Bauwelt sein GUI_ITEM_LORE1=§7Du kannst dieses Item zum Öffnen der BauGUI nutzen GUI_ITEM_LORE2=§7oder Doppel F (Swap hands) drücken. GUI_EDITOR_TITLE=Bau GUI Editor @@ -258,7 +251,6 @@ SHIELD_PRINTING_HELP_STEP_7 = §87. §7Wende das gedruckte mit §8/§eshieldprin SHIELD_PRINTING_NO_REGION = §cDu bist in keiner Region. SHIELD_PRINTING_NOT_RUNNING = §cShield printing ist nicht aktiv. -SHIELD_PRINTING_DISALLOWED = §cDu darfst Shield printing nicht benutzen. SHIELD_PRINTING_BOSSBAR = §fBewegungen: {0} SHIELD_PRINTING_BOSSBAR_COPIED = §fBewegungen: {0} Kopiert: {1} @@ -295,7 +287,6 @@ SIMULATOR_CHANGE_HELP = §8/§esimulator change §8-§7 Wechsel zu einem anderen SIMULATOR_DELETE_HELP = §8/§esimulator delete §8[§7name§8] §8-§7 Löscht den Simulator SIMULATOR_START_HELP = §8/§esimulator start §8[§7name§8] §8-§7 Startet die Simulation SIMULATOR_COPY_HELP = §8/§esimulator copy §8[§7to-copy§8] §8[§7name§8] §8-§7 Kopiert einen Simulator -SIMULATOR_NO_PERMS = §cDu darfst hier nicht den Simulator nutzen SIMULATOR_GUI_ITEM_NAME = §eTNT Simulator @@ -305,6 +296,7 @@ SIMULATOR_GUI_CREATE_SIM = §eSimulator erstellen SIMULATOR_GUI_CREATE_SIM_GUI = Simulator erstellen SIMULATOR_NAME_ALREADY_EXISTS = §cSimulator existiert bereits SIMULATOR_NAME_INVALID = §cUngültiger Name +SIMULATOR_ERROR_COPY = §cFehler beim kopieren SIMULATOR_NOT_EXISTS = §cSimulator existiert nicht SIMULATOR_CREATE = §aSimulator erstellt SIMULATOR_EDIT_LOCATION = §7Editiere Positionen @@ -320,7 +312,7 @@ SIMULATOR_WAND_LORE_1 = §eRechtsklick §8- §7Füge eine Position hinzu SIMULATOR_WAND_LORE_2 = §eSneaken §8- §7Freie Bewegung SIMULATOR_WAND_LORE_3 = §eLinksklick §8- §7Starte die Simulation SIMULATOR_WAND_LORE_4 = §eRechtsklick Luft §8- §7Öffne die GUI -SIMULATOR_WAND_LORE_5 = §eOffhand §8- §7Simulator Vorschau +SIMULATOR_WAND_LORE_5 = §eDoppel Shift §8- §7Wechsel zwischen TNT und Redstone Block SIMULATOR_REGION_FROZEN = §cSimulator kann nicht in eingefrorenen Regionen genutzt werden @@ -450,7 +442,6 @@ TPSLIMIT_GUI_ITEM_NAME = §eTPS Limiter TPSLIMIT_GUI_ITEM_LORE = §7Aktuell: §e{0} TPSLIMIT_ANVIL_GUI = Neues TPS Limit TPSLIMIT_CURRENT = §7Jetziges TPS limit§8: §e{0} -TPSLIMIT_NO_PERMS = §cDu darfst hier nicht den TPS-Limiter nutzen TPSLIMIT_SET = §eTPS limit auf {0} gesetzt. TPSLIMIT_FROZEN = §eTPS eingefroren. @@ -542,7 +533,6 @@ LOADER_PAUSED=§7Der Loader ist nun pausiert. LOADER_SMALL_TIME=§cDie Wartezeit ist zu klein LOADER_NEW_TIME=§7Die Schusswartezeit ist nun: {0} LOADER_NEW_LOAD_TIME=§7Die Setzwartezeit ist nun: {0} -LOADER_PERMS=§cDu darfst hier nicht den Detonator nutzen LOADER_NOTHING_RECORDED=§cEs wurden keine Elemente aufgenommen! LOADER_GUI_TITLE=Loader Einstellungen @@ -661,7 +651,6 @@ OTHER_CLEAR_HELP_PLAYER=§8/§eclear §8[§7Player§8] §8- §7Leere ein Spieler OTHER_CLEAR_CLEARED=Dein Inventar wurde geleert. OTHER_CLEAR_FROM=Dein Inventar wurde von {0} §7geleert. OTHER_CLEAR_TO=Das Inventar von {0} §7wurde geleert. -OTHER_CLEAR_NO_PERMS=§cDu darfst hier keine fremden Inventare leeren. OTHER_DECLUTTER_HELP=§8/§edeclutter §8- §7Räume dein Inventar auf OTHER_DECLUTTER_DONE=§aDein Inventar wurde aufgeräumt. OTHER_GAMEMODE_UNKNOWN=§cUnbekannter Spielmodus. @@ -677,7 +666,6 @@ OTHER_TELEPORT_SELF_2=§cNoch zu reisende Blöcke: 0; ETA: 0:00 OTHER_TELEPORT_SELF_3=§cEin wenig bewegung muss ein. OTHER_TELEPORT_SELF_4=§cFür eine solche Distanz? OTHER_TIME_HELP=§8/§etime §8<§7Zeit 0=Morgen§8, §76000=Mittag§8, §718000=Mitternacht§8> - §7Setzt die Zeit auf dem Bau -OTHER_TIME_NO_PERM=§cDu darfst hier nicht die Zeit ändern OTHER_TIME_INVALID=§cBitte gib eine Zahl zwischen 0 und 24000 an OTHER_TIME_RESULT=§7§oWhooosh OTHER_TPS_HEAD = §7TPS: 1s 10s 1m 5m 10m @@ -739,17 +727,6 @@ MATERIAL_INTERACTABLE=§8- §eInterargierbarer Block MATERIAL_FLAMMABLE=§8- §eFlammbarer Block MATERIAL_BURNABLE=§8- §eBrennbarer Block MATERIAL_WATERLOGGABLE=§8- §eWasserspeicherbarer Block -# Redstonetester -RT_HELP=§8/§eredstonetester §8-§7 Gibt den RedstoneTester -RT_GIVEN=§7Messe die Zeit zwischen der Aktivierung zweier Redstone Komponenten -RT_ITEM_NAME=§eRedstonetester -RT_ITEM_LORE_1=§eLinksklick Block §8-§7 Setzt die 1. Position -RT_ITEM_LORE_2=§eRechtsklick Block §8-§7 Setzt die 2. Position -RT_ITEM_LORE_3=§eShift-Rechtsklick Luft §8-§7 Zurücksetzten -RT_LOC=§8: §e{0} {1} {2} -RT_INVALID_LOC=§cUnbekannte Position -RT_RESULT=§7Differenz§8: §e{0}§7 Ticks §8,§7 R-Ticks §e{1} -RT_ACTIVATE=§7Positionen gelöscht§8. # Region Items REGION_ITEM_COLOR=§7Color: §e{0} REGION_ITEM_COLOR_CHOOSE=Farbe Wählen @@ -775,24 +752,18 @@ REGION_COLOR_HELP_COLOR=§8/§ecolor §8[§7Color§8] §8- §7Setze die Farbe de REGION_COLOR_HELP_COLOR_TYPE=§8/§ecolor §8[§7Color§8] §8[§7Type§8] §8- §7Setze die Farbe der Region oder Global REGION_COLOR_GLOBAL=§7Alle Regions farben auf §e{0}§7 gesetzt REGION_COLOR_NO_REGION=§cDu befindest dich derzeit in keiner Region -REGION_COLOR_NO_PERMS=§cDies ist nicht deine Welt! REGION_FIRE_HELP=§8/§efire §8- §7Toggle Feuerschaden -REGION_FIRE_NO_PERMS=§cDu darfst hier nicht Feuerschaden (de-)aktivieren REGION_FIRE_ENABLED=§cRegions Feuerschaden deaktiviert REGION_FIRE_DISABLED=§aRegions Feuerschaden aktiviert REGION_FREEZE_HELP=§8/§efreeze §8- §7Toggle Freeze -REGION_FREEZE_NO_PERMS=§cDu darfst diese Welt nicht einfrieren REGION_FREEZE_ENABLED=§cRegion eingefroren REGION_FREEZE_DISABLED=§aRegion aufgetaut REGION_ITEMS_HELP=§8/§eitems §8- §7Toggle Items -REGION_ITEMS_NO_PERMS=§cDu darfst hier nicht Items (de-)aktivieren REGION_ITEMS_ENABLED=§aItems aktiviert in dieser Region REGION_ITEMS_DISABLED=§cItems deaktiviert in dieser Region -REGION_ITEMS_DISABLED_GLOBAL=§cItems sind auf dem Server deaktiviert. REGION_PROTECT_HELP=§8/§eprotect §8- §7Schütze die Region REGION_PROTECT_DISABLE=§cBoden Schutz aufgehoben REGION_PROTECT_ENABLE=§aBoden geschützt -REGION_PROTECT_NO_PERMS=§cDu darfst hier nicht den Boden schützen REGION_PROTECT_FALSE_REGION=§cDu befindest dich derzeit in keiner (M)WG-Region REGION_REGION_HELP_UNDO=§8/§eregion undo §8- §7Mache die letzten 20 /testblock oder /reset rückgängig REGION_REGION_HELP_REDO=§8/§eregion redo §8- §7Wiederhole die letzten 20 §8/§7rg undo @@ -800,8 +771,6 @@ REGION_REGION_HELP_RESTORE=§8/§eregion restore §8- §7Setzte die Region zurü REGION_REGION_HELP_RESTORE_SCHEMATIC=§8/§eregion restore §8[§7Schematic§8] §8- §7Setzte die Region zurück, ohne das Gebaute zu löschen REGION_REGION_HELP_COPYPOINT=§8/§eregion copypoint §8- §7Teleportiere dich zum Regions Kopierpunkt REGION_REGION_HELP_TESTBLOCKPOINT=§8/§eregion testblockpoint §8- §7Teleportiere dich zum Regions Testblockpunkt -REGION_REGION_HELP_CHANGETYPE_INFO=§8/§eregion changetype §8- §7Gebe den Regions Type aus -REGION_REGION_HELP_CHANGETYPE=§8/§eregion changetype §8[§7Type§8] §8- §8Setzte den Regions Type REGION_REGION_HELP_CHANGESKIN_INFO=§8/§eregion changeskin §8- §7Gebe den Regions Skin aus REGION_REGION_HELP_CHANGESKIN=§8/§eregion changeskin §8[§7Skin§8] §8- §8Setzte den Regions Skin REGION_REGION_NOTHING_UNDO=§cNichts zum rückgängig machen @@ -817,13 +786,6 @@ REGION_REGION_TP_COPY=§7Zum Kopierpunkt teleportiert REGION_REGION_TP_TEST_BLOCK=§7Zum Testblock teleportiert REGION_REGION_TP_UNKNOWN=§cNicht definierter Teleportierpunkt REGION_REGION_NO_REGION=§cDu bist in keiner Region -REGION_REGION_NO_PERMS=§cDu darfst hier nicht die Region verändern -REGION_REGION_CHANGETYPE_INFO=§7Regions Type ist §e{0} -REGION_REGION_CHANGETYPE_UNKNOWN=§cRegions Type ist nicht valide -REGION_REGION_CHANGETYPE_INVALID=§cRegions Type ist nicht erlaubt hier -REGION_REGION_CHANGETYPE_CHANGE=§7Regions Type ist auf §e{0}§7 geändert -REGION_REGION_CHANGETYPE_CHANGE_UPDATE=§7Klicke §e§lHIER §7um den Type anzuwenden -REGION_REGION_CHANGETYPE_CHANGE_UPDATE_HOVER=§8/§ereset REGION_REGION_CHANGESKIN_INFO=§7Regions Skin ist §e{0} REGION_REGION_CHANGESKIN_INFO_CREATOR=§7Skin erstellt von §e{0} REGION_REGION_CHANGESKIN_UNKNOWN=§cRegions Skin ist nicht valide @@ -835,7 +797,6 @@ REGION_RESET_HELP_RESET=§8/§ereset §8- §7Setzte die Region zurück REGION_RESET_HELP_SCHEMATIC=§8/§ereset §8[§7Schematic§8] §8- §7Setzte die Region mit einer Schematic zurück REGION_RESET_RESETED=§7Region zurückgesetzt REGION_RESET_ERROR=§cFehler beim Zurücksetzen der Region -REGION_RESET_NO_PERMS=§cDu darfst hier nicht die Region zurücksetzen REGION_RESET_NO_REGION=§cDu befindest dich derzeit in keiner Region REGION_TB_HELP_RESET=§8/§etestblock §8- §7Setzte den Testblock zurück REGION_TB_HELP_RESET_EXTENSION=§8/§etestblock §8[§7ExtensionType§8] §8- §7Setzte den Testblock zurück @@ -843,7 +804,6 @@ REGION_TB_HELP_SCHEMATIC=§8/§etestblock §8[§7Schematic§8] §8- §7Setzte de REGION_TB_HELP_SCHEMATIC_EXTENSION=§8/§etestblock §8[§7Schematic§8] §8[§7ExtensionType§8] §8- §7Setzte den Testblock mit einer Schematic zurück REGION_TB_DONE=§7Testblock zurückgesetzt REGION_TB_ERROR=§cFehler beim Zurücksetzen des Testblocks -REGION_TB_NO_PERMS=§cDu darfst hier nicht den Testblock zurücksetzen REGION_TB_NO_REGION=§cDu befindest dich derzeit in keiner Region REGION_TB_NO_SCHEMSHARING=§cDu kannst aktuell keine Schematics teilen bis {0}. REGION_TB_NO_SCHEMRECEIVING=§cDer Besitzer dieses Bauservers kann keine Schematics erhalten bis {0}. @@ -852,10 +812,9 @@ REGION_TNT_HELP_MODE=§8/§etnt §8[§7Mode§8] §8- §7Setzte das TNT verhalten REGION_TNT_ON=§aTNT-Schaden aktiviert REGION_TNT_OFF=§cTNT-Schaden deaktiviert REGION_TNT_TB=§aTNT-Schaden außerhalb Baurahmen aktiviert -REGION_TNT_NO_PERMS=§cDu darfst hier nicht TNT-Schaden (de-)aktivieren REGION_TNT_BUILD_DESTROY=§cEine Explosion hätte Blöcke im Baubereich zerstört REGION_TNT_TB_DESTROY=§cEine Explosion hätte Blöcke im Testblockbereich zerstört -AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 5 Minuten nichts passiert. +AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 15 Minuten nichts passiert. AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt SKIN_HELP = §8/§eskin §8[§7Kuerzel§8] §8[§7Creator§8|§epublic§8] §8[§7Name...§8] §8- §7Erstellt die Skin Schematics. 'public' als Creator nutzen für keinen Creator, danach die nachricht an YoyoNow kopieren (mit Click kopieren) @@ -870,7 +829,6 @@ PANZERN_PREPARE1 = §71. Gucke nochmal nach, ob Läufe auch bis zur Panzergrenze PANZERN_PREPARE2 = §72. Teppich in Gänge auf dem Boden vereinfacht das panzern. PANZERN_PREPARE3 = §73. Schildtechnik sollte explizit eingeschlossen sein. PANZERN_PREPARE4 = §74. Innerhalb der zu panzernden Region zu stehen, beim Befehlausführen kann das Panzern verbessern. -PANZERN_NO_PERM = §cDu darfst hier nicht das Panzern System verwenden PANZERN_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection PANZERN_PROGRESS = §e{0} §7Blöcke übrig, §e{1} §7Blöcke pro Sekunde, §e{2} §7Block Delta PANZERN_DONE = §aZuende gepanzert @@ -880,7 +838,6 @@ LAUFBAU_HELP = §8/§elaufbau §8[§7smallest§8|§7blastresistant§8] §8- §7B LAUFBAU_HELP_SETTINGS = §8/§elaufbau settings §8- §7Öffnet die Settings GUI LAUFBAU_PREPARE1 = §71. Trace die Kanonen so oft wie nötig, in allen Modi. LAUFBAU_PREPARE2 = §72. Versuche alle Fails aus dem Trace zu löschen. -LAUFBAU_NO_PERM = §cDu darfst hier nicht das Laufbau System verwenden LAUFBAU_NO_WORLDEDIT = §cDu hast keine WorldEdit Selection LAUFBAU_STATE_FILTERING_TRACES = Traces filtern LAUFBAU_STATE_PROCESSING_TRACES = Traces verbinden @@ -988,7 +945,6 @@ LAUFBAU_TILT_PARTIAL = §8-§7 Neigung teilweise # UTILS SELECT_HELP = §8/§eselect §8[§7RegionsTyp§8] §8- §7Wähle einen RegionsTyp aus SELECT_EXTENSION_HELP = §8/§eselect §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension -SELECT_NO_PERMS = §cDu darfst hier nicht den Select Befehl verwenden SELECT_GLOBAL_REGION = §cDie globale Region kannst du nicht auswählen SELECT_NO_TYPE = §cDiese Region hat keinen {0} SELECT_NO_EXTENSION = §cDiese Region hat keine Ausfahrmaße @@ -1040,7 +996,6 @@ PISTON_HELP_3 = §7Die Anzahl ist Gelb, wenn zu viele Blöcke vorhanden sind. PISTON_INFO = §7Bewegte Blöcke {0}{1}§8/§712 # Warp -WARP_DISALLOWED = §cDu darfst hier nicht das Warp System nutzen WARP_LOC_X = §7X§8: §e{0} WARP_LOC_Y = §7Y§8: §e{0} WARP_LOC_Z = §7Z§8: §e{0} @@ -1066,12 +1021,9 @@ WARP_HELP_LIST=§8/§ewarp list §8- §7Liste alle Warp-Punkt auf # WORLD STOP_HELP = §8/§estop §8- §7Stoppt den Server -STOP_NO_PERMS = §cDu hast keine Rechte den Server zu stoppen STOP_MESSAGE = §eDer Server wird gestoppt -WORLD_EDIT_NO_PERMS = §cDu darfst hier kein WorldEdit benutzen KICKALL_HELP = §8/§ekickall §8- §7Kickt alle Spieler vom Server außer den Owner -KICKALL_NO_PERM = §cDies ist nicht deine Welt! # Techhider TECHHIDER_HELP = §8/§etechhider §8- §7Techhider umschalten diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java index 88a46ddc..9707d871 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java @@ -22,16 +22,19 @@ package de.steamwar.bausystem; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils; -import de.steamwar.bausystem.features.world.RamUsage; import de.steamwar.bausystem.linkage.LinkageUtils; import de.steamwar.bausystem.region.loader.PrototypeLoader; import de.steamwar.bausystem.region.loader.RegionLoader; import de.steamwar.bausystem.region.loader.Updater; +import de.steamwar.bausystem.utils.TickListener; import de.steamwar.bausystem.worlddata.WorldData; +import de.steamwar.command.AbstractValidator; +import de.steamwar.command.SWCommandUtils; import de.steamwar.message.Message; import lombok.Getter; import org.bukkit.Bukkit; -import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; @@ -53,12 +56,8 @@ public class BauSystem extends JavaPlugin implements Listener { @Getter private static BauSystem instance; - private World world; - @Override public void onEnable() { - world = Bukkit.getWorlds().get(0); - // LOGGER fixLogging(); @@ -79,25 +78,26 @@ public class BauSystem extends JavaPlugin implements Listener { new Updater(PrototypeLoader.file, PrototypeLoader::load); new Updater(RegionLoader.file, RegionLoader::load); - LinkageUtils.link(); - RamUsage.init(); + SWCommandUtils.addValidator(Player.class, validator(Permission.BUILD)); + SWCommandUtils.addValidator(CommandSender.class, validator(Permission.BUILD)); + SWCommandUtils.addValidator("supervisor", validator(Permission.SUPERVISOR)); + SWCommandUtils.addValidator("owner", validator(Permission.OWNER)); - // This could disable any watchdog stuff. We need to investigate if this is a problem. - /* - Thread thread = new Thread(() -> { - while (true) { - WatchdogThread.tick(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + LinkageUtils.link(); + TickListener.impl.init(); + } + + private AbstractValidator validator(Permission permission) { + return (commandSender, object, messageSender) -> { + if (commandSender instanceof Player) { + if (permission.hasPermission((Player) commandSender)) { + return true; } + messageSender.send("NO_PERMISSION"); + return false; } - }); - thread.setName("WatchdogThread ticker"); - thread.setDaemon(true); - thread.start(); - */ + return true; + }; } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/Permission.java b/BauSystem_Main/src/de/steamwar/bausystem/Permission.java index b2f14e4f..0985a62d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/Permission.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/Permission.java @@ -20,43 +20,77 @@ package de.steamwar.bausystem; import de.steamwar.bausystem.config.BauServer; -import de.steamwar.command.CommandMetaData; -import de.steamwar.command.TypeValidator; +import de.steamwar.bausystem.features.world.BauMemberUpdate; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.sql.BauweltMember; +import de.steamwar.sql.SteamwarUser; import lombok.AllArgsConstructor; -import org.bukkit.command.CommandSender; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.util.HashSet; +import java.util.Set; import java.util.function.Predicate; @AllArgsConstructor public enum Permission { - WORLD(BauweltMember::isWorld), - WORLDEDIT(BauweltMember::isWorldEdit), - MEMBER(bauweltMember -> true), - OWNER(bauweltMember -> false); + OWNER(bauweltMember -> false), + SUPERVISOR(bauweltMember -> { + return bauweltMember.isSupervisor(); + }), + BUILD(bauweltMember -> { + if (isTempOnlySpectator(bauweltMember)) return false; + return bauweltMember.isBuild() || SUPERVISOR.permissionPredicate.test(bauweltMember); + }), + /** + * Only used for {@link BauMemberUpdate} + */ + REAL_SPECTATOR(bauweltMember -> { + return !bauweltMember.isBuild() && !bauweltMember.isSupervisor(); + }), + /** + * Primarily used for {@link de.steamwar.bausystem.linkage.specific.GuiItem} + */ + MEMBER(bauweltMember -> { + return true; + }); + + private static final Set TEMP_ONLY_SPECTATOR = new HashSet<>(); + + private static boolean isTempOnlySpectator(BauweltMember bauweltMember) { + return TEMP_ONLY_SPECTATOR.contains(bauweltMember.getMemberID()); + } + + public static boolean isTempOnlySpectator(Player player) { + return TEMP_ONLY_SPECTATOR.contains(SteamwarUser.get(player.getUniqueId()).getId()); + } + + public static void forceOnlySpectator(Player player) { + TEMP_ONLY_SPECTATOR.add(SteamwarUser.get(player.getUniqueId()).getId()); + BauMemberUpdate.baumemberUpdate(); + } + + /** + * Only used by {@link BauMemberUpdate} + */ + public static void removeForceOnlySpectator(Player player) { + TEMP_ONLY_SPECTATOR.remove(SteamwarUser.get(player.getUniqueId()).getId()); + } private final Predicate permissionPredicate; - public boolean hasPermission(Player member) { - if (member.getUniqueId().equals(BauServer.getInstance().getOwner())) { - return true; - } - - BauweltMember bauMember = BauweltMember.getBauMember(BauServer.getInstance().getOwner(), member.getUniqueId()); - if (bauMember == null) { - return false; - } - - return permissionPredicate.test(bauMember); + public boolean hasPermission(BauweltMember bauweltMember) { + if (bauweltMember == null) return false; + return permissionPredicate.test(bauweltMember); } - public static boolean hasPermission(Player member, Permission permission) { - return permission.hasPermission(member); + public boolean hasPermission(Player member) { + if (SteamwarUser.get(member.getUniqueId()).getId() == BauServer.getInstance().getOwnerID()) { + return this != REAL_SPECTATOR; + } + BauweltMember bauweltMember = BauweltMember.getBauMember(BauServer.getInstance().getOwner(), member.getUniqueId()); + if (bauweltMember == null) return this == REAL_SPECTATOR; + return permissionPredicate.test(bauweltMember); } } \ No newline at end of file diff --git a/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java b/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java index 2f929687..edce8c58 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/configplayer/Config.java @@ -97,7 +97,7 @@ public class Config implements Listener { public void saveAll() { playerConfigurations.forEach((uuid, yapionObject) -> { - String string = yapionObject.toYAPION(new StringOutput()).getResult(); + String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\+", "\\"); UserConfig.updatePlayerConfig(uuid, "bausystem", string); }); playerConfigurations.clear(); @@ -112,7 +112,7 @@ public class Config implements Listener { UUID uuid = player.getUniqueId(); if (playerConfigurations.containsKey(uuid)) { YAPIONObject yapionObject = playerConfigurations.get(uuid); - String string = yapionObject.toYAPION(new StringOutput()).getResult(); + String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\\\+", "\\\\"); UserConfig.updatePlayerConfig(uuid, "bausystem", string); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java index 11cacde1..689be980 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributeRemoveCommand.java @@ -44,7 +44,7 @@ public class AttributeRemoveCommand extends SWCommand { @Register({"all"}) @Register({"*"}) - public void genericCommand(Player player) { + public void genericCommand(@Validator Player player) { ItemStack itemStack = player.getInventory().getItemInMainHand(); ItemMeta itemMeta = itemStack.getItemMeta(); itemMeta.setLore(new ArrayList<>()); @@ -53,7 +53,7 @@ public class AttributeRemoveCommand extends SWCommand { } @Register(description = "ATTRIBUTE_REMOVE_COMMAND_HELP") - public void genericCommand(Player player, @Mapper("attribute") String attribute) { + public void genericCommand(@Validator Player player, @Mapper("attribute") String attribute) { ItemStack itemStack = player.getInventory().getItemInMainHand(); ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta == null) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java index 01d652b4..808ca339 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesCopyCommand.java @@ -41,7 +41,7 @@ public class AttributesCopyCommand extends SWCommand { } @Register - public void genericCommand(Player player) { + public void genericCommand(@Validator Player player) { Block block = player.getTargetBlockExact(8, FluidCollisionMode.ALWAYS); if (block == null) return; ItemStack mainHand = player.getInventory().getItemInMainHand(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java index de4b192a..965d8bad 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/attributescopy/AttributesPlaceListener.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.attributescopy; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -40,6 +41,7 @@ public class AttributesPlaceListener implements Listener { @EventHandler public void onBlockPlace(BlockPlaceEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; ItemStack itemStack = event.getItemInHand(); ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta == null) return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java index 8e2b8c1a..3401267e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartCommand.java @@ -32,7 +32,7 @@ public class AutoStartCommand extends SWCommand { } @Register(description = "AUTOSTART_COMMAND_HELP") - public void genericCommand(Player p) { + public void genericCommand(@Validator Player p) { SWUtils.giveItemToPlayer(p, AutostartListener.getWandItem(p)); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java index a66e3785..f622d70b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutoStartGuiItem.java @@ -50,6 +50,6 @@ public class AutoStartGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.MEMBER; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java index 7da0fea1..28126ec5 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.autostart; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.RegionUtils; @@ -29,6 +30,7 @@ import de.steamwar.bausystem.utils.ItemUtils; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; import lombok.Getter; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.data.type.Chest; import org.bukkit.configuration.file.FileConfiguration; @@ -66,6 +68,7 @@ public class AutostartListener implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!ItemUtils.isItem(event.getItem(), "autostart")) { return; } @@ -75,6 +78,12 @@ public class AutostartListener implements Listener { if (event.getClickedBlock().getBlockData() instanceof Chest) { return; } + if (event.getClickedBlock().getType() == Material.BEDROCK) { + event.getClickedBlock().setType(Material.SLIME_BLOCK); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + event.getClickedBlock().setType(Material.BEDROCK, false); + }, 1); + } activate(event.getPlayer()); } @@ -83,6 +92,7 @@ public class AutostartListener implements Listener { if (!(event.getPlayer() instanceof Player)) { return; } + if(!Permission.BUILD.hasPermission((Player) event.getPlayer())) return; if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) { return; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java index ba7035dc..b7911275 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/backup/BackupCommand.java @@ -62,7 +62,7 @@ public class BackupCommand extends SWCommand { } @Register(value = "create", description = "BACKUP_HELP_CREATE") - public void backupCreate(@Validator Player p) { + public void backupCreate(@Validator("owner") Player p) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) { return; @@ -79,7 +79,7 @@ public class BackupCommand extends SWCommand { } @Register(value = "load", description = "BACKUP_HELP_LOAD") - public void backupLoad(@Validator Player p, @Mapper("backupName") String backupName) { + public void backupLoad(@Validator("owner") Player p, @Mapper("backupName") String backupName) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) { return; @@ -130,7 +130,7 @@ public class BackupCommand extends SWCommand { } SWListInv swListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("BACKUP_INV_NAME", p), swListEntries, (clickType, s) -> { p.getOpenInventory().close(); - backupLoad(p, s); + p.performCommand("backup load " + s); }); swListInv.open(); } @@ -140,13 +140,6 @@ public class BackupCommand extends SWCommand { return SWCommandUtils.createMapper(s -> s, (commandSender, s) -> listBackup((Player) commandSender)); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator backupValidator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "BACKUP_NO_PERMS"); - }; - } - private List listBackup(Player p) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/BauCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/BauCommand.java deleted file mode 100644 index 69ee7af8..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/BauCommand.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 . - */ - -package de.steamwar.bausystem.features.bau; - -import de.steamwar.command.SWCommand; -import de.steamwar.linkage.Linked; -import de.steamwar.linkage.LinkedInstance; -import org.bukkit.entity.Player; - -@Linked -public class BauCommand extends SWCommand { - - @LinkedInstance - public InfoCommand infoCommand; - - public BauCommand() { - super("bau", "b", "gs"); - } - - @Register(value = "info", description = "BAU_COMMAND_HELP_INFO") - public void infoCommand(Player p) { - infoCommand.sendBauInfo(p); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/ForceSpectatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/ForceSpectatorCommand.java new file mode 100644 index 00000000..7bef91df --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/ForceSpectatorCommand.java @@ -0,0 +1,73 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.bau; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeMapper; +import de.steamwar.linkage.Linked; +import de.steamwar.techhider.TechHider; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Collection; +import java.util.stream.Collectors; + +@Linked +public class ForceSpectatorCommand extends SWCommand { + + public ForceSpectatorCommand() { + super("forcespectator"); + } + + @Register + public void forceSpectator(@Validator("supervisor") Player player, @Mapper("builder") Player other) { + Permission.forceOnlySpectator(other); + } + + @Mapper("builder") + public TypeMapper spectatorMapper() { + return new TypeMapper<>() { + @Override + public Player map(CommandSender commandSender, String[] previousArguments, String s) { + Player player = Bukkit.getPlayer(s); + if (player == null) { + return null; + } + if (Permission.BUILD.hasPermission(player) && !Permission.SUPERVISOR.hasPermission(player)) { + return player; + } + return null; + } + + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + return Bukkit.getOnlinePlayers().stream() + .filter(Permission.BUILD::hasPermission) + .filter(player -> !Permission.SUPERVISOR.hasPermission(player)) + .map(Player::getName) + .collect(Collectors.toList()); + } + }; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java index 345dc1b3..2d638888 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/bau/InfoCommand.java @@ -1,6 +1,7 @@ package de.steamwar.bausystem.features.bau; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.config.BauServer; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.flags.Flag; @@ -12,7 +13,7 @@ import de.steamwar.sql.BauweltMember; import de.steamwar.sql.SteamwarUser; import org.bukkit.entity.Player; -import java.util.List; +import java.util.*; @Linked public class InfoCommand extends SWCommand { @@ -24,17 +25,8 @@ public class InfoCommand extends SWCommand { super("bauinfo"); } - @Register(help = true) - public void genericHelp(Player p, String... args) { - BauSystem.MESSAGE.send("BAU_INFO_COMMAND_HELP", p); - } - - @Register + @Register(description = "BAU_INFO_COMMAND_HELP") public void genericCommand(Player p) { - sendBauInfo(p); - } - - public void sendBauInfo(Player p) { BauSystem.MESSAGE.send("BAU_INFO_COMMAND_OWNER", p, SteamwarUser.get(bauServer.getOwnerID()).getUserName()); Region region = Region.getRegion(p.getLocation()); for (Flag flag : Flag.getFlags()) { @@ -47,18 +39,28 @@ public class InfoCommand extends SWCommand { } } - List members = BauweltMember.getMembers(bauServer.getOwnerID()); - StringBuilder membermessage = new StringBuilder(); - membermessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_MEMBER", p, members.size())); + if (Permission.BUILD.hasPermission(p)) { + List members = BauweltMember.getMembers(bauServer.getOwnerID()); + Map> memberByPermission = new HashMap<>(); + members.forEach(member -> { + if (Permission.SUPERVISOR.hasPermission(member)) { + memberByPermission.computeIfAbsent(Permission.SUPERVISOR, __ -> new ArrayList<>()).add(member); + } else if (Permission.BUILD.hasPermission(member)) { + memberByPermission.computeIfAbsent(Permission.BUILD, __ -> new ArrayList<>()).add(member); + } else { + memberByPermission.computeIfAbsent(Permission.MEMBER, __ -> new ArrayList<>()).add(member); + } + }); - for (BauweltMember member : members) { - membermessage.append(BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_INFO", p, - SteamwarUser.get(member.getMemberID()).getUserName(), - member.isWorldEdit() ? BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WE_ALLOW", p) : BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WE_DISALLOW", p), - member.isWorld() ? BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WORLD_ALLOW", p) : BauSystem.MESSAGE.parse("BAU_INFO_MEMBER_WORLD_DISALLOW", p) - )); + List supervisor = memberByPermission.getOrDefault(Permission.SUPERVISOR, Collections.emptyList()); + BauSystem.MESSAGE.send("BAU_INFO_COMMAND_MEMBER", p, "§eSupervisor", supervisor.size(), supervisor.isEmpty() ? "§8" : joining(supervisor)); + + List builder = memberByPermission.getOrDefault(Permission.BUILD, Collections.emptyList()); + BauSystem.MESSAGE.send("BAU_INFO_COMMAND_MEMBER", p, "§6Builder", builder.size(), builder.isEmpty() ? "§8" : joining(builder)); + + List spectator = memberByPermission.getOrDefault(Permission.MEMBER, Collections.emptyList()); + BauSystem.MESSAGE.send("BAU_INFO_COMMAND_MEMBER", p, "§7Spectator", spectator.size(), spectator.isEmpty() ? "§8" : joining(spectator)); } - p.sendMessage(membermessage.toString()); StringBuilder tpsMessage = new StringBuilder(); tpsMessage.append(BauSystem.MESSAGE.parsePrefixed("BAU_INFO_COMMAND_TPS", p)); @@ -69,4 +71,16 @@ public class InfoCommand extends SWCommand { tpsMessage.append(" ").append(TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)); p.sendMessage(tpsMessage.toString()); } + + private String joining(List bauweltMembers) { + StringBuilder st = new StringBuilder(); + for (int i = 0; i < bauweltMembers.size(); i++) { + if (i != 0) { + st.append("§8, "); + } + st.append("§7"); + st.append(SteamwarUser.get(bauweltMembers.get(i).getMemberID()).getUserName()); + } + return st.toString(); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java index 7772f9c7..dbeae70d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/countingwand/CountingwandGuiItem.java @@ -48,6 +48,6 @@ public class CountingwandGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.MEMBER; } } \ No newline at end of file diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java index fd9899f8..0fa990aa 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStone.java @@ -44,7 +44,6 @@ public class DesignEndStone { private REntityServer entityServer = new REntityServer(); private List entities = new ArrayList<>(); private Set locations = new HashSet<>(); - private List players = new ArrayList<>(); public DesignEndStone(Region region) { this.minX = region.getMinPointBuild().getX(); @@ -95,12 +94,10 @@ public class DesignEndStone { } public void toggle(Player player) { - if (players.contains(player)) { - players.remove(player); + if (entityServer.getPlayers().contains(player)) { entityServer.removePlayer(player); BauSystem.MESSAGE.sendPrefixless("DESIGN_ENDSTONE_DISABLE", player, ChatMessageType.ACTION_BAR); } else { - players.add(player); entityServer.addPlayer(player); calc(); BauSystem.MESSAGE.sendPrefixless("DESIGN_ENDSTONE_ENABLE", player, ChatMessageType.ACTION_BAR); @@ -108,7 +105,7 @@ public class DesignEndStone { } public boolean removePlayer(Player player) { - players.remove(player); - return players.isEmpty(); + entityServer.removePlayer(player); + return entityServer.getPlayers().isEmpty(); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java index bafa3206..92934c23 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/design/endstone/DesignEndStoneCommand.java @@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.design.endstone; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.utils.RegionType; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.command.SWCommand; import de.steamwar.linkage.Linked; import org.bukkit.Location; @@ -33,6 +34,7 @@ import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; @Linked @@ -45,7 +47,7 @@ public class DesignEndStoneCommand extends SWCommand implements Listener { private Map designEndStoneMap = new HashMap<>(); @Register(description = "DESIGN_ENDSTONE_COMMAND_HELP") - public void genericCommand(Player player) { + public void genericCommand(@Validator Player player) { Region region = Region.getRegion(player.getLocation()); if (!region.hasType(RegionType.BUILD)) { BauSystem.MESSAGE.send("DESIGN_ENDSTONE_REGION_ERROR", player); @@ -56,14 +58,20 @@ public class DesignEndStoneCommand extends SWCommand implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { - Region region = Region.getRegion(event.getPlayer().getLocation()); - DesignEndStone designEndStone = designEndStoneMap.get(region); - if (designEndStone == null) { - return; - } - if (designEndStone.removePlayer(event.getPlayer())) { - designEndStoneMap.remove(region); - } + disableDesignEndStone(event.getPlayer()); + } + + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(this::disableDesignEndStone); + } + + private void disableDesignEndStone(Player player) { + new HashSet<>(designEndStoneMap.entrySet()).forEach(regionDesignEndStoneEntry -> { + if (regionDesignEndStoneEntry.getValue().removePlayer(player)) { + designEndStoneMap.remove(regionDesignEndStoneEntry.getKey()); + } + }); } @EventHandler diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java index 2207ce45..3f633663 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorBauGuiItem.java @@ -47,6 +47,6 @@ public class DetonatorBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.MEMBER; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java index bb71245d..c8d493bd 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorCommand.java @@ -58,12 +58,12 @@ public class DetonatorCommand extends SWCommand { } @Register(value = "wand", description = "DETONATOR_HELP_WAND") - public void giveWand(Player p) { + public void giveWand(@Validator Player p) { SWUtils.giveItemToPlayer(p, getWAND(p)); } @Register(value = "click", description = "DETONATOR_HELP_CLICK") - public void clickDetonator(Player p) { + public void clickDetonator(@Validator Player p) { Detonator.activateDetonator(new ItemStorage(p)); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java index be8e8ce9..cabe00c6 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.detonator; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage; import de.steamwar.bausystem.features.detonator.storage.ItemStorage; @@ -65,6 +66,7 @@ public class DetonatorListener implements Listener { @EventHandler public void onBlockBreak(BlockBreakEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; Player p = event.getPlayer(); if (Detonator.isDetonator(p.getInventory().getItemInMainHand())) { event.setCancelled(true); @@ -75,6 +77,7 @@ public class DetonatorListener implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!Detonator.isDetonator(event.getItem())) { return; } @@ -89,7 +92,7 @@ public class DetonatorListener implements Listener { @EventHandler(ignoreCancelled = true) public void onPlayerMove(PlayerMoveEvent event) { - if (!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) { + if (!Permission.BUILD.hasPermission(event.getPlayer()) ||!Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) { if (Detonator.hasActiveDetonatorShow(event.getPlayer())) { Detonator.hideDetonator(event.getPlayer()); } @@ -110,6 +113,7 @@ public class DetonatorListener implements Listener { @EventHandler public void onPlayerItemHeld(PlayerItemHeldEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (Detonator.isDetonator(event.getPlayer().getInventory().getItemInMainHand())) { HAS_UPDATED.add(event.getPlayer()); } @@ -117,6 +121,7 @@ public class DetonatorListener implements Listener { @EventHandler public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (Detonator.isDetonator(event.getMainHandItem()) || Detonator.isDetonator(event.getOffHandItem())) { HAS_UPDATED.add(event.getPlayer()); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java index 74a915da..3b8dc600 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGUI.java @@ -81,7 +81,7 @@ public class BauGUI { } } else { p.closeInventory(); - BauSystem.MESSAGE.send("GUI_NO_PERMISSION", p); + BauSystem.MESSAGE.send("NO_PERMISSION", p); } }); }); @@ -108,26 +108,13 @@ public class BauGUI { if (!permission.hasPermission(p)) { List lore = meta.getLore(); if (lore == null) { - lore = Collections.singletonList(BauSystem.MESSAGE.parse(permissionString(permission), p)); + lore = Collections.singletonList(BauSystem.MESSAGE.parse("NO_PERMISSION", p)); } else { - lore.add(BauSystem.MESSAGE.parse(permissionString(permission), p)); + lore.add(BauSystem.MESSAGE.parse("NO_PERMISSION", p)); } meta.setLore(lore); } itemStack.setItemMeta(meta); return itemStack; } - - private static String permissionString(Permission permission) { - switch (permission) { - case OWNER: - return "GUI_NO_OWNER"; - case WORLD: - return "GUI_NO_WORLD"; - case WORLDEDIT: - return "GUI_NO_WORLDEDIT"; - default: - return "GUI_NO_MEMBER"; - } - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java index 9b52890c..77a13716 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarCommand.java @@ -35,7 +35,7 @@ public class HotbarCommand extends SWCommand { } @Register(value = "load", description = "HOTBAR_HELP_LOAD") - public void loadHotbar(Player p) { + public void loadHotbar(@Validator Player p) { DefaultHotbar.setHotbar(p); BauSystem.MESSAGE.send("HOTBAR_LOADED", p); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java index de00331f..8a4c78de 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/hotbar/HotbarListener.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.features.hotbar; +import de.steamwar.bausystem.Permission; import de.steamwar.linkage.Linked; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -30,6 +31,7 @@ public class HotbarListener implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (allNull(event.getPlayer().getInventory().getContents()) && allNull(event.getPlayer().getInventory().getArmorContents())) { DefaultHotbar.setHotbar(event.getPlayer()); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java b/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java index f72d08f2..d69e3410 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/inventoryfiller/InventoryFiller.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.inventoryfiller; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.configplayer.Config; import de.steamwar.linkage.Linked; import net.md_5.bungee.api.ChatMessageType; @@ -38,6 +39,7 @@ public class InventoryFiller implements Listener { @EventHandler public void onPlayerDropItem(PlayerDropItemEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return; if (!event.getPlayer().isSneaking()) return; Block block = event.getPlayer().getTargetBlockExact(5); @@ -59,6 +61,7 @@ public class InventoryFiller implements Listener { */ @EventHandler public void onPlayerItemHeld(PlayerItemHeldEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return; if (!event.getPlayer().isSneaking()) return; ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java index 1340f1c1..9ca7a480 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerCommand.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.killchecker; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.bausystem.utils.bossbar.BossBarService; import de.steamwar.command.SWCommand; import de.steamwar.linkage.Linked; @@ -54,7 +55,7 @@ public class KillcheckerCommand extends SWCommand implements Listener { } @Register(value = "enable", description = "KILLCHECKER_HELP_ENABLE") - public void genericCommand(Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) { + public void genericCommand(@Validator Player player, @OptionalValue("-outline") @StaticValue(value = {"-area", "-outline"}, allowISE = true) boolean onlyOutline) { Region region = Region.getRegion(player.getLocation()); KillcheckerVisualizer killcheckerVisualizer = visualizers.computeIfAbsent(region, region1 -> new KillcheckerVisualizer(region1, bossBarService)); killcheckerVisualizer.recalc(); @@ -74,16 +75,22 @@ public class KillcheckerCommand extends SWCommand implements Listener { BauSystem.MESSAGE.send("KILLCHECKER_DISABLE", player); } + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(this::hide); + } + @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { - Player player = event.getPlayer(); - Set regions = new HashSet<>(); - visualizers.forEach((region, visualizer) -> { - if (visualizer.disconnect(player)) { - regions.add(region); + hide(event.getPlayer()); + } + + private void hide(Player player) { + new HashSet<>(visualizers.entrySet()).forEach(regionKillcheckerVisualizerEntry -> { + if (regionKillcheckerVisualizerEntry.getValue().hide(player)) { + visualizers.remove(regionKillcheckerVisualizerEntry.getKey()); } }); - regions.forEach(visualizers::remove); } private void recalc(Block block) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java index d7c89254..c68ad901 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/killchecker/KillcheckerVisualizer.java @@ -57,9 +57,6 @@ public class KillcheckerVisualizer { private final int zArea; private final int xArea; - private final Set players = new HashSet<>(); - private final Set areaPlayers = new HashSet<>(); - private final Region region; private final BossBarService bossBarService; @@ -261,7 +258,7 @@ public class KillcheckerVisualizer { double zPercent = xCount / (double) zArea; percent = (xPercent + yPercent + zPercent) / 3; kills = zKills + yKills + xKills; - players.forEach(this::updateBossBar); + outline.getPlayers().forEach(this::updateBossBar); Set pointSet = new HashSet<>(killCount.keySet()); Set outlinePointsCacheLast = new HashSet<>(outlinePointsCache); @@ -356,40 +353,21 @@ public class KillcheckerVisualizer { return new Cuboid(minX, minY, minZ, maxX, maxY, maxZ); } - public boolean show(Player player, boolean onlyOutline) { + public void show(Player player, boolean onlyOutline) { outline.addPlayer(player); if (!onlyOutline) { inner.addPlayer(player); - areaPlayers.add(player); - } else if (areaPlayers.contains(player)) { + } else { inner.removePlayer(player); - areaPlayers.remove(player); } updateBossBar(player); - return players.add(player); } public boolean hide(Player player) { outline.removePlayer(player); - if (areaPlayers.contains(player)) { - inner.removePlayer(player); - } - players.remove(player); - areaPlayers.remove(player); + inner.removePlayer(player); bossBarService.remove(player, region, "killchecker"); - if (players.isEmpty()) { - outline.close(); - inner.close(); - return true; - } - return false; - } - - public boolean disconnect(Player player) { - players.remove(player); - areaPlayers.remove(player); - bossBarService.remove(player, region, "killchecker"); - if (players.isEmpty()) { + if (outline.getPlayers().isEmpty() && inner.getPlayers().isEmpty()) { outline.close(); inner.close(); return true; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java index 22e0df02..266cd65b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/Loader.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.loader; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.loader.elements.LoaderElement; import de.steamwar.bausystem.features.loader.elements.LoaderInteractionElement; import de.steamwar.bausystem.features.loader.elements.impl.LoaderTNT; @@ -70,6 +71,7 @@ public class Loader implements Listener { BauSystem.runTaskTimer(BauSystem.getInstance(), () -> { if (stage != Stage.RUNNING) return; + if(!Permission.BUILD.hasPermission(p)) return; if (waitTime > 0) { waitTime--; return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java index b065c3d2..ffe27e64 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderCommand.java @@ -21,13 +21,16 @@ package de.steamwar.bausystem.features.loader; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeValidator; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; @Linked -public class LoaderCommand extends SWCommand { +public class LoaderCommand extends SWCommand implements Listener { public LoaderCommand() { super("loader"); @@ -102,10 +105,12 @@ public class LoaderCommand extends SWCommand { loader.setTicksBetweenBlocks(delay); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator loaderValidator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "LOADER_PERMS"); - }; + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(player -> { + Loader loader = Loader.getLoader(player); + if (loader == null) return; + loader.stop(); + }); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java index ec2153ae..cc3dce23 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderRecorder.java @@ -43,6 +43,8 @@ import org.bukkit.inventory.EquipmentSlot; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; public class LoaderRecorder implements Listener { @@ -124,53 +126,10 @@ public class LoaderRecorder implements Listener { addWaitTime(false); Block block = event.getClickedBlock(); - Material type = block.getType(); - switch (type) { - case COMPARATOR: - loaderElementList.add(new LoaderComparator(block.getLocation())); - message("LOADER_BUTTON_COMPARATOR"); - break; - case REPEATER: - loaderElementList.add(new LoaderRepeater(block.getLocation())); - message("LOADER_BUTTON_REPEATER"); - break; - case NOTE_BLOCK: - loaderElementList.add(new LoaderNoteBlock(block.getLocation())); - message("LOADER_BUTTON_NOTEBLOCK"); - break; - case LEVER: - loaderElementList.add(new LoaderLever(block.getLocation())); - message("LOADER_BUTTON_SWITCH"); - break; - case DAYLIGHT_DETECTOR: - loaderElementList.add(new LoaderDaylightDetector(block.getLocation())); - message("LOADER_BUTTON_DAYLIGHT_DETECTOR"); - break; - case LECTERN: - loaderElementList.add(new LoaderLectern(block.getLocation())); - message("LOADER_BUTTON_LECTERN"); - break; - case IRON_TRAPDOOR: - break; - default: - if (type.name().endsWith("_TRAPDOOR")) { - loaderElementList.add(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_TRAPDOOR", type)); - message("LOADER_BUTTON_TRAPDOOR"); - } else if (type.name().endsWith("_DOOR")) { - loaderElementList.add(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_DOOR", type)); - message("LOADER_BUTTON_DOOR"); - } else if (type.name().endsWith("FENCE_GATE")) { - loaderElementList.add(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_FENCEGATE", type)); - message("LOADER_BUTTON_FENCEGATE"); - } else if (type.name().endsWith("STONE_BUTTON")) { - loaderElementList.add(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_STONE_BUTTON", type, 20)); - message("LOADER_BUTTON_STONE_BUTTON"); - } else if (type.name().endsWith("BUTTON")) { - loaderElementList.add(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_WOOD_BUTTON", type, 30)); - message("LOADER_BUTTON_WOOD_BUTTON"); - } - break; - } + getLoaderInteractionElement(block, (loaderInteractionElement, s) -> { + loaderElementList.add(loaderInteractionElement); + message(s); + }); } private Map blockSet = new HashMap<>(); @@ -226,6 +185,46 @@ public class LoaderRecorder implements Listener { } } + public static void getLoaderInteractionElement(Block block, BiConsumer, String> consumer) { + Material type = block.getType(); + switch (type) { + case COMPARATOR: + consumer.accept(new LoaderComparator(block.getLocation()), "LOADER_BUTTON_COMPARATOR"); + break; + case REPEATER: + consumer.accept(new LoaderRepeater(block.getLocation()), "LOADER_BUTTON_REPEATER"); + break; + case NOTE_BLOCK: + consumer.accept(new LoaderNoteBlock(block.getLocation()), "LOADER_BUTTON_NOTEBLOCK"); + break; + case LEVER: + consumer.accept(new LoaderLever(block.getLocation()), "LOADER_BUTTON_SWITCH"); + break; + case DAYLIGHT_DETECTOR: + consumer.accept(new LoaderDaylightDetector(block.getLocation()), "LOADER_BUTTON_DAYLIGHT_DETECTOR"); + break; + case LECTERN: + consumer.accept(new LoaderLectern(block.getLocation()), "LOADER_BUTTON_LECTERN"); + break; + case IRON_TRAPDOOR: + case IRON_DOOR: + break; + default: + if (type.name().endsWith("_TRAPDOOR")) { + consumer.accept(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_TRAPDOOR", type), "LOADER_BUTTON_TRAPDOOR"); + } else if (type.name().endsWith("_DOOR")) { + consumer.accept(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_DOOR", type), "LOADER_BUTTON_DOOR"); + } else if (type.name().endsWith("FENCE_GATE")) { + consumer.accept(new LoaderOpenable(block.getLocation(), "LOADER_BUTTON_FENCEGATE", type), "LOADER_BUTTON_FENCEGATE"); + } else if (type.name().endsWith("STONE_BUTTON")) { + consumer.accept(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_STONE_BUTTON", type, 20), "LOADER_BUTTON_STONE_BUTTON"); + } else if (type.name().endsWith("BUTTON")) { + consumer.accept(new LoaderTicks(block.getLocation(), "LOADER_BUTTON_WOOD_BUTTON", type, 30), "LOADER_BUTTON_WOOD_BUTTON"); + } + break; + } + } + private void message(String type) { SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("LOADER_MESSAGE_INTERACT", player, BauSystem.MESSAGE.parse(type, player), loaderElementList.size())); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java index b3e2ba2f..fdcda57a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loader/LoaderScoreboardElement.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.loader; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.ScoreboardElement; import de.steamwar.linkage.Linked; @@ -40,6 +41,7 @@ public class LoaderScoreboardElement implements ScoreboardElement { @Override public String get(Region region, Player p) { + if(!Permission.BUILD.hasPermission(p)) return null; Loader loader = Loader.getLoader(p); if (loader == null) return null; if (loader.getStage() == Loader.Stage.RUNNING) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java index 42d5175c..503c1b47 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/loadtimer/LoadtimerCommand.java @@ -32,12 +32,12 @@ public class LoadtimerCommand extends SWCommand { } @Register(value = "start", description = "LOADTIMER_HELP_START_1") - public void start(Player p) { + public void start(@Validator Player p) { start(p, TimerMode.HALF); } @Register(value = "start", description = {"LOADTIMER_HELP_START_2", "LOADTIMER_HELP_START_3"}) - public void start(Player p, TimerMode mode) { + public void start(@Validator Player p, TimerMode mode) { Region r = Region.getRegion(p.getLocation()); if (r.isGlobal()) return; if (!Loadtimer.hasTimer(r)) @@ -45,7 +45,7 @@ public class LoadtimerCommand extends SWCommand { } @Register(value = "stop", description = "LOADTIMER_HELP_STOP") - public void stop(Player p) { + public void stop(@Validator Player p) { Region r = Region.getRegion(p.getLocation()); if (r.isGlobal()) return; if (Loadtimer.hasTimer(r)) diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java index fd0df724..531eda68 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerCommand.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.observer; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.command.SWCommand; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; @@ -46,13 +47,13 @@ public class ObserverTracerCommand extends SWCommand { } @Register(value = "delete", description = "OBSERVER_HELP_DELETE") - public void delete(Player p) { + public void delete(@Validator Player p) { ObserverTracerListener.observerTracerMap.remove(p); BauSystem.MESSAGE.send("OBSERVER_DELETE", p); } @Register(value = "retrace", description = "OBSERVER_HELP_RETRACE") - public void retrace(Player p) { + public void retrace(@Validator Player p) { if (ObserverTracerListener.observerTracerMap.containsKey(p)) { BauSystem.MESSAGE.send("OBSERVER_RETRACE_NO_TRACE", p); return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java index b841755b..a2d9c991 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/observer/ObserverTracerListener.java @@ -20,6 +20,8 @@ package de.steamwar.bausystem.features.observer; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -55,6 +57,7 @@ public class ObserverTracerListener implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!enabled.contains(event.getPlayer())) { return; } @@ -87,6 +90,11 @@ public class ObserverTracerListener implements Listener { } } + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(observerTracerMap::remove); + } + @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { enabled.add(event.getPlayer()); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java index 543d8727..7c60aef2 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ColorCommand.java @@ -85,7 +85,7 @@ public class ColorCommand extends SWCommand { @ClassValidator(value = Player.class, local = true) public TypeValidator validator() { return (commandSender, player, messageSender) -> { - return !messageSender.send(!bauServer.getOwner().equals(player.getUniqueId()), "REGION_COLOR_NO_PERMS"); + return !messageSender.send(!bauServer.getOwner().equals(player.getUniqueId()), "NO_PERMISSION"); }; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java index da5b2665..3a0d4403 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FireCommand.java @@ -46,10 +46,6 @@ public class FireCommand extends SWCommand { } } - private String getNoPermMessage() { - return "REGION_FIRE_NO_PERMS"; - } - private String getEnableMessage() { return "REGION_FIRE_ENABLED"; } @@ -69,11 +65,4 @@ public class FireCommand extends SWCommand { return false; } } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), getNoPermMessage()); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java index 339ea122..d154ce66 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/FreezeCommand.java @@ -46,10 +46,6 @@ public class FreezeCommand extends SWCommand { } } - private String getNoPermMessage() { - return "REGION_FREEZE_NO_PERMS"; - } - private String getEnableMessage(){ return "REGION_FREEZE_ENABLED"; } @@ -69,11 +65,4 @@ public class FreezeCommand extends SWCommand { return true; } } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), getNoPermMessage()); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java index d1709dc7..8c4452cb 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ItemsCommand.java @@ -49,10 +49,6 @@ public class ItemsCommand extends SWCommand { } } - private String getNoPermMessage() { - return "REGION_ITEMS_NO_PERMS"; - } - private String getEnableMessage(){ return "REGION_ITEMS_ENABLED"; } @@ -72,11 +68,4 @@ public class ItemsCommand extends SWCommand { return true; } } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), getNoPermMessage()); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java index 3793d3ec..4fc33cf0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ProtectCommand.java @@ -54,13 +54,6 @@ public class ProtectCommand extends SWCommand { } } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_PROTECT_NO_PERMS"); - }; - } - private Region regionCheck(Player player) { Region region = Region.getRegion(player.getLocation()); if (region.getFloorLevel() == 0) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java index 5caf0af3..efad26fd 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java @@ -71,7 +71,7 @@ public class RegionCommand extends SWCommand { } @Register(value = "undo", description = "REGION_REGION_HELP_UNDO") - public void undoCommand(@Validator("WORLD_EDIT") Player p) { + public void undoCommand(@Validator Player p) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) return; @@ -83,7 +83,7 @@ public class RegionCommand extends SWCommand { } @Register(value = "redo", description = "REGION_REGION_HELP_REDO") - public void redoCommand(@Validator("WORLD_EDIT") Player p) { + public void redoCommand(@Validator Player p) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) { return; @@ -97,7 +97,7 @@ public class RegionCommand extends SWCommand { } @Register(value = "restore", description = "REGION_REGION_HELP_RESTORE") - public void genericRestoreCommand(@Validator("WORLD_EDIT") Player p) { + public void genericRestoreCommand(@Validator Player p) { Region region = Region.getRegion(p.getLocation()); if(checkGlobalRegion(region, p)) return; @@ -114,7 +114,7 @@ public class RegionCommand extends SWCommand { } @Register(value = "restore", description = "REGION_REGION_HELP_RESTORE_SCHEMATIC") - public void schematicRestoreCommand(@Validator("WORLD_EDIT") Player p, SchematicNode node) { + public void schematicRestoreCommand(@Validator Player p, SchematicNode node) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) return; @@ -164,36 +164,6 @@ public class RegionCommand extends SWCommand { BauSystem.MESSAGE.send("REGION_REGION_TP_TEST_BLOCK", p); } - @Register(value = "changetype", description = "REGION_REGION_HELP_CHANGETYPE_INFO") - @Register("type") - public void changeTypeCommand(Player p) { - Region region = Region.getRegion(p.getLocation()); - if (checkGlobalRegion(region, p)) { - return; - } - BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_INFO", p, region.getPrototype().getDisplayName()); - } - - @Register(value = "changetype", description = "REGION_REGION_HELP_CHANGETYPE") - @Register("type") - public void changeTypeCommand(@Validator("WORLD") Player p, @Mapper("regionTypeMapper") String s) { - Region region = Region.getRegion(p.getLocation()); - if (checkGlobalRegion(region, p)) { - return; - } - Prototype prototype = Prototype.getByDisplayName(s); - if (prototype == null) { - BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_UNKNOWN", p); - } else { - if (region.setPrototype(prototype)) { - BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_CHANGE", p, s); - BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_CHANGE_UPDATE", p, BauSystem.MESSAGE.parse("REGION_REGION_CHANGETYPE_CHANGE_UPDATE_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/reset")); - } else { - BauSystem.MESSAGE.send("REGION_REGION_CHANGETYPE_INVALID", p); - } - } - } - @Register(value = "changeskin", description = "REGION_REGION_HELP_CHANGESKIN_INFO") @Register("skin") public void changeSkinCommand(Player p) { @@ -210,7 +180,7 @@ public class RegionCommand extends SWCommand { @Register(value = "changeskin", description = "REGION_REGION_HELP_CHANGESKIN") @Register("skin") - public void changeSkinCommand(@Validator("WORLD") Player p, @Mapper("skinTypeMapper") String s) { + public void changeSkinCommand(@Validator Player p, @Mapper("skinTypeMapper") String s) { Region region = Region.getRegion(p.getLocation()); if (checkGlobalRegion(region, p)) { return; @@ -227,26 +197,6 @@ public class RegionCommand extends SWCommand { } } - @Mapper(value = "regionTypeMapper", local = true) - private TypeMapper regionTypeMapper() { - return new TypeMapper() { - @Override - public List tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) { - Player p = (Player) commandSender; - Region region = Region.getRegion(p.getLocation()); - if (region.isGlobal()) { - return Collections.emptyList(); - } - return region.getPrototypes().stream().map(Prototype::getByName).map(Prototype::getDisplayName).map(c -> c.replace(' ', '_')).collect(Collectors.toList()); - } - - @Override - public String map(CommandSender commandSender, PreviousArguments previousArguments, String s) { - return s.replace('_', ' '); - } - }; - } - @Mapper(value = "skinTypeMapper", local = true) private TypeMapper skinTypeMapper() { return new TypeMapper() { @@ -266,18 +216,4 @@ public class RegionCommand extends SWCommand { } }; } - - @Validator(value = "WORLD", local = true) - public TypeValidator worldValidator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_REGION_NO_PERMS"); - }; - } - - @Validator(value = "WORLD_EDIT", local = true) - public TypeValidator worldEditValidator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_REGION_NO_PERMS"); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java index 03a22027..680224a7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/ResetCommand.java @@ -97,13 +97,6 @@ public class ResetCommand extends SWCommand { } } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_RESET_NO_PERMS"); - }; - } - private Region regionCheck(Player player) { Region region = Region.getRegion(player.getLocation()); if (region == GlobalRegion.getInstance()) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java index af9f3837..27dcbe8f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TNTCommand.java @@ -157,11 +157,4 @@ public class TNTCommand extends SWCommand { break; } } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "REGION_TNT_NO_PERMS"); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java index 3572cf71..6b319062 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/TestblockCommand.java @@ -157,11 +157,6 @@ public class TestblockCommand extends SWCommand { }; } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "REGION_TB_NO_PERMS"); - } - private Region regionCheck(Player player) { Region region = Region.getRegion(player.getLocation()); if (!region.hasType(RegionType.TESTBLOCK)) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java index 01714fba..79101ee9 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FireBauGuiItem.java @@ -57,6 +57,6 @@ public class FireBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLD; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java index 43d1903f..1406638c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/FreezeBauGuiItem.java @@ -57,6 +57,6 @@ public class FreezeBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLD; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java index 652c2fb2..a11e508d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ProtectBauGuiItem.java @@ -58,6 +58,6 @@ public class ProtectBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java index 79f6537a..e5295b2e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/ResetBauGuiItem.java @@ -65,6 +65,6 @@ public class ResetBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java index 7b0f25e0..355b5209 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TestblockBauGuiItem.java @@ -64,6 +64,6 @@ public class TestblockBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java index 673a9295..38f1b04a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/items/TntBauGuiItem.java @@ -116,6 +116,6 @@ public class TntBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLD; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java index 9d640d52..0194514f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java @@ -31,7 +31,7 @@ public class ScriptCommand extends SWCommand { } @Register - public void genericCommand(Player player) { + public void genericCommand(@Validator Player player) { ScriptGUI.open(player); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java index 61b8862d..14f8d983 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptListener.java @@ -19,6 +19,8 @@ package de.steamwar.bausystem.features.script; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.bausystem.utils.FlatteningWrapper; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; @@ -42,6 +44,8 @@ public class ScriptListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onLeftClick(PlayerInteractEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; + ItemStack item = event.getItem(); if (item == null || FlatteningWrapper.impl.isNoBook(item) || item.getItemMeta() == null) { return; @@ -68,6 +72,13 @@ public class ScriptListener implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; ScriptRunner.updateGlobalScript(event.getPlayer()); } + + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(ScriptRunner::remove); + event.getNewBuilder().forEach(ScriptRunner::updateGlobalScript); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java index 77bd991e..da5f1f21 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/CommandListener.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.features.script.event; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.script.ScriptRunner; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; @@ -41,6 +42,7 @@ public class CommandListener implements Listener { @EventHandler public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; String[] split = event.getMessage().split(" "); if (calledCommands.getOrDefault(event.getPlayer(), new HashSet<>()).contains(split[0])) { return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java index 89f9667e..c32b0231 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/EventListener.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.script.event; import de.steamwar.bausystem.BauSystem; +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; @@ -64,17 +65,20 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfJoin, LuaValue.NIL, event); } @EventHandler(priority = EventPriority.HIGH) public void onPlayerQuit(PlayerQuitEvent event) { StorageLib.removePlayer(event.getPlayer()); + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.SelfLeave, LuaValue.NIL, event); } @EventHandler(priority = EventPriority.HIGH) public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (LAST_FS.containsKey(event.getPlayer())) { Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { ScriptRunner.callEvent(event.getPlayer(), SteamWarGlobalLuaPlugin.EventType.DoubleSwap, LuaValue.NIL, event); @@ -86,6 +90,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onBlockPlace(BlockPlaceEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; LuaTable table = new LuaTable(); table.set("x", event.getBlock().getX()); table.set("y", event.getBlock().getY()); @@ -96,6 +101,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onBlockBreak(BlockBreakEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; LuaTable table = new LuaTable(); table.set("x", event.getBlock().getX()); table.set("y", event.getBlock().getY()); @@ -108,6 +114,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.LOW) public void onPlayerInteract(PlayerInteractEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (ignore.remove(event.getPlayer())) { return; } @@ -125,6 +132,7 @@ public class EventListener implements Listener { table.set("blockY", event.getClickedBlock().getY()); table.set("blockZ", event.getClickedBlock().getZ()); table.set("blockFace", event.getBlockFace().name()); + table.set("blockType", event.getClickedBlock().getType().name()); } else { table.set("hasBlock", LuaValue.valueOf(false)); } @@ -144,6 +152,7 @@ public class EventListener implements Listener { Region tntRegion = Region.getRegion(event.getLocation()); for (Player player : Bukkit.getOnlinePlayers()) { + if(!Permission.BUILD.hasPermission(player)) continue; if (tntRegion.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) { ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTSpawn, LuaValue.NIL, event); } @@ -165,6 +174,7 @@ public class EventListener implements Listener { boolean inBuild = event.blockList().stream().anyMatch(block -> tntRegion.inRegion(block.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)); for (Player player : Bukkit.getOnlinePlayers()) { + if(!Permission.BUILD.hasPermission(player)) continue; if (tntRegion.inRegion(player.getLocation(), RegionType.NORMAL, RegionExtensionType.NORMAL)) { ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.TNTExplode, table, event); if (inBuild) { @@ -176,6 +186,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onPlayerDropItem(PlayerDropItemEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; ignore.add(event.getPlayer()); LuaTable table = new LuaTable(); table.set("type", event.getItemDrop().getItemStack().getType().name()); @@ -185,6 +196,7 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onEntityDeath(EntityDeathEvent event) { for (Player player : Bukkit.getOnlinePlayers()) { + if(!Permission.BUILD.hasPermission(player)) continue; LuaTable table = new LuaTable(); table.set("type", event.getEntityType().name()); ScriptRunner.callEvent(player, SteamWarGlobalLuaPlugin.EventType.EntityDeath, table, event); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java index d27a314e..52843f79 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/event/HotkeyListener.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.script.event; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.script.ScriptRunner; import de.steamwar.linkage.Linked; import de.steamwar.linkage.api.Plain; @@ -36,6 +37,7 @@ public class HotkeyListener implements PluginMessageListener, Plain { @Override public void onPluginMessageReceived(String channel, Player player, byte[] message) { + if(!Permission.BUILD.hasPermission(player)) return; if (!channel.equals("sw:hotkeys")) return; if (message.length < 5) return; int action = message[4] & 0xFF; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java index 1e8ec13a..c047531c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/SteamWarLuaPlugin.java @@ -22,15 +22,21 @@ package de.steamwar.bausystem.features.script.lua; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.BukkitPlayer; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.extension.platform.Actor; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.features.script.ScriptRunner; import de.steamwar.bausystem.features.script.lua.libs.LuaLib; import de.steamwar.bausystem.features.world.WorldEditListener; import de.steamwar.bausystem.utils.WorldEditUtils; import de.steamwar.inventory.SWAnvilInv; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.BaseComponent; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -39,11 +45,10 @@ import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; -import org.luaj.vm2.lib.OneArgFunction; -import org.luaj.vm2.lib.ThreeArgFunction; -import org.luaj.vm2.lib.TwoArgFunction; -import org.luaj.vm2.lib.VarArgFunction; +import org.luaj.vm2.lib.*; +import java.lang.reflect.Proxy; +import java.net.InetSocketAddress; import java.util.*; import java.util.logging.Level; @@ -102,14 +107,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction { double x = arg1.checkdouble(); double y = arg2.checkdouble(); double z = arg3.checkdouble(); - - Location loc = new Location(player.getWorld(), x, y, z); - - return tableOf(new LuaValue[] { - valueOf("x"), valueOf(loc.getBlockX()), - valueOf("y"), valueOf(loc.getBlockY()), - valueOf("z"), valueOf(loc.getBlockZ()) - }); + return pos(x, y, z); } }); env.set("exec", new VarArgFunction() { @@ -122,6 +120,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction { return LuaValue.NIL; } + command = preprocessEvent.getMessage().substring(1); Bukkit.getLogger().log(Level.INFO, player.getName() + " dispatched command: " + command); String[] commandSplit = command.split(" "); if (!commandSplit[0].equals("select") && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) { @@ -166,11 +165,86 @@ public class SteamWarLuaPlugin extends TwoArgFunction { env.set("rawget", NIL); env.set("rawlen", NIL); env.set("rawset", NIL); - env.set("setmetatable", NIL); env.set("xpcall", NIL); return null; } + public static LuaTable pos(double x, double y, double z) { + LuaTable position = new LuaTable(); + position.set("x", x); + position.set("y", y); + position.set("z", z); + + position.set("add", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + LuaTable table = luaValue.checktable(); + double dx = table.get("x").checkdouble(); + double dy = table.get("y").checkdouble(); + double dz = table.get("z").checkdouble(); + return pos(x + dx, y + dy, z + dz); + } + }); + + position.set("subtract", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + LuaTable table = luaValue.checktable(); + double dx = table.get("x").checkdouble(); + double dy = table.get("y").checkdouble(); + double dz = table.get("z").checkdouble(); + return pos(x - dx, y - dy, z - dz); + } + }); + + position.set("addX", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + return pos(x + luaValue.checkdouble(), y, z); + } + }); + position.set("subtractX", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + return pos(x - luaValue.checkdouble(), y, z); + } + }); + position.set("addY", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + return pos(x, y + luaValue.checkdouble(), z); + } + }); + position.set("subtractY", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + return pos(x, y - luaValue.checkdouble(), z); + } + }); + position.set("addZ", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + return pos(x, y, z + luaValue.checkdouble()); + } + }); + position.set("subtractZ", new OneArgFunction() { + @Override + public LuaValue call(LuaValue luaValue) { + return pos(x, y, z - luaValue.checkdouble()); + } + }); + + position.set("blockPos", new ZeroArgFunction() { + @Override + public LuaValue call() { + Location location = new Location(Bukkit.getWorlds().get(0), x, y, z); + return pos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + }); + + return position; + } + public static String varArgsToString(Varargs args) { StringBuilder builder = new StringBuilder(); for (int i = 1; i <= args.narg(); i++) { @@ -192,7 +266,7 @@ public class SteamWarLuaPlugin extends TwoArgFunction { class Print extends VarArgFunction { @Override public Varargs invoke(Varargs args) { - player.sendMessage(varArgsToString(args)); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args))); return LuaValue.NIL; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java index b88ee9d0..a4af0d3a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/LuaLib.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.features.script.lua.libs; +import de.steamwar.bausystem.region.Point; import lombok.AllArgsConstructor; import org.bukkit.entity.Player; import org.luaj.vm2.*; @@ -69,6 +70,15 @@ public interface LuaLib { return de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin.varArgsToString(varargs); } + default LuaTable toPos(Point point) { + if (point == null) return LuaTable.tableOf(); + return LuaValue.tableOf(new LuaValue[] { + LuaValue.valueOf("x"), LuaValue.valueOf(point.getX()), + LuaValue.valueOf("y"), LuaValue.valueOf(point.getY()), + LuaValue.valueOf("z"), LuaValue.valueOf(point.getZ()) + }); + } + default Class parent() { return null; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java index 6ce317b3..d8576f81 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/PlayerLib.java @@ -19,9 +19,11 @@ package de.steamwar.bausystem.features.script.lua.libs; +import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin; import de.steamwar.linkage.Linked; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; import org.luaj.vm2.LuaTable; @@ -43,6 +45,12 @@ public class PlayerLib implements LuaLib { table.set("chat", new Print(player)); table.set("actionbar", new SendActionbar(player)); + table.set("pos", getter(() -> { + return SteamWarLuaPlugin.pos(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ()); + })); + table.set("blockPos", getter(() -> { + return SteamWarLuaPlugin.pos(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()); + })); table.set("x", getterAndSetter("x", () -> player.getLocation().getX(), x -> { Location location = player.getLocation(); location.setX(x); @@ -93,7 +101,7 @@ public class PlayerLib implements LuaLib { @Override public Varargs invoke(Varargs args) { - player.sendMessage(varArgsToString(args)); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', varArgsToString(args))); return LuaValue.NIL; } } @@ -107,7 +115,7 @@ public class PlayerLib implements LuaLib { @Override public Varargs invoke(Varargs args) { - player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(varArgsToString(args))); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(ChatColor.translateAlternateColorCodes('&', varArgsToString(args)))); return LuaValue.NIL; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java index 17c07230..f615dad3 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/RegionLib.java @@ -78,6 +78,17 @@ public class RegionLib implements LuaLib { Loader loader = Loader.getLoader(player); table.set("loader", getter(() -> loader == null ? "OFF" : loader.getStage().name())); + + table.set("copyPoint", getter(() -> toPos(region.get().getCopyPoint()))); + table.set("minPointBuild", getter(() -> toPos(region.get().getMinPointBuild()))); + table.set("maxPointBuild", getter(() -> toPos(region.get().getMaxPointBuild()))); + table.set("minPointBuildExtension", getter(() -> toPos(region.get().getMinPointBuildExtension()))); + table.set("maxPointBuildExtension", getter(() -> toPos(region.get().getMaxPointBuildExtension()))); + table.set("testblockPoint", getter(() -> toPos(region.get().getTestBlockPoint()))); + table.set("minPointTestblock", getter(() -> toPos(region.get().getMinPointTestblock()))); + table.set("maxPointTestblock", getter(() -> toPos(region.get().getMaxPointTestblock()))); + table.set("minPointTestblockExtension", getter(() -> toPos(region.get().getMinPointTestblockExtension()))); + table.set("maxPointTestblockExtension", getter(() -> toPos(region.get().getMaxPointTestblockExtension()))); return table; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ScoreboardLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ScoreboardLib.java new file mode 100644 index 00000000..af9c67ae --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ScoreboardLib.java @@ -0,0 +1,75 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.script.lua.libs; + +import de.steamwar.bausystem.features.world.BauScoreboard; +import de.steamwar.bausystem.utils.ScoreboardElement; +import de.steamwar.linkage.Linked; +import org.bukkit.entity.Player; +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; +import org.luaj.vm2.Varargs; +import org.luaj.vm2.lib.TwoArgFunction; +import org.luaj.vm2.lib.VarArgFunction; + +@Linked +public class ScoreboardLib implements LuaLib { + + @Override + public String name() { + return "scoreboard"; + } + + @Override + public LuaTable get(Player player) { + LuaTable luaTable = new LuaTable(); + + LuaTable groups = new LuaTable(); + for (ScoreboardElement.ScoreboardGroup group : ScoreboardElement.ScoreboardGroup.values()) { + groups.set(group.name(), group.ordinal()); + } + luaTable.set("group", groups); + + luaTable.set("element", new VarArgFunction() { + @Override + public Varargs invoke(Varargs varargs) { + if (varargs.narg() < 2) { + return NIL; + } + String elementKey = varargs.arg(1).checkjstring(); + ScoreboardElement.ScoreboardGroup elementGroup = ScoreboardElement.ScoreboardGroup.values()[varargs.arg(2).checkint()]; + int priority = varargs.narg() > 2 ? varargs.arg(2).checkint() : Integer.MAX_VALUE; + + return new VarArgFunction() { + @Override + public Varargs invoke(Varargs args) { + if (args.narg() == 0) { + BauScoreboard.setAdditionalElement(player, elementKey, elementGroup, priority, null); + } else { + BauScoreboard.setAdditionalElement(player, elementKey, elementGroup, priority, args.arg1().checkjstring()); + } + return NIL; + } + }; + } + }); + return luaTable; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java index 80134fba..10a41830 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/ServerLib.java @@ -20,11 +20,15 @@ package de.steamwar.bausystem.features.script.lua.libs; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.features.loader.Loader; +import de.steamwar.bausystem.features.loader.LoaderRecorder; import de.steamwar.bausystem.features.tpslimit.TPSUtils; -import de.steamwar.core.TPSWatcher; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; +import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.luaj.vm2.LuaString; import org.luaj.vm2.LuaTable; @@ -46,10 +50,14 @@ public class ServerLib implements LuaLib { public LuaTable get(Player player) { LuaTable serverLib = LuaValue.tableOf(); serverLib.set("time", getter(() -> new SimpleDateFormat(BauSystem.MESSAGE.parse("TIME", player)).format(Calendar.getInstance().getTime()))); + serverLib.set("onlinePlayerCount", getter(Bukkit.getOnlinePlayers()::size)); serverLib.set("ticks", getter(TPSUtils.currentTick)); serverLib.set("getBlockAt", new OneArgFunction() { @Override public LuaValue call(LuaValue arg1) { + if (!Permission.SUPERVISOR.hasPermission(player)) { + return LuaValue.NIL; + } LuaTable pos = arg1.checktable(); return valueOf(player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint()).getType().name()); } @@ -57,6 +65,9 @@ public class ServerLib implements LuaLib { serverLib.set("setBlockAt", new TwoArgFunction() { @Override public LuaValue call(LuaValue arg1, LuaValue arg2) { + if (!Permission.SUPERVISOR.hasPermission(player)) { + return LuaValue.NIL; + } LuaTable pos = arg1.checktable(); LuaString material = arg2.checkstring(); Material mat = SWItem.getMaterial(material.tojstring()); @@ -67,17 +78,19 @@ public class ServerLib implements LuaLib { return NIL; } }); - - LuaValue tpsLib = LuaValue.tableOf(); - tpsLib.set("oneSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND))); - tpsLib.set("tenSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS))); - tpsLib.set("oneMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE))); - 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(TPSLimitUtils::getCurrentTPSLimit)); - - serverLib.set("tps", tpsLib); + serverLib.set("interactAt", new OneArgFunction() { + @Override + public LuaValue call(LuaValue arg1) { + LuaTable pos = arg1.checktable(); + Block block = player.getWorld().getBlockAt(pos.get("x").checkint(), pos.get("y").checkint(), pos.get("z").checkint()); + LoaderRecorder.getLoaderInteractionElement(block, (loaderInteractionElement, s) -> { + loaderInteractionElement.execute(aLong -> { + // Ignore + }); + }); + return NIL; + } + }); return serverLib; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java index 033c5f98..898b68a7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java @@ -19,8 +19,14 @@ package de.steamwar.bausystem.features.script.lua.libs; +import com.google.gson.*; import de.steamwar.bausystem.region.Region; +import de.steamwar.core.Core; import de.steamwar.linkage.Linked; +import de.steamwar.linkage.api.Disable; +import de.steamwar.linkage.api.Enable; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; @@ -29,15 +35,173 @@ import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.TwoArgFunction; import org.luaj.vm2.lib.VarArgFunction; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; import java.util.HashMap; +import java.util.Map; +import java.util.UUID; @Linked -public class StorageLib implements LuaLib { +public class StorageLib implements LuaLib, Enable, Disable { + + private final Gson gson = new Gson(); + private final File storageDirectory = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "script_storage"); private static final HashMap GLOBAL_STORAGE = new HashMap<>(); - private static final HashMap> PLAYER_STORAGE = new HashMap<>(); + private static final HashMap> PLAYER_STORAGE = new HashMap<>(); private static final HashMap> REGION_STORAGE = new HashMap<>(); + @Override + public void enable() { + if (Core.getVersion() <= 15) return; + if (!storageDirectory.exists()) storageDirectory.mkdirs(); + + try { + JsonObject jsonObject = JsonParser.parseReader(new FileReader(new File(storageDirectory, "global.json"))).getAsJsonObject(); + jsonObject.keySet().forEach(key -> { + GLOBAL_STORAGE.put(key, fromJson(jsonObject.get(key))); + }); + } catch (Exception e) {} + + File regionStorageDirectory = new File(storageDirectory, "region"); + regionStorageDirectory.mkdirs(); + for (File regionStorage : regionStorageDirectory.listFiles()) { + try { + JsonObject jsonObject = JsonParser.parseReader(new FileReader(regionStorage)).getAsJsonObject(); + HashMap map = new HashMap<>(); + jsonObject.keySet().forEach(key -> { + map.put(key, fromJson(jsonObject.get(key))); + }); + Region region = Region.getREGION_MAP().get(regionStorage.getName().substring(0, regionStorage.getName().length() - ".json".length())); + REGION_STORAGE.put(region, map); + } catch (Exception e) {} + } + + File playerStorageDirectory = new File(storageDirectory, "player"); + playerStorageDirectory.mkdirs(); + for (File playerStorage : playerStorageDirectory.listFiles()) { + try { + JsonObject jsonObject = JsonParser.parseReader(new FileReader(playerStorage)).getAsJsonObject(); + HashMap map = new HashMap<>(); + jsonObject.keySet().forEach(key -> { + map.put(key, fromJson(jsonObject.get(key))); + }); + SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length()))); + PLAYER_STORAGE.put(steamwarUser.getUUID(), map); + } catch (Exception e) {} + } + } + + private LuaValue fromJson(JsonElement jsonElement) { + if (jsonElement.isJsonNull()) { + return LuaValue.NIL; + } + if (jsonElement.isJsonPrimitive()) { + JsonPrimitive jsonPrimitive = jsonElement.getAsJsonPrimitive(); + if (jsonPrimitive.isBoolean()) { + return LuaValue.valueOf(jsonPrimitive.getAsBoolean()); + } + if (jsonPrimitive.isNumber()) { + try { + return LuaValue.valueOf(jsonPrimitive.getAsInt()); + } catch (NumberFormatException e) {} + try { + return LuaValue.valueOf(jsonPrimitive.getAsDouble()); + } catch (NumberFormatException e) {} + } + if (jsonPrimitive.isString()) { + return LuaValue.valueOf(jsonPrimitive.getAsString()); + } + return null; + } + if (jsonElement.isJsonObject()) { + JsonObject jsonObject = jsonElement.getAsJsonObject(); + LuaTable luaTable = new LuaTable(); + jsonObject.keySet().forEach(string -> { + LuaValue value = fromJson(jsonObject.get(string)); + if (value == null) return; + luaTable.set(string, value); + }); + return luaTable; + } + return null; + } + + @Override + public void disable() { + if (Core.getVersion() <= 15) return; + if (!storageDirectory.exists()) storageDirectory.mkdirs(); + try { + FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json")); + gson.toJson(toJson(GLOBAL_STORAGE), fileWriter); + fileWriter.close(); + } catch (IOException e) {} + + File regionStorageDirectory = new File(storageDirectory, "region"); + regionStorageDirectory.mkdirs(); + for (Map.Entry> entry : REGION_STORAGE.entrySet()) { + try { + FileWriter fileWriter = new FileWriter(new File(regionStorageDirectory, entry.getKey().getName() + ".json")); + gson.toJson(toJson(entry.getValue()), fileWriter); + fileWriter.close(); + } catch (IOException e) {} + } + + File playerStorageDirectory = new File(storageDirectory, "player"); + playerStorageDirectory.mkdirs(); + for (Map.Entry> entry : PLAYER_STORAGE.entrySet()) { + try { + FileWriter fileWriter = new FileWriter(new File(playerStorageDirectory, SteamwarUser.get(entry.getKey()).getId() + ".json")); + gson.toJson(toJson(entry.getValue()), fileWriter); + fileWriter.close(); + } catch (IOException e) {} + } + } + + private JsonObject toJson(HashMap valueMap) { + JsonObject jsonObject = new JsonObject(); + valueMap.forEach((string, luaValue) -> { + JsonElement value = toJson(luaValue); + if (value == null) return; + jsonObject.add(string, value); + }); + return jsonObject; + } + + private JsonElement toJson(LuaValue luaValue) { + if (luaValue.isnil()) { + return JsonNull.INSTANCE; + } + try { + return new JsonPrimitive(luaValue.checkboolean()); + } catch (Exception e) {} + try { + return new JsonPrimitive(luaValue.checkint()); + } catch (Exception e) {} + try { + return new JsonPrimitive(luaValue.checkdouble()); + } catch (Exception e) {} + + if (luaValue.isstring()) { + return new JsonPrimitive(luaValue.tojstring()); + } + if (luaValue.istable()) { + LuaTable luaTable = luaValue.checktable(); + JsonObject jsonObject = new JsonObject(); + for (LuaValue key : luaTable.keys()) { + JsonElement value = toJson(luaTable.get(key)); + if (value == null) continue; + try { + jsonObject.add(key.checkjstring(), value); + } catch (Exception e) {} + } + return jsonObject; + } + return null; + } + @Override public String name() { return "storage"; @@ -92,7 +256,7 @@ public class StorageLib implements LuaLib { storageLib.set("global", global); LuaTable playerStorage = new LuaTable(); - HashMap playerStorageMap = PLAYER_STORAGE.computeIfAbsent(player, k -> new HashMap<>()); + HashMap playerStorageMap = PLAYER_STORAGE.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()); playerStorage.set("get", new OneArgFunction() { @Override public LuaValue call(LuaValue arg) { @@ -137,34 +301,38 @@ public class StorageLib implements LuaLib { storageLib.set("player", playerStorage); LuaTable regionStorage = new LuaTable(); - HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>()); regionStorage.set("get", new OneArgFunction() { @Override public LuaValue call(LuaValue arg) { + HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>()); return regionStorageMap.getOrDefault(arg.checkjstring(), NIL); } }); regionStorage.set("set", new TwoArgFunction() { @Override public LuaValue call(LuaValue arg1, LuaValue arg2) { + HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>()); return regionStorageMap.put(arg1.checkjstring(), arg2); } }); regionStorage.set("has", new OneArgFunction() { @Override public LuaValue call(LuaValue arg) { + HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>()); return valueOf(regionStorageMap.containsKey(arg.checkjstring())); } }); regionStorage.set("remove", new OneArgFunction() { @Override public LuaValue call(LuaValue arg) { + HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>()); return regionStorageMap.remove(arg.checkjstring()); } }); regionStorage.set("accessor", new OneArgFunction() { @Override public LuaValue call(LuaValue arg) { + HashMap regionStorageMap = REGION_STORAGE.computeIfAbsent(Region.getRegion(player.getLocation()), k -> new HashMap<>()); String key = arg.checkjstring(); return new VarArgFunction() { @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java new file mode 100644 index 00000000..3b0b430d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/TpsLib.java @@ -0,0 +1,53 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.script.lua.libs; + +import de.steamwar.bausystem.features.tpslimit.TPSSystem; +import de.steamwar.core.TPSWatcher; +import de.steamwar.linkage.Linked; +import org.bukkit.entity.Player; +import org.luaj.vm2.LuaTable; + +@Linked +public class TpsLib implements LuaLib { + + @Override + public Class parent() { + return ServerLib.class; + } + + @Override + public String name() { + return "tps"; + } + + @Override + public LuaTable get(Player player) { + LuaTable tpsLib = new LuaTable(); + tpsLib.set("oneSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND))); + tpsLib.set("tenSecond", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS))); + tpsLib.set("oneMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE))); + 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.getInstance()::getCurrentTPSLimit)); + return tpsLib; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java index 197300d0..1aa4149a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrinting.java @@ -20,8 +20,10 @@ package de.steamwar.bausystem.features.shieldprinting; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.features.shieldprinting.impl.*; import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; import de.steamwar.bausystem.utils.bossbar.BossBarService; import de.steamwar.inventory.SWItem; @@ -43,6 +45,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockCanBuildEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; @@ -259,18 +262,14 @@ public class ShieldPrinting implements Listener { } @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getClickedBlock() == null) return; - if (event.getItem() == null) return; - if (Region.getRegion(event.getClickedBlock().getLocation()) != region) return; - Vector vector = event.getClickedBlock().getLocation().toVector(); - if (!shieldMap.containsKey(vector)) return; - event.getClickedBlock().setType(Material.AIR); + public void onPlayerJoin(PlayerJoinEvent event) { + updateBossbar(event.getPlayer()); } @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - updateBossbar(event.getPlayer()); + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(player -> BossBarService.instance.remove(player, region, "shieldprinting")); + event.getNewBuilder().forEach(this::updateBossbar); } private void updateBossbars() { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java index d1b60349..5bb60219 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/shieldprinting/ShieldPrintingCommand.java @@ -26,9 +26,7 @@ import de.steamwar.command.SWCommand; import de.steamwar.command.TypeValidator; import de.steamwar.linkage.Linked; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEvent; import java.util.HashMap; import java.util.Map; @@ -108,8 +106,8 @@ public class ShieldPrintingCommand extends SWCommand implements Listener { @ClassValidator(value = Player.class, local = true) public TypeValidator validator() { return (commandSender, player, messageSender) -> { - if (!Permission.hasPermission(player, Permission.WORLD)) { - messageSender.send("SHIELD_PRINTING_DISALLOWED", player); + if (!Permission.BUILD.hasPermission(player)) { + messageSender.send("NO_PERMISSION", player); return false; } Region region = Region.getRegion(player.getLocation()); @@ -120,20 +118,4 @@ public class ShieldPrintingCommand extends SWCommand implements Listener { return true; }; } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getClickedBlock() == null) { - return; - } - Region region = Region.getRegion(event.getClickedBlock().getLocation()); - if (region.isGlobal()) { - return; - } - ShieldPrinting shieldPrinting = SHIELD_PRINTING_MAP.get(region); - if (shieldPrinting == null) { - return; - } - shieldPrinting.onPlayerInteract(event); - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/OrderUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/OrderUtils.java deleted file mode 100644 index 2c377cea..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/OrderUtils.java +++ /dev/null @@ -1,92 +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 . - */ - -package de.steamwar.bausystem.features.simulator; - -import de.steamwar.bausystem.BauSystem; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@UtilityClass -public class OrderUtils { - - private final List activationOrder = new ArrayList<>(); - - private final Map nameMap = new HashMap<>(); - - static { - add(Material.REPEATER, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_REPEATER"); - add(Material.OBSERVER, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_OBSERVER"); - add(Material.COMPARATOR, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_COMPARATOR"); - } - - public Material next(Material material) { - int index = activationOrder.indexOf(material); - if (index == -1) { - return activationOrder.get(0); - } - if (index + 1 >= activationOrder.size()) { - return activationOrder.get(0); - } - return activationOrder.get(index + 1); - } - - public Material previous(Material material) { - int index = activationOrder.indexOf(material); - if (index == -1) { - return activationOrder.get(0); - } - if (index - 1 < 0) { - return activationOrder.get(activationOrder.size() - 1); - } - return activationOrder.get(index - 1); - } - - public List orderList(Material material, Player player) { - List lore = new ArrayList<>(); - for (Material m : activationOrder) { - String element = BauSystem.MESSAGE.parse(name(m), player); - if (m == material) { - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ACTIVE", player, element)); - } else { - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_INACTIVE", player, element)); - } - } - return lore; - } - - public int order(Material material) { - return activationOrder.indexOf(material); - } - - public String name(Material material) { - return nameMap.getOrDefault(material, "SIMULATOR_TNT_SPAWN_ACTIVATED_WITH_UNKNOWN"); - } - - private void add(Material material, String name) { - activationOrder.add(material); - nameMap.put(material, name); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java index baae7add..d03dc55c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorBauGuiItem.java @@ -1,20 +1,20 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2021 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.simulator; @@ -55,6 +55,6 @@ public class SimulatorBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLD; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java index 640d0360..06af3e68 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCommand.java @@ -1,20 +1,20 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.simulator; @@ -22,105 +22,78 @@ package de.steamwar.bausystem.features.simulator; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.SWUtils; -import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI; -import de.steamwar.bausystem.utils.ItemUtils; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.execute.SimulatorExecutor; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; import de.steamwar.command.TypeValidator; import de.steamwar.linkage.Linked; +import de.steamwar.linkage.LinkedInstance; +import de.steamwar.linkage.MinVersion; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; import java.util.Collection; @Linked +@MinVersion(19) public class SimulatorCommand extends SWCommand { + @LinkedInstance + public SimulatorCursor simulatorCursor; + public SimulatorCommand() { - super("simulator", "sim"); + super("sim", "simulator"); } @Register(description = "SIMULATOR_HELP") public void genericCommand(@Validator Player p) { - SimulatorCursor.hide(p, null); SWUtils.giveItemToPlayer(p, SimulatorStorage.getWand(p)); + simulatorCursor.calcCursor(p); } @Register(value = "change", description = "SIMULATOR_CHANGE_HELP") public void change(@Validator Player p) { - ItemStack itemStack = p.getInventory().getItemInMainHand(); - if (!ItemUtils.isItem(itemStack, "simulator")) { + if (!SimulatorCursor.isSimulatorItem(p.getInventory().getItemInMainHand()) && !SimulatorCursor.isSimulatorItem(p.getInventory().getItemInOffHand())) { BauSystem.MESSAGE.send("SIMULATOR_NO_SIM_IN_HAND", p); return; } - SimulatorSelectionGUI.open(p, itemStack); - } - - @Register(value = "create", description = "SIMULATOR_CREATE_HELP") - public void create(@Validator Player p, String name) { - createSimulator(p, name); - } - - public static boolean createSimulator(Player p, String name) { - if (SimulatorStorage.getSimulatorNames().contains(name)) { - BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", p); - return false; - } - if (!name.matches("[a-zA-Z_0-9-]+")) { - BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", p); - return false; - } - SimulatorStorage.createNewSimulator(name); - BauSystem.MESSAGE.send("SIMULATOR_CREATE", p); - return true; - } - - @Register(value = "delete", description = "SIMULATOR_DELETE_HELP") - public void delete(@Validator Player p, @Mapper("simulators") String name) { - if (!SimulatorStorage.getSimulatorNames().contains(name)) { - BauSystem.MESSAGE.send("SIMULATOR_NOT_EXISTS", p); - return; - } - SimulatorStorage.delete(name); - BauSystem.MESSAGE.send("SIMULATOR_DELETED", p); - } - - @Register(value = "start", description = "SIMULATOR_START_HELP") - public void start(@Validator Player p, @Mapper("simulators") String name) { - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(name); - if (tntSimulator == null) { - BauSystem.MESSAGE.send("SIMULATOR_NOT_EXISTS", p); - return; - } - tntSimulator.start(p); + SimulatorStorage.openSimulatorSelector(p); } @Register(value = "copy", description = "SIMULATOR_COPY_HELP") - public void copy(@Validator Player p, @Mapper("simulators") String toCopy, String name) { - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(toCopy); - if (tntSimulator == null) { - BauSystem.MESSAGE.send("SIMULATOR_NOT_EXISTS", p); - return; - } + public void copy(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator, String name) { if (SimulatorStorage.getSimulator(name) != null) { BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", p); return; } - SimulatorStorage.copySimulator(tntSimulator, name); + if (!name.matches("[a-zA-Z_0-9-]+")) { + BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", p); + return; + } + if (!SimulatorStorage.copy(simulator, name)) { + BauSystem.MESSAGE.send("SIMULATOR_ERROR_COPY", p); + } } - @Mapper("simulators") - public TypeMapper allSimulators() { - return new TypeMapper() { + @Register(value = "delete", description = "SIMULATOR_DELETE_HELP") + public void delete(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) { + SimulatorStorage.delete(simulator); + BauSystem.MESSAGE.send("SIMULATOR_DELETED", p); + } + + @Register(value = "start", description = "SIMULATOR_START_HELP") + public void start(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) { + SimulatorExecutor.run(simulator); + } + + @ClassMapper(value = Simulator.class, local = true) + public TypeMapper allSimulators() { + return new TypeMapper<>() { @Override - public String map(CommandSender commandSender, PreviousArguments previousArguments, String s) { - if (SimulatorStorage.getSimulatorNames().contains(s)) { - return s; - } else { - return null; - } + public Simulator map(CommandSender commandSender, PreviousArguments previousArguments, String s) { + return SimulatorStorage.getSimulator(s); } @Override @@ -129,11 +102,4 @@ public class SimulatorCommand extends SWCommand { } }; } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "SIMULATOR_NO_PERMS"); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java index e8fc1bac..a7664158 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorCursor.java @@ -1,107 +1,248 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.simulator; +import com.comphenix.tinyprotocol.Reflection; +import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; +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.SimulatorExecutor; +import de.steamwar.bausystem.features.simulator.gui.SimulatorGroupGui; +import de.steamwar.bausystem.features.simulator.gui.SimulatorGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; +import de.steamwar.bausystem.utils.ItemUtils; import de.steamwar.bausystem.utils.RayTraceUtils; +import de.steamwar.entity.REntity; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; -import lombok.experimental.UtilityClass; -import net.md_5.bungee.api.ChatMessageType; +import de.steamwar.inventory.SWAnvilInv; +import de.steamwar.linkage.Linked; +import de.steamwar.linkage.MinVersion; +import lombok.AllArgsConstructor; +import lombok.Getter; 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.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.*; +import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; -@UtilityClass -public class SimulatorCursor { +@Linked +@MinVersion(19) +public class SimulatorCursor implements Listener { - private static final World WORLD = Bukkit.getWorlds().get(0); - private Map rEntityServerMap = new HashMap<>(); + 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"); - public void show(Player player, TNTSimulator tntSimulator, RayTraceUtils.RRayTraceResult result) { - REntityServer cursor = rEntityServerMap.get(player); + private Map cursorType = Collections.synchronizedMap(new HashMap<>()); + private Map cursors = Collections.synchronizedMap(new HashMap<>()); + private final Set calculating = new HashSet<>(); - if (cursor != null) - cursor.close(); - - tntSimulator.show(player); - - if (result == null) - return; - - if (result.getHitEntity() != null) { - List elements = tntSimulator.getEntity(result.getHitEntity()); - - cursor = new REntityServer(); - RFallingBlockEntity entity = new RFallingBlockEntity(cursor, (elements.isEmpty() ? getPos(player, result) : elements.get(0).getPosition()).toLocation(WORLD), Material.TNT); - entity.setNoGravity(true); - entity.setGlowing(true); - cursor.addPlayer(player); - rEntityServerMap.put(player, cursor); - BauSystem.MESSAGE.sendPrefixless("SIMULATOR_POSITION_EDIT", player, ChatMessageType.ACTION_BAR); - return; - } - - if (SimulatorStorage.getSimulator(player.getInventory().getItemInOffHand()) != null && result.getHitPosition().distanceSquared(player.getLocation().toVector()) < 25) { - return; - } - - cursor = new REntityServer(); - RFallingBlockEntity entity = new RFallingBlockEntity(cursor, getPos(player, result).toLocation(WORLD), Material.TNT); - entity.setNoGravity(true); - cursor.addPlayer(player); - rEntityServerMap.put(player, cursor); - BauSystem.MESSAGE.sendPrefixless("SIMULATOR_POSITION_ADD", player, ChatMessageType.ACTION_BAR); + public static boolean isSimulatorItem(ItemStack itemStack) { + return ItemUtils.isItem(itemStack, "simulator"); } - public void hide(Player player) { - REntityServer cursor = rEntityServerMap.get(player); - if (cursor == null) return; + public SimulatorCursor() { + BiFunction function = (player, object) -> { + calcCursor(player); + return object; + }; + TinyProtocol.instance.addFilter(position, function); + TinyProtocol.instance.addFilter(look, function); + TinyProtocol.instance.addFilter(positionLook, function); + } - cursor.close(); - SimulatorStorage.getSimulatorNames().forEach(s -> { - SimulatorStorage.getSimulator(s).hide(player); + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + calcCursor(event.getPlayer()); + }, 0); + } + + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + calcCursor(event.getPlayer()); + } + + @EventHandler + public void onPlayerItemHeld(PlayerItemHeldEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + calcCursor(event.getPlayer()); + }, 1); + } + + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getChanged().forEach(this::calcCursor); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + cursorType.remove(event.getPlayer()); + cursors.remove(event.getPlayer()); + synchronized (calculating) { + calculating.remove(event.getPlayer()); + } + } + + private static final Map LAST_SNEAKS = new HashMap<>(); + + static { + Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> { + long millis = System.currentTimeMillis(); + LAST_SNEAKS.entrySet().removeIf(entry -> millis - entry.getValue() > 200); + }, 1, 1); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerToggleSneak(PlayerToggleSneakEvent event) { + if (!event.isSneaking()) return; + Player player = event.getPlayer(); + if (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand())) { + return; + } + if (LAST_SNEAKS.containsKey(player)) { + cursorType.put(player, cursorType.getOrDefault(player, CursorType.TNT).switchType()); + calcCursor(player); + } else { + LAST_SNEAKS.put(player, System.currentTimeMillis()); + } + } + + public void calcCursor(Player player) { + synchronized (calculating) { + if (calculating.contains(player)) return; + calculating.add(player); + } + if (!Permission.BUILD.hasPermission(player) || (!isSimulatorItem(player.getInventory().getItemInMainHand()) && !isSimulatorItem(player.getInventory().getItemInOffHand()))) { + if (removeCursor(player) || SimulatorWatcher.show(null, player)) { + SWUtils.sendToActionbar(player, ""); + } + synchronized (calculating) { + calculating.remove(player); + } + return; + } + Simulator simulator = SimulatorStorage.getSimulator(player); + SimulatorWatcher.show(simulator, player); + + List entities = SimulatorWatcher.getEntitiesOfSimulator(simulator); + RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities); + if (rayTraceResult == null) { + removeCursor(player); + if (simulator == null) { + SWUtils.sendToActionbar(player, "§eSelect Simulator"); + } else { + SWUtils.sendToActionbar(player, "§eOpen Simulator"); + } + synchronized (calculating) { + calculating.remove(player); + } + return; + } + + showCursor(player, rayTraceResult, simulator != null); + synchronized (calculating) { + calculating.remove(player); + } + } + + private synchronized boolean removeCursor(Player player) { + REntityServer entityServer = cursors.get(player); + boolean hadCursor = entityServer != null && !entityServer.getEntities().isEmpty(); + if (entityServer != null) { + entityServer.getEntities().forEach(REntity::die); + } + return hadCursor; + } + + private synchronized void showCursor(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, boolean hasSimulatorSelected) { + REntityServer entityServer = cursors.computeIfAbsent(player, __ -> { + REntityServer rEntityServer = new REntityServer(); + rEntityServer.addPlayer(player); + return rEntityServer; }); - } - public void hide(Player player, TNTSimulator tntSimulator) { - REntityServer cursor = rEntityServerMap.get(player); + CursorType type = cursorType.getOrDefault(player, CursorType.TNT); + REntity hitEntity = rayTraceResult.getHitEntity(); + Location location = hitEntity != null ? new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD) : + type.position.apply(player, rayTraceResult).toLocation(WORLD); - if (cursor != null) - cursor.close(); - - if (tntSimulator != null) { - tntSimulator.hide(player); + Material material = hitEntity != null ? Material.GLASS : type.getMaterial(); + List entities = entityServer.getEntitiesByType(RFallingBlockEntity.class); + entities.removeIf(rFallingBlockEntity -> { + if (rFallingBlockEntity.getMaterial() != material) { + rFallingBlockEntity.die(); + return true; + } + rFallingBlockEntity.move(location); + return false; + }); + if (entities.isEmpty()) { + RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(entityServer, location, material); + rFallingBlockEntity.setNoGravity(true); + if (material == Material.GLASS) { + rFallingBlockEntity.setGlowing(true); + } + } + + if (hasSimulatorSelected) { + if (hitEntity != null) { + SWUtils.sendToActionbar(player, "§eEdit Position"); + } else { + SWUtils.sendToActionbar(player, "§eAdd new " + type.name); + } + } else { + SWUtils.sendToActionbar(player, "§eCreate new Simulator"); } - rEntityServerMap.remove(player); } - public static Vector getPos(Player player, RayTraceUtils.RRayTraceResult result) { + public static Vector getPosFree(Player player, RayTraceUtils.RRayTraceResult result) { Vector pos = result.getHitPosition(); BlockFace face = result.getHitBlockFace(); @@ -140,4 +281,177 @@ public class SimulatorCursor { return pos; } + + private static Vector getPosBlockAligned(Player player, RayTraceUtils.RRayTraceResult result) { + Vector pos = result.getHitPosition(); + + BlockFace face = result.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; + } + + @Getter + @AllArgsConstructor + public enum CursorType { + TNT(Material.TNT, SimulatorCursor::getPosFree, "TNT", vector -> new TNTElement(vector).add(new TNTPhase())), + REDSTONE_BLOCK(Material.REDSTONE_BLOCK, SimulatorCursor::getPosBlockAligned, "Redstone Block", vector -> new RedstoneElement(vector).add(new RedstonePhase())), + OBSERVER(Material.OBSERVER, SimulatorCursor::getPosBlockAligned, "Observer", vector -> new ObserverElement(vector).add(new ObserverPhase())), + ; + + private Material material; + private BiFunction position; + private String name; + private Function> elementFunction; + + public CursorType switchType() { + if (this == TNT) { + return REDSTONE_BLOCK; + } + if (this == REDSTONE_BLOCK) { + return OBSERVER; + } + return TNT; + } + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (!ItemUtils.isItem(event.getItem(), "simulator")) { + return; + } + + event.setCancelled(true); + Player player = event.getPlayer(); + Simulator simulator = SimulatorStorage.getSimulator(player); + + if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) { + if (simulator == null) { + return; + } + SimulatorExecutor.run(simulator); + return; + } + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_AIR) { + return; + } + + + RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), SimulatorWatcher.getEntitiesOfSimulator(simulator)); + if (simulator == null) { + if (rayTraceResult == null) { + SimulatorStorage.openSimulatorSelector(player); + } else { + SWAnvilInv anvilInv = new SWAnvilInv(player, "Name"); + anvilInv.setCallback(s -> { + Simulator sim = SimulatorStorage.getSimulator(s); + if (sim != null) { + BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", player); + return; + } + if (!s.matches("[a-zA-Z_0-9-]+")) { + BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", player); + return; + } + sim = new Simulator(s); + SimulatorStorage.addSimulator(s, sim); + createElement(player, rayTraceResult, sim); + SimulatorStorage.setSimulator(player, sim); + }); + anvilInv.open(); + } + return; + } + + if (rayTraceResult == null) { + new SimulatorGui(player, simulator).open(); + return; + } + + if (rayTraceResult.getHitEntity() != null) { + REntity hitEntity = rayTraceResult.getHitEntity(); + Vector vector = new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()); + List> elements = simulator.getGroups().stream().map(SimulatorGroup::getElements).flatMap(List::stream).filter(element -> { + return element.getWorldPos().distanceSquared(vector) < (1 / 16.0) * (1 / 16.0); + }).collect(Collectors.toList()); + + switch (elements.size()) { + case 0: + return; + case 1: + // Open single element present in Simulator + SimulatorElement element = elements.get(0); + SimulatorGroup group1 = element.getGroup(simulator); + SimulatorBaseGui back = new SimulatorGui(player, simulator); + if (group1.getElements().size() > 1) { + back = new SimulatorGroupGui(player, simulator, group1, back); + } + element.open(player, simulator, group1, back); + break; + default: + List parents = elements.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList()); + if (parents.size() == 1) { + // Open multi element present in Simulator in existing group + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + new SimulatorGroupGui(player, simulator, parents.get(0), simulatorGui).open(); + } else { + // Open multi element present in Simulator in implicit group + SimulatorGroup group2 = new SimulatorGroup(); + group2.setMaterial(null); + group2.getElements().addAll(elements); + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + new SimulatorGroupGui(player, simulator, group2, simulatorGui).open(); + } + break; + } + return; + } + + // Add new Element to current simulator + createElement(player, rayTraceResult, simulator); + } + + private void createElement(Player player, RayTraceUtils.RRayTraceResult rayTraceResult, Simulator simulator) { + CursorType type = cursorType.getOrDefault(player, CursorType.TNT); + Vector vector = type.position.apply(player, rayTraceResult); + if (type == CursorType.REDSTONE_BLOCK) { + vector.subtract(new Vector(0.5, 0, 0.5)); + } + SimulatorElement element = type.elementFunction.apply(vector); + SimulatorGroup group = new SimulatorGroup().add(element); + simulator.getGroups().add(group); + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + element.open(player, simulator, group, simulatorGui); + SimulatorWatcher.update(simulator); + calcCursor(player); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java index a549e0a2..b3fbcba8 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorStorage.java @@ -1,124 +1,172 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ package de.steamwar.bausystem.features.simulator; +import com.google.common.io.Files; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.SWUtils; -import de.steamwar.bausystem.features.simulator.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui; +import de.steamwar.bausystem.features.simulator.storage.SimFormatSimulatorLoader; +import de.steamwar.bausystem.features.simulator.storage.SimulatorFormatSimulatorLoader; +import de.steamwar.bausystem.features.simulator.storage.SimulatorSaver; +import de.steamwar.bausystem.features.simulator.storage.YAPIONFormatSimulatorLoader; import de.steamwar.bausystem.utils.ItemUtils; +import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; -import de.steamwar.linkage.api.Disable; +import de.steamwar.linkage.MinVersion; import de.steamwar.linkage.api.Enable; -import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import yapion.exceptions.YAPIONException; -import yapion.hierarchy.types.YAPIONArray; -import yapion.hierarchy.types.YAPIONObject; -import yapion.parser.YAPIONParser; import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.*; @Linked -public class SimulatorStorage implements Enable, Disable { - - public static final World WORLD = Bukkit.getWorlds().get(0); - private static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators"); +@MinVersion(19) +public class SimulatorStorage implements Enable { + public static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators"); + private static Map simulatorMap = new HashMap<>(); private static NamespacedKey simulatorSelection = SWUtils.getNamespaceKey("simulator_selection"); - private static Map tntSimulators = new HashMap<>(); - - public static void createNewSimulator(String name) { - tntSimulators.put(name, new TNTSimulator()); - } - - public static Set getSimulatorNames() { - return tntSimulators.keySet(); - } - - public static TNTSimulator getSimulator(String name) { - return tntSimulators.get(name); - } - - public static TNTSimulator getSimulator(Player player) { - TNTSimulator current = getSimulator(player.getInventory().getItemInMainHand()); - if (current != null) return current; + public static Simulator getSimulator(Player player) { + Simulator simulator = getSimulator(player.getInventory().getItemInMainHand()); + if (simulator != null) return simulator; return getSimulator(player.getInventory().getItemInOffHand()); } - public static TNTSimulator getSimulator(ItemStack itemStack) { - if (itemStack == null) { - return null; - } - if (!ItemUtils.isItem(itemStack, "simulator")) { + public static Simulator getSimulator(ItemStack itemStack) { + if (!SimulatorCursor.isSimulatorItem(itemStack)) { return null; } String selection = ItemUtils.getTag(itemStack, simulatorSelection); if (selection == null) { return null; } - return tntSimulators.get(selection); + return simulatorMap.get(selection); } - public static void setSimulator(Player player, ItemStack itemStack, TNTSimulator simulator) { - for (Map.Entry entry : tntSimulators.entrySet()) { - if (entry.getValue() == simulator) { - ItemUtils.setTag(itemStack, simulatorSelection, entry.getKey()); - ItemMeta itemMeta = itemStack.getItemMeta(); - itemMeta.setDisplayName(BauSystem.MESSAGE.parse("SIMULATOR_WAND_NAME_SELECTED", player, entry.getKey())); - itemStack.setItemMeta(itemMeta); - return; + public static Simulator getSimulator(String name) { + return simulatorMap.get(name); + } + + public static void addSimulator(String name, Simulator simulator) { + simulatorMap.putIfAbsent(name, simulator); + } + + @Override + public void enable() { + SimFormatSimulatorLoader simFormatSimulatorLoader = new SimFormatSimulatorLoader(); + SimulatorFormatSimulatorLoader simulatorFormatSimulatorLoader = new SimulatorFormatSimulatorLoader(); + YAPIONFormatSimulatorLoader yapionFormatSimulatorLoader = new YAPIONFormatSimulatorLoader(); + + File[] files = simulatorsDir.listFiles(); + if (files == null) return; + for (File file : files) { + try { + List simulators = simFormatSimulatorLoader.load(file) + .orElse(null); + if (simulators != null) { + simulators.forEach(simulator -> { + simulatorMap.put(simulator.getName(), simulator); + }); + continue; + } + } catch (Exception e) { + // Ignore + } + + try { + List simulators = simulatorFormatSimulatorLoader.load(file) + .orElse(null); + if (simulators != null) { + simulators.forEach(simulator -> { + simulatorMap.put(simulator.getName(), simulator); + SimulatorSaver.saveSimulator(simulatorsDir, simulator); + }); + continue; + } + } catch (Exception e) { + // Ignore + } + + try { + List simulators = yapionFormatSimulatorLoader.load(file) + .orElse(null); + if (simulators != null) { + simulators.forEach(simulator -> { + simulatorMap.put(simulator.getName(), simulator); + SimulatorSaver.saveSimulator(simulatorsDir, simulator); + }); + } + } catch (Exception e) { + // Ignore } } } - public static void delete(String name) { - TNTSimulator tntSimulator = tntSimulators.remove(name); - if (tntSimulator != null) { - tntSimulator.close(); - } - new File(simulatorsDir, name + ".simulator").delete(); - } + public static void openSimulatorSelector(Player player) { + SimulatorPageGui simulatorPageGui = new SimulatorPageGui(player, null, 6 * 9, new ArrayList<>(simulatorMap.values())) { + @Override + public String baseTitle() { + return "Simulators"; + } - public static void copySimulator(TNTSimulator tntSimulator, String name) { - tntSimulators.put(name, new TNTSimulator(tntSimulator.toYAPION())); - } + @Override + public void headerAndFooter() { + inventory.setItem(49, new SWItem(Material.NAME_TAG, "§eCreate", clickType -> { + SWAnvilInv anvilInv = new SWAnvilInv(player, "Name"); + anvilInv.setCallback(s -> { + Simulator sim = SimulatorStorage.getSimulator(s); + if (sim != null) { + BauSystem.MESSAGE.send("SIMULATOR_NAME_ALREADY_EXISTS", player); + return; + } + if (!s.matches("[a-zA-Z_0-9-]+")) { + BauSystem.MESSAGE.send("SIMULATOR_NAME_INVALID", player); + return; + } + sim = new Simulator(s); + SimulatorStorage.addSimulator(s, sim); + SimulatorStorage.setSimulator(player, sim); + }); + anvilInv.open(); + })); + } - public static void removeSimulator(ItemStack itemStack) { - if (!ItemUtils.isItem(itemStack, "simulator")) { - return; - } - ItemUtils.setTag(itemStack, simulatorSelection, null); + @Override + public SWItem convert(Simulator simulator) { + return simulator.toItem(player, clickType -> { + setSimulator(player, simulator); + player.closeInventory(); + }); + } + }; + simulatorPageGui.open(); } public static ItemStack getWand(Player p) { @@ -130,68 +178,48 @@ public class SimulatorStorage implements Enable, Disable { return itemStack; } - @Override - public void enable() { - if (!simulatorsDir.exists()) { - simulatorsDir.mkdir(); + public static void setSimulator(Player player, Simulator simulator) { + ItemStack mainHand = player.getInventory().getItemInMainHand(); + ItemStack offHand = player.getInventory().getItemInOffHand(); + ItemStack itemStack; + if (SimulatorCursor.isSimulatorItem(mainHand)) { + itemStack = mainHand; + } else if (SimulatorCursor.isSimulatorItem(offHand)) { + itemStack = offHand; + } else { + itemStack = null; } - File[] files = simulatorsDir.listFiles(); - if (files == null) return; - - for (File file : files) { - YAPIONObject yapionObject; - try { - yapionObject = YAPIONParser.parse(file); - } catch (YAPIONException | IOException e) { - continue; - } - if (file.getName().endsWith(".yapion")) { - String name = file.getName().substring(0, file.getName().length() - 7); - try { - SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(name)); - convert(file, steamwarUser); - } catch (Exception e) { - file.delete(); - } - } else { - String name = file.getName().substring(0, file.getName().length() - ".simulator".length()); - tntSimulators.put(name, new TNTSimulator(yapionObject)); - } - } - } - - private static void convert(File file, SteamwarUser steamwarUser) { - YAPIONObject yapionObject; - try { - yapionObject = YAPIONParser.parse(file); - } catch (YAPIONException | IOException e) { + if (itemStack == null) { return; } - try { - file.delete(); - } catch (Exception e) { - e.printStackTrace(); - } - for (String s : yapionObject.getKeys()) { - String newName = steamwarUser.getUserName() + (s.isEmpty() ? "" : "_" + s); - YAPIONArray content = yapionObject.getArray(s); - if (content.isEmpty()) continue; - TNTSimulator tntSimulator = new TNTSimulator(); - for (YAPIONObject element : content.streamObject().collect(Collectors.toList())) { - tntSimulator.getTntElementList().add(new TNTElement(element, null, tntSimulator.getEntityServer())); - } - tntSimulators.put(newName, tntSimulator); - } + + ItemUtils.setTag(itemStack, simulatorSelection, simulator.getName()); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(BauSystem.MESSAGE.parse("SIMULATOR_WAND_NAME_SELECTED", player, simulator.getName())); + itemStack.setItemMeta(itemMeta); } - @Override - public void disable() { - for (Map.Entry entry : tntSimulators.entrySet()) { - try { - entry.getValue().toYAPION().toFile(new File(simulatorsDir, entry.getKey() + ".simulator")); - } catch (Exception e) { - e.printStackTrace(); - } + public static List getSimulatorNames() { + return new ArrayList<>(simulatorMap.keySet()); + } + + public static void delete(Simulator simulator) { + simulatorMap.remove(simulator.getName()); + new File(simulatorsDir, simulator.getName() + ".sim").delete(); + } + + public static boolean copy(Simulator simulator, String name) { + try { + File file = new File(simulatorsDir, name + ".sim"); + Files.copy(new File(simulatorsDir, simulator.getName() + ".sim"), file); + new SimFormatSimulatorLoader().load(file).ifPresent(simulators -> { + simulators.forEach(sim -> { + simulatorMap.put(sim.getName(), sim); + }); + }); + return true; + } catch (IOException e) { + return false; } } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorWatcher.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorWatcher.java new file mode 100644 index 00000000..d5f98986 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/SimulatorWatcher.java @@ -0,0 +1,129 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.storage.SimulatorSaver; +import de.steamwar.bausystem.shared.Pair; +import de.steamwar.entity.REntity; +import de.steamwar.entity.REntityServer; +import de.steamwar.entity.RFallingBlockEntity; +import de.steamwar.linkage.Linked; +import de.steamwar.linkage.MinVersion; +import lombok.experimental.UtilityClass; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.util.Vector; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +@UtilityClass +public class SimulatorWatcher { + + private final World WORLD = Bukkit.getWorlds().get(0); + private Map entityServers = new HashMap<>(); + private Map> watchers = new HashMap<>(); + + public void watch(Player player, Simulator simulator, Runnable watcher) { + if (simulator == null || watcher == null) { + watchers.remove(player); + } else { + watchers.put(player, new Pair<>(simulator, watcher)); + } + } + + public synchronized void update(Simulator simulator) { + REntityServer rEntityServer = entityServers.get(simulator); + if (rEntityServer != null) { + rEntityServer.getEntities().forEach(REntity::die); + createSim(rEntityServer, simulator); + } + + new ArrayList<>(watchers.values()).forEach(simulatorRunnablePair -> { + if (simulatorRunnablePair.getKey() == simulator) { + simulatorRunnablePair.getValue().run(); + } + }); + SimulatorSaver.saveSimulator(SimulatorStorage.simulatorsDir, simulator); + } + + @Linked + @MinVersion(19) + public static class QuitListener implements Listener { + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + watchers.remove(event.getPlayer()); + show(null, event.getPlayer()); + } + } + + private REntityServer createSim(REntityServer server, Simulator simulator) { + if (simulator == null) { + return null; + } + Map>> positionCache = new HashMap<>(); + simulator.getGroups().stream().map(group -> group.getElements().stream().map(element -> new Pair<>(group, element)).collect(Collectors.toList())).flatMap(List::stream).forEach(pair -> { + SimulatorGroup group = pair.getKey(); + SimulatorElement element = pair.getValue(); + + boolean wasNotPresent = positionCache.computeIfAbsent(element.getPosition(), __ -> new HashSet<>()) + .add(element.getClass()); + if (!wasNotPresent) return; + Material material = group.isDisabled() || element.isDisabled() ? element.getWorldDisabledMaterial() : element.getWorldMaterial(); + Location location = element.getWorldPos().toLocation(WORLD); + RFallingBlockEntity rFallingBlockEntity = new RFallingBlockEntity(server, location, material); + rFallingBlockEntity.setNoGravity(true); + }); + return server; + } + + public synchronized boolean show(Simulator sim, Player player) { + AtomicBoolean removed = new AtomicBoolean(); + entityServers.forEach((simulator, rEntityServer) -> { + if (rEntityServer == null) return; + if (rEntityServer.getPlayers().contains(player) && sim != simulator) { + rEntityServer.removePlayer(player); + removed.set(true); + } + }); + if (sim == null) return removed.get(); + entityServers.computeIfAbsent(sim, __ -> createSim(new REntityServer(), sim)).addPlayer(player); + return removed.get(); + } + + synchronized List getEntitiesOfSimulator(Simulator simulator) { + REntityServer entityServer = entityServers.get(simulator); + if (entityServer == null) { + return Collections.emptyList(); + } + return entityServer.getEntities(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java deleted file mode 100644 index ef00d521..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulator.java +++ /dev/null @@ -1,279 +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 . - */ - -package de.steamwar.bausystem.features.simulator; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.configplayer.Config; -import de.steamwar.bausystem.features.simulator.gui.TNTElementGUI; -import de.steamwar.bausystem.features.simulator.gui.TNTSimulatorGui; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTGroup; -import de.steamwar.bausystem.features.tracer.Recorder; -import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.shared.Pair; -import de.steamwar.bausystem.utils.RayTraceUtils; -import de.steamwar.entity.REntity; -import de.steamwar.entity.REntityServer; -import de.steamwar.linkage.LinkedInstance; -import lombok.Getter; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import yapion.hierarchy.types.YAPIONArray; -import yapion.hierarchy.types.YAPIONObject; -import yapion.hierarchy.types.YAPIONType; - -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -@Getter -public class TNTSimulator { - - private Set players = new HashSet<>(); - private REntityServer entityServer = new REntityServer(); - - private Material material = Material.TNT; - - private List tntElementList = new ArrayList<>(); - - @LinkedInstance - public Recorder traceRecorder; - - private Region autoTraceRegion; - - public TNTSimulator() { - - } - - public TNTSimulator(YAPIONObject yapionObject) { - material = Material.valueOf(yapionObject.getStringOrDefault("material", Material.TNT.name())); - YAPIONArray yapionArray = yapionObject.getArrayOrDefault("tntElements", new YAPIONArray()); - for (YAPIONObject element : yapionArray.streamObject().collect(Collectors.toList())) { - if (element.containsKey("elements", YAPIONType.ARRAY)) { - tntElementList.add(new TNTGroup(element, entityServer)); - } else { - tntElementList.add(new TNTElement(element, null, entityServer)); - } - } - } - - public YAPIONObject toYAPION() { - YAPIONObject yapionObject = new YAPIONObject(); - yapionObject.add("material", material.name()); - YAPIONArray yapionArray = new YAPIONArray(); - for (SimulatorElement element : tntElementList) { - yapionArray.add(element.toYAPION()); - } - yapionObject.add("tntElements", yapionArray); - return yapionObject; - } - - public void close() { - entityServer.close(); - } - - public void show(Player player) { - if (!players.contains(player)) { - entityServer.addPlayer(player); - players.add(player); - } - } - - public void hide(Player player) { - if (players.contains(player)) { - entityServer.removePlayer(player); - players.remove(player); - } - } - - void _hide(Player player) { - players.remove(player); - } - - public List getEntities() { - return tntElementList.stream().flatMap(element -> element.getEntities().stream()).collect(Collectors.toList()); - } - - public List getEntity(REntity entity) { - List tntSpawns = new ArrayList<>(); - for (SimulatorElement spawn : tntElementList) { - spawn.getEntity(tntSpawns, entity); - } - return tntSpawns; - } - - public void clear() { - new ArrayList<>(tntElementList).forEach(this::remove); - } - - public void remove(SimulatorElement element) { - if (element instanceof TNTElement) { - TNTElement tntElement = (TNTElement) element; - if (tntElement.hasParent()) { - tntElement.getParent().remove(tntElement); - if (tntElement.getParent().getElements().isEmpty()) { - remove(tntElement.getParent()); - } - } else { - element.remove(tntElement); - } - } else if (element instanceof TNTGroup) { - TNTGroup tntGroup = (TNTGroup) element; - tntGroup.getElements().forEach(tntElement -> { - tntElement.remove(tntElement); - }); - tntGroup.getElements().clear(); - } - element.close(); - tntElementList.remove(element); - } - - public void change() { - tntElementList.forEach(simulatorElement -> { - simulatorElement.change(); - if (simulatorElement instanceof TNTGroup) { - ((TNTGroup) simulatorElement).getElements().forEach(SimulatorElement::change); - } - }); - } - - public void edit(Player player, RayTraceUtils.RRayTraceResult result) { - if (result == null) { - TNTSimulatorGui.open(player, this, null, this::getTntElementList, null); - return; - } - - SimulatorCursor.show(player, this, result); - - if (result.getHitEntity() != null) { - List elements = getEntity(result.getHitEntity()); - if (elements.isEmpty()) return; - - if (elements.size() == 1) { - TNTElementGUI.open(player, (TNTElement) elements.get(0), null); - } else { - List tntGroups = tntElementList.stream().filter(TNTGroup.class::isInstance).map(TNTGroup.class::cast).collect(Collectors.toList()); - List newElementList = new ArrayList<>(); - for (TNTGroup tntGroup : tntGroups) { - if (new HashSet<>(elements).containsAll(tntGroup.getElements())) { - newElementList.add(tntGroup); - elements.removeAll(tntGroup.getElements()); - } - } - newElementList.addAll(elements); - if (newElementList.size() == 1) { - SimulatorElement element = newElementList.get(0); - if (element instanceof TNTGroup) { - TNTGroup tntGroup = (TNTGroup) element; - TNTSimulatorGui.open(player, null, tntGroup, () -> { - List elementList = new ArrayList<>(); - elementList.addAll(tntGroup.getElements()); - return elementList; - }, null); - } else { - TNTElementGUI.open(player, (TNTElement) elements.get(0), null); - } - } else { - TNTSimulatorGui.open(player, null, null, () -> newElementList, null); - } - } - return; - } - - if (SimulatorStorage.getSimulator(player.getInventory().getItemInOffHand()) != null && result.getHitPosition().distanceSquared(player.getLocation().toVector()) < 25) { - return; - } - - TNTElement tntElement = new TNTElement(SimulatorCursor.getPos(player, result), null, entityServer); - tntElementList.add(tntElement); - TNTElementGUI.open(player, tntElement, null); - } - - public void start(Player p) { - Region region = Region.getRegion(p.getLocation()); - Map>>> result = new HashMap<>(); - boolean regionFrozen = false; - for (SimulatorElement element : tntElementList) { - regionFrozen |= element.locations(result, region, p.getLocation()); - } - if (regionFrozen) { - BauSystem.MESSAGE.send("SIMULATOR_REGION_FROZEN", p); - return; - } - - AtomicBoolean needsAutoTrace = new AtomicBoolean(); - players.forEach(player -> { - boolean simulatorAutoTrace = Config.getInstance().get(player).getPlainValueOrDefault("simulatorAutoTrace", false); - if (simulatorAutoTrace) { - needsAutoTrace.set(true); - player.performCommand("trace show"); - } - }); - if (needsAutoTrace.get()) { - traceRecorder.startRecording(region); - autoTraceRegion = region; - } - - AtomicInteger maxTick = new AtomicInteger(0); - Map>>> toSpawn = new HashMap<>(); - result.forEach((integer, integerSetMap) -> { - List>>> internal = new ArrayList<>(); - integerSetMap.forEach((integer1, pairs) -> { - internal.add(new Pair<>(integer1, pairs)); - }); - internal.sort(Comparator.comparingInt(Pair::getKey)); - - toSpawn.put(integer, internal.stream().map(Pair::getValue).map(ArrayList::new).peek(Collections::shuffle).collect(Collectors.toList())); - - if (maxTick.get() < integer) { - maxTick.set(integer); - } - }); - - AtomicInteger currentTick = new AtomicInteger(0); - BauSystem.runTaskTimer(BauSystem.getInstance(), bukkitTask -> { - int tick = currentTick.get(); - if (tick > maxTick.get()) { - traceRecorder.stopRecording(autoTraceRegion); - autoTraceRegion = null; - bukkitTask.cancel(); - } - currentTick.incrementAndGet(); - - List>> toSpawnInTick = toSpawn.get(tick); - if (toSpawnInTick == null) return; - toSpawnInTick.forEach(pairs -> { - AtomicBoolean hasSomeLeft = new AtomicBoolean(true); - while(hasSomeLeft.get()) { - hasSomeLeft.set(false); - pairs.forEach(pair -> { - if (pair.getValue() > 0) { - hasSomeLeft.set(true); - pair.getKey().run(); - pair.setValue(pair.getValue() - 1); - } - }); - } - }); - }, 1, 1); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java deleted file mode 100644 index a3862c9f..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/TNTSimulatorListener.java +++ /dev/null @@ -1,130 +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 . - */ - -package de.steamwar.bausystem.features.simulator; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.Permission; -import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI; -import de.steamwar.bausystem.utils.ItemUtils; -import de.steamwar.bausystem.utils.RayTraceUtils; -import de.steamwar.linkage.Linked; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.*; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -import java.util.function.Function; - -@Linked -public class TNTSimulatorListener implements Listener { - - private boolean permissionCheck(Player player) { - if (!Permission.hasPermission(player, Permission.WORLD)) { - BauSystem.MESSAGE.send("SIMULATOR_NO_PERMS", player); - return false; - } - return true; - } - - static RayTraceUtils.RRayTraceResult trace(Player player, Location to, TNTSimulator simulator) { - return RayTraceUtils.traceREntity(player, to, simulator.getEntities()); - } - - @EventHandler - public void onPlayerMove(PlayerMoveEvent e) { - if (ItemUtils.isItem(e.getPlayer().getInventory().getItemInMainHand(), "simulator")) { - simulatorShowHide(e.getPlayer(), i -> null, PlayerInventory::getItemInMainHand, e.getTo()); - } else { - SimulatorCursor.hide(e.getPlayer()); - } - } - - @EventHandler - public void onPlayerItemHeld(PlayerItemHeldEvent e) { - simulatorShowHide(e.getPlayer(), i -> i.getItem(e.getPreviousSlot()), i -> i.getItem(e.getNewSlot()), e.getPlayer().getLocation()); - } - - @EventHandler - public void onPlayerDropItem(PlayerDropItemEvent e) { - simulatorShowHide(e.getPlayer(), i -> e.getItemDrop().getItemStack(), i -> null, e.getPlayer().getLocation()); - } - - private TNTSimulator simulatorShowHide(Player player, Function oldItemFunction, Function newItemFunction, Location location) { - TNTSimulator oldSimulator = SimulatorStorage.getSimulator(oldItemFunction.apply(player.getInventory())); - SimulatorCursor.hide(player, oldSimulator); - - TNTSimulator simulator = SimulatorStorage.getSimulator(newItemFunction.apply(player.getInventory())); - if (simulator == null) return null; - - SimulatorCursor.show(player, simulator, trace(player, location, simulator)); - return simulator; - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent e) { - if (ItemUtils.isItem(e.getPlayer().getInventory().getItemInMainHand(), "simulator")) { - simulatorShowHide(e.getPlayer(), i -> null, PlayerInventory::getItemInMainHand, e.getPlayer().getLocation()); - } - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - SimulatorCursor.hide(event.getPlayer(), null); - SimulatorStorage.getSimulatorNames().forEach(s -> { - SimulatorStorage.getSimulator(s)._hide(event.getPlayer()); - }); - } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - if (!ItemUtils.isItem(event.getItem(), "simulator")) { - return; - } - - event.setCancelled(true); - if (!permissionCheck(event.getPlayer())) { - return; - } - TNTSimulator simulator = SimulatorStorage.getSimulator(event.getItem()); - - switch (event.getAction()) { - case LEFT_CLICK_BLOCK: - case LEFT_CLICK_AIR: - if (simulator == null) { - return; - } - simulator.start(event.getPlayer()); - break; - case RIGHT_CLICK_BLOCK: - case RIGHT_CLICK_AIR: - if (simulator == null) { - SimulatorSelectionGUI.open(event.getPlayer(), event.getItem()); - } else { - simulator.edit(event.getPlayer(), trace(event.getPlayer(), event.getPlayer().getLocation(), simulator)); - } - break; - default: - break; - } - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java new file mode 100644 index 00000000..91b7a8e1 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/Simulator.java @@ -0,0 +1,65 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data; + +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.inventory.InvCallback; +import de.steamwar.inventory.SWItem; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.bukkit.Material; +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 Material material = Material.BARREL; + private final String name; + private boolean autoTrace = false; + private final List groups = new ArrayList<>(); + + public void move(int x, int y, int z) { + groups.forEach(simulatorGroup -> { + simulatorGroup.move(x, y, z); + }); + } + + public SWItem toItem(Player player, InvCallback invCallback) { + return new SWItem(material, "§e" + name, invCallback); + } + + public void toSimulatorActions(BiConsumer tickStart, BiConsumer tickEnd) { + groups.forEach(simulatorGroup -> { + simulatorGroup.toSimulatorActions(tickStart, tickEnd); + }); + } + + public Simulator add(SimulatorGroup group) { + groups.add(group); + return this; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java new file mode 100644 index 00000000..de0d2b69 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorBlockAlignedElement.java @@ -0,0 +1,35 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data; + +import org.bukkit.Material; +import org.bukkit.util.Vector; + +public abstract class SimulatorBlockAlignedElement extends SimulatorElement { + + protected SimulatorBlockAlignedElement(Material material, Vector position) { + super(material, position); + } + + @Override + public final boolean canBeInGroup(SimulatorGroup simulatorGroup) { + return simulatorGroup.getElements().stream().allMatch(SimulatorBlockAlignedElement.class::isInstance); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorElement.java new file mode 100644 index 00000000..119143db --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorElement.java @@ -0,0 +1,126 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data; + +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.InvCallback; +import de.steamwar.inventory.SWItem; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + +@Getter +@Setter +public abstract class SimulatorElement { + protected Material material; + protected final Vector position; + protected boolean disabled = false; + protected final List phases = new ArrayList<>(); + + protected SimulatorElement(Material material, Vector position) { + this.material = material; + this.position = position; + } + + public SimulatorElement add(T setting) { + phases.add(setting); + return this; + } + + public void sort() { + phases.sort(Comparator.comparingInt(SimulatorPhase::getTickOffset)); + } + + public abstract String getName(Player player); + + public int getBaseTick() { + return phases.stream() + .mapToInt(value -> value.tickOffset) + .min() + .orElse(0); + } + + public void changeBaseTicks(int tick) { + phases.forEach(t -> { + t.tickOffset += tick; + }); + } + + public void move(double x, double y, double z) { + position.setX(position.getX() + x); + position.setY(position.getY() + y); + position.setZ(position.getZ() + z); + } + + public abstract Material getWorldMaterial(); + + public abstract Material getWorldDisabledMaterial(); + + public abstract boolean canBeInGroup(SimulatorGroup simulatorGroup); + + public Vector getWorldPos() { + return position; + } + + public SWItem toItem(Player player, InvCallback invCallback) { + List lore = new ArrayList<>(); + lore.add("§7Phase count§8:§e " + phases.size()); + lore.add("§7Tick§8:§e " + getBaseTick()); + lore.add(""); + lore.add("§7X§8:§e " + position.getX()); + lore.add("§7Y§8:§e " + position.getY()); + lore.add("§7Z§8:§e " + position.getZ()); + if (disabled) { + lore.add(""); + lore.add("§cDisabled"); + } + return new SWItem(material, "§e" + getName(player), lore, disabled, invCallback); + } + + public void toSimulatorActions(BiConsumer tickStart, BiConsumer tickEnd) { + if (disabled) return; + phases.forEach(phase -> { + phase.toSimulatorActions(position.clone(), tickStart, tickEnd); + }); + } + + public abstract void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back); + + public SimulatorGroup getGroup(Simulator simulator) { + return simulator.getGroups().stream() + .filter(simulatorGroup -> simulatorGroup.getElements().contains(this)) + .findFirst() + .orElse(null); + } + + public abstract String getType(); + public void saveExtra(YAPIONObject elementObject) {} + public void loadExtra(YAPIONObject elementObject) {} +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorGroup.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorGroup.java new file mode 100644 index 00000000..8031dd1c --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorGroup.java @@ -0,0 +1,93 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data; + +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.inventory.InvCallback; +import de.steamwar.inventory.SWItem; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.BiConsumer; + +@Getter +@Setter +public final class SimulatorGroup { + private Material material = Material.CHEST; + private boolean disabled = false; + private final List> elements = new ArrayList<>(); + + public SimulatorGroup add(SimulatorElement element) { + if (!elements.contains(element)) { + elements.add(element); + } + return this; + } + + public void sort() { + elements.sort(Comparator.comparingInt(SimulatorElement::getBaseTick)); + } + + public int getBaseTick() { + return elements.stream() + .mapToInt(SimulatorElement::getBaseTick) + .min() + .orElse(0); + } + + public void changeBaseTicks(int tick) { + elements.forEach(simulatorElement -> { + simulatorElement.changeBaseTicks(tick); + }); + } + + public void move(double x, double y, double z) { + elements.forEach(simulatorElement -> { + simulatorElement.move(x, y, z); + }); + } + + public SWItem toItem(Player player, InvCallback groupCallback, InvCallback itemCallback) { + if (elements.size() == 1) { + return elements.get(0).toItem(player, itemCallback); + } else { + List lore = new ArrayList<>(); + lore.add("§7Element count§8:§e " + elements.size()); + lore.add("§7Tick§8:§e " + getBaseTick()); + if (disabled) { + lore.add(""); + lore.add("§cDisabled"); + } + return new SWItem(material != null ? material : Material.ENDER_CHEST, "§eGroup", lore, disabled, groupCallback); + } + } + + public void toSimulatorActions(BiConsumer tickStart, BiConsumer tickEnd) { + if (disabled) return; + elements.forEach(simulatorElement -> { + simulatorElement.toSimulatorActions(tickStart, tickEnd); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorPhase.java new file mode 100644 index 00000000..b226d124 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/SimulatorPhase.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data; + +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; + +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + +@Getter +@Setter +public abstract class SimulatorPhase { + public static final int ORDER_LIMIT = 30; + + protected int tickOffset = 0; + protected int lifetime = 80; + protected int order = 0; + + public abstract void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd); + public void saveExtra(YAPIONObject phaseObject) {} + public void loadExtra(YAPIONObject phaseObject) {} +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java new file mode 100644 index 00000000..7fdff328 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverElement.java @@ -0,0 +1,99 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data.observer; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorBlockAlignedElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.bausystem.features.simulator.gui.SimulatorObserverGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; + +public final class ObserverElement extends SimulatorBlockAlignedElement { + + public ObserverElement(Vector position) { + super(Material.OBSERVER, position); + } + + @Override + public String getName(Player player) { + return "Observer"; + } + + @Override + public Material getWorldMaterial() { + return Material.OBSERVER; + } + + @Override + public Material getWorldDisabledMaterial() { + return Material.GRAY_STAINED_GLASS; + } + + public void toSimulatorActions(BiConsumer tickStart, BiConsumer tickEnd) { + if (disabled) return; + phases.forEach(phase -> { + phase.toSimulatorActions(position.clone(), tickStart, tickEnd); + }); + + int end = phases.stream().mapToInt(SimulatorPhase::getTickOffset).max().orElse(0) + 4; + AtomicReference blockState = new AtomicReference<>(); + tickStart.accept(0, new SimulatorAction(-100, 1) { + @Override + public void accept(World world) { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + blockState.set(block.getState()); + block.setType(Material.OBSERVER, false); + } + }); + tickEnd.accept(end, new SimulatorAction(0, 1) { + @Override + public void accept(World world) { + BlockState oldState = blockState.get(); + if (oldState != null) { + oldState.update(true, true); + } else { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + block.setType(Material.AIR); + } + } + }); + } + + @Override + public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) { + new SimulatorObserverGui(player, simulator, group, this, back).open(); + } + + @Override + public String getType() { + return "Observer"; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java new file mode 100644 index 00000000..e3707c3e --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/observer/ObserverPhase.java @@ -0,0 +1,81 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data.observer; + +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.type.Observer; +import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; + +import java.util.function.BiConsumer; + +@NoArgsConstructor +public final class ObserverPhase extends SimulatorPhase { + + @Getter + @Setter + private BlockFace orientation = BlockFace.UP; + + public ObserverPhase(int tickOffset) { + this.tickOffset = tickOffset; + } + + { + this.lifetime = 0; + } + + @Override + public void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd) { + Observer observer = (Observer) Material.OBSERVER.createBlockData(); + observer.setFacing(orientation.getOppositeFace()); + observer.setPowered(true); + + tickStart.accept(tickOffset, new SimulatorAction(order, 1) { + @Override + public void accept(World world) { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + Block updateBlock = block.getRelative(orientation); + BlockState state = updateBlock.getState(); + updateBlock.setType(Material.SPONGE, true); + block.setBlockData(observer, true); + state.update(true, true); + } + }); + } + + @Override + public void saveExtra(YAPIONObject phaseObject) { + phaseObject.add("orientation", orientation.name()); + } + + @Override + public void loadExtra(YAPIONObject phaseObject) { + orientation = BlockFace.valueOf(phaseObject.getPlainValue("orientation")); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java new file mode 100644 index 00000000..3b949609 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstoneElement.java @@ -0,0 +1,66 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data.redstone; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorBlockAlignedElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.gui.SimulatorRedstoneGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public final class RedstoneElement extends SimulatorBlockAlignedElement { + + public RedstoneElement(Vector position) { + super(Material.REDSTONE_BLOCK, position); + } + + @Override + public String getName(Player player) { + return "Redstone"; + } + + @Override + public Material getWorldMaterial() { + return Material.REDSTONE_BLOCK; + } + + @Override + public Material getWorldDisabledMaterial() { + return Material.WHITE_STAINED_GLASS; + } + + @Override + public Vector getWorldPos() { + return position.clone().add(new Vector(0.5, 0, 0.5)); + } + + @Override + public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) { + new SimulatorRedstoneGui(player, simulator, group, this, back).open(); + } + + @Override + public String getType() { + return "Redstone"; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstonePhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstonePhase.java new file mode 100644 index 00000000..614be659 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/redstone/RedstonePhase.java @@ -0,0 +1,70 @@ + +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data.redstone; + +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import lombok.NoArgsConstructor; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.util.Vector; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; + +@NoArgsConstructor +public final class RedstonePhase extends SimulatorPhase { + + public RedstonePhase(int tickOffset) { + this.tickOffset = tickOffset; + } + + { + this.lifetime = 1; + } + + @Override + public void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd) { + AtomicReference blockState = new AtomicReference<>(); + tickStart.accept(tickOffset, new SimulatorAction(order, 1) { + @Override + public void accept(World world) { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + blockState.set(block.getState()); + block.setType(Material.REDSTONE_BLOCK); + } + }); + tickStart.accept(tickOffset + lifetime, new SimulatorAction(ORDER_LIMIT + 1, 1) { + @Override + public void accept(World world) { + BlockState state = blockState.get(); + if (state != null) { + state.update(true, true); + } else { + Block block = world.getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + block.setType(Material.AIR); + } + } + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTElement.java new file mode 100644 index 00000000..29e90d83 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTElement.java @@ -0,0 +1,105 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data.tnt; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.gui.SimulatorTNTGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.InvCallback; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public final class TNTElement extends SimulatorElement { + + public TNTElement(Vector position) { + super(Material.TNT, position); + } + + @Override + public String getName(Player player) { + return "TNT"; + } + + public void move(double x, double y, double z) { + position.setX(position.getX() + x); + position.setY(position.getY() + y); + position.setZ(position.getZ() + z); + } + + public void align(Vector offset) { + if (offset.getX() != 0) { + if (position.getX() - (int) position.getX() == 0.49) { + position.setX(position.getX() + 0.02); + } + if (position.getX() - (int) position.getX() == -0.49) { + position.setX(position.getX() - 0.02); + } + position.setX(position.getBlockX() + offset.getX()); + } + + if (offset.getZ() != 0) { + if (position.getZ() - (int) position.getZ() == 0.49) { + position.setZ(position.getZ() + 0.02); + } + if (position.getZ() - (int) position.getZ() == -0.49) { + position.setZ(position.getZ() - 0.02); + } + position.setZ(position.getBlockZ() + offset.getZ()); + } + } + + @Override + public SWItem toItem(Player player, InvCallback invCallback) { + long sum = phases.stream().mapToInt(TNTPhase::getCount).sum(); + SWItem swItem = super.toItem(player, invCallback); + swItem.getItemStack().setAmount((int) Math.min(64, Math.max(1, sum))); + swItem.setName("§e" + getName(player) + "§8:§7 " + sum); + return swItem; + } + + @Override + public Material getWorldMaterial() { + return Material.TNT; + } + + @Override + public Material getWorldDisabledMaterial() { + return Material.RED_STAINED_GLASS; + } + + @Override + public boolean canBeInGroup(SimulatorGroup simulatorGroup) { + return simulatorGroup.getElements().stream().allMatch(TNTElement.class::isInstance); + } + + @Override + public void open(Player player, Simulator simulator, SimulatorGroup group, SimulatorBaseGui back) { + new SimulatorTNTGui(player, simulator, this, group, back).open(); + } + + @Override + public String getType() { + return "TNT"; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java new file mode 100644 index 00000000..4c03ac9b --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/data/tnt/TNTPhase.java @@ -0,0 +1,97 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.data.tnt; + +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.execute.SimulatorAction; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.region.flags.flagvalues.FreezeMode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; + +import java.util.function.BiConsumer; + +@Getter +@Setter +@NoArgsConstructor +public final class TNTPhase extends SimulatorPhase { + private int count = 1; + private boolean xJump = false; + private boolean yJump = false; + private boolean zJump = false; + + public TNTPhase(int tickOffset) { + this.tickOffset = tickOffset; + } + + public boolean hasJump() { + return xJump || yJump || zJump; + } + + public void setJump(boolean jump) { + xJump = jump; + yJump = jump; + zJump = jump; + } + + @Override + public void toSimulatorActions(Vector position, BiConsumer tickStart, BiConsumer tickEnd) { + tickStart.accept(tickOffset, new SimulatorAction(order, count) { + @Override + public void accept(World world) { + Location location = position.toLocation(world); + if (Region.getRegion(location).get(Flag.FREEZE) == FreezeMode.ACTIVE) return; + TNTPrimed tnt = world.spawn(location, TNTPrimed.class); + if (!xJump) tnt.setVelocity(tnt.getVelocity().setX(0)); + if (!yJump) tnt.setVelocity(tnt.getVelocity().setY(0)); + if (!zJump) tnt.setVelocity(tnt.getVelocity().setZ(0)); + tnt.setFuseTicks(lifetime); + } + }); + tickEnd.accept(tickOffset + lifetime, new SimulatorAction(0, 1) { + @Override + public void accept(World world) { + } + }); + } + + @Override + public void saveExtra(YAPIONObject phaseObject) { + phaseObject.add("count", count); + phaseObject.add("xJump", xJump); + phaseObject.add("yJump", yJump); + phaseObject.add("zJump", zJump); + } + + @Override + public void loadExtra(YAPIONObject phaseObject) { + count = phaseObject.getPlainValue("count"); + xJump = phaseObject.getPlainValue("xJump"); + yJump = phaseObject.getPlainValue("yJump"); + zJump = phaseObject.getPlainValue("zJump"); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorAction.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorAction.java new file mode 100644 index 00000000..c6c9f1da --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorAction.java @@ -0,0 +1,36 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.World; + +import java.util.function.Consumer; + +@Getter +@AllArgsConstructor +public abstract class SimulatorAction implements Consumer { + private int order; + + @Setter + private int count; +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java new file mode 100644 index 00000000..893161f4 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/execute/SimulatorExecutor.java @@ -0,0 +1,127 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.execute; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.tpslimit.TPSUtils; +import de.steamwar.bausystem.features.tracer.record.Recorder; +import de.steamwar.bausystem.features.tracer.record.SingleTraceRecorder; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.utils.TickEndEvent; +import de.steamwar.bausystem.utils.TickStartEvent; +import de.steamwar.linkage.Linked; +import de.steamwar.linkage.MinVersion; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +import java.util.*; +import java.util.concurrent.atomic.AtomicLong; + +@Linked +@MinVersion(19) +public class SimulatorExecutor implements Listener { + + private static final World WORLD = Bukkit.getWorlds().get(0); + private static Set currentlyRunning = new HashSet<>(); + private static Map>> tickStartActions = new HashMap<>(); + private static Map> tickEndActions = new HashMap<>(); + + public static boolean run(Simulator simulator) { + if (currentlyRunning.contains(simulator)) return false; + currentlyRunning.add(simulator); + + long currentTick = TPSUtils.currentRealTick.get(); + AtomicLong lastTick = new AtomicLong(); + simulator.toSimulatorActions((tickOffset, simulatorAction) -> { + lastTick.set(Math.max(lastTick.get(), tickOffset)); + tickStartActions.computeIfAbsent(currentTick + tickOffset, __ -> new HashMap<>()) + .computeIfAbsent(simulatorAction.getOrder(), __ -> new ArrayList<>()) + .add(simulatorAction); + }, (tickOffset, simulatorAction) -> { + lastTick.set(Math.max(lastTick.get(), tickOffset)); + tickEndActions.computeIfAbsent(currentTick + tickOffset, __ -> new ArrayList<>()) + .add(simulatorAction); + }); + + tickEndActions.computeIfAbsent(currentTick + lastTick.get() + 4, __ -> new ArrayList<>()) + .add(new SimulatorAction(0, 1) { + @Override + public void accept(World world) { + currentlyRunning.remove(simulator); + } + }); + + if (simulator.isAutoTrace()) { + simulator.getGroups() + .stream() + .map(SimulatorGroup::getElements) + .flatMap(List::stream) + .map(SimulatorElement::getPosition) + .map(pos -> pos.toLocation(WORLD)) + .map(Region::getRegion) + .distinct() + .forEach(region -> { + if (Recorder.INSTANCE.isDisabled(region)) { + Recorder.INSTANCE.set(region, new SingleTraceRecorder(region)); + } + }); + } + return true; + } + + @EventHandler + public void onTickStart(TickStartEvent event) { + long currentTick = TPSUtils.currentRealTick.get(); + Map> actionsToRun = tickStartActions.remove(currentTick); + if (actionsToRun == null) return; + + List keys = new ArrayList<>(actionsToRun.keySet()); + keys.sort(null); + for (int actionKey : keys) { + runActions(actionsToRun.get(actionKey)); + } + } + + @EventHandler + public void onTickEnd(TickEndEvent event) { + long currentTick = TPSUtils.currentRealTick.get() - 1; + List actionsToRun = tickEndActions.remove(currentTick); + if (actionsToRun == null) return; + runActions(actionsToRun); + } + + private void runActions(List actionsToRun) { + while (!actionsToRun.isEmpty()) { + Collections.shuffle(actionsToRun); + for (int i = actionsToRun.size() - 1 ; i >= 0; i--) { + SimulatorAction action = actionsToRun.get(i); + action.accept(WORLD); + action.setCount(action.getCount() - 1); + if (action.getCount() == 0) { + actionsToRun.remove(i); + } + } + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/ItemUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/ItemUtils.java deleted file mode 100644 index 8a4bceb5..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/ItemUtils.java +++ /dev/null @@ -1,39 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui; - -import de.steamwar.inventory.SWItem; -import lombok.experimental.UtilityClass; -import org.bukkit.NamespacedKey; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; - -import java.util.UUID; - -@UtilityClass -public class ItemUtils { - - public static SWItem unique(SWItem swItem) { - ItemMeta itemMeta = swItem.getItemMeta(); - itemMeta.getPersistentDataContainer().set(NamespacedKey.minecraft(UUID.randomUUID().toString()), PersistentDataType.INTEGER, 0); - swItem.setItemMeta(itemMeta); - return swItem; - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupChooserGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupChooserGui.java new file mode 100644 index 00000000..10396677 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupChooserGui.java @@ -0,0 +1,90 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui; +import de.steamwar.inventory.InvCallback; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.stream.Collectors; + +public class SimulatorGroupChooserGui extends SimulatorPageGui { + + private final SimulatorElement subject; + private final SimulatorGroup parent; + private final SimulatorBaseGui back; + + public SimulatorGroupChooserGui(Player player, Simulator simulator, SimulatorElement subject, SimulatorGroup parent, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, simulator.getGroups().stream().filter(e -> e != parent).filter(e -> subject.canBeInGroup(e)).collect(Collectors.toList())); + this.subject = subject; + this.parent = parent; + this.back = back; + } + + @Override + public void headerAndFooter() { + inventory.setItem(4, new SWItem(simulator.getMaterial(), "§e" + simulator.getName(), clickType -> { + })); + if (parent.getElements().size() != 1) { + inventory.setItem(49, new SWItem(Material.BARRIER, "§cRemove from Group", clickType -> { + SimulatorGroup newParent = new SimulatorGroup(); + newParent.add(subject); + simulator.getGroups().add(newParent); + parent.getElements().remove(subject); + back.open(); + SimulatorWatcher.update(simulator); + if (parent.getElements().size() == 1) { + parent.setDisabled(false); + parent.setMaterial(Material.BARREL); + } + })); + } + inventory.addCloseCallback(clickType -> { + back.open(); + }); + } + + @Override + public String baseTitle() { + return "Choose Group"; + } + + @Override + public SWItem convert(SimulatorGroup simulatorGroup) { + InvCallback invCallback = clickType -> { + simulatorGroup.add(subject); + parent.getElements().remove(subject); + if (parent.getElements().size() == 1) { + parent.setDisabled(false); + parent.setMaterial(Material.BARREL); + } + back.open(); + SimulatorWatcher.update(simulator); + }; + return simulatorGroup.toItem(player, invCallback, invCallback); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupGui.java new file mode 100644 index 00000000..c3b8ee1a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupGui.java @@ -0,0 +1,108 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.stream.Collectors; + +public class SimulatorGroupGui extends SimulatorPageGui> { + + private SimulatorGroup simulatorGroup; + private final SimulatorBaseGui back; + + public SimulatorGroupGui(Player player, Simulator simulator, SimulatorGroup simulatorGroup, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, simulatorGroup.getElements()); + this.simulatorGroup = simulatorGroup; + this.back = back; + } + + @Override + public String baseTitle() { + return "Group"; + } + + @Override + public void headerAndFooter() { + if (simulatorGroup.getMaterial() == null) { + List parents = data.stream().map(e -> e.getGroup(simulator)).distinct().collect(Collectors.toList()); + if (parents.size() == 1) { + simulatorGroup = parents.get(0); + data = simulatorGroup.getElements(); + } + } + + if (simulatorGroup.getElements().removeIf(element -> element.getPhases().isEmpty())) { + SimulatorWatcher.update(simulator); + } + if (simulatorGroup.getElements().size() < 2) { + back.open(); + return; + } + + simulatorGroup.sort(); + + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + simulatorGroup.getElements().clear(); + SimulatorWatcher.update(simulator); + })); + + inventory.setItem(4, simulatorGroup.toItem(player, clickType -> { + if (simulatorGroup.getMaterial() == null) return; + new SimulatorMaterialGui(player, simulator, simulatorGroup::getMaterial, simulatorGroup::setMaterial, this).open(); + }, clickType -> { + })); + + inventory.setItem(48, new SWItem(Material.REPEATER, "§eSettings", clickType -> { + new SimulatorGroupSettingsGui(player, simulator, simulatorGroup, this).open(); + })); + boolean disabled = simulatorGroup.getMaterial() == null ? simulatorGroup.getElements().stream().allMatch(SimulatorElement::isDisabled) : simulatorGroup.isDisabled(); + inventory.setItem(50, new SWItem(disabled ? Material.ENDER_PEARL : Material.ENDER_EYE, simulatorGroup.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + if (simulatorGroup.getMaterial() == null) { + simulatorGroup.getElements().forEach(simulatorElement -> { + simulatorElement.setDisabled(!disabled); + }); + } else { + simulatorGroup.setDisabled(!disabled); + } + SimulatorWatcher.update(simulator); + })); + } + + @Override + public SWItem convert(SimulatorElement element) { + return element.toItem(player, clickType -> { + element.open(player, simulator, simulatorGroup, this); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupSettingsGui.java new file mode 100644 index 00000000..e9439ce9 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGroupSettingsGui.java @@ -0,0 +1,173 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +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.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.Arrays; + +public class SimulatorGroupSettingsGui extends SimulatorBaseGui { + + private final SimulatorGroup simulatorGroup; + private final SimulatorBaseGui back; + + public SimulatorGroupSettingsGui(Player player, Simulator simulator, SimulatorGroup simulatorGroup, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.simulatorGroup = simulatorGroup; + this.back = back; + } + + @Override + public String title() { + return "Group"; + } + + @Override + public void populate() { + if (simulatorGroup.getElements().size() < 2) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, simulatorGroup.toItem(player, clickType -> { + if (simulatorGroup.getMaterial() == null) return; + new SimulatorMaterialGui(player, simulator, simulatorGroup::getMaterial, simulatorGroup::setMaterial, this).open(); + }, clickType -> { + })); + + // Base Tick + int baseTicks = simulatorGroup.getBaseTick(); + inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + simulatorGroup.changeBaseTicks(clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> { + new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + simulatorGroup.changeBaseTicks(integer - baseTicks); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64))); + inventory.setItem(18, baseTick); + inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) { + simulatorGroup.changeBaseTicks(-baseTicks); + } else { + simulatorGroup.changeBaseTicks(clickType.isShiftClick() ? -5 : -1); + } + SimulatorWatcher.update(simulator); + }); + + boolean allTNT = simulatorGroup.getElements().stream().allMatch(TNTElement.class::isInstance); + + if (allTNT) { + // Subpixel Alignment + inventory.setItem(21, new SWItem(Material.SUNFLOWER, "§7Align§8: §eCenter", clickType -> { + simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> { + tnt.align(new Vector(0.5, 0, 0.5)); + }); + SimulatorWatcher.update(simulator); + })); + + // Z + inventory.setItem(20, new SWItem(Material.OAK_BUTTON, "§7Align§8: §eNegativ Z", clickType -> { + simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> { + tnt.align(new Vector(0, 0, 0.49)); + }); + SimulatorWatcher.update(simulator); + })); + + inventory.setItem(22, new SWItem(Material.OAK_BUTTON, "§7Align§8: §ePositiv Z", clickType -> { + simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> { + tnt.align(new Vector(0, 0, 0.51)); + }); + SimulatorWatcher.update(simulator); + })); + + // X + inventory.setItem(12, new SWItem(Material.STONE_BUTTON, "§7Align§8: §eNegativ X", clickType -> { + simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> { + tnt.align(new Vector(0.49, 0, 0)); + }); + SimulatorWatcher.update(simulator); + })); + + inventory.setItem(30, new SWItem(Material.STONE_BUTTON, "§7Align§8: §ePositiv X", clickType -> { + simulatorGroup.getElements().stream().map(TNTElement.class::cast).forEach(tnt -> { + tnt.align(new Vector(0.51, 0, 0)); + }); + SimulatorWatcher.update(simulator); + })); + } + + //Pos X + inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> { + simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(24, new SWItem(Material.PAPER, "§eX", clickType -> { + })); + inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> { + simulatorGroup.move(clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Y + inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> { + simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, new SWItem(Material.PAPER, "§eY", clickType -> { + })); + inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> { + simulatorGroup.move(0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Z + inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList(allTNT ? "§7Shift§8: §e+0.0625" : "§7Shift§8: §e+5"), false, clickType -> { + simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? 0.0625 : 5) : 1); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(26, new SWItem(Material.PAPER, "§eZ", clickType -> { + })); + inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList(allTNT ? "§7Shift§8: §e-0.0625" : "§7Shift§8: §e-5"), false, clickType -> { + simulatorGroup.move(0, 0, clickType.isShiftClick() ? (allTNT ? -0.0625 : -5) : -1); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGui.java new file mode 100644 index 00000000..e35f0eaa --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorGui.java @@ -0,0 +1,65 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +public class SimulatorGui extends SimulatorPageGui { + + public SimulatorGui(Player player, Simulator simulator) { + super(player, simulator, 6 * 9, simulator.getGroups()); + } + + @Override + public String baseTitle() { + return "Simulator - " + simulator.getName(); + } + + @Override + public void headerAndFooter() { + if (simulator.getGroups().removeIf(element -> element.getElements().isEmpty() || element.getElements().stream().allMatch(simulatorElement -> simulatorElement.getPhases().isEmpty()))) { + SimulatorWatcher.update(simulator); + } + + inventory.setItem(4, simulator.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, simulator::getMaterial, simulator::setMaterial, this).open(); + })); + inventory.setItem(49, new SWItem(Material.REPEATER, "§eSettings", clickType -> { + new SimulatorSettingsGui(player, simulator, this).open(); + })); + } + + @Override + public SWItem convert(SimulatorGroup simulatorGroup) { + return simulatorGroup.toItem(player, clickType -> { + new SimulatorGroupGui(player, simulator, simulatorGroup, this).open(); + }, clickType -> { + SimulatorElement element = simulatorGroup.getElements().get(0); + element.open(player, simulator, simulatorGroup, this); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java new file mode 100644 index 00000000..84f1e682 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorMaterialGui.java @@ -0,0 +1,78 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorPageGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class SimulatorMaterialGui extends SimulatorPageGui { + + private static final List MATERIALS = Arrays.stream(Material.values()) + .filter(material -> !material.isAir()) + .filter(material -> !material.isLegacy()) + .filter(Material::isItem) + .collect(Collectors.toList()); + + private final Supplier currentMaterial; + private Material material; + private final Consumer change; + private final SimulatorBaseGui back; + + public SimulatorMaterialGui(Player player, Simulator simulator, Supplier currentMaterial, Consumer change, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, MATERIALS); + this.currentMaterial = currentMaterial; + this.change = change; + this.back = back; + } + + @Override + public String baseTitle() { + return "Material"; + } + + @Override + public void headerAndFooter() { + material = currentMaterial.get(); + inventory.setItem(4, new SWItem(material, "§eMaterial", clickType -> { + })); + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + } + + @Override + public SWItem convert(Material material) { + return new SWItem(material, "§eNew Material", Arrays.asList(material == this.material ? "§eSelected" : "§eClick to select"), material == this.material, clickType -> { + change.accept(material); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java new file mode 100644 index 00000000..42669387 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverGui.java @@ -0,0 +1,188 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class SimulatorObserverGui extends SimulatorScrollGui { + + private final SimulatorGroup parent; + private final ObserverElement observer; + private final SimulatorBaseGui back; + + public SimulatorObserverGui(Player player, Simulator simulator, SimulatorGroup parent, ObserverElement observer, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, observer.getPhases()); + this.parent = parent; + this.observer = observer; + this.back = back; + } + + @Override + public String baseTitle() { + return "Observer"; + } + + @Override + public void headerAndFooter() { + if (observer.getPhases().isEmpty()) { + back.open(); + SimulatorWatcher.update(simulator); + return; + } + + observer.sort(); + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + if (parent.getElements().contains(observer)) { + back.open(); + } else { + SimulatorGroup newParent = observer.getGroup(simulator); + if (newParent == null) { + player.closeInventory(); + return; + } + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + if (newParent.getElements().size() == 1) { + simulatorGui.open(); + } else { + new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open(); + } + } + })); + + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + observer.getPhases().clear(); + SimulatorWatcher.update(simulator); + })); + + // Material Chooser + inventory.setItem(4, observer.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, observer::getMaterial, observer::setMaterial, this).open(); + })); + + // Settings + inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> { + new SimulatorObserverSettingsGui(player, simulator, observer, this).open(); + })); + + // Enable/Disable + inventory.setItem(48, new SWItem(observer.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, observer.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + observer.setDisabled(!observer.isDisabled()); + SimulatorWatcher.update(simulator); + })); + + // Group chooser + inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { + new SimulatorGroupChooserGui(player, simulator, observer, observer.getGroup(simulator), this).open(); + })); + } + + @Override + public SWItem[] column(ObserverPhase observerPhase, int index) { + int min; + if (index > 0) { + min = data.get(index - 1).getTickOffset() + 4; + } else { + min = 0; + } + + int max; + if (index < data.size() - 1) { + max = data.get(index + 1).getTickOffset() - 4; + } else { + max = Integer.MAX_VALUE - 4; + } + + List lore = new ArrayList<>(); + lore.add("§7Time§8:§e " + observerPhase.getTickOffset()); + lore.add("§7Order§8:§e " + observerPhase.getOrder()); + lore.add(""); + lore.add("§7Orientation§8:§e " + observerPhase.getOrientation().name()); + lore.add(""); + lore.add("§7Click§8:§e Edit"); + lore.add("§7Middle-Click§8:§e Remove"); + SWItem observer = new SWItem(Material.OBSERVER, "§eObserver", lore, false, clickType -> { + if (clickType == ClickType.MIDDLE) { + this.observer.getPhases().remove(observerPhase); + SimulatorWatcher.update(simulator); + } else { + new SimulatorObserverPhaseSettingsGui(player, simulator, this.observer, observerPhase, this).open(); + } + }); + observer.getItemStack().setAmount(Math.min(Math.max(observerPhase.getTickOffset(), 1), 64)); + + Supplier getter = observerPhase::getTickOffset; + Consumer setter = observerPhase::setTickOffset; + return new SWItem[] { + new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + observer, + new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> { + setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + new SWItem(Material.ANVIL, "§eEdit Activation", clickType -> { + new SimulatorObserverPhaseSettingsGui(player, simulator, this.observer, observerPhase, this).open(); + }), + }; + } + + @Override + public SWItem[] lastColumn() { + return new SWItem[]{ + new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + addNewPhase(clickType.isShiftClick()); + }), + new SWItem(Material.QUARTZ, "§eObserver§8:§a New Phase", clickType -> { + addNewPhase(false); + }), + new SWItem(SWItem.getDye(8), "§7", clickType -> { + }), + }; + } + + private void addNewPhase(boolean shift) { + ObserverPhase lastElement = observer.getPhases().get(observer.getPhases().size() - 1); + ObserverPhase newPhase = new ObserverPhase(lastElement.getTickOffset() + 4); + if (shift) newPhase.setTickOffset(newPhase.getTickOffset() + 5); + scroll += 2; + observer.add(newPhase); + SimulatorWatcher.update(simulator); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java new file mode 100644 index 00000000..f7925c34 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverPhaseSettingsGui.java @@ -0,0 +1,172 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui { + + private final ObserverElement observerElement; + private final ObserverPhase observer; + private final SimulatorBaseGui back; + + public SimulatorObserverPhaseSettingsGui(Player player, Simulator simulator, ObserverElement observerElement, ObserverPhase observer, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.observerElement = observerElement; + this.observer = observer; + this.back = back; + } + + @Override + public String title() { + return "Observer"; + } + + @Override + public void populate() { + if (!observerElement.getPhases().contains(observer)) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, observerElement.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, observerElement::getMaterial, observerElement::setMaterial, this).open(); + })); + + // Delete + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + observerElement.getPhases().remove(observer); + back.open(); + SimulatorWatcher.update(simulator); + })); + + int index = observerElement.getPhases().indexOf(observer); + int min; + if (index > 0) { + ObserverPhase previous = observerElement.getPhases().get(index - 1); + min = previous.getTickOffset() + 4; + } else { + min = 0; + } + + int max; + if (index < observerElement.getPhases().size() - 1) { + ObserverPhase next = observerElement.getPhases().get(index + 1); + max = next.getTickOffset() - 4; + } else { + max = Integer.MAX_VALUE - 4; + } + + //Tick Offset + int offset = observer.getTickOffset(); + inventory.setItem(10, SWItem.getDye(offset < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.setTickOffset(Math.min(max, offset + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + SWItem offsetItem = new SWItem(Material.REPEATER, "§eStart at§8:§7 " + offset, clickType -> { + new SimulatorAnvilGui<>(player, "Start at", offset + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + observer.setTickOffset(Math.min(Math.max(integer, min), max)); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64))); + inventory.setItem(19, offsetItem); + + inventory.setItem(28, SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Order + int order = observer.getOrder(); + inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR"); + SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eActivation Order§8:§7 " + order, clickType -> { + new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> { + if (integer < -SimulatorPhase.ORDER_LIMIT) return false; + if (integer > SimulatorPhase.ORDER_LIMIT) return false; + observer.setOrder(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open(); + }); + orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30))); + inventory.setItem(22, orderItem); + + inventory.setItem(31, SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + // Update orientation + inventory.setItem(25, new SWItem(Material.SUNFLOWER, "§7", clickType -> { + })); + inventory.setItem(15, new SWItem(observer.getOrientation() == BlockFace.UP ? Material.LIME_CONCRETE : Material.GRAY_CONCRETE, "§eUp", clickType -> { + observer.setOrientation(BlockFace.UP); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(33, new SWItem(observer.getOrientation() == BlockFace.DOWN ? Material.RED_CONCRETE : Material.GRAY_CONCRETE, "§eDown", clickType -> { + observer.setOrientation(BlockFace.DOWN); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(16, new SWItem(observer.getOrientation() == BlockFace.NORTH ? Material.LIME_WOOL : Material.GRAY_WOOL, "§eNorth", clickType -> { + observer.setOrientation(BlockFace.NORTH); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(34, new SWItem(observer.getOrientation() == BlockFace.SOUTH ? Material.RED_WOOL : Material.GRAY_WOOL, "§eSouth", clickType -> { + observer.setOrientation(BlockFace.SOUTH); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(24, new SWItem(observer.getOrientation() == BlockFace.EAST ? Material.LIME_STAINED_GLASS : Material.GRAY_STAINED_GLASS, "§eEast", clickType -> { + observer.setOrientation(BlockFace.EAST); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(26, new SWItem(observer.getOrientation() == BlockFace.WEST ? Material.RED_STAINED_GLASS : Material.GRAY_STAINED_GLASS, "§eWest", clickType -> { + observer.setOrientation(BlockFace.WEST); + SimulatorWatcher.update(simulator); + })); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java new file mode 100644 index 00000000..8084c7b1 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorObserverSettingsGui.java @@ -0,0 +1,142 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorObserverSettingsGui extends SimulatorBaseGui { + + private final ObserverElement observer; + private final SimulatorBaseGui back; + + public SimulatorObserverSettingsGui(Player player, Simulator simulator, ObserverElement observer, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.observer = observer; + this.back = back; + } + + @Override + public String title() { + return "Observer"; + } + + @Override + public void populate() { + if (observer.getPhases().isEmpty()) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, observer.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, observer::getMaterial, observer::setMaterial, this).open(); + })); + + // Base Tick + int baseTicks = observer.getBaseTick(); + inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.changeBaseTicks(clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> { + new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + observer.changeBaseTicks(integer - baseTicks); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64))); + inventory.setItem(18, baseTick); + inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) { + observer.changeBaseTicks(-baseTicks); + } else { + observer.changeBaseTicks(clickType.isShiftClick() ? -5 : -1); + } + SimulatorWatcher.update(simulator); + }); + + //Pos X + inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + observer.getPosition().getBlockX(), clickType -> { + new SimulatorAnvilGui<>(player, "X", observer.getPosition().getBlockX() + "", Integer::parseInt, i -> { + observer.getPosition().setX(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.move(clickType.isShiftClick() ? -5 : -1, 0, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Y + inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.move(0, clickType.isShiftClick() ? 5 : 1, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + observer.getPosition().getBlockY(), clickType -> { + new SimulatorAnvilGui<>(player, "Y", observer.getPosition().getBlockY() + "", Integer::parseInt, i -> { + observer.getPosition().setY(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.move(0, clickType.isShiftClick() ? -5 : -1, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Z + inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + observer.move(0, 0, clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + observer.getPosition().getBlockZ(), clickType -> { + new SimulatorAnvilGui<>(player, "Z", observer.getPosition().getBlockZ() + "", Integer::parseInt, i -> { + observer.getPosition().setZ(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + observer.move(0, 0, clickType.isShiftClick() ? -5 : -1); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java new file mode 100644 index 00000000..2e288895 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneGui.java @@ -0,0 +1,232 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui; +import de.steamwar.inventory.SWItem; +import lombok.AllArgsConstructor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class SimulatorRedstoneGui extends SimulatorScrollGui { + + private final SimulatorGroup parent; + private final RedstoneElement redstone; + private final SimulatorBaseGui back; + + public SimulatorRedstoneGui(Player player, Simulator simulator, SimulatorGroup parent, RedstoneElement redstone, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, new ArrayList<>()); + this.parent = parent; + this.redstone = redstone; + this.back = back; + } + + @Override + public String baseTitle() { + return "Redstone"; + } + + @Override + public void headerAndFooter() { + if (redstone.getPhases().isEmpty()) { + back.open(); + SimulatorWatcher.update(simulator); + return; + } + + data.clear(); + redstone.getPhases().forEach(redstonePhase -> { + data.add(new RedstoneSubPhase(true, redstonePhase)); + data.add(new RedstoneSubPhase(false, redstonePhase)); + }); + data.sort(null); + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + if (parent.getElements().contains(redstone)) { + back.open(); + } else { + SimulatorGroup newParent = redstone.getGroup(simulator); + if (newParent == null) { + player.closeInventory(); + return; + } + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + if (newParent.getElements().size() == 1) { + simulatorGui.open(); + } else { + new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open(); + } + } + })); + + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + redstone.getPhases().clear(); + SimulatorWatcher.update(simulator); + })); + + // Material Chooser + inventory.setItem(4, redstone.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, redstone::getMaterial, redstone::setMaterial, this).open(); + })); + + // Settings + inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> { + new SimulatorRedstoneSettingsGui(player, simulator, redstone, this).open(); + })); + + // Enable/Disable + inventory.setItem(48, new SWItem(redstone.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, redstone.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + redstone.setDisabled(!redstone.isDisabled()); + SimulatorWatcher.update(simulator); + })); + + // Group chooser + inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { + new SimulatorGroupChooserGui(player, simulator, redstone, redstone.getGroup(simulator), this).open(); + })); + } + + @Override + public SWItem[] column(RedstoneSubPhase redstoneSubPhase, int index) { + int min; + if (index % 2 == 0 && index > 0) { + RedstoneSubPhase subPhase = data.get(index - 1); + min = subPhase.phase.getTickOffset() + subPhase.phase.getLifetime() + 1; + } else { + min = 0; + } + + int max; + if (index % 2 == 0 && index < data.size() - 2) { + RedstoneSubPhase subPhase = data.get(index + 2); + max = subPhase.phase.getTickOffset() - redstoneSubPhase.phase.getLifetime() - 1; + } else if (index % 2 != 0 && index < data.size() - 1) { + RedstoneSubPhase subPhase = data.get(index + 1); + max = subPhase.phase.getTickOffset() - redstoneSubPhase.phase.getTickOffset() - 1; + } else { + max = Integer.MAX_VALUE - 5; + } + + List lore = new ArrayList<>(); + int time = redstoneSubPhase.phase.getTickOffset() + (redstoneSubPhase.place ? 0 : redstoneSubPhase.phase.getLifetime()); + if (redstoneSubPhase.place) { + lore.add("§7Time§8:§e " + time); + lore.add("§7Order§8:§e " + redstoneSubPhase.phase.getOrder()); + } else { + lore.add("§7Time§8:§e " + time); + lore.add("§7Activation Time§8:§e " + redstoneSubPhase.phase.getLifetime()); + } + lore.add(""); + lore.add("§7Click§8:§e Edit"); + lore.add("§7Middle-Click§8:§e Remove"); + SWItem redstone = new SWItem(redstoneSubPhase.place ? Material.REDSTONE_BLOCK : Material.STONE, redstoneSubPhase.place ? "§eActivate" : "§eDeactivate", lore, false, clickType -> { + if (clickType == ClickType.MIDDLE) { + this.redstone.getPhases().remove(redstoneSubPhase.phase); + SimulatorWatcher.update(simulator); + } else { + new SimulatorRedstonePhaseSettingsGui(player, simulator, this.redstone, redstoneSubPhase.phase, this).open(); + } + }); + redstone.getItemStack().setAmount(Math.max(1, Math.min(time, 64))); + + Supplier getter = redstoneSubPhase.place ? redstoneSubPhase.phase::getTickOffset : redstoneSubPhase.phase::getLifetime; + Consumer setter = redstoneSubPhase.place ? redstoneSubPhase.phase::setTickOffset : redstoneSubPhase.phase::setLifetime; + return new SWItem[] { + new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + redstone, + new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> { + setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + new SWItem(Material.ANVIL, "§eEdit Activation", clickType -> { + new SimulatorRedstonePhaseSettingsGui(player, simulator, this.redstone, redstoneSubPhase.phase, this).open(); + }), + }; + } + + @Override + public SWItem[] lastColumn() { + return new SWItem[]{ + new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + addNewPhase(clickType.isShiftClick()); + }), + new SWItem(Material.REDSTONE, "§eRedstone§8:§a New Phase", clickType -> { + addNewPhase(false); + }), + new SWItem(SWItem.getDye(8), "§7", clickType -> { + }), + }; + } + + private void addNewPhase(boolean shift) { + RedstonePhase lastElement = redstone.getPhases().get(redstone.getPhases().size() - 1); + RedstonePhase newPhase = new RedstonePhase(lastElement.getTickOffset() + lastElement.getLifetime() + 1); + if (shift) newPhase.setTickOffset(newPhase.getTickOffset() + 5); + scroll += 2; + redstone.add(newPhase); + SimulatorWatcher.update(simulator); + } + + @AllArgsConstructor + public static class RedstoneSubPhase implements Comparable { + private boolean place; + private RedstonePhase phase; + + @Override + public int compareTo(RedstoneSubPhase o) { + int thisTick = phase.getTickOffset() + (place ? 0 : phase.getLifetime()); + int otherTick = o.phase.getTickOffset() + (o.place ? 0 : o.phase.getLifetime()); + + int compare = Integer.compare(thisTick, otherTick); + if (compare != 0) { + return compare; + } + + if (place && !o.place) { + return -1; + } + if (!place && o.place) { + return 1; + } + if (!place) { + return 0; + } + + return Integer.compare(phase.getOrder(), o.phase.getOrder()); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstonePhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstonePhaseSettingsGui.java new file mode 100644 index 00000000..27901b09 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstonePhaseSettingsGui.java @@ -0,0 +1,168 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui { + private final RedstoneElement redstoneElement; + private final RedstonePhase redstone; + private final SimulatorBaseGui back; + + public SimulatorRedstonePhaseSettingsGui(Player player, Simulator simulator, RedstoneElement redstoneElement, RedstonePhase redstone, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.redstoneElement = redstoneElement; + this.redstone = redstone; + this.back = back; + } + + @Override + public String title() { + return "Redstone"; + } + + @Override + public void populate() { + if (!redstoneElement.getPhases().contains(redstone)) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, redstoneElement.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, redstoneElement::getMaterial, redstoneElement::setMaterial, this).open(); + })); + + // Delete + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + redstoneElement.getPhases().remove(redstone); + back.open(); + SimulatorWatcher.update(simulator); + })); + + int index = redstoneElement.getPhases().indexOf(redstone); + int min; + if (index > 0) { + RedstonePhase previous = redstoneElement.getPhases().get(index - 1); + min = previous.getTickOffset() + previous.getLifetime() + 1; + } else { + min = 0; + } + + int maxLifetime; + int maxOffset; + if (index < redstoneElement.getPhases().size() - 1) { + RedstonePhase next = redstoneElement.getPhases().get(index + 1); + maxLifetime = next.getTickOffset() - redstone.getTickOffset() - 1; + maxOffset = next.getTickOffset() - redstone.getLifetime() - 1; + } else { + maxLifetime = Integer.MAX_VALUE - 5; + maxOffset = Integer.MAX_VALUE - 5; + } + + //Tick Offset + int offset = redstone.getTickOffset(); + inventory.setItem(10, SWItem.getDye(offset < maxOffset ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.setTickOffset(Math.min(maxOffset, offset + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + SWItem offsetItem = new SWItem(Material.REPEATER, "§eStart at§8:§7 " + offset, clickType -> { + new SimulatorAnvilGui<>(player, "Start at", offset + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + redstone.setTickOffset(Math.min(Math.max(integer, min), maxOffset)); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64))); + inventory.setItem(19, offsetItem); + + inventory.setItem(28, SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + redstone.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Lifetime + int lifetime = redstone.getLifetime(); + inventory.setItem(11, SWItem.getDye(lifetime < maxLifetime ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.setLifetime(Math.min(maxLifetime, lifetime + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + SWItem lifetimeItem = new SWItem(Material.CLOCK, "§eActivation Time§8:§7 " + lifetime, clickType -> { + new SimulatorAnvilGui<>(player, "Activation Time", lifetime + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + redstone.setLifetime(Math.min(integer, maxLifetime)); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.CLOCK).open(); + }); + lifetimeItem.getItemStack().setAmount(Math.max(1, Math.min(lifetime, 64))); + inventory.setItem(20, lifetimeItem); + + inventory.setItem(29, SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + redstone.setLifetime(Math.max(0, lifetime - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Order + int order = redstone.getOrder(); + inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR"); + SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eActivation Order§8:§7 " + order, clickType -> { + new SimulatorAnvilGui<>(player, "Activation Order", order + "", Integer::parseInt, integer -> { + if (integer < -SimulatorPhase.ORDER_LIMIT) return false; + if (integer > SimulatorPhase.ORDER_LIMIT) return false; + redstone.setOrder(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open(); + }); + orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30))); + inventory.setItem(22, orderItem); + + inventory.setItem(31, SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + redstone.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneSettingsGui.java new file mode 100644 index 00000000..184d73a1 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorRedstoneSettingsGui.java @@ -0,0 +1,141 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui { + private final RedstoneElement redstone; + private final SimulatorBaseGui back; + + public SimulatorRedstoneSettingsGui(Player player, Simulator simulator, RedstoneElement redstone, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.redstone = redstone; + this.back = back; + } + + @Override + public String title() { + return "Redstone"; + } + + @Override + public void populate() { + if (redstone.getPhases().isEmpty()) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, redstone.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, redstone::getMaterial, redstone::setMaterial, this).open(); + })); + + // Base Tick + int baseTicks = redstone.getBaseTick(); + inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.changeBaseTicks(clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> { + new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + redstone.changeBaseTicks(integer - baseTicks); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64))); + inventory.setItem(18, baseTick); + inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) { + redstone.changeBaseTicks(-baseTicks); + } else { + redstone.changeBaseTicks(clickType.isShiftClick() ? -5 : -1); + } + SimulatorWatcher.update(simulator); + }); + + //Pos X + inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.move(clickType.isShiftClick() ? 5 : 1, 0, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + redstone.getPosition().getBlockX(), clickType -> { + new SimulatorAnvilGui<>(player, "X", redstone.getPosition().getBlockX() + "", Integer::parseInt, i -> { + redstone.getPosition().setX(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + redstone.move(clickType.isShiftClick() ? -5 : -1, 0, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Y + inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.move(0, clickType.isShiftClick() ? 5 : 1, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + redstone.getPosition().getBlockY(), clickType -> { + new SimulatorAnvilGui<>(player, "Y", redstone.getPosition().getBlockY() + "", Integer::parseInt, i -> { + redstone.getPosition().setY(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + redstone.move(0, clickType.isShiftClick() ? -5 : -1, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Z + inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + redstone.move(0, 0, clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + redstone.getPosition().getBlockZ(), clickType -> { + new SimulatorAnvilGui<>(player, "Z", redstone.getPosition().getBlockZ() + "", Integer::parseInt, i -> { + redstone.getPosition().setZ(i); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + redstone.move(0, 0, clickType.isShiftClick() ? -5 : -1); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSelectionGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSelectionGUI.java deleted file mode 100644 index 2ca90d2a..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSelectionGUI.java +++ /dev/null @@ -1,79 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.SimulatorCommand; -import de.steamwar.bausystem.features.simulator.SimulatorStorage; -import de.steamwar.bausystem.features.simulator.TNTSimulator; -import de.steamwar.inventory.SWAnvilInv; -import de.steamwar.inventory.SWItem; -import de.steamwar.inventory.SWListInv; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.List; - -@UtilityClass -public class SimulatorSelectionGUI { - - public void open(Player player, ItemStack hand) { - List> swListEntryList = new ArrayList<>(); - - for (String name : SimulatorStorage.getSimulatorNames()) { - TNTSimulator simulator = SimulatorStorage.getSimulator(name); - SWItem swItem = new SWItem(simulator.getMaterial(), "§f" + name, new ArrayList<>(), false, null); - swListEntryList.add(new SWListInv.SWListEntry<>(swItem, simulator)); - } - - SWListInv inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SIMULATOR_GUI_SELECT_SIM", player), false, swListEntryList, (clickType, tntSimulator) -> { - TNTSimulator current = SimulatorStorage.getSimulator(hand); - if (current != null) { - current.hide(player); - } - SimulatorStorage.setSimulator(player, hand, tntSimulator); - player.getInventory().setItemInMainHand(hand); - player.closeInventory(); - }); - - inv.setItem(49, new SWItem(Material.NAME_TAG, BauSystem.MESSAGE.parse("SIMULATOR_GUI_CREATE_SIM", player), clickType -> { - SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("SIMULATOR_GUI_CREATE_SIM_GUI", player), ""); - swAnvilInv.setItem(Material.PAPER); - swAnvilInv.setCallback(s -> { - player.closeInventory(); - if (SimulatorCommand.createSimulator(player, s)) { - TNTSimulator current = SimulatorStorage.getSimulator(hand); - if (current != null) { - current.hide(player); - } - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(s); - SimulatorStorage.setSimulator(player, hand, tntSimulator); - player.getInventory().setItemInMainHand(hand); - } - }); - swAnvilInv.open(); - })); - - inv.open(); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSettingsGui.java new file mode 100644 index 00000000..ccb00412 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorSettingsGui.java @@ -0,0 +1,99 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorSettingsGui extends SimulatorBaseGui { + + private final SimulatorBaseGui back; + + public SimulatorSettingsGui(Player player, Simulator simulator, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.back = back; + } + + @Override + public String title() { + return simulator.getName() + " Settings"; + } + + @Override + public void populate() { + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, simulator.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, simulator::getMaterial, simulator::setMaterial, this).open(); + })); + + //AutoTrace + inventory.setItem(20, new SWItem(simulator.isAutoTrace() ? Material.CHAIN_COMMAND_BLOCK : Material.COMMAND_BLOCK, "§eAutoTrace§8: " + (simulator.isAutoTrace() ? "§aOn" : "§cOff"), clickType -> { + simulator.setAutoTrace(!simulator.isAutoTrace()); + SimulatorWatcher.update(simulator); + })); + + //Pos X + inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + simulator.move(clickType.isShiftClick() ? 5 : 1, 0, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(24, new SWItem(Material.PAPER, "§eX", clickType -> { + })); + inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + simulator.move(clickType.isShiftClick() ? -5 : -1, 0, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Y + inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + simulator.move(0, clickType.isShiftClick() ? 5 : 1, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, new SWItem(Material.PAPER, "§eY", clickType -> { + })); + inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + simulator.move(0, clickType.isShiftClick() ? -5 : -1, 0); + SimulatorWatcher.update(simulator); + }); + + //Pos Z + inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + simulator.move(0, 0, clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(26, new SWItem(Material.PAPER, "§eZ", clickType -> { + })); + inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + simulator.move(0, 0, clickType.isShiftClick() ? -5 : -1); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java new file mode 100644 index 00000000..a9c178ce --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTGui.java @@ -0,0 +1,162 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +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.gui.base.SimulatorBaseGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +import java.util.Arrays; + +public class SimulatorTNTGui extends SimulatorScrollGui { + + private TNTElement tnt; + private SimulatorGroup parent; + private SimulatorBaseGui back; + + public SimulatorTNTGui(Player player, Simulator simulator, TNTElement tnt, SimulatorGroup parent, SimulatorBaseGui back) { + super(player, simulator, 6 * 9, tnt.getPhases()); + this.tnt = tnt; + this.parent = parent; + this.back = back; + } + + @Override + public String baseTitle() { + return "TNT"; + } + + @Override + public void headerAndFooter() { + if (tnt.getPhases().isEmpty()) { + back.open(); + SimulatorWatcher.update(simulator); + return; + } + + tnt.sort(); + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + if (parent.getElements().contains(tnt)) { + back.open(); + } else { + SimulatorGroup newParent = tnt.getGroup(simulator); + if (newParent == null) { + player.closeInventory(); + return; + } + SimulatorGui simulatorGui = new SimulatorGui(player, simulator); + if (newParent.getElements().size() == 1) { + simulatorGui.open(); + } else { + new SimulatorGroupGui(player, simulator, newParent, simulatorGui).open(); + } + } + })); + + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + tnt.getPhases().clear(); + SimulatorWatcher.update(simulator); + })); + + // Material Chooser + inventory.setItem(4, tnt.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, tnt::getMaterial, tnt::setMaterial, this).open(); + })); + + inventory.setItem(47, new SWItem(Material.REPEATER, "§eSettings", clickType -> { + new SimulatorTNTSettingsGui(player, simulator, tnt, this).open(); + })); + inventory.setItem(48, new SWItem(tnt.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, tnt.isDisabled() ? "§cDisabled" : "§aEnabled", clickType -> { + tnt.setDisabled(!tnt.isDisabled()); + SimulatorWatcher.update(simulator); + })); + 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()); + parent.add(tntElement); + new SimulatorGroupGui(player, simulator, parent, new SimulatorGui(player, simulator)).open(); + SimulatorWatcher.update(simulator); + })); + inventory.setItem(51, new SWItem(Material.LEAD, "§eJoin Group", clickType -> { + new SimulatorGroupChooserGui(player, simulator, tnt, tnt.getGroup(simulator), this).open(); + })); + } + + @Override + public SWItem[] column(TNTPhase tntSetting, int index) { + SWItem tnt = new SWItem(Material.TNT, "§eTNT§8:§7 " + tntSetting.getCount(), Arrays.asList("§7Tick§8: §e" + tntSetting.getTickOffset(), "§7Fuse§8:§e " + tntSetting.getLifetime(), "", "§7Order§8:§e " + tntSetting.getOrder(), "", "§7X-Jump§8: " + (tntSetting.isXJump() ? "§aOn" : "§cOff"), "§7Y-Jump§8: " + (tntSetting.isYJump() ? "§aOn" : "§cOff"), "§7Z-Jump§8: " + (tntSetting.isZJump() ? "§aOn" : "§cOff"), "", "§7Click§8:§e Edit", "§7Middle-Click§8:§e Remove"), false, clickType -> { + if (clickType == ClickType.MIDDLE) { + this.tnt.getPhases().remove(tntSetting); + SimulatorWatcher.update(simulator); + } else { + new SimulatorTNTPhaseSettingsGui(player, simulator, this.tnt, tntSetting, this).open(); + } + }); + tnt.getItemStack().setAmount(Math.min(tntSetting.getCount(), 64)); + + return new SWItem[]{ + new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + tntSetting.setCount(tntSetting.getCount() + (clickType.isShiftClick() ? 5 : 1)); + SimulatorWatcher.update(simulator); + }), + tnt, + new SWItem(SWItem.getDye(tntSetting.getCount() > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> { + tntSetting.setCount(Math.max(1, tntSetting.getCount() - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }), + new SWItem(Material.ANVIL, "§eEdit Phase", clickType -> { + new SimulatorTNTPhaseSettingsGui(player, simulator, this.tnt, tntSetting, this).open(); + }), + }; + } + + @Override + public SWItem[] lastColumn() { + return new SWItem[]{ + new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> { + addNewPhase(clickType.isShiftClick()); + }), + new SWItem(Material.GUNPOWDER, "§eTNT§8:§a New Phase", clickType -> { + addNewPhase(false); + }), + new SWItem(SWItem.getDye(8), "§7", clickType -> { + }), + }; + } + + private void addNewPhase(boolean shift) { + TNTPhase lastElement = tnt.getPhases().get(tnt.getPhases().size() - 1); + TNTPhase newPhase = new TNTPhase(lastElement.getTickOffset() + 1); + if (shift) newPhase.setCount(newPhase.getCount() + 5); + scroll++; + tnt.add(newPhase); + SimulatorWatcher.update(simulator); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTPhaseSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTPhaseSettingsGui.java new file mode 100644 index 00000000..9bfc4fe5 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTPhaseSettingsGui.java @@ -0,0 +1,196 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui { + private final TNTElement tntElement; + private final TNTPhase tnt; + private final SimulatorBaseGui back; + + public SimulatorTNTPhaseSettingsGui(Player player, Simulator simulator, TNTElement tntElement, TNTPhase tnt, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.tntElement = tntElement; + this.tnt = tnt; + this.back = back; + } + + @Override + public String title() { + return "TNT"; + } + + @Override + public void populate() { + if (!tntElement.getPhases().contains(tnt)) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + inventory.setItem(4, tntElement.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, tntElement::getMaterial, tntElement::setMaterial, this).open(); + })); + + //Delete + inventory.setItem(8, new SWItem(Material.BARRIER, "§eDelete", clickType -> { + tntElement.getPhases().remove(tnt); + back.open(); + SimulatorWatcher.update(simulator); + })); + + //Count + int count = tnt.getCount(); + inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + tnt.setCount(count + (clickType.isShiftClick() ? 5 : 1)); + SimulatorWatcher.update(simulator); + }); + + SWItem countItem = new SWItem(Material.TNT, "§eCount§8:§7 " + count, clickType -> { + new SimulatorAnvilGui<>(player, "Count", count + "", Integer::parseInt, integer -> { + if (integer < 1) return false; + tnt.setCount(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.TNT).open(); + }); + countItem.getItemStack().setAmount(Math.max(1, Math.min(count, 64))); + inventory.setItem(18, countItem); + + inventory.setItem(27, SWItem.getDye(count > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + tnt.setCount(Math.max(1, count - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Tick Offset + int offset = tnt.getTickOffset(); + inventory.setItem(10, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + tnt.setTickOffset(offset + (clickType.isShiftClick() ? 5 : 1)); + SimulatorWatcher.update(simulator); + }); + + SWItem offsetItem = new SWItem(Material.REPEATER, "§eStart at§8:§7 " + offset, clickType -> { + new SimulatorAnvilGui<>(player, "Start at", offset + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + tnt.setTickOffset(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + offsetItem.getItemStack().setAmount(Math.max(1, Math.min(offset, 64))); + inventory.setItem(19, offsetItem); + + inventory.setItem(28, SWItem.getDye(offset > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + tnt.setTickOffset(Math.max(0, offset - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Lifetime + int lifetime = tnt.getLifetime(); + inventory.setItem(11, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + tnt.setLifetime(lifetime + (clickType.isShiftClick() ? 5 : 1)); + SimulatorWatcher.update(simulator); + }); + + SWItem lifetimeItem = new SWItem(Material.CLOCK, "§eLifetime§8:§7 " + lifetime, clickType -> { + new SimulatorAnvilGui<>(player, "Lifetime", lifetime + "", Integer::parseInt, integer -> { + if (integer < 1) return false; + tnt.setLifetime(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.CLOCK).open(); + }); + lifetimeItem.getItemStack().setAmount(Math.max(1, Math.min(lifetime, 64))); + inventory.setItem(20, lifetimeItem); + + inventory.setItem(29, SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + tnt.setLifetime(Math.max(1, lifetime - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Order + int order = tnt.getOrder(); + inventory.setItem(13, SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + tnt.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + Material negativeNumbers = Material.getMaterial(Core.getVersion() >= 19 ? "RECOVERY_COMPASS" : "FIREWORK_STAR"); + SWItem orderItem = new SWItem(order >= 0 ? Material.COMPASS : negativeNumbers, "§eCalculation Order§8:§7 " + order, clickType -> { + new SimulatorAnvilGui<>(player, "Calculation Order", order + "", Integer::parseInt, integer -> { + if (integer < -SimulatorPhase.ORDER_LIMIT) return false; + if (integer > SimulatorPhase.ORDER_LIMIT) return false; + tnt.setOrder(integer); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(order >= 0 ? Material.COMPASS : negativeNumbers).open(); + }); + orderItem.getItemStack().setAmount(Math.max(1, Math.min(Math.abs(order), 30))); + inventory.setItem(22, orderItem); + + inventory.setItem(31, SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + tnt.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1))); + SimulatorWatcher.update(simulator); + }); + + //Jump + SWItem jumpX = new SWItem(tnt.isXJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump X§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> { + tnt.setXJump(!tnt.isXJump()); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(33, jumpX); + + SWItem jumpY = new SWItem(tnt.isYJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Y§8: " + (tnt.isYJump() ? "§aon" : "§coff"), clickType -> { + tnt.setYJump(!tnt.isYJump()); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(16, jumpY); + + SWItem jumpZ = new SWItem(tnt.isZJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Z§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> { + tnt.setZJump(!tnt.isZJump()); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(35, jumpZ); + + SWItem jumpAll = new SWItem(Material.TNT, "§7TNT §eJump §8: " + (tnt.hasJump() ? "§aon" : "§coff"), clickType -> { + tnt.setJump(!tnt.hasJump()); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, jumpAll); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTSettingsGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTSettingsGui.java new file mode 100644 index 00000000..1dcf005c --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/SimulatorTNTSettingsGui.java @@ -0,0 +1,179 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui; + +import de.steamwar.bausystem.features.simulator.SimulatorWatcher; +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui; +import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui; +import de.steamwar.inventory.SWItem; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SimulatorTNTSettingsGui extends SimulatorBaseGui { + private final TNTElement tnt; + private final SimulatorBaseGui back; + + public SimulatorTNTSettingsGui(Player player, Simulator simulator, TNTElement tnt, SimulatorBaseGui back) { + super(player, simulator, 5 * 9); + this.tnt = tnt; + this.back = back; + } + + @Override + public String title() { + return "TNT"; + } + + @Override + public void populate() { + if (tnt.getPhases().isEmpty()) { + back.open(); + return; + } + + // Back Arrow + inventory.setItem(0, new SWItem(Material.ARROW, "§eBack", clickType -> { + back.open(); + })); + + // Material Chooser + List lore = new ArrayList<>(); + lore.add("§7Phase count§8:§e " + tnt.getPhases().size()); + lore.add("§7Tick§8:§e " + tnt.getBaseTick()); + if (tnt.isDisabled()) { + lore.add(""); + lore.add("§cDisabled"); + } + inventory.setItem(4, tnt.toItem(player, clickType -> { + new SimulatorMaterialGui(player, simulator, tnt::getMaterial, tnt::setMaterial, this).open(); + })); + + // Base Tick + int baseTicks = tnt.getBaseTick(); + inventory.setItem(9, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> { + tnt.changeBaseTicks(clickType.isShiftClick() ? 5 : 1); + SimulatorWatcher.update(simulator); + }); + SWItem baseTick = new SWItem(Material.REPEATER, "§eTicks§8:§7 " + baseTicks, clickType -> { + new SimulatorAnvilGui<>(player, "Ticks", baseTicks + "", Integer::parseInt, integer -> { + if (integer < 0) return false; + tnt.changeBaseTicks(integer - baseTicks); + SimulatorWatcher.update(simulator); + return true; + }, this).setItem(Material.REPEATER).open(); + }); + baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64))); + inventory.setItem(18, baseTick); + inventory.setItem(27, SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> { + if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) { + tnt.changeBaseTicks(-baseTicks); + } else { + tnt.changeBaseTicks(clickType.isShiftClick() ? -5 : -1); + } + SimulatorWatcher.update(simulator); + }); + + // Subpixel Alignment + inventory.setItem(21, new SWItem(Material.SUNFLOWER, "§7Align§8: §eCenter", clickType -> { + tnt.align(new Vector(0.5, 0, 0.5)); + SimulatorWatcher.update(simulator); + })); + + // Z + inventory.setItem(20, new SWItem(Material.OAK_BUTTON, "§7Align§8: §eNegativ Z", clickType -> { + tnt.align(new Vector(0, 0, 0.49)); + SimulatorWatcher.update(simulator); + })); + + inventory.setItem(22, new SWItem(Material.OAK_BUTTON, "§7Align§8: §ePositiv Z", clickType -> { + tnt.align(new Vector(0, 0, 0.51)); + SimulatorWatcher.update(simulator); + })); + + // X + inventory.setItem(12, new SWItem(Material.STONE_BUTTON, "§7Align§8: §eNegativ X", clickType -> { + tnt.align(new Vector(0.49, 0, 0)); + SimulatorWatcher.update(simulator); + })); + + inventory.setItem(30, new SWItem(Material.STONE_BUTTON, "§7Align§8: §ePositiv X", clickType -> { + tnt.align(new Vector(0.51, 0, 0)); + SimulatorWatcher.update(simulator); + })); + + // Pos X + inventory.setItem(15, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> { + tnt.move(clickType.isShiftClick() ? 0.0625 : 1, 0, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(24, new SWItem(Material.PAPER, "§eX§8:§7 " + tnt.getPosition().getX(), clickType -> { + new SimulatorAnvilGui<>(player, "X", tnt.getPosition().getX() + "", Double::parseDouble, d -> { + tnt.getPosition().setX(d); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(33, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> { + tnt.move(clickType.isShiftClick() ? -0.0625 : -1, 0, 0); + SimulatorWatcher.update(simulator); + }); + + // Pos Y + inventory.setItem(16, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> { + tnt.move(0, clickType.isShiftClick() ? 0.0625 : 1, 0); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(25, new SWItem(Material.PAPER, "§eY§8:§7 " + tnt.getPosition().getY(), clickType -> { + new SimulatorAnvilGui<>(player, "Y", tnt.getPosition().getY() + "", Double::parseDouble, d -> { + tnt.getPosition().setY(d); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(34, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> { + tnt.move(0, clickType.isShiftClick() ? -0.0625 : -1, 0); + SimulatorWatcher.update(simulator); + }); + + // Pos Z + inventory.setItem(17, SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> { + tnt.move(0, 0, clickType.isShiftClick() ? 0.0625 : 1); + SimulatorWatcher.update(simulator); + }); + inventory.setItem(26, new SWItem(Material.PAPER, "§eZ§8:§7 " + tnt.getPosition().getZ(), clickType -> { + new SimulatorAnvilGui<>(player, "Z", tnt.getPosition().getZ() + "", Double::parseDouble, d -> { + tnt.getPosition().setZ(d); + SimulatorWatcher.update(simulator); + return true; + }, this).open(); + })); + inventory.setItem(35, SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> { + tnt.move(0, 0, clickType.isShiftClick() ? -0.0625 : -1); + SimulatorWatcher.update(simulator); + }); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTElementGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTElementGUI.java deleted file mode 100644 index 93181f90..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTElementGUI.java +++ /dev/null @@ -1,390 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.OrderUtils; -import de.steamwar.bausystem.features.simulator.SimulatorStorage; -import de.steamwar.bausystem.features.simulator.TNTSimulator; -import de.steamwar.bausystem.features.simulator.gui.components.ChangeMaterial; -import de.steamwar.bausystem.features.simulator.gui.components.ChangePosition; -import de.steamwar.bausystem.features.simulator.gui.components.Disabled; -import de.steamwar.bausystem.features.simulator.tnt.TNTElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTGroup; -import de.steamwar.inventory.SWAnvilInv; -import de.steamwar.inventory.SWInventory; -import de.steamwar.inventory.SWItem; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.util.Consumer; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique; - -@UtilityClass -public class TNTElementGUI { - - private SWInventory open(Player player, String name) { - SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_GUI_NAME", player, name)); - SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {}); - for (int i = 0; i < 9; i++) { - inv.setItem(i, gray); - inv.setItem(i + 36, gray); - } - return inv; - } - - public void open(Player player, TNTElement tntElement, Runnable back) { - SWInventory inv = open(player, ""); - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player); - Runnable editObserver = () -> { - List locationLore = new ArrayList<>(); - locationLore.add(""); - locationLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, tntElement.getPosition().getX())); - locationLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, tntElement.getPosition().getY())); - locationLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, tntElement.getPosition().getZ())); - inv.setItem(20, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_LOCATION", player), locationLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - editLocation(player, tntElement, () -> open(player, tntElement, back)); - })); - - List propertiesLore = new ArrayList<>(); - propertiesLore.add(""); - propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_COUNT", player, tntElement.getCount())); - propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, tntElement.getTickOffset())); - propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_FUSE", player, tntElement.getFuseTicks())); - propertiesLore.add(""); - propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_X", player, active(player, tntElement.isXVelocity()))); - propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Y", player, active(player, tntElement.isYVelocity()))); - propertiesLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Z", player, active(player, tntElement.isZVelocity()))); - inv.setItem(22, new SWItem(Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_PROPERTIES", player), propertiesLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - editProperties(player, tntElement, () -> open(player, tntElement, back)); - })); - - List otherLore = new ArrayList<>(); - otherLore.add(""); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ACTIVATED_WITH", player, BauSystem.MESSAGE.parse(OrderUtils.name(tntElement.getOrder()), player))); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_NAME_LORE", player, tntElement.getMaterial().name())); - if (tntElement.isDisabled()) { - otherLore.add(""); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", player)); - } - inv.setItem(24, new SWItem(Material.ANVIL, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_OTHER", player), otherLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - editOther(player, tntElement, () -> open(player, tntElement, back)); - })); - - // Delete tnt - inv.setItem(44, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_REMOVE_TNT", player), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntSimulator.remove(tntElement); - player.closeInventory(); - })); - }; - editObserver.run(); - tntElement.register(editObserver, player::closeInventory); - inv.addCloseRunnable(() -> { - tntElement.unregister(editObserver); - }); - - inv.open(); - } - - private void editLocation(Player player, TNTElement tntElement, Runnable back) { - SWInventory inv = open(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_EDIT_LOCATION", player)); - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - Runnable editObserver = () -> { - ChangePosition.show(inv, player, tntElement, vectorUnaryOperator -> { - if (tntElement.getParent() == null) { - tntElement.setPosition(vectorUnaryOperator.apply(tntElement.getPosition())); - } else { - tntElement.setPosition(vectorUnaryOperator.apply(tntElement.getPosition()).subtract(tntElement.getParent().getPosition())); - } - }, () -> editLocation(player, tntElement, back)); - - // Alignment - inv.setItem(23, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_Z", player), clickType -> { // Z negative - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.align(new Vector(0, 0, 0.49)); - tntElement.change(); - })); - inv.setItem(25, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_Z", player), clickType -> { // Z positive - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.align(new Vector(0, 0, 0.51)); - tntElement.change(); - })); - inv.setItem(15, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_POSITIVE_X", player), clickType -> { // X positive - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.align(new Vector(0.51, 0, 0)); - tntElement.change(); - })); - inv.setItem(33, new SWItem(Material.OAK_BUTTON, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_NEGATIVE_X", player), clickType -> { // X negative - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.align(new Vector(0.49, 0, 0)); - tntElement.change(); - })); - inv.setItem(24, new SWItem(Material.SUNFLOWER, BauSystem.MESSAGE.parse("SIMULATOR_ALIGNMENT_CENTER", player), clickType -> { // CENTER - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.align(new Vector(0.5, 0, 0.5)); - tntElement.change(); - })); - }; - editObserver.run(); - tntElement.register(editObserver, player::closeInventory); - inv.addCloseRunnable(() -> { - tntElement.unregister(editObserver); - }); - - inv.open(); - } - - private void editProperties(Player player, TNTElement tntElement, Runnable back) { - SWInventory inv = open(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_EDIT_PROPERTIES", player)); - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player); - String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player); - List plusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_FIVE_SHIFT", player)); - List minusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_FIVE_SHIFT", player)); - List lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player)); - - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player); - Runnable editObserver = () -> { - // Change Count of spawned TNT - inv.setItem(10, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setCount(tntElement.getCount() + ((clickType.isShiftClick()) ? 5 : 1)); - tntElement.change(); - }))); - SWItem countItem = new SWItem(Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_COUNT", player, tntElement.getCount()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_COUNT_ANVIL_GUI_NAME", player), tntElement.getCount(), c -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setCount(c); - tntElement.change(); - editProperties(player, tntElement, back); - }, () -> editProperties(player, tntElement, back))); - countItem.getItemStack().setAmount(tntElement.getCount()); - inv.setItem(19, countItem); - inv.setItem(28, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setCount(tntElement.getCount() - ((clickType.isShiftClick()) ? 5 : 1)); - tntElement.change(); - }))); - - // Change TickOffset - inv.setItem(11, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setTickOffset(tntElement.getOwnTickOffset() + (clickType.isShiftClick() ? 5 : 1)); - tntElement.change(); - }))); - SWItem tickItem = new SWItem(SWItem.getMaterial("DIODE"), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, tntElement.getTickOffset()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME", player), tntElement.getTickOffset(), tick -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setTickOffset(tick - tntElement.getParentTickOffset()); - tntElement.change(); - editProperties(player, tntElement, back); - }, () -> editProperties(player, tntElement, back))); - tickItem.getItemStack().setAmount(Math.max(tntElement.getTickOffset(), 1)); - inv.setItem(20, tickItem); - inv.setItem(29, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setTickOffset(tntElement.getOwnTickOffset() - (clickType.isShiftClick() ? 5 : 1)); - tntElement.change(); - }))); - - // Change FuseTicks - inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setFuseTicks(tntElement.getFuseTicks() + (clickType.isShiftClick() ? 5 : 1)); - tntElement.change(); - }))); - SWItem fuseTickItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_FUSE", player, tntElement.getFuseTicks()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_FUSE_ANVIL_GUI_NAME", player), tntElement.getFuseTicks(), tick -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setFuseTicks(tick); - tntElement.change(); - editProperties(player, tntElement, back); - }, () -> editProperties(player, tntElement, back))); - fuseTickItem.getItemStack().setAmount(Math.max(tntElement.getFuseTicks(), 1)); - inv.setItem(21, fuseTickItem); - inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setFuseTicks(tntElement.getFuseTicks() - (clickType.isShiftClick() ? 5 : 1)); - tntElement.change(); - }))); - - // Velocity Settings - inv.setItem(24, Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_NAME", player), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - if (tntElement.isXVelocity() || tntElement.isYVelocity() || tntElement.isZVelocity()) { - tntElement.setXVelocity(false); - tntElement.setYVelocity(false); - tntElement.setZVelocity(false); - } else { - tntElement.setXVelocity(true); - tntElement.setYVelocity(true); - tntElement.setZVelocity(true); - } - tntElement.change(); - }); - inv.setItem(32, new SWItem(getWool(tntElement.isXVelocity()), getColor(tntElement.isXVelocity()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_X", player, active(player, tntElement.isXVelocity())), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setXVelocity(!tntElement.isXVelocity()); - tntElement.change(); - })); - inv.setItem(15, new SWItem(getWool(tntElement.isYVelocity()), getColor(tntElement.isYVelocity()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Y", player, active(player, tntElement.isYVelocity())), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setYVelocity(!tntElement.isYVelocity()); - tntElement.change(); - })); - inv.setItem(34, new SWItem(getWool(tntElement.isZVelocity()), getColor(tntElement.isZVelocity()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_Z", player, active(player, tntElement.isZVelocity())), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntElement.setZVelocity(!tntElement.isZVelocity()); - tntElement.change(); - })); - }; - editObserver.run(); - tntElement.register(editObserver, player::closeInventory); - inv.addCloseRunnable(() -> { - tntElement.unregister(editObserver); - }); - - inv.open(); - } - - private void editOther(Player player, TNTElement tntElement, Runnable back) { - SWInventory inv = open(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_EDIT_OTHER", player)); - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player); - Runnable editObserver = () -> { - inv.setItem(19, new SWItem(tntElement.getOrder(), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ACTIVATED_NAME", player), OrderUtils.orderList(tntElement.getOrder(), player), false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - if (clickType.isShiftClick()) { - tntElement.setOrder(OrderUtils.previous(tntElement.getOrder())); - } else { - tntElement.setOrder(OrderUtils.next(tntElement.getOrder())); - } - tntElement.change(); - })); - - ChangeMaterial.show(inv, player, 21, tntElement, Material.BARREL, () -> editOther(player, tntElement, back)); - Disabled.show(inv, player, 22, tntSimulator, tntElement); - - if (!tntElement.hasParent()) { - inv.setItem(24, new SWItem(Material.TNT, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ADD_IGNITION_PHASE", player), Arrays.asList(), false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - // Create TNTGroup - tntSimulator.getTntElementList().remove(tntElement); - Vector vector = tntElement.getOwnPosition().clone(); - int tickOffset = tntElement.getOwnTickOffset(); - TNTGroup tntGroup = new TNTGroup(vector); - tntGroup.setTickOffset(tickOffset); - tntGroup.add(tntElement); - tntElement.setTickOffset(0); - tntElement.setPosition(new Vector(0, 0, 0)); - tntSimulator.getTntElementList().add(tntGroup); - - // Add new TNT - TNTElement newElement = new TNTElement(new Vector(0, 0, 0), tntGroup, tntSimulator.getEntityServer()); - newElement.setTickOffset(1); - tntGroup.add(newElement); - - tntElement.change(); - open(player, newElement, () -> TNTSimulatorGui.open(player, null, tntGroup, () -> new ArrayList<>(tntGroup.getElements()), () -> { - TNTSimulatorGui.open(player, tntSimulator, null, () -> new ArrayList<>(tntSimulator.getTntElementList()), null); - })); - })); - } else { - inv.setItem(24, new SWItem()); - } - - inv.setItem(25, new SWItem(Material.DISPENSER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_ADD_TNT", player), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - Vector vector = tntElement.getOwnPosition().clone(); - TNTElement newElement = new TNTElement(vector, null, tntSimulator.getEntityServer()); - if (tntElement.hasParent()) { - newElement.setTickOffset(tntElement.getOwnTickOffset() + 1); - tntElement.getParent().add(newElement); - open(player, newElement, () -> TNTSimulatorGui.open(player, null, tntElement.getParent(), () -> new ArrayList<>(tntElement.getParent().getElements()), () -> { - TNTSimulatorGui.open(player, tntSimulator, null, () -> new ArrayList<>(tntSimulator.getTntElementList()), null); - })); - } else { - tntSimulator.getTntElementList().add(newElement); - open(player, newElement, () -> TNTSimulatorGui.open(player, tntSimulator, null, tntSimulator::getTntElementList, null)); - } - })); - - // Delete tnt - inv.setItem(44, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_REMOVE_TNT", player), clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntSimulator.remove(tntElement); - player.closeInventory(); - })); - }; - editObserver.run(); - tntElement.register(editObserver, player::closeInventory); - inv.addCloseRunnable(() -> { - tntElement.unregister(editObserver); - }); - - inv.open(); - } - - private String active(Player p, boolean active) { - return active ? BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_ON", p) : BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_VELOCITY_OFF", p); - } - - private Material getWool(boolean b) { - return b ? Material.LIME_WOOL : Material.RED_WOOL; - } - - private byte getColor(boolean b) { - return (byte) (b ? 10 : 1); - } - - private void changeCount(Player player, String name, int defaultValue, Consumer result, Runnable failure) { - SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + ""); - swAnvilInv.setItem(Material.PAPER); - swAnvilInv.setCallback(s -> { - try { - result.accept(Integer.parseInt(s)); - } catch (NumberFormatException e) { - failure.run(); - } - }); - swAnvilInv.open(); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTGroupEditGUI.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTGroupEditGUI.java deleted file mode 100644 index 9c4aa70a..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTGroupEditGUI.java +++ /dev/null @@ -1,198 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.SimulatorStorage; -import de.steamwar.bausystem.features.simulator.TNTSimulator; -import de.steamwar.bausystem.features.simulator.gui.components.ChangeMaterial; -import de.steamwar.bausystem.features.simulator.gui.components.ChangePosition; -import de.steamwar.bausystem.features.simulator.gui.components.Disabled; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTGroup; -import de.steamwar.inventory.SWAnvilInv; -import de.steamwar.inventory.SWInventory; -import de.steamwar.inventory.SWItem; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.util.Consumer; -import org.bukkit.util.Vector; - -import java.util.Arrays; -import java.util.List; -import java.util.function.UnaryOperator; - -import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique; - -@UtilityClass -public class TNTGroupEditGUI { - - private static final Vector X_VECTOR = new Vector(0.0625, 0, 0); - private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0); - private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625); - - private static final Vector FX_VECTOR = new Vector(1, 0, 0); - private static final Vector FY_VECTOR = new Vector(0, 1, 0); - private static final Vector FZ_VECTOR = new Vector(0, 0, 1); - - public void open(Player player, TNTSimulator tntSimulator, List simulatorElements, Runnable back) { - SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_MOVE_ALL_GUI_NAME", player)); - SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {}); - for (int i = 0; i < 9; i++) { - inv.setItem(i, gray); - inv.setItem(i + 36, gray); - } - - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player); - String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player); - List plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player)); - List minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player)); - List lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player)); - - Vector vector = simulatorElements.get(0).getPosition(); - - // X Position - inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(simulatorElements, clickType.isShiftClick() ? X_VECTOR : FX_VECTOR); - tntSimulator.change(); - }))); - inv.setItem(21, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, vector.getX()), lore, false, clickType -> {})); - inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(simulatorElements, (clickType.isShiftClick() ? X_VECTOR : FX_VECTOR).clone().multiply(-1)); - tntSimulator.change(); - }))); - - // Y Position - inv.setItem(13, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(simulatorElements, clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR); - tntSimulator.change(); - }))); - inv.setItem(22, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, vector.getY()), lore, false, clickType -> {})); - inv.setItem(31, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(simulatorElements, (clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR).clone().multiply(-1)); - tntSimulator.change(); - }))); - - // Z Position - inv.setItem(14, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(simulatorElements, clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR); - tntSimulator.change(); - }))); - inv.setItem(23, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, vector.getZ()), lore, false, clickType -> {})); - inv.setItem(32, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(simulatorElements, (clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR).clone().multiply(-1)); - }))); - - inv.open(); - } - - public void moveAll(List simulatorElements, Vector vector) { - for (SimulatorElement element : simulatorElements) { - if (element instanceof TNTGroup) { - TNTGroup group = (TNTGroup) element; - group.setPosition(group.getPosition().add(vector)); - } else if (element instanceof TNTElement) { - TNTElement tntElement = (TNTElement) element; - tntElement.setPosition(tntElement.getOwnPosition().add(vector)); - } - } - } - - public void open(Player player, TNTGroup tntGroup, Runnable back) { - SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_GROUP_MENU", player)); - SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {}); - for (int i = 0; i < 9; i++) { - inv.setItem(i, gray); - inv.setItem(i + 36, gray); - } - - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player); - String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player); - List plusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_FIVE_SHIFT", player)); - List minusOneFiveShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_FIVE_SHIFT", player)); - List lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player)); - - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player); - Runnable editObserver = () -> { - ChangePosition.show(inv, player, tntGroup, vectorUnaryOperator -> { - tntGroup.setPosition(vectorUnaryOperator.apply(tntGroup.getPosition())); - }, () -> open(player, tntGroup, back)); - ChangeMaterial.show(inv, player, 14, tntGroup, Material.BARREL, () -> open(player, tntGroup, back)); - Disabled.show(inv, player, 32, tntSimulator, tntGroup); - - // Change TickOffset - inv.setItem(16, new SWItem(SWItem.getDye(10), plusOneName, plusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntGroup.setTickOffset(tntGroup.getTickOffset() + (clickType.isShiftClick() ? 5 : 1)); - tntGroup.change(); - })); - SWItem tickItem = new SWItem(SWItem.getMaterial("DIODE"), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, tntGroup.getTickOffset()), lore, false, clickType -> changeCount(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK_ANVIL_GUI_NAME", player), tntGroup.getTickOffset(), tick -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntGroup.setTickOffset(tick); - tntGroup.change(); - open(player, tntGroup, back); - }, () -> open(player, tntGroup, back))); - tickItem.getItemStack().setAmount(Math.max(tntGroup.getTickOffset(), 1)); - inv.setItem(25, tickItem); - inv.setItem(34, new SWItem(SWItem.getDye(1), minusOneName, minusOneFiveShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - tntGroup.setTickOffset(tntGroup.getTickOffset() - (clickType.isShiftClick() ? 5 : 1)); - tntGroup.change(); - })); - }; - editObserver.run(); - tntGroup.register(editObserver, player::closeInventory); - inv.addCloseRunnable(() -> { - tntGroup.unregister(editObserver); - }); - - inv.open(); - } - - private void changeCount(Player player, String name, int defaultValue, Consumer result, Runnable failure) { - SWAnvilInv swAnvilInv = new SWAnvilInv(player, name, defaultValue + ""); - swAnvilInv.setItem(Material.PAPER); - swAnvilInv.setCallback(s -> { - try { - result.accept(Integer.parseInt(s)); - } catch (NumberFormatException e) { - failure.run(); - } - }); - swAnvilInv.open(); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTSimulatorGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTSimulatorGui.java deleted file mode 100644 index e813580a..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/TNTSimulatorGui.java +++ /dev/null @@ -1,216 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.configplayer.Config; -import de.steamwar.bausystem.features.simulator.SimulatorStorage; -import de.steamwar.bausystem.features.simulator.TNTSimulator; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTElement; -import de.steamwar.bausystem.features.simulator.tnt.TNTGroup; -import de.steamwar.inventory.SWInventory; -import de.steamwar.inventory.SWItem; -import de.steamwar.inventory.SWListInv; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.function.Supplier; - -import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique; - -@UtilityClass -public class TNTSimulatorGui { - - private static final Vector X_VECTOR = new Vector(0.0625, 0, 0); - private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0); - private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625); - - private static final Vector FX_VECTOR = new Vector(1, 0, 0); - private static final Vector FY_VECTOR = new Vector(0, 1, 0); - private static final Vector FZ_VECTOR = new Vector(0, 0, 1); - - public void open(Player player, TNTSimulator currentTntSimulator, TNTGroup currentTntGroup, Supplier> simulatorElements, Runnable back) { - List> swListEntryList = new ArrayList<>(); - - int totalTNTCount = 0; - for (SimulatorElement element : simulatorElements.get()) { - swListEntryList.add(new SWListInv.SWListEntry<>(element.menu(player), element)); - totalTNTCount += element.tntCount(); - } - swListEntryList.sort(Comparator.comparing(o -> o.getObject().tick())); - - SWListInv inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SIMULATOR_GUI_NAME", player), false, swListEntryList, (clickType, simulatorElement) -> { - if (simulatorElement instanceof TNTGroup) { - TNTGroup tntGroup = (TNTGroup) simulatorElement; - open(player, null, tntGroup, () -> new ArrayList<>(tntGroup.getElements()), () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back)); - } else { - TNTElementGUI.open(player, (TNTElement) simulatorElement, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back)); - } - }); - if (back != null) { - inv.setItem(47, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - SWItem swItem = new SWItem(Material.TNT_MINECART, BauSystem.MESSAGE.parse("SIMULATOR_GUI_TOTAL_TNT", player, totalTNTCount), clickType -> { - }); - swItem.getItemStack().setAmount(totalTNTCount); - List elements = simulatorElements.get(); - inv.setItem(elements.isEmpty() ? 49 : 50, swItem); - if (currentTntGroup != null) { - Runnable editObserver = () -> { - List otherLore = new ArrayList<>(); - otherLore.add(""); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, currentTntGroup.getPosition().getX())); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, currentTntGroup.getPosition().getY())); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, currentTntGroup.getPosition().getZ())); - otherLore.add(""); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_NAME_LORE", player, currentTntGroup.getMaterial().name())); - otherLore.add(""); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_TICK", player, currentTntGroup.getTickOffset())); - if (currentTntGroup.isDisabled()) { - otherLore.add(""); - otherLore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", player)); - } - inv.setItem(48, new SWItem(Material.ANVIL, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_GROUP", player), otherLore, false, clickType -> { - TNTGroupEditGUI.open(player, currentTntGroup, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back)); - })); - }; - editObserver.run(); - currentTntGroup.register(editObserver, player::closeInventory); - inv.addCloseRunnable(() -> { - currentTntGroup.unregister(editObserver); - }); - } else { - if (!elements.isEmpty()) { - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player); - inv.setItem(48, new SWItem(Material.ANVIL, BauSystem.MESSAGE.parse("SIMULATOR_EDIT_GROUP", player), new ArrayList<>(), false, clickType -> { - TNTGroupEditGUI.open(player, tntSimulator, elements, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back)); - })); - } - } - if (currentTntSimulator != null) { - if (totalTNTCount > 0) { - inv.setItem(48, new SWItem(Material.MAGENTA_GLAZED_TERRACOTTA, BauSystem.MESSAGE.parse("SIMULATOR_GUI_MOVE_ALL", player), clickType -> { - moveAll(player, currentTntSimulator, () -> open(player, currentTntSimulator, currentTntGroup, simulatorElements, back)); - })); - } - - boolean simulatorAutoTrace = Config.getInstance().get(player).getPlainValueOrDefault("simulatorAutoTrace", false); - inv.setItem(47, new SWItem(simulatorAutoTrace ? Material.CHAIN_COMMAND_BLOCK : Material.COMMAND_BLOCK, BauSystem.MESSAGE.parse("SIMULATOR_GUI_AUTO_TRACE", player, simulatorAutoTrace), clickType -> { - Config.getInstance().get(player).put("simulatorAutoTrace", !simulatorAutoTrace); - open(player, currentTntSimulator, currentTntGroup, simulatorElements, back); - })); - } - - if (currentTntSimulator != null || currentTntGroup != null) { - inv.setItem(51, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("SIMULATOR_GUI_DELETE", player), clickType -> { - if (currentTntSimulator != null) { - currentTntSimulator.getTntElementList().forEach(SimulatorElement::close); - currentTntSimulator.clear(); - player.closeInventory(); - } else { - TNTSimulator tntSimulator = SimulatorStorage.getSimulator(player); - tntSimulator.remove(currentTntGroup); - } - })); - } - - inv.open(); - } - - public void moveAll(Player player, TNTSimulator tntSimulator, Runnable back) { - SWInventory inv = new SWInventory(player, 45, BauSystem.MESSAGE.parse("SIMULATOR_MOVE_ALL_GUI_NAME", player)); - SWItem gray = new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§f", clickType -> {}); - for (int i = 0; i < 9; i++) { - inv.setItem(i, gray); - inv.setItem(i + 36, gray); - } - - if (back != null) { - inv.setItem(36, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("SIMULATOR_BACK", player), clickType -> back.run())); - } - - String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player); - String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player); - List plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player)); - List minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player)); - List lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player)); - - // X Position - inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(tntSimulator, clickType.isShiftClick() ? X_VECTOR : FX_VECTOR); - tntSimulator.change(); - }))); - inv.setItem(21, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_POSITION_X", player), lore, false, clickType -> {})); - inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(tntSimulator, (clickType.isShiftClick() ? X_VECTOR : FX_VECTOR).clone().multiply(-1)); - tntSimulator.change(); - }))); - - // Y Position - inv.setItem(13, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(tntSimulator, clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR); - tntSimulator.change(); - }))); - inv.setItem(22, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_POSITION_Y", player), lore, false, clickType -> {})); - inv.setItem(31, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(tntSimulator, (clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR).clone().multiply(-1)); - tntSimulator.change(); - }))); - - // Z Position - inv.setItem(14, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(tntSimulator, clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR); - tntSimulator.change(); - }))); - inv.setItem(23, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_POSITION_Z", player), lore, false, clickType -> {})); - inv.setItem(32, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - moveAll(tntSimulator, (clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR).clone().multiply(-1)); - tntSimulator.change(); - }))); - - inv.open(); - } - - public void moveAll(TNTSimulator tntSimulator, Vector vector) { - for (SimulatorElement element : tntSimulator.getTntElementList()) { - if (element instanceof TNTGroup) { - TNTGroup group = (TNTGroup) element; - group.setPosition(group.getPosition().add(vector)); - } else if (element instanceof TNTElement) { - TNTElement tntElement = (TNTElement) element; - tntElement.setPosition(tntElement.getOwnPosition().add(vector)); - } - } - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java new file mode 100644 index 00000000..380dc618 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorAnvilGui.java @@ -0,0 +1,78 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui.base; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.inventory.SWAnvilInv; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; + +public class SimulatorAnvilGui { + + private SWAnvilInv anvilInv; + + public SimulatorAnvilGui(Player player, String title, String defaultText, Function mapper, Function value, SimulatorBaseGui back) { + if (defaultText == null) { + anvilInv = new SWAnvilInv(player, title); + } else { + anvilInv = new SWAnvilInv(player, title + ": " + defaultText); + } + AtomicBoolean error = new AtomicBoolean(); + anvilInv.addCloseCallback(() -> { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + if (error.get()) { + anvilInv.open(); + } else { + back.open(); + } + error.set(false); + }, 0); + }); + anvilInv.setCallback(s -> { + T t; + try { + t = mapper.apply(s); + } catch (NumberFormatException e) { + error.set(true); + return; + } + try { + if (!value.apply(t)) { + error.set(true); + } + } catch (Exception e) { + // Ignore + } + }); + } + + public SimulatorAnvilGui setItem(Material material) { + anvilInv.setItem(material); + return this; + } + + public void open() { + anvilInv.open(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java new file mode 100644 index 00000000..41f95a88 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorBaseGui.java @@ -0,0 +1,100 @@ +/* + * 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 . + */ + +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.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +public abstract class SimulatorBaseGui { + + protected final Player player; + protected final Simulator simulator; + private Inventory inv; + protected SWInventory inventory; + + protected final int size; + + protected SimulatorBaseGui(Player player, Simulator simulator, int size) { + this.player = player; + this.simulator = simulator; + this.size = size; + } + + public final void open() { + String newTitle = title(); + String originalTitle = player.getOpenInventory().getTitle(); + + if (inv != null && (Core.getVersion() > 19 || newTitle.equals(originalTitle))) { + // TODO: Flickering is better but not gone! + for (int i = 9; i < size - 9; i++) { + inv.setItem(i, null); + } + setup(); + if (player.getOpenInventory().getTopInventory() != inv) { + inventory.open(); + SimulatorWatcher.watch(player, simulator, this::open); + } + if (Core.getVersion() > 19) { + player.getOpenInventory().setTitle(title()); + } + populate(); + if (player.getOpenInventory().getTopInventory() == inv) { + inventory.open(); + SimulatorWatcher.watch(player, simulator, this::open); + } + return; + } + + player.getOpenInventory().close(); + + inventory = new SWInventory(player, () -> { + inv = Bukkit.createInventory(null, size, title()); + return inv; + }); + setup(); + inventory.addCloseCallback(clickType -> { + SimulatorWatcher.watch(player, null, null); + }); + + SimulatorWatcher.watch(player, simulator, this::open); + populate(); + inventory.open(); + } + + private void setup() { + for (int i = 0; i < 9; i++) { + inventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8", clickType -> { + })); + inventory.setItem(size - 9 + i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§8", clickType -> { + })); + } + } + + public abstract String title(); + + public abstract void populate(); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorPageGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorPageGui.java new file mode 100644 index 00000000..e3c3ccbd --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorPageGui.java @@ -0,0 +1,83 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui.base; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWItem; +import org.bukkit.entity.Player; + +import java.util.List; + +public abstract class SimulatorPageGui extends SimulatorBaseGui { + + protected int page = 0; + protected List data; + + protected SimulatorPageGui(Player player, Simulator simulator, int size, List data) { + super(player, simulator, size); + this.data = data; + } + + public final int maxPage() { + return data.size() / (size - 18); + } + + @Override + public final String title() { + return baseTitle() + " " + (page + 1) + "/" + (maxPage() + 1); + } + + @Override + public final void populate() { + headerAndFooter(); + page = Math.min(page, maxPage()); + + inventory.setItem(size - 9, SWItem.getDye(page > 0 ? 10 : 8), page > 0 ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(page > 0 ? "SWLISINV_PREVIOUS_PAGE_ACTIVE" : "SWLISINV_PREVIOUS_PAGE_INACTIVE", player), clickType -> { + if (page > 0) { + page--; + open(); + } + }); + boolean hasNext = page < maxPage() - (data.size() % (size - 18) == 0 ? 1 : 0); + inventory.setItem(size - 1, SWItem.getDye(hasNext ? 10 : 8), hasNext ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(hasNext ? "SWLISINV_NEXT_PAGE_ACTIVE" : "SWLISINV_NEXT_PAGE_INACTIVE", player), clickType -> { + if (hasNext) { + page++; + open(); + } + }); + + int minElement = page * (size - 18); + int maxElement = Math.min(data.size(), (page + 1) * (size - 18)); + int index = 9; + + for (int i = minElement; i < maxElement; i++) { + T element = data.get(i); + inventory.setItem(index++, convert(element)); + } + } + + public abstract String baseTitle(); + + public void headerAndFooter() { + } + + public abstract SWItem convert(T t); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorScrollGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorScrollGui.java new file mode 100644 index 00000000..a4cfbb5d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/base/SimulatorScrollGui.java @@ -0,0 +1,94 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.gui.base; + + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.core.Core; +import de.steamwar.inventory.SWItem; +import org.bukkit.entity.Player; + +import java.util.List; + +public abstract class SimulatorScrollGui extends SimulatorBaseGui { + protected int scroll = 0; + protected final List data; + + protected SimulatorScrollGui(Player player, Simulator simulator, int size, List data) { + super(player, simulator, size); + this.data = data; + } + + private int maxScroll() { + return Math.max(0, Math.min(scroll, data.size() - 9 + 1)); + } + + @Override + public final String title() { + return baseTitle() + " " + maxScroll() + "/" + Math.max((data.size() - 9 + 1), 0); + } + + @Override + public final void populate() { + headerAndFooter(); + scroll = maxScroll(); + + inventory.setItem(size - 9, SWItem.getDye(scroll > 0 ? 10 : 8), scroll > 0 ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(scroll > 0 ? "SWLISINV_PREVIOUS_PAGE_ACTIVE" : "SWLISINV_PREVIOUS_PAGE_INACTIVE", player), clickType -> { + if (scroll > 0) { + scroll = Math.max(0, scroll - 9); + open(); + } + }); + boolean hasNext = (data.size() + 1) - scroll > 9; + inventory.setItem(size - 1, SWItem.getDye(hasNext ? 10 : 8), hasNext ? (byte) 10 : (byte) 8, Core.MESSAGE.parse(hasNext ? "SWLISINV_NEXT_PAGE_ACTIVE" : "SWLISINV_NEXT_PAGE_INACTIVE", player), clickType -> { + if (hasNext) { + scroll = Math.min(scroll + 9, data.size() + 1 - 9); + open(); + } + }); + + for (int i = 0; i < 9; i++) { + if (scroll + i < data.size()) { + T element = data.get(scroll + i); + SWItem[] column = column(element, scroll + i); + populateColumn(column, i); + } else { + SWItem[] column = lastColumn(); + populateColumn(column, i); + break; + } + } + } + + public abstract String baseTitle(); + + public void headerAndFooter() { + } + + public void populateColumn(SWItem[] column, int index) { + for (int j = 0; j < column.length; j++) { + inventory.setItem(index + j * 9 + 9, column[j]); + } + } + + public abstract SWItem[] column(T t, int index); + + public abstract SWItem[] lastColumn(); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangeMaterial.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangeMaterial.java deleted file mode 100644 index 5c6750fc..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangeMaterial.java +++ /dev/null @@ -1,66 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui.components; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; -import de.steamwar.inventory.SWInventory; -import de.steamwar.inventory.SWItem; -import de.steamwar.inventory.SWListInv; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@UtilityClass -public class ChangeMaterial { - - private static final List MATERIALS = new ArrayList<>(); - static { - Arrays.stream(Material.values()) - .filter(Material::isItem) - .filter(material -> !material.isLegacy()) - .forEach(MATERIALS::add); - } - - public void show(SWInventory inv, Player player, int position, SimulatorElement simulatorElement, Material defaultMaterial, Runnable back) { - inv.setItem(position, new SWItem(simulatorElement.getMaterial(), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL", player), Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL_LORE_1", player, simulatorElement.getMaterial().name().toLowerCase()), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL_LORE_2", player), BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_MATERIAL_LORE_3", player)), false, clickType -> { - if (clickType.isLeftClick()) { - List> swListEntries = new ArrayList<>(); - MATERIALS.forEach(current -> { - swListEntries.add(new SWListInv.SWListEntry<>(new SWItem(current, BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_NAME", player, current.name().toLowerCase()), Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_CLICK", player)), false, ignored -> { - }), current)); - }); - SWListInv swListInv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SIMULATOR_MATERIAL_GUI_NAME", player), false, swListEntries, (invClickType, material) -> { - simulatorElement.setMaterial(material); - simulatorElement.change(); - back.run(); - }); - swListInv.open(); - } else { - simulatorElement.setMaterial(defaultMaterial); - simulatorElement.change(); - } - })); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangePosition.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangePosition.java deleted file mode 100644 index 16f1090c..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/ChangePosition.java +++ /dev/null @@ -1,163 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui.components; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.TNTSimulator; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; -import de.steamwar.inventory.SWAnvilInv; -import de.steamwar.inventory.SWInventory; -import de.steamwar.inventory.SWItem; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.util.Consumer; -import org.bukkit.util.Vector; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.function.UnaryOperator; - -import static de.steamwar.bausystem.features.simulator.gui.ItemUtils.unique; - -@UtilityClass -public class ChangePosition { - - private static final Vector X_VECTOR = new Vector(0.0625, 0, 0); - private static final Vector Y_VECTOR = new Vector(0, 0.0625, 0); - private static final Vector Z_VECTOR = new Vector(0, 0, 0.0625); - - private static final Vector FX_VECTOR = new Vector(1, 0, 0); - private static final Vector FY_VECTOR = new Vector(0, 1, 0); - private static final Vector FZ_VECTOR = new Vector(0, 0, 1); - - public void show(SWInventory inv, Player player, SimulatorElement simulatorElement, Consumer> toChangeVector, Runnable back) { - String plusOneName = BauSystem.MESSAGE.parse("SIMULATOR_PLUS_ONE", player); - String minusOneName = BauSystem.MESSAGE.parse("SIMULATOR_MINUS_ONE", player); - List plusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_PLUS_PIXEL_SHIFT", player)); - List minusOnePixelShiftLore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_MINUS_PIXEL_SHIFT", player)); - List lore = Arrays.asList(BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_LORE", player)); - - // X Position - inv.setItem(10, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - toChangeVector.accept(vector -> { - vector.add(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR); - return vector; - }); - simulatorElement.change(); - }))); - inv.setItem(19, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_X", player, simulatorElement.getPosition().getX()), lore, false, clickType -> { - changePosition(player, simulatorElement.getPosition().getX(), x -> { - toChangeVector.accept(vector -> { - vector.setX(clamp(x)); - return vector; - }); - simulatorElement.change(); - back.run(); - }, back); - })); - inv.setItem(28, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - toChangeVector.accept(vector -> { - vector.subtract(clickType.isShiftClick() ? X_VECTOR : FX_VECTOR); - return vector; - }); - simulatorElement.change(); - }))); - - // Y Position - inv.setItem(11, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - toChangeVector.accept(vector -> { - vector.add(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR); - return vector; - }); - simulatorElement.change(); - }))); - inv.setItem(20, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Y", player, simulatorElement.getPosition().getY()), lore, false, clickType -> { - changePosition(player, simulatorElement.getPosition().getY(), y -> { - toChangeVector.accept(vector -> { - vector.setY(clamp(y)); - return vector; - }); - simulatorElement.change(); - back.run(); - }, back); - })); - inv.setItem(29, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - toChangeVector.accept(vector -> { - vector.subtract(clickType.isShiftClick() ? Y_VECTOR : FY_VECTOR); - return vector; - }); - simulatorElement.change(); - }))); - - // Z Position - inv.setItem(12, unique(new SWItem(SWItem.getDye(10), plusOneName, plusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - toChangeVector.accept(vector -> { - vector.add(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR); - return vector; - }); - simulatorElement.change(); - }))); - inv.setItem(21, new SWItem(Material.PAPER, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_Z", player, simulatorElement.getPosition().getZ()), lore, false, clickType -> { - changePosition(player, simulatorElement.getPosition().getZ(), z -> { - toChangeVector.accept(vector -> { - vector.setZ(clamp(z)); - return vector; - }); - simulatorElement.change(); - back.run(); - }, back); - })); - inv.setItem(30, unique(new SWItem(SWItem.getDye(1), minusOneName, minusOnePixelShiftLore, false, clickType -> { - if (clickType == ClickType.DOUBLE_CLICK) return; - toChangeVector.accept(vector -> { - vector.subtract(clickType.isShiftClick() ? Z_VECTOR : FZ_VECTOR); - return vector; - }); - simulatorElement.change(); - }))); - } - - private double clamp(double d) { - return (int) (d * 10000) * 0.0001; - } - - private void changePosition(Player player, double defaultValue, Consumer result, Runnable failure) { - SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("SIMULATOR_TNT_SPAWN_POSITION_ANVIL_GUI_NAME", player), defaultValue + ""); - swAnvilInv.setItem(Material.PAPER); - swAnvilInv.setCallback(s -> { - try { - result.accept(Double.parseDouble(s.replace(',', '.'))); - } catch (NumberFormatException e) { - failure.run(); - } - }); - swAnvilInv.open(); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/Disabled.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/Disabled.java deleted file mode 100644 index a6798165..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/gui/components/Disabled.java +++ /dev/null @@ -1,42 +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 . - */ - -package de.steamwar.bausystem.features.simulator.gui.components; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.TNTSimulator; -import de.steamwar.bausystem.features.simulator.tnt.SimulatorElement; -import de.steamwar.inventory.SWInventory; -import de.steamwar.inventory.SWItem; -import lombok.experimental.UtilityClass; -import org.bukkit.Material; -import org.bukkit.entity.Player; - -import java.util.ArrayList; - -@UtilityClass -public class Disabled { - - public void show(SWInventory inv, Player player, int position, TNTSimulator tntSimulator, SimulatorElement simulatorElement) { - inv.setItem(position, new SWItem(simulatorElement.isDisabled() ? Material.ENDER_PEARL : Material.ENDER_EYE, BauSystem.MESSAGE.parse(simulatorElement.isDisabled() ? "SIMULATOR_TNT_SPAWN_DISABLED" : "SIMULATOR_TNT_SPAWN_ENABLED", player), new ArrayList<>(), !simulatorElement.isDisabled(), clickType -> { - simulatorElement.setDisabled(!simulatorElement.isDisabled()); - simulatorElement.change(); - })); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java new file mode 100644 index 00000000..218c89a4 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimFormatSimulatorLoader.java @@ -0,0 +1,135 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.storage; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import de.steamwar.bausystem.features.simulator.data.SimulatorElement; +import de.steamwar.bausystem.features.simulator.data.SimulatorGroup; +import de.steamwar.bausystem.features.simulator.data.SimulatorPhase; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverElement; +import de.steamwar.bausystem.features.simulator.data.observer.ObserverPhase; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement; +import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement; +import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase; +import org.bukkit.Material; +import org.bukkit.util.Vector; +import yapion.exceptions.YAPIONException; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONObject; +import yapion.parser.YAPIONParser; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; + +public class SimFormatSimulatorLoader implements SimulatorLoader { + + @Override + public Optional> load(File file) { + if (!file.getName().endsWith(".sim")) { + return Optional.empty(); + } + + YAPIONObject yapionObject; + try { + yapionObject = YAPIONParser.parse(file); + } catch (YAPIONException | IOException e) { + return Optional.empty(); + } + + String name = file.getName().substring(0, file.getName().length() - ".sim".length()); + + Simulator simulator = new Simulator(name); + loadSimulator(yapionObject, simulator); + return Optional.of(Collections.singletonList(simulator)); + } + + private void loadSimulator(YAPIONObject simulatorObject, Simulator simulator) { + simulator.setMaterial(Material.valueOf(simulatorObject.getPlainValue("material"))); + simulator.setAutoTrace(simulatorObject.getPlainValue("autoTrace")); + + YAPIONArray groups = simulatorObject.getArray("groups"); + groups.streamObject().forEach(groupObject -> { + SimulatorGroup simulatorGroup = new SimulatorGroup(); + loadGroup(groupObject, simulatorGroup); + simulator.add(simulatorGroup); + }); + } + + private void loadGroup(YAPIONObject groupObject, SimulatorGroup group) { + group.setMaterial(Material.valueOf(groupObject.getPlainValue("material"))); + group.setDisabled(groupObject.getPlainValue("disabled")); + + YAPIONArray elements = groupObject.getArray("elements"); + elements.streamObject().forEach(elementObject -> { + SimulatorElement element; + Supplier phaseConstructor; + Vector position = new Vector(elementObject.getDouble("x"), elementObject.getDouble("y"), elementObject.getDouble("z")); + String type = elementObject.getPlainValue("type"); + switch (type) { + case "TNT": + element = new TNTElement(position); + phaseConstructor = TNTPhase::new; + break; + case "Redstone": + element = new RedstoneElement(position); + phaseConstructor = RedstonePhase::new; + break; + case "Observer": + element = new ObserverElement(position); + phaseConstructor = ObserverPhase::new; + break; + default: + element = null; + phaseConstructor = null; + break; + } + if (element == null) { + return; + } + loadElement(elementObject, element, phaseConstructor); + group.add(element); + }); + } + + private void loadElement(YAPIONObject elementObject, SimulatorElement element, Supplier phaseConstructor) { + element.setMaterial(Material.valueOf(elementObject.getPlainValue("material"))); + element.setDisabled(elementObject.getPlainValue("disabled")); + element.loadExtra(elementObject); + + YAPIONArray phases = elementObject.getArray("phases"); + phases.streamObject().forEach(phaseObject -> { + SimulatorPhase phase = phaseConstructor.get(); + loadPhase(phaseObject, phase); + ((SimulatorElement) element).add(phase); + }); + } + + private void loadPhase(YAPIONObject phaseObject, SimulatorPhase phase) { + phase.setTickOffset(phaseObject.getPlainValue("tickOffset")); + phase.setLifetime(phaseObject.getPlainValue("lifetime")); + phase.setOrder(phaseObject.getPlainValue("order")); + phase.loadExtra(phaseObject); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorFormatSimulatorLoader.java new file mode 100644 index 00000000..a386f86d --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorFormatSimulatorLoader.java @@ -0,0 +1,136 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.storage; + +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 org.bukkit.Material; +import org.bukkit.util.Vector; +import yapion.exceptions.YAPIONException; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONObject; +import yapion.parser.YAPIONParser; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class SimulatorFormatSimulatorLoader implements SimulatorLoader { + + @Override + public Optional> load(File file) { + if (!file.getName().endsWith(".simulator")) { + return Optional.empty(); + } + + YAPIONObject yapionObject; + try { + yapionObject = YAPIONParser.parse(file); + } catch (YAPIONException | IOException e) { + return Optional.empty(); + } + + String name = file.getName().substring(0, file.getName().length() - ".simulator".length()); + + Simulator simulator = new Simulator(name); + simulator.setMaterial(Material.valueOf(yapionObject.getStringOrDefault("material", "BARREL"))); + + YAPIONArray tntElements = yapionObject.getArrayOrDefault("tntElements", new YAPIONArray()); + for (YAPIONObject element : tntElements.streamObject().collect(Collectors.toList())) { + if (element.containsKey("elements")) { + simulator.add(loadGroup(element)); + } else { + simulator.add(loadElement(element)); + } + } + + file.delete(); + return Optional.of(Collections.singletonList(simulator)); + } + + private SimulatorGroup loadGroup(YAPIONObject element) { + double x = element.getDoubleOrDefault("x", 0); + double y = element.getDoubleOrDefault("y", 0); + double z = element.getDoubleOrDefault("z", 0); + int tickOffset = element.getIntOrDefault("tickOffset", 0); + + SimulatorGroup simulatorGroup = new SimulatorGroup(); + simulatorGroup.setDisabled(element.getBooleanOrDefault("disabled", false)); + + YAPIONArray elements = element.getArrayOrDefault("elements", new YAPIONArray()); + for (YAPIONObject e : elements.streamObject().collect(Collectors.toList())) { + simulatorGroup.add(loadElement(e, x, y, z, tickOffset)); + } + + return simulatorGroup; + } + + private TNTElement loadElement(YAPIONObject element, double dx, double dy, double dz, int dTickOffset) { + TNTElement tntElement = new TNTElement(new Vector(element.getDouble("x") + dx, element.getDouble("y") + dy, element.getDouble("z") + dz)); + tntElement.setDisabled(element.getBooleanOrDefault("disabled", false)); + tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT"))); + + TNTPhase tntPhase = loadPhase(element); + tntPhase.setTickOffset(tntPhase.getTickOffset() + dTickOffset); + tntElement.add(tntPhase); + + return tntElement; + } + + private SimulatorGroup loadElement(YAPIONObject element) { + SimulatorGroup simulatorGroup = new SimulatorGroup(); + + TNTElement tntElement = new TNTElement(new Vector(element.getDouble("x"), element.getDouble("y"), element.getDouble("z"))); + tntElement.setDisabled(element.getBooleanOrDefault("disabled", false)); + tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT"))); + simulatorGroup.add(tntElement); + + tntElement.add(loadPhase(element)); + + return simulatorGroup; + } + + private TNTPhase loadPhase(YAPIONObject element) { + TNTPhase tntPhase = new TNTPhase(); + tntPhase.setLifetime(element.getIntOrDefault("fuseTicks", 80)); + tntPhase.setCount(element.getIntOrDefault("count", 1)); + tntPhase.setTickOffset(element.getIntOrDefault("tickOffset", 0)); + tntPhase.setXJump(element.getBooleanOrDefault("xVelocity", false)); + tntPhase.setYJump(element.getBooleanOrDefault("yVelocity", false)); + tntPhase.setZJump(element.getBooleanOrDefault("zVelocity", false)); + switch (element.getStringOrDefault("order", "REPEATER")) { + case "REPEATER": + tntPhase.setOrder(0); + break; + case "OBSERVER": + tntPhase.setOrder(1); + break; + case "COMPARATOR": + tntPhase.setOrder(2); + break; + } + return tntPhase; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorLoader.java new file mode 100644 index 00000000..4c9e3f92 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorLoader.java @@ -0,0 +1,31 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.storage; + +import de.steamwar.bausystem.features.simulator.data.Simulator; + +import java.io.File; +import java.util.List; +import java.util.Optional; + +public interface SimulatorLoader { + + Optional> load(File file); +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorSaver.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorSaver.java new file mode 100644 index 00000000..48ccfd7a --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/SimulatorSaver.java @@ -0,0 +1,84 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.storage; + +import de.steamwar.bausystem.features.simulator.data.Simulator; +import lombok.experimental.UtilityClass; +import yapion.hierarchy.output.FileOutput; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONObject; + +import java.io.File; +import java.io.IOException; + +@UtilityClass +public class SimulatorSaver { + + public void saveSimulator(File directory, Simulator simulator) { + if (!directory.exists()) { + directory.mkdirs(); + } + + YAPIONObject simulatorObject = new YAPIONObject(); + simulatorObject.add("material", simulator.getMaterial().name()); + simulatorObject.add("autoTrace", simulator.isAutoTrace()); + + YAPIONArray groups = new YAPIONArray(); + simulator.getGroups().forEach(group -> { + YAPIONObject groupObject = new YAPIONObject(); + groupObject.add("material", group.getMaterial().name()); + groupObject.add("disabled", group.isDisabled()); + + YAPIONArray elements = new YAPIONArray(); + group.getElements().forEach(element -> { + YAPIONObject elementObject = new YAPIONObject(); + elementObject.add("type", element.getType()); + elementObject.add("material", element.getMaterial().name()); + elementObject.add("disabled", element.isDisabled()); + elementObject.add("x", element.getPosition().getX()); + elementObject.add("y", element.getPosition().getY()); + elementObject.add("z", element.getPosition().getZ()); + element.saveExtra(elementObject); + + YAPIONArray phases = new YAPIONArray(); + element.getPhases().forEach(phase -> { + YAPIONObject phaseObject = new YAPIONObject(); + phaseObject.add("tickOffset", phase.getTickOffset()); + phaseObject.add("lifetime", phase.getLifetime()); + phaseObject.add("order", phase.getOrder()); + phase.saveExtra(phaseObject); + phases.add(phaseObject); + }); + elementObject.add("phases", phases); + elements.add(elementObject); + }); + groupObject.add("elements", elements); + groups.add(groupObject); + }); + simulatorObject.add("groups", groups); + + File file = new File(directory, simulator.getName() + ".sim"); + try { + simulatorObject.toJSONLossy(new FileOutput(file)).close(); + } catch (IOException e) { + // Ignore + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/YAPIONFormatSimulatorLoader.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/YAPIONFormatSimulatorLoader.java new file mode 100644 index 00000000..0c715443 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/storage/YAPIONFormatSimulatorLoader.java @@ -0,0 +1,90 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.simulator.storage; + +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.sql.SteamwarUser; +import org.bukkit.Material; +import org.bukkit.util.Vector; +import yapion.exceptions.YAPIONException; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONObject; +import yapion.parser.YAPIONParser; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class YAPIONFormatSimulatorLoader implements SimulatorLoader { + + @Override + public Optional> load(File file) { + if (!file.getName().endsWith(".yapion")) { + return Optional.empty(); + } + + YAPIONObject yapionObject; + try { + yapionObject = YAPIONParser.parse(file); + } catch (YAPIONException | IOException e) { + return Optional.empty(); + } + + String name = file.getName().substring(0, file.getName().length() - 7); + SteamwarUser steamwarUser = SteamwarUser.get(Integer.parseInt(name)); + + List simulators = new ArrayList<>(); + for (String s : yapionObject.getKeys()) { + String newName = steamwarUser.getUserName() + (s.isEmpty() ? "" : "_" + s); + YAPIONArray content = yapionObject.getArray(s); + if (content.isEmpty()) continue; + Simulator simulator = new Simulator(newName); + for (YAPIONObject element : content.streamObject().collect(Collectors.toList())) { + SimulatorGroup simulatorGroup = new SimulatorGroup(); + simulator.add(simulatorGroup); + + TNTElement tntElement = new TNTElement(new Vector(element.getDouble("positionX"), element.getDouble("positionY"), element.getDouble("positionZ"))); + tntElement.setDisabled(element.getBooleanOrDefault("disabled", false)); // IDK if this existed back then? + tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT"))); + simulatorGroup.add(tntElement); + + TNTPhase tntPhase = new TNTPhase(); + tntPhase.setLifetime(element.getIntOrDefault("fuseTicks", 80)); + tntPhase.setCount(element.getIntOrDefault("count", 1)); + tntPhase.setTickOffset(element.getIntOrDefault("tickOffset", 0)); + tntPhase.setXJump(element.getBooleanOrDefault("xVelocity", false)); + tntPhase.setYJump(element.getBooleanOrDefault("yVelocity", false)); + tntPhase.setZJump(element.getBooleanOrDefault("zVelocity", false)); + tntPhase.setOrder(element.getBooleanOrDefault("comparator", false) ? 2 : 0); + tntElement.add(tntPhase); + } + simulators.add(simulator); + } + + file.delete(); + return Optional.of(simulators); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/SimulatorElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/SimulatorElement.java deleted file mode 100644 index 181e3389..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/SimulatorElement.java +++ /dev/null @@ -1,90 +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 . - */ - -package de.steamwar.bausystem.features.simulator.tnt; - -import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.shared.Pair; -import de.steamwar.entity.REntity; -import de.steamwar.inventory.SWItem; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import yapion.hierarchy.types.YAPIONObject; - -import java.util.*; - -public interface SimulatorElement { - - Map> observer = new HashMap<>(); - Map closeObserver = new HashMap<>(); - - YAPIONObject toYAPION(); - List getEntities(); - void getEntity(List elements, REntity entity); - - Vector getPosition(); - void setPosition(Vector position); - - void remove(TNTElement tntElement); - - SWItem menu(Player p); - boolean locations(Map>>> result, Region region, Location location); // Ticks to subtick order to spawning runnable to count of activations - int tntCount(); - int tick(); - - // Observer - default void change() { - observer.getOrDefault(this, new HashSet<>()).forEach(Runnable::run); - if (this instanceof TNTGroup) { - ((TNTGroup) this).getElements().forEach(SimulatorElement::change); - } - } - default void register(Runnable observer, Runnable close) { - SimulatorElement.observer.computeIfAbsent(this, k -> new HashSet<>()).add(observer); - SimulatorElement.closeObserver.put(observer, close); - } - default void unregister(Runnable observer) { - SimulatorElement.observer.computeIfPresent(this, (k, v) -> { - v.remove(observer); - return v.isEmpty() ? null : v; - }); - SimulatorElement.closeObserver.remove(observer); - } - default void close() { - Set allRunnables = observer.remove(this); - if (allRunnables == null) return; - allRunnables.forEach(runnable -> { - Runnable closeRunnable = closeObserver.remove(runnable); - if (closeRunnable == null) return; - closeRunnable.run(); - }); - if (this instanceof TNTGroup) { - ((TNTGroup) this).getElements().forEach(SimulatorElement::close); - } - } - - // API - Material getMaterial(); - void setMaterial(Material material); - - boolean isDisabled(); - void setDisabled(boolean disabled); -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java deleted file mode 100644 index 666c3359..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTElement.java +++ /dev/null @@ -1,318 +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 . - */ - -package de.steamwar.bausystem.features.simulator.tnt; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.features.simulator.OrderUtils; -import de.steamwar.bausystem.features.simulator.SimulatorStorage; -import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.region.flags.Flag; -import de.steamwar.bausystem.region.flags.flagvalues.FreezeMode; -import de.steamwar.bausystem.region.utils.RegionExtensionType; -import de.steamwar.bausystem.region.utils.RegionType; -import de.steamwar.bausystem.shared.Pair; -import de.steamwar.entity.REntity; -import de.steamwar.entity.REntityServer; -import de.steamwar.entity.RFallingBlockEntity; -import de.steamwar.inventory.SWItem; -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.entity.Player; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.util.Vector; -import yapion.hierarchy.types.YAPIONObject; - -import java.util.*; - -@Getter -public class TNTElement implements SimulatorElement { - - private static final World WORLD = Bukkit.getWorlds().get(0); - - private final REntityServer entityServer; - private RFallingBlockEntity entity; - TNTGroup tntGroup = null; - - private final Vector position; - private int fuseTicks = 80; - private int count = 1; - private int tickOffset = 0; - - @Setter - private boolean xVelocity = false; - - @Setter - private boolean yVelocity = false; - - @Setter - private boolean zVelocity = false; - private Material order = Material.REPEATER; - private Material material = Material.TNT; - private boolean disabled = false; - - public TNTElement(Vector position, TNTGroup tntGroup, REntityServer entityServer) { - this.entityServer = entityServer; - this.tntGroup = tntGroup; - this.position = position; - initEntity(); - } - - public TNTElement(YAPIONObject yapionObject, TNTGroup tntGroup, REntityServer entityServer) { - this.entityServer = entityServer; - this.tntGroup = tntGroup; - this.position = new Vector(yapionObject.getDoubleOrDefault("x", yapionObject.getDoubleOrDefault("positionX", 0)), yapionObject.getDoubleOrDefault("y", yapionObject.getDoubleOrDefault("positionY", 0)), yapionObject.getDoubleOrDefault("z", yapionObject.getDoubleOrDefault("positionZ", 0))); - this.disabled = yapionObject.getBooleanOrDefault("disabled", false); - this.fuseTicks = yapionObject.getIntOrDefault("fuseTicks", 80); - this.count = yapionObject.getIntOrDefault("count", 1); - this.tickOffset = yapionObject.getIntOrDefault("tickOffset", 0); - this.xVelocity = yapionObject.getBooleanOrDefault("xVelocity", false); - this.yVelocity = yapionObject.getBooleanOrDefault("yVelocity", false); - this.zVelocity = yapionObject.getBooleanOrDefault("zVelocity", false); - this.order = Material.valueOf(yapionObject.getStringOrDefault("order", yapionObject.getBooleanOrDefault("comparator", false) ? Material.COMPARATOR.name() : Material.REPEATER.name())); - this.material = Material.valueOf(yapionObject.getStringOrDefault("material", Material.TNT.name())); - initEntity(); - } - - private void initEntity() { - this.entity = new RFallingBlockEntity(entityServer, getPosition().toLocation(WORLD), Material.TNT); - this.entity.setNoGravity(true); - _updatePosition(); - } - - @Override - public YAPIONObject toYAPION() { - YAPIONObject yapionObject = new YAPIONObject(); - yapionObject.add("x", position.getX()); - yapionObject.add("y", position.getY()); - yapionObject.add("z", position.getZ()); - yapionObject.add("fuseTicks", fuseTicks); - yapionObject.add("count", count); - yapionObject.add("tickOffset", tickOffset); - yapionObject.add("xVelocity", xVelocity); - yapionObject.add("yVelocity", yVelocity); - yapionObject.add("zVelocity", zVelocity); - yapionObject.add("order", order.name()); - yapionObject.add("material", material.name()); - yapionObject.add("disabled", disabled); - return yapionObject; - } - - @Override - public List getEntities() { - if (disabled) return new ArrayList<>(); - return Arrays.asList(entity); - } - - @Override - public void getEntity(List elements, REntity entity) { - if (disabled) return; - if (this.entity.getEntityId() == entity.getEntityId() || getPosition().distanceSquared(new Vector(entity.getX(), entity.getY(), entity.getZ())) < 0.01) { - elements.add(this); - } - } - - @Override - public Vector getPosition() { - if (tntGroup != null) { - return tntGroup.getPosition().clone().add(position); - } - return position.clone(); - } - - @Override - public void setPosition(Vector position) { - this.position.setX(position.getX()); - this.position.setY(position.getY()); - this.position.setZ(position.getZ()); - _updatePosition(); - } - - void _updatePosition() { - if (disabled || (getParent() != null && getParent().isDisabled())) { - entity.move(-200000, 0, -200000, 0F, 0F, (byte) 0); - } else { - Vector position = getPosition(); - entity.move(position.getX(), position.getY(), position.getZ(), 0F, 0F, (byte) 0); - } - } - - public int getTickOffset() { - if (tntGroup != null) { - return tntGroup.getTickOffset() + tickOffset; - } - return tickOffset; - } - - @Override - public void remove(TNTElement tntElement) { - entity.die(); - } - - @Override - public SWItem menu(Player p) { - List lore = new ArrayList<>(); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_1", p, count)); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_2", p, getTickOffset())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_3", p, getFuseTicks())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_4", p)); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_5", p, getPosition().getX())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_6", p, getPosition().getY())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_LORE_7", p, getPosition().getZ())); - if (disabled) { - lore.add(""); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", p)); - } - SWItem swItem = new SWItem(material, BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_SPAWN_NAME", p), lore, disabled, null); - if (!disabled) swItem.getItemStack().setAmount(Math.max(tntCount(), 1)); - return swItem; - } - - @Override - public boolean locations(Map>>> result, Region region, Location radius) { - if (disabled) return false; - Location location = getPosition().toLocation(SimulatorStorage.WORLD); - if (region.isGlobal() && location.distanceSquared(radius) > 10000) { - return false; - } - if (!region.inRegion(location, RegionType.NORMAL, RegionExtensionType.NORMAL)) { - return false; - } - Region thisRegion = Region.getRegion(location); - if (thisRegion.getFlagStorage().get(Flag.FREEZE) == FreezeMode.ACTIVE) { - return true; - } - - result.computeIfAbsent(getTickOffset(), ignore -> new HashMap<>()) - .computeIfAbsent(OrderUtils.order(order), ignore -> new HashSet<>()) - .add(new Pair<>(() -> { - SimulatorStorage.WORLD.spawn(location, TNTPrimed.class, tntPrimed -> { - tntPrimed.setFuseTicks(fuseTicks); - if (!xVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setX(0)); - if (!yVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setY(0)); - if (!zVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setZ(0)); - }); - }, count)); - return false; - } - - @Override - public int tntCount() { - return disabled ? 0 : count; - } - - @Override - public int tick() { - return getTickOffset(); - } - - public void setCount(int count) { - if (count < 0) count = 0; - if (count > 400) count = 400; - this.count = count; - } - - public int getOwnTickOffset() { - return tickOffset; - } - - public int getParentTickOffset() { - if (tntGroup != null) { - return tntGroup.getTickOffset(); - } - return 0; - } - - public void setTickOffset(int tickOffset) { - if (getTickOffset() - this.tickOffset + tickOffset < 0) { - this.tickOffset = -this.getParentTickOffset(); - return; - } - if (getTickOffset() - this.tickOffset + tickOffset > 400) { - this.tickOffset = 400 - this.getParentTickOffset(); - return; - } - this.tickOffset = tickOffset; - } - - public void setFuseTicks(int fuseTicks) { - if (fuseTicks < 0) fuseTicks = 0; - if (fuseTicks > 160) fuseTicks = 160; - this.fuseTicks = fuseTicks; - } - - public Vector getOwnPosition() { - return position.clone(); - } - - public void setOrder(Material material) { - this.order = material; - } - - public void setMaterial(Material material) { - this.material = material; - } - - public boolean hasParent() { - return tntGroup != null; - } - - public TNTGroup getParent() { - return tntGroup; - } - - public void setDisabled(boolean disabled) { - this.disabled = disabled; - _updatePosition(); - } - - public void align(Vector offset) { - Vector vector = getPosition(); - Vector parentVector = new Vector(0, 0, 0); - if (tntGroup != null) { - parentVector = tntGroup.getPosition(); - } - - if (offset.getX() != 0) { - if (vector.getX() - (int) vector.getX() == 0.49) { - vector.setX(vector.getX() + 0.02); - } - if (vector.getX() - (int) vector.getX() == -0.49) { - vector.setX(vector.getX() - 0.02); - } - vector.setX(vector.getBlockX() + offset.getX()); - } - - if (offset.getZ() != 0) { - if (vector.getZ() - (int) vector.getZ() == 0.49) { - vector.setZ(vector.getZ() + 0.02); - } - if (vector.getZ() - (int) vector.getZ() == -0.49) { - vector.setZ(vector.getZ() - 0.02); - } - vector.setZ(vector.getBlockZ() + offset.getZ()); - } - - setPosition(vector.subtract(parentVector)); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java deleted file mode 100644 index f3327578..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulator/tnt/TNTGroup.java +++ /dev/null @@ -1,186 +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 . - */ - -package de.steamwar.bausystem.features.simulator.tnt; - -import de.steamwar.bausystem.BauSystem; -import de.steamwar.bausystem.region.Region; -import de.steamwar.bausystem.shared.Pair; -import de.steamwar.entity.REntity; -import de.steamwar.entity.REntityServer; -import de.steamwar.inventory.SWItem; -import lombok.Getter; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import yapion.hierarchy.types.YAPIONArray; -import yapion.hierarchy.types.YAPIONObject; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -@Getter -public class TNTGroup implements SimulatorElement { - - private final Vector position; - private int tickOffset = 0; - private Material material = Material.BARREL; - private boolean disabled = false; - private List elements = new ArrayList<>(); - - public TNTGroup(Vector position) { - this.position = position; - } - - public TNTGroup(YAPIONObject yapionObject, REntityServer entityServer) { - this.position = new Vector(yapionObject.getDoubleOrDefault("x", 0), yapionObject.getDoubleOrDefault("y", 0), yapionObject.getDoubleOrDefault("z", 0)); - this.tickOffset = yapionObject.getIntOrDefault("tickOffset", 0); - this.material = Material.getMaterial(yapionObject.getStringOrDefault("material", "BARREL")); - this.disabled = yapionObject.getBooleanOrDefault("disabled", false); - YAPIONArray elements = yapionObject.getArrayOrDefault("elements", new YAPIONArray()); - for (YAPIONObject element : elements.streamObject().collect(Collectors.toList())) { - TNTElement tntElement = new TNTElement(element, this, entityServer); - this.elements.add(tntElement); - tntElement._updatePosition(); - } - } - - @Override - public YAPIONObject toYAPION() { - YAPIONObject yapionObject = new YAPIONObject(); - yapionObject.add("x", position.getX()); - yapionObject.add("y", position.getY()); - yapionObject.add("z", position.getZ()); - yapionObject.add("tickOffset", tickOffset); - yapionObject.add("material", material.name()); - yapionObject.add("disabled", disabled); - YAPIONArray yapionArray = new YAPIONArray(); - for (TNTElement element : elements) { - yapionArray.add(element.toYAPION()); - } - yapionObject.add("elements", yapionArray); - return yapionObject; - } - - public void add(TNTElement tntElement) { - tntElement.tntGroup = this; - elements.add(tntElement); - } - - @Override - public List getEntities() { - if (disabled) new ArrayList<>(); - return elements.stream().flatMap(tntElement -> tntElement.getEntities().stream()).collect(Collectors.toList()); - } - - @Override - public void getEntity(List elements, REntity entity) { - if (disabled) return; - for (TNTElement tntElement : this.elements) { - tntElement.getEntity(elements, entity); - } - } - - @Override - public Vector getPosition() { - return position.clone(); - } - - @Override - public void setPosition(Vector position) { - this.position.setX(position.getX()); - this.position.setY(position.getY()); - this.position.setZ(position.getZ()); - elements.forEach(TNTElement::_updatePosition); - } - - @Override - public void remove(TNTElement tntElement) { - if (elements.remove(tntElement)) { - tntElement.remove(tntElement); - } - } - - @Override - public SWItem menu(Player p) { - List lore = new ArrayList<>(); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_1", p, elements.size())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_2", p, tickOffset)); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_3", p)); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_4", p, position.getX())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_5", p, position.getY())); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_LORE_6", p, position.getZ())); - if (disabled) { - lore.add(""); - lore.add(BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_DISABLED", p)); - } - SWItem swItem = new SWItem(material, BauSystem.MESSAGE.parse("SIMULATOR_GUI_TNT_GROUP_NAME", p), lore, disabled, null); - if (!disabled) swItem.getItemStack().setAmount(Math.max(tntCount(), 1)); - return swItem; - } - - @Override - public boolean locations(Map>>> result, Region region, Location location) { - if (disabled) return false; - for (TNTElement element : elements) { - if (element.locations(result, region, location)) { - return true; - } - } - return false; - } - - @Override - public int tntCount() { - if (disabled) return 0; - return elements.stream().mapToInt(TNTElement::tntCount).sum(); - } - - @Override - public int tick() { - return getTickOffset(); - } - - public void setTickOffset(int tickOffset) { - if (tickOffset < 0) tickOffset = 0; - if (tickOffset > 400) tickOffset = 400; - for (TNTElement tntElement : elements) { - if (tntElement.getTickOffset() - this.tickOffset + tickOffset < 0) { - tickOffset = Math.max(tickOffset, -tntElement.getOwnTickOffset()); - } - if (tntElement.getTickOffset() - this.tickOffset + tickOffset > 400) { - tickOffset = Math.min(tickOffset, 400 - tntElement.getOwnTickOffset()); - } - } - this.tickOffset = tickOffset; - } - - public void setMaterial(Material material) { - this.material = material; - } - - public void setDisabled(boolean disabled) { - this.disabled = disabled; - elements.forEach(TNTElement::_updatePosition); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java index 86585417..daff9d87 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/laufbau/LaufbauCommand.java @@ -78,11 +78,4 @@ public class LaufbauCommand extends SWCommand { public void laufbauSettings(@Validator Player player) { new LaufbauSettings(player); } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "LAUFBAU_NO_PERM"); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java index 3bb2379e..cca7a266 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/slaves/panzern/PanzernCommand.java @@ -91,13 +91,6 @@ public class PanzernCommand extends SWCommand { }.runTaskTimer(BauSystem.getInstance(), 1, 1); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "PANZERN_NO_PERM"); - }; - } - @Mapper(value = "block", local = true) private TypeMapper blockMapper() { Set strings = new HashSet<>(); @@ -130,7 +123,7 @@ public class PanzernCommand extends SWCommand { if (!material.isBlock()) { continue; } - if (material.name().contains("STAIRS") || material.name().contains("SLAB")) { + if (material.name().contains("STAIRS") || material.name().contains("SLAB") || material.name().contains("GLASS")) { strings.add(material.name().toLowerCase()); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index 07748a98..de40c6c7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.smartplace; import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.configplayer.Config; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; @@ -39,7 +40,10 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -67,11 +71,13 @@ public class SmartPlaceListener implements Plain, Listener { } } CONTAINERS.add(Material.GRINDSTONE); + CONTAINERS.remove(Material.COMPARATOR); state.update(true, false); IGNORED.add(Material.TNT); IGNORED.add(Material.REDSTONE_ORE); IGNORED.add(SWItem.getMaterial("BEEHIVE")); + IGNORED.add(SWItem.getMaterial("SEA_PICKLE")); IGNORED.remove(Material.STONE); IGNORED.remove(Material.BARRIER); } @@ -89,32 +95,42 @@ public class SmartPlaceListener implements Plain, Listener { public SmartPlaceListener() { TinyProtocol.instance.addFilter(useItem, (player, packet) -> { + if(!Permission.BUILD.hasPermission(player)) return packet; if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet; Block block = player.getTargetBlockExact(6); - boolean shouldSneak = !(block != null && (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) && !CONTAINERS.contains(block.getType()) && !IGNORED.contains(block.getType())); + boolean shouldSneak = false; + if (block != null) { + if (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) { + shouldSneak = true; + } + if (CONTAINERS.contains(block.getType())) { + ItemStack itemStack = player.getInventory().getItemInMainHand(); + if (itemStack.getType() == Material.TNT) { + if (block.getType() == Material.CHEST || block.getType() == Material.BARREL || block.getType().name().endsWith("SHULKER_BOX")) { + shouldSneak = false; + } + } + } else { + shouldSneak = false; + } + if (IGNORED.contains(block.getType())) { + shouldSneak = false; + } + } boolean sneaking = player.isSneaking(); - run(player, packet, true, sneaking, shouldSneak); - return null; - }); - } - - private void run(Player player, Object packet, boolean first, boolean sneaking, boolean shouldSneak) { - Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { if (sneaking) SMART_PLACING.add(player); player.setSneaking(shouldSneak || sneaking); - packetExecutor.invoke(playerConnection.get(getHandle.invoke(player)), packet); - SMART_PLACING.remove(player); - player.setSneaking(sneaking); - - if (!WAS_EXECUTED.contains(player) && first) { - run(player, packet, false, sneaking, shouldSneak); - } - WAS_EXECUTED.remove(player); - }, first ? 0 : 1); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + SMART_PLACING.remove(player); + player.setSneaking(sneaking); + }, 0); + return packet; + }); } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return; WAS_EXECUTED.add(event.getPlayer()); if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; @@ -133,6 +149,7 @@ public class SmartPlaceListener implements Plain, Listener { @EventHandler public void onBlockPlace(BlockPlaceEvent event) { + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return; if (!SMART_PLACING.contains(event.getPlayer())) { if (CONTAINERS.contains(event.getBlockAgainst().getType())) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java index b6c6975e..38725cf0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/techhider/TechHiderCommand.java @@ -20,16 +20,22 @@ package de.steamwar.bausystem.features.techhider; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.features.world.SpectatorListener; import de.steamwar.bausystem.features.xray.XrayCommand; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.ScoreboardElement; +import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeMapper; import de.steamwar.core.CraftbukkitWrapper; import de.steamwar.linkage.Linked; import de.steamwar.linkage.LinkedInstance; import de.steamwar.techhider.TechHider; import net.md_5.bungee.api.ChatMessageType; +import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -55,7 +61,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE public XrayCommand xrayCommand; @Register(description = "TECHHIDER_HELP") - public void toggleHider(Player player) { + public void toggleHider(@Validator Player player) { Region region = Region.getRegion(player.getLocation()); if (region.isGlobal()) { BauSystem.MESSAGE.send("TECHHIDER_GLOBAL", player); @@ -79,7 +85,7 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE Set hiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks"))); Set hiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities"))); - TechHider current = new TechHider((p, cX, cY) -> { + TechHider current = new TechHider((TechHider.LocationEvaluator) (p, cX, cY) -> { if (rg.buildChunkOutside(cX, cY)) return true; return !hidden.get(rg).contains(p); }, Material.valueOf(obfuscateWith.toUpperCase()), hiddenBlocks.stream().map(String::toUpperCase).map(Material::valueOf).collect(Collectors.toSet()), hiddenBlockEntities); @@ -104,6 +110,33 @@ public class TechHiderCommand extends SWCommand implements Listener, ScoreboardE }); } + @Register + public void toggleHider(@Validator("supervisor") Player player, @Mapper("spectator") Player other) { + SpectatorListener.toggleNoTechHider(other); + } + + @Mapper("spectator") + public TypeMapper spectatorMapper() { + return new TypeMapper<>() { + @Override + public Player map(CommandSender commandSender, String[] previousArguments, String s) { + Player player = Bukkit.getPlayer(s); + if (player != null && Permission.REAL_SPECTATOR.hasPermission(player)) { + return player; + } + return null; + } + + @Override + public Collection tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { + return Bukkit.getOnlinePlayers().stream() + .filter(Permission.REAL_SPECTATOR::hasPermission) + .map(Player::getName) + .collect(Collectors.toList()); + } + }; + } + @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { hidden.values().forEach(set -> set.remove(event.getPlayer())); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java b/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java index cf34f6f1..8b0796b8 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/testblock/blockcounter/BlockCounter.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.testblock.blockcounter; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.configplayer.Config; import de.steamwar.bausystem.region.Region; import lombok.experimental.UtilityClass; @@ -49,6 +50,8 @@ public class BlockCounter { } public String getMessage(Player player, int count, int tntCount, long tick, long lastTick) { + if(!Permission.BUILD.hasPermission(player)) return null; + double countPerTNT = (double) count / tntCount; double countPerTick = (double) count / Math.max((lastTick - tick), 1); if (isActive(player)) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java index 43eb40da..6de8d252 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java @@ -26,6 +26,7 @@ import de.steamwar.bausystem.linkage.specific.BauGuiItem; import de.steamwar.bausystem.region.GlobalRegion; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.utils.ScoreboardElement; +import de.steamwar.bausystem.utils.TickEndEvent; import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; import de.steamwar.bausystem.utils.bossbar.BossBarService; import de.steamwar.command.AbstractSWCommand; @@ -37,22 +38,20 @@ import de.steamwar.core.TPSWatcher; import de.steamwar.inventory.SWAnvilInv; import de.steamwar.inventory.SWItem; import de.steamwar.linkage.Linked; -import de.steamwar.linkage.api.Plain; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.boss.BarColor; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.scheduler.BukkitTask; import java.util.Arrays; -import java.util.concurrent.atomic.AtomicInteger; @Linked -public class TPSSystem implements Plain { +public class TPSSystem implements Listener { @Getter private double currentTPSLimit = 20; @@ -65,6 +64,8 @@ public class TPSSystem implements Plain { } public TPSSystem() { + instance = this; + if (TPSFreezeUtils.isCanFreeze()) { new TPSFreezeCommand(); new TickFreezeCommand(); @@ -83,16 +84,11 @@ public class TPSSystem implements Plain { new TickDefaultCommand(); new TPSBaseCommand(); new TickBaseCommand(); - - instance = this; } - private BukkitTask stepper = null; - private void setTPS(double tps) { - if (stepper != null) { - stepper.cancel(); - stepper = null; + if (currentlyStepping) { + currentlyStepping = false; Bukkit.getOnlinePlayers().forEach(player -> { BossBarService.instance.remove(player, GlobalRegion.getInstance(), "TickStep"); }); @@ -120,37 +116,34 @@ public class TPSSystem implements Plain { }); } - private void setSkip(int steps, double tpsLimitToUse) { - double currentLimit = tpsLimitToUse == 20 ? 0 : currentTPSLimit; - setTPS(tpsLimitToUse); - stepper = new BukkitRunnable() { - AtomicInteger stepsLeft = new AtomicInteger(steps); + private boolean currentlyStepping = false; + private double currentLimit; + private int stepsTotal; + private int stepsLeft; - @Override - public void run() { - if (steps > 1) { - Bukkit.getOnlinePlayers().forEach(player -> { - BauSystemBossbar bossbar = BossBarService.instance.get(player, GlobalRegion.getInstance(), "TickStep"); - bossbar.setColor(BarColor.YELLOW); - bossbar.setTitle(BauSystem.MESSAGE.parse("TICK_BOSSBAR", player, (steps - stepsLeft.get()), steps)); - bossbar.setProgress((steps - stepsLeft.get()) / (double) steps); - }); - } - if (stepsLeft.decrementAndGet() < 0) { - setTPS(currentLimit); - } - } - }.runTaskTimer(BauSystem.getInstance(), 1, 1); + private void setSkip(int steps, double tpsLimitToUse) { + currentLimit = tpsLimitToUse == 20 ? 0 : currentTPSLimit; + setTPS(tpsLimitToUse); + stepsLeft = steps; + stepsTotal = steps; + currentlyStepping = true; } - public TypeValidator player() { - return (commandSender, player, messageSender) -> { - if (!Permission.hasPermission(player, Permission.WORLD)) { - messageSender.send("TPSLIMIT_NO_PERMS"); - return false; - } - return true; - }; + @EventHandler + public void onTickEnd(TickEndEvent event) { + if (!currentlyStepping) return; + if (stepsTotal > 1) { + Bukkit.getOnlinePlayers().forEach(player -> { + BauSystemBossbar bossbar = BossBarService.instance.get(player, GlobalRegion.getInstance(), "TickStep"); + bossbar.setColor(BarColor.YELLOW); + bossbar.setTitle(BauSystem.MESSAGE.parse("TICK_BOSSBAR", player, (stepsTotal - stepsLeft), stepsTotal)); + bossbar.setProgress((stepsTotal - stepsLeft) / (double) stepsTotal); + }); + } + stepsLeft--; + if (stepsLeft <= 0) { + setTPS(currentLimit); + } } private class TPSBaseCommand extends SWCommand { @@ -160,11 +153,6 @@ public class TPSSystem implements Plain { setMessage(BauSystem.MESSAGE); addDefaultHelpMessage("TPSLIMIT_HELP"); } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator player() { - return TPSSystem.this.player(); - } } @AbstractSWCommand.PartOf(TPSBaseCommand.class) @@ -230,11 +218,6 @@ public class TPSSystem implements Plain { super("tick"); setMessage(BauSystem.MESSAGE); } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator player() { - return TPSSystem.this.player(); - } } @AbstractSWCommand.PartOf(TickBaseCommand.class) @@ -341,7 +324,7 @@ public class TPSSystem implements Plain { @Override public String get(Region region, Player p) { - if (TPSSystem.getInstance().stepper != null) { + if (TPSSystem.getInstance() != null && TPSSystem.getInstance().currentlyStepping) { long time = System.currentTimeMillis() % 1000; if (time < 250) { return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: §7•••"; @@ -403,7 +386,7 @@ public class TPSSystem implements Plain { @Override public Permission permission() { - return Permission.WORLD; + return Permission.BUILD; } } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java index ab213c83..9a93977e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BindCommand.java @@ -1,9 +1,17 @@ package de.steamwar.bausystem.features.util; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.event.platform.CommandEvent; +import com.sk89q.worldedit.extension.platform.Actor; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.SWUtils; import de.steamwar.bausystem.features.script.ScriptCommand; import de.steamwar.bausystem.features.script.ScriptRunner; +import de.steamwar.bausystem.features.world.WorldEditListener; +import de.steamwar.bausystem.utils.WorldEditUtils; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeMapper; @@ -20,14 +28,18 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataType; +import org.luaj.vm2.LuaValue; import java.lang.reflect.Field; import java.util.*; +import java.util.logging.Level; import java.util.stream.Collectors; @Linked public class BindCommand extends SWCommand implements Listener { + private static final boolean hasFAWE = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null; + @Linked public static class UnBindCommand extends SWCommand { @@ -62,7 +74,7 @@ public class BindCommand extends SWCommand implements Listener { } @Register(description = "OTHER_BIND_HELP") - public void bind(Player player, @Mapper("command") @ErrorMessage("OTHER_BIND_ERROR") String... command) { + public void bind(@Validator Player player, @Mapper("command") @ErrorMessage("OTHER_BIND_ERROR") String... command) { bindInternal(player, command); } @@ -91,6 +103,7 @@ public class BindCommand extends SWCommand implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { if (!event.hasItem()) return; + if(!Permission.BUILD.hasPermission(event.getPlayer())) return; ItemStack itemStack = event.getItem(); ItemMeta meta = itemStack.getItemMeta(); if (meta == null) { @@ -104,10 +117,22 @@ public class BindCommand extends SWCommand implements Listener { event.setCancelled(true); Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - PlayerCommandPreprocessEvent playerCommandPreprocessEvent = new PlayerCommandPreprocessEvent(event.getPlayer(), "/" + command); - Bukkit.getPluginManager().callEvent(playerCommandPreprocessEvent); - if (playerCommandPreprocessEvent.isCancelled()) return; - Bukkit.getServer().dispatchCommand(event.getPlayer(), command); + PlayerCommandPreprocessEvent preprocessEvent = new PlayerCommandPreprocessEvent(event.getPlayer(), "/" + command); + Bukkit.getPluginManager().callEvent(preprocessEvent); + if (preprocessEvent.isCancelled()) return; + + String processedCommand = preprocessEvent.getMessage().substring(1); + Bukkit.getLogger().log(Level.INFO, event.getPlayer().getName() + " dispatched command: " + processedCommand); + String[] commandSplit = processedCommand.split(" "); + if (!commandSplit[0].equals("select") && hasFAWE && WorldEditListener.isWorldEditCommand("/" + commandSplit[0])) { + EditSession editSession = WorldEditUtils.getEditSession(event.getPlayer()); + Actor actor = BukkitAdapter.adapt(event.getPlayer()); + WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().handleCommandOnCurrentThread(new CommandEvent(actor, processedCommand, editSession)); + editSession.flushSession(); + WorldEditUtils.addToPlayer(event.getPlayer(), editSession); + } else { + Bukkit.getServer().dispatchCommand(event.getPlayer(), processedCommand); + } }, 1); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java index 290223a2..c534e38d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/BookReplaceCommand.java @@ -17,7 +17,7 @@ public class BookReplaceCommand extends SWCommand { } @Register("color") - public void color(Player player) { + public void color(@Validator Player player) { ItemStack itemStack = player.getInventory().getItemInMainHand(); ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta instanceof BookMeta) { @@ -29,7 +29,7 @@ public class BookReplaceCommand extends SWCommand { } @Register("uncolor") - public void uncolor(Player player) { + public void uncolor(@Validator Player player) { ItemStack itemStack = player.getInventory().getItemInMainHand(); ItemMeta itemMeta = itemStack.getItemMeta(); if (itemMeta instanceof BookMeta) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java index 3e8899d6..1df08e5d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/ClearCommand.java @@ -48,13 +48,6 @@ public class ClearCommand extends SWCommand { BauSystem.MESSAGE.send("OTHER_CLEAR_TO", p, target.getName()); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "OTHER_CLEAR_NO_PERMS"); - }; - } - private void clear(Player player) { player.getInventory().clear(); player.getInventory().setHelmet(new ItemStack(Material.AIR)); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java index e2de740f..5b87464c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/DebugStickCommand.java @@ -34,7 +34,7 @@ public class DebugStickCommand extends SWCommand { } @Register(description = "DEBUG_STICK_COMMAND_HELP") - public void genericCommand(Player p) { + public void genericCommand(@Validator Player p) { SWUtils.giveItemToPlayer(p, new ItemStack(Material.DEBUG_STICK)); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java index 49654a05..e08b40c0 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/KillAllCommand.java @@ -45,12 +45,12 @@ public class KillAllCommand extends SWCommand { } @Register(description = "OTHER_KILLALL_HELP_SELF") - public void genericCommand(Player player) { + public void genericCommand(@Validator Player player) { genericCommand(player, RegionSelectionType.LOCAL); } @Register(description = "OTHER_KILLALL_HELP_ALL") - public void genericCommand(Player player, RegionSelectionType regionSelectionType) { + public void genericCommand(@Validator Player player, RegionSelectionType regionSelectionType) { Region region = Region.getRegion(player.getLocation()); AtomicLong count = new AtomicLong(0); if (regionSelectionType == RegionSelectionType.GLOBAL || GlobalRegion.getInstance() == region) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java index 6f7a92c7..7893b8c4 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/MaterialCommand.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.util; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.SWUtils; +import de.steamwar.bausystem.features.world.WorldEditListener; import de.steamwar.bausystem.shared.EnumDisplay; import de.steamwar.command.PreviousArguments; import de.steamwar.command.SWCommand; @@ -51,6 +52,7 @@ public class MaterialCommand extends SWCommand implements Listener { public MaterialCommand() { super("material", "baumaterial"); + WorldEditListener.addCommandExclusion("material"); } private Map searchMap = new HashMap<>(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java index ba5d5000..867ad83d 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/NoClipCommand.java @@ -24,6 +24,7 @@ import com.comphenix.tinyprotocol.TinyProtocol; import com.mojang.authlib.GameProfile; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.features.tpslimit.TPSUtils; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; import de.steamwar.bausystem.utils.NMSWrapper; import de.steamwar.command.SWCommand; import de.steamwar.core.ProtocolWrapper; @@ -97,7 +98,7 @@ public class NoClipCommand extends SWCommand implements Listener { } @Register(help = true) - public void genericCommand(Player player, String... args) { + public void genericCommand(@Validator Player player) { if (NOCLIPS.contains(player)) { NOCLIPS.remove(player); player.setGameMode(GameMode.CREATIVE); @@ -116,6 +117,16 @@ public class NoClipCommand extends SWCommand implements Listener { } } + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + event.getNewSpectator().forEach(player -> { + if (NOCLIPS.contains(player)) { + NOCLIPS.remove(player); + player.setGameMode(GameMode.CREATIVE); + } + }); + } + @EventHandler(ignoreCancelled = true) public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { if (NOCLIPS.contains(event.getPlayer())) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java index 0f1cfe5e..de9ea34a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculator.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.util; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.entity.REntityServer; import de.steamwar.entity.RFallingBlockEntity; import de.steamwar.linkage.Linked; @@ -49,6 +50,7 @@ public class PistonCalculator implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; if (!event.hasItem() || event.getItem().getType() != Material.SLIME_BALL) return; if (event.getClickedBlock() == null) return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java index 8aef617f..71fefaa4 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/PistonCalculatorCommand.java @@ -32,7 +32,7 @@ public class PistonCalculatorCommand extends SWCommand { } @Register - public void help(Player player) { + public void help(@Validator Player player) { BauSystem.MESSAGE.send("PISTON_HELP_1", player); BauSystem.MESSAGE.send("PISTON_HELP_2", player); BauSystem.MESSAGE.send("PISTON_HELP_3", player); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java index bd8566ea..e9c2c09a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SelectCommand.java @@ -45,13 +45,6 @@ public class SelectCommand extends SWCommand { baurahmenCommand(p, RegionType.TESTBLOCK, regionExtensionType); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLDEDIT), "SELECT_NO_PERMS"); - }; - } - private void setSelection(RegionType regionType, RegionExtensionType regionExtensionType, Region region, Player p) { Point minPoint = region.getMinPoint(regionType, regionExtensionType); Point maxPoint = region.getMaxPoint(regionType, regionExtensionType); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java index 9bb2331d..1f50a2ae 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SkullCommand.java @@ -43,7 +43,7 @@ public class SkullCommand extends SWCommand { } @Register(description = "SKULL_HELP") - public void giveCommand(Player p, @Mapper("player") @ErrorMessage("SKULL_INVALID") String skull) { + public void giveCommand(@Validator Player p, @Mapper("player") @ErrorMessage("SKULL_INVALID") String skull) { ItemStack is = SWItem.getPlayerSkull(skull).getItemStack(); SkullMeta sm = (SkullMeta) is.getItemMeta(); assert sm != null; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SlotCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SlotCommand.java index 4ea5d62b..37ff3b89 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/SlotCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/SlotCommand.java @@ -41,7 +41,7 @@ public class SlotCommand extends SWCommand { } @Register - public void slotCommand(Player player, Integer slot) { + public void slotCommand(@Validator Player player, Integer slot) { if (slot < 1 || slot > 9) { BauSystem.MESSAGE.send("OTHER_SLOT_INVALID_SLOT", player); return; @@ -50,7 +50,7 @@ public class SlotCommand extends SWCommand { } @Register(value = "pick", description = "OTHER_NOCLIP_SLOT_HELP_PICK") - public void eyedropBlock(Player player) { + public void eyedropBlock(@Validator Player player) { Block block = player.getTargetBlockExact(6); ItemStack itemStack; if (block == null) { @@ -61,7 +61,7 @@ public class SlotCommand extends SWCommand { } @Register(value = "drop", description = "OTHER_NOCLIP_SLOT_HELP_DROP") - public void dropBlock(Player player) { + public void dropBlock(@Validator Player player) { player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/StructureVoidCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/StructureVoidCommand.java index 277eb59a..44bae130 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/StructureVoidCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/StructureVoidCommand.java @@ -34,7 +34,7 @@ public class StructureVoidCommand extends SWCommand { } @Register(description = "STRUCTURE_VOID_COMMAND_HELP") - public void genericCommand(Player p) { + public void genericCommand(@Validator Player p) { SWUtils.giveItemToPlayer(p, new ItemStack(Material.STRUCTURE_VOID, 1)); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java index 9bb8368f..3284876a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/TNTClickListener.java @@ -20,6 +20,7 @@ package de.steamwar.bausystem.features.util; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; @@ -34,9 +35,9 @@ public class TNTClickListener implements Listener { @EventHandler public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { - if (event.getHand() != EquipmentSlot.HAND) { - return; - } + if (!Permission.BUILD.hasPermission(event.getPlayer())) return; + if (event.getHand() != EquipmentSlot.HAND) return; + Entity entity = event.getRightClicked(); if (event.getRightClicked() instanceof TNTPrimed) { TNTPrimed tntPrimed = (TNTPrimed) entity; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/TimeCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/TimeCommand.java index 15f48590..249f4072 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/TimeCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/TimeCommand.java @@ -66,13 +66,6 @@ public class TimeCommand extends SWCommand { }, s -> tabCompletions); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "OTHER_TIME_NO_PERM"); - }; - } - public enum Time { NIGHT(18000), DAY(6000), diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/DebugstickBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/DebugstickBauGuiItem.java index 725d75b1..c6341818 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/DebugstickBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/DebugstickBauGuiItem.java @@ -50,6 +50,6 @@ public class DebugstickBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.MEMBER; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/KillAllBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/KillAllBauGuiItem.java index 42a4588a..a5f76346 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/KillAllBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/KillAllBauGuiItem.java @@ -62,6 +62,6 @@ public class KillAllBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.MEMBER; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/NavWandBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/NavWandBauGuiItem.java index 30ac88a2..6b9b6775 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/NavWandBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/NavWandBauGuiItem.java @@ -39,7 +39,7 @@ public class NavWandBauGuiItem extends BauGuiItem { } @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.MEMBER; } @Override public ItemStack getItem(Player player) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SchemBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SchemBauGuiItem.java index dc5569e4..027d6c9c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SchemBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SchemBauGuiItem.java @@ -18,7 +18,7 @@ public class SchemBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.BUILD; } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java index 2e90be13..b0feb305 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SelectBauGuiItem.java @@ -88,7 +88,7 @@ public class SelectBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.BUILD; } @AllArgsConstructor diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SkullBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SkullBauGuiItem.java index f9ec57c8..c7e500db 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SkullBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/SkullBauGuiItem.java @@ -54,6 +54,6 @@ public class SkullBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.MEMBER; + return Permission.BUILD; } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/WorldEditBauGuiItem.java b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/WorldEditBauGuiItem.java index ddfa66d7..9ef2400f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/WorldEditBauGuiItem.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/util/items/WorldEditBauGuiItem.java @@ -40,7 +40,7 @@ public class WorldEditBauGuiItem extends BauGuiItem { @Override public Permission permission() { - return Permission.WORLDEDIT; + return Permission.BUILD; } @Override diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java index 8fa832a7..aad07fcb 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpCommand.java @@ -122,13 +122,6 @@ public class WarpCommand extends SWCommand implements Disable, Enable { BauSystem.MESSAGE.sendPrefixless("WARP_GUI_DISTANCE", player, warp.getLocation().distance(player.getLocation())); } - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!Permission.hasPermission(player, Permission.WORLD), "WARP_DISALLOWED"); - }; - } - @Linked public static class WarpsLink extends SWCommand { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java index 7c5c87a6..30fd21e3 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/warp/WarpGui.java @@ -55,7 +55,7 @@ public class WarpGui { ), warp))); SWListInv inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("WARP_GUI_NAME", player), false, entries, (clickType, warp) -> { - if (clickType.isRightClick() && Permission.hasPermission(player, Permission.WORLD)) { + if (clickType.isRightClick() && Permission.BUILD.hasPermission(player)) { openWarpGui(player, warp); } else { warp.teleport(player); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/AFKStopperListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/AFKStopperListener.java index 52249a23..81e2f4dd 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/AFKStopperListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/AFKStopperListener.java @@ -20,63 +20,57 @@ package de.steamwar.bausystem.features.world; import de.steamwar.bausystem.BauSystem; +import de.steamwar.core.CheckpointUtils; import de.steamwar.linkage.Linked; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; @Linked public class AFKStopperListener implements Listener { - // CPU > 50% - // RAM > 60% - private int afkTicks = 0; public AFKStopperListener() { Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> { - // System.out.println("CPU: " + load + " RAM: " + usage); - if (Bukkit.getOnlinePlayers().isEmpty()) { - if (RamUsage.getLoad() >= 50.0 || RamUsage.getUsage() >= 0.6) { - Bukkit.shutdown(); - return; - } - } else if (RamUsage.getLoad() < 50.0 && RamUsage.getUsage() < 0.6) { - afkTicks = 0; - return; - } switch (afkTicks) { - case 90: - Bukkit.shutdown(); - break; case 15: for (Player p : Bukkit.getOnlinePlayers()) { p.kickPlayer(BauSystem.MESSAGE.parse("AFK_KICK_MESSAGE", p)); } - case 12: + case 14: BauSystem.MESSAGE.broadcast("AFK_WARNING_MESSAGE"); default: afkTicks++; } - }, 20*60, 20*60); //every minute + }, 1200, 1200); //every minute } @EventHandler public void onPlayerMove(PlayerMoveEvent event) { - if (event.getTo() == null) return; - if (event.getFrom().getPitch() != event.getTo().getPitch()) { + Location to = event.getTo(); + if (to == null) + return; + + Location from = event.getFrom(); + if (from.getPitch() != to.getPitch() || from.getYaw() != to.getYaw()) afkTicks = 0; - } - if (event.getFrom().getYaw() != event.getTo().getYaw()) { - afkTicks = 0; - } } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) //Potential fix for potential race condition with WE axe spontaneously not working public void onPlayerJoin(PlayerJoinEvent event) { event.getPlayer().setOp(true); } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + if(Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().size() == 1 && Bukkit.getOnlinePlayers().contains(event.getPlayer()))) + CheckpointUtils.freeze(); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/AntiBauAddMemberFix.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/AntiBauAddMemberFix.java new file mode 100644 index 00000000..a7a3bad6 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/AntiBauAddMemberFix.java @@ -0,0 +1,45 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.world; + +import de.steamwar.bausystem.config.BauServer; +import de.steamwar.linkage.Linked; +import de.steamwar.sql.BauweltMember; +import de.steamwar.sql.SteamwarUser; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +@Linked +public class AntiBauAddMemberFix implements Listener { + + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerJoin(PlayerJoinEvent event) { + if (event.getPlayer().getUniqueId().equals(BauServer.getInstance().getOwner())) { + return; + } + if (BauweltMember.getBauMember(BauServer.getInstance().getOwner(), event.getPlayer().getUniqueId()) == null) { + event.getPlayer().kickPlayer(""); + throw new SecurityException("The player " + event.getPlayer().getName() + " joined on the server of " + SteamwarUser.get(BauServer.getInstance().getOwnerID()).getUserName() + " without being added!"); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/AxiomPermissionCheck.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/AxiomPermissionCheck.java index 5ee07dae..587c8d59 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/AxiomPermissionCheck.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/AxiomPermissionCheck.java @@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.world; import com.moulberry.axiom.event.AxiomHandshakeEvent; import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.config.BauServer; import de.steamwar.linkage.Linked; import de.steamwar.linkage.PluginCheck; import org.bukkit.event.EventHandler; @@ -32,7 +33,10 @@ public class AxiomPermissionCheck implements Listener { @EventHandler public void onAxiomHandshake(AxiomHandshakeEvent event) { - if (Permission.WORLDEDIT.hasPermission(event.getPlayer())) return; + if (Permission.SUPERVISOR.hasPermission(event.getPlayer()) || BauServer.getInstance().getOwner().equals(event.getPlayer().getUniqueId())) { + event.setMaxBufferSize(Short.MAX_VALUE); + return; + } event.setCancelled(true); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauLockStateScoreboard.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauLockStateScoreboard.java new file mode 100644 index 00000000..ab3630d4 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauLockStateScoreboard.java @@ -0,0 +1,68 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.config.BauServer; +import de.steamwar.bausystem.region.Region; +import de.steamwar.bausystem.utils.ScoreboardElement; +import de.steamwar.linkage.Linked; +import de.steamwar.sql.UserConfig; +import org.bukkit.entity.Player; + +@Linked +public class BauLockStateScoreboard implements ScoreboardElement { + + private static final String BAU_LOCK_CONFIG_NAME = "baulockstate"; + + @Override + public ScoreboardGroup getGroup() { + return ScoreboardGroup.FOOTER; + } + + @Override + public int order() { + return -10; + } + + @Override + public String get(Region region, Player p) { + if (!BauServer.getInstance().getOwner().equals(p.getUniqueId())) { + return null; + } + String state = UserConfig.getConfig(p.getUniqueId(), BAU_LOCK_CONFIG_NAME); + switch (state == null ? BauLockState.OPEN : BauLockState.valueOf(state)) { + case OPEN: + return null; + default: + return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_LOCK_" + state.toUpperCase(), p); + } + } + + public enum BauLockState { + + NOBODY, + SERVERTEAM, + TEAM_AND_SERVERTEAM, + TEAM, + OPEN + } + +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauMemberUpdate.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauMemberUpdate.java new file mode 100644 index 00000000..46c10ef1 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauMemberUpdate.java @@ -0,0 +1,148 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.region.GlobalRegion; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; +import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar; +import de.steamwar.bausystem.utils.bossbar.BossBarService; +import de.steamwar.command.SWCommand; +import de.steamwar.linkage.Linked; +import de.steamwar.network.packets.PacketHandler; +import de.steamwar.network.packets.server.BaumemberUpdatePacket; +import org.bukkit.Bukkit; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.HashSet; +import java.util.Set; + +@Linked +public class BauMemberUpdate extends PacketHandler implements Listener { + + private static final Set SPECTATORS = new HashSet<>(); + + @Handler + public void baumemberUpdate(BaumemberUpdatePacket baumemberUpdatePacket) { + baumemberUpdate(); + } + + public static void baumemberUpdate() { + Set newSpectator = new HashSet<>(); + Set newBuilder = new HashSet<>(); + Bukkit.getOnlinePlayers().forEach(player -> { + if (Permission.REAL_SPECTATOR.hasPermission(player)) { + if (!SPECTATORS.contains(player)) { + SPECTATORS.add(player); + Permission.removeForceOnlySpectator(player); + newSpectator.add(player); + player.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, -1, 1, false,false, false)); + showSpectatorNotice(player); + } + } else { + if (Permission.SUPERVISOR.hasPermission(player)) { + Permission.removeForceOnlySpectator(player); + } + if (SPECTATORS.contains(player)) { + SPECTATORS.remove(player); + newBuilder.add(player); + player.removePotionEffect(PotionEffectType.GLOWING); + BossBarService.instance.remove(player, GlobalRegion.getInstance(), "spectator"); + } + } + }); + Bukkit.getPluginManager().callEvent(new BauMemberUpdateEvent(newSpectator, newBuilder)); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + SPECTATORS.add(event.getPlayer()); + event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, -1, 1, false,false, false)); + showSpectatorNotice(event.getPlayer()); + } else { + event.getPlayer().removePotionEffect(PotionEffectType.GLOWING); + } + } + + private static void showSpectatorNotice(Player player) { + BauSystemBossbar bossbar = BossBarService.instance.get(player, GlobalRegion.getInstance(), "spectator"); + bossbar.setTitle(BauSystem.MESSAGE.parse("SPECTATOR", player)); + bossbar.setColor(BarColor.WHITE); + bossbar.setStyle(BarStyle.SOLID); + bossbar.setProgress(1.0); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + SPECTATORS.remove(event.getPlayer()); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + event.setDeathMessage(null); + if (SPECTATORS.contains(event.getEntity())) { + event.getDrops().clear(); + } + } + + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent event) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + if (SPECTATORS.contains(event.getPlayer())) { + event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, -1, 1, false, false, false)); + } + }, 1); + } + + @EventHandler + public void onPlayerItemConsume(PlayerItemConsumeEvent event) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + if (SPECTATORS.contains(event.getPlayer())) { + event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, -1, 1, false,false, false)); + } + }, 1); + } + + @Linked + public static class TestCommand extends SWCommand { // TODO: Remove before merge + + public TestCommand() { + super("test"); + } + + @Register + public void test(Player player) { + PacketHandler.handlePacket(new BaumemberUpdatePacket()); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java index 6efda09f..74098b1b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/BauScoreboard.java @@ -4,41 +4,56 @@ import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.region.GlobalRegion; import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.shared.Pair; import de.steamwar.bausystem.utils.ScoreboardElement; import de.steamwar.linkage.Linked; import de.steamwar.scoreboard.SWScoreboard; import de.steamwar.scoreboard.ScoreboardCallback; +import org.apache.commons.lang3.tuple.MutableTriple; +import org.apache.commons.lang3.tuple.Triple; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; import java.util.*; @Linked public class BauScoreboard implements Listener { - public static final List ELEMENTS = new ArrayList<>(); + private static final Map> ELEMENTS = new HashMap<>(); + private static final Map>> ADDITIONAL_SCOREBOARD_LINES = new HashMap<>(); + + public static void addElement(ScoreboardElement scoreboardElement) { + List elements = ELEMENTS.computeIfAbsent(scoreboardElement.getGroup(), scoreboardGroup -> new ArrayList<>()); + elements.add(scoreboardElement); + elements.sort(Comparator.comparingInt(ScoreboardElement::order)); + } + + public static void setAdditionalElement(Player player, String key, ScoreboardElement.ScoreboardGroup group, int priority, String value) { + Map> playerElements = ADDITIONAL_SCOREBOARD_LINES.computeIfAbsent(player, player1 -> new HashMap<>()); + if (value == null || value.isBlank()) { + playerElements.remove(key); + return; + } + MutableTriple element = playerElements.computeIfAbsent(key, s -> new MutableTriple<>(null, null, null)); + element.setLeft(group); + element.setMiddle(priority); + element.setRight(value); + } @EventHandler public void handlePlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - Map> map = new HashMap<>(); - for (ScoreboardElement element : ELEMENTS) { - map.computeIfAbsent(element.getGroup(), scoreboardGroup -> new ArrayList<>()).add(element); - } - map.forEach((scoreboardGroup, scoreboardElements) -> { - scoreboardElements.sort(Comparator.comparingInt(ScoreboardElement::order)); - }); - SWScoreboard.createScoreboard(player, new ScoreboardCallback() { @Override public HashMap getData() { Region region = Region.getRegion(player.getLocation()); List elements = new ArrayList<>(); - calcGroup(elements, "§0", region, ScoreboardElement.ScoreboardGroup.HEADER); + calcGroup(elements, null, region, ScoreboardElement.ScoreboardGroup.HEADER); calcGroup(elements, "§1", region, ScoreboardElement.ScoreboardGroup.REGION); calcGroup(elements, "§2", region, ScoreboardElement.ScoreboardGroup.OTHER); calcGroup(elements, "§3", region, ScoreboardElement.ScoreboardGroup.FOOTER); @@ -52,16 +67,25 @@ public class BauScoreboard implements Listener { } private void calcGroup(List elements, String separator, Region region, ScoreboardElement.ScoreboardGroup group) { - if (map.containsKey(group)) { - List groupElements = new ArrayList<>(); - for (ScoreboardElement element : map.get(group)) { + List groupElements = new ArrayList<>(); + if (ELEMENTS.containsKey(group)) { + for (ScoreboardElement element : ELEMENTS.get(group)) { groupElements.add(element.get(region, player)); } - groupElements.removeIf(Objects::isNull); - if (!groupElements.isEmpty()) { - elements.add(separator); - elements.addAll(groupElements); - } + } + if (ADDITIONAL_SCOREBOARD_LINES.containsKey(player)) { + ADDITIONAL_SCOREBOARD_LINES.get(player).values() + .stream() + .filter(triple -> triple.getLeft() == group) + .sorted(Comparator.comparing(MutableTriple::getMiddle)) + .forEach(triple -> { + groupElements.add(triple.getRight()); + }); + } + groupElements.removeIf(Objects::isNull); + if (!groupElements.isEmpty()) { + if (separator != null) elements.add(separator); + elements.addAll(groupElements); } } @@ -74,4 +98,9 @@ public class BauScoreboard implements Listener { } }); } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + ADDITIONAL_SCOREBOARD_LINES.remove(event.getPlayer()); + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/ClipboardListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/ClipboardListener.java index 3d3ca140..c9d3887c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/ClipboardListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/ClipboardListener.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.features.world; +import de.steamwar.bausystem.Permission; import de.steamwar.linkage.Linked; import de.steamwar.sql.SchematicData; import de.steamwar.sql.SchematicNode; @@ -35,6 +36,8 @@ public class ClipboardListener implements Listener { @EventHandler public void onLogin(PlayerJoinEvent e) { + if(!Permission.SUPERVISOR.hasPermission(e.getPlayer())) return; + try { SchematicNode schematic = SchematicNode.getSchematicNode(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), CLIPBOARD_SCHEMNAME, (Integer) null); if (schematic != null) { @@ -47,6 +50,8 @@ public class ClipboardListener implements Listener { @EventHandler public void onLogout(PlayerQuitEvent e) { + if(!Permission.SUPERVISOR.hasPermission(e.getPlayer())) return; + SchematicNode schematic = SchematicNode.getSchematicNode(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), CLIPBOARD_SCHEMNAME, (Integer) null); boolean newSchem = false; if (schematic == null) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/ItemFrameListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/ItemFrameListener.java index 9a294708..535551ab 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/ItemFrameListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/ItemFrameListener.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.features.world; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.SWUtils; import de.steamwar.linkage.Linked; import org.bukkit.Material; @@ -40,6 +41,9 @@ public class ItemFrameListener implements Listener { if (!(event.getEntity() instanceof ItemFrame)) { return; } + + if(!Permission.BUILD.hasPermission((Player) event.getDamager())) return; + event.setCancelled(true); ItemFrame itemFrame = (ItemFrame) event.getEntity(); ItemStack itemStack = itemFrame.getItem(); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/KickallCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/KickallCommand.java index ee9ace1b..d4e5d3f7 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/KickallCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/KickallCommand.java @@ -19,6 +19,7 @@ package de.steamwar.bausystem.features.world; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.config.BauServer; import de.steamwar.command.SWCommand; import de.steamwar.command.TypeValidator; @@ -38,16 +39,11 @@ public class KickallCommand extends SWCommand { } @Register(description = "KICKALL_HELP") - public void genericCommand(@Validator Player player) { + public void genericCommand(Player player) { + if(!Permission.OWNER.hasPermission(player)) return; + Bukkit.getOnlinePlayers().forEach(p -> { if (!bauServer.getOwner().equals(p.getUniqueId())) p.kickPlayer(""); }); } - - @ClassValidator(value = Player.class, local = true) - public TypeValidator validator() { - return (commandSender, player, messageSender) -> { - return !messageSender.send(!bauServer.getOwner().equals(player.getUniqueId()), "KICKALL_NO_PERM"); - }; - } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/RamUsage.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/RamUsage.java deleted file mode 100644 index 1d187444..00000000 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/RamUsage.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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 . - */ - -package de.steamwar.bausystem.features.world; - -import lombok.experimental.UtilityClass; - -import java.io.*; -import java.util.concurrent.locks.LockSupport; - -@UtilityClass -public class RamUsage { - - private File meminfo = new File("/proc/meminfo"); - private File stat = new File("/proc/stat"); - - private double usageSelf = 0D; - private double usage = 0D; - private double load = 0D; - - public static void init() { - } - - static { - Thread thread = new Thread(() -> { - while (true) { - long maxMemory = Runtime.getRuntime().maxMemory(); - long totalMemory = Runtime.getRuntime().totalMemory(); - long freeMemory = Runtime.getRuntime().freeMemory(); - long usedMemory = totalMemory - freeMemory; - usageSelf = usedMemory / (double) totalMemory; - double usageSelfByMax = usedMemory / (double) maxMemory; - // System.out.println("Self: " + usageSelf + "/" + usageSelfByMax + /* " " + maxMemory + " " + totalMemory + " " + freeMemory + " " + usedMemory + */ " Ram: " + usage + " CPU: " + load); - - usage = _getUsage(); - load = _getLoad(); - Thread.yield(); - LockSupport.parkNanos(1000000000L); - } - }); - thread.setDaemon(true); - thread.setName("RamUsage"); - thread.start(); - } - - public static double getUsage() { - return usage; - } - - private static double _getUsage() { - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(meminfo)))) { - String memTotal = bufferedReader.readLine().replaceAll(" +", " "); - bufferedReader.readLine(); - String memAvailable = bufferedReader.readLine().replaceAll(" +", " "); - - long memTotalLong = getNumber(memTotal); - long memAvailableLong = getNumber(memAvailable); - return (memTotalLong - memAvailableLong) / (double) memTotalLong; - } catch (IOException e) { - return 1D; - } - } - - public static double getLoad() { - return load; - } - - private long lastCpuSecond = -1; - private long lastCpuForth = -1; - private long lastCpuFifth = -1; - - private static double _getLoad() { - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(stat)))) { - String[] strings = bufferedReader.readLine().split(" "); - - long cpuSecond = Long.parseLong(strings[2]); - long cpuForth = Long.parseLong(strings[4]); - long cpuFifth = Long.parseLong(strings[5]); - - if (lastCpuSecond == -1) { - lastCpuSecond = cpuSecond; - lastCpuForth = cpuForth; - lastCpuFifth = cpuFifth; - return 0D; - } - - long cpuSecondDiff = cpuSecond - lastCpuSecond; - long cpuForthDiff = cpuForth - lastCpuForth; - long cpuSixthDiff = cpuFifth - lastCpuFifth; - - lastCpuSecond = cpuSecond; - lastCpuForth = cpuForth; - lastCpuFifth = cpuFifth; - - return (cpuSecondDiff + cpuForthDiff) / (double) (cpuSecondDiff + cpuForthDiff + cpuSixthDiff); - } catch (IOException e) { - return 1D; - } - } - - private static long getNumber(String s) { - return Long.parseLong(s.split(" ")[1]); - } -} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.java index 7956a3ef..1ccfb014 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditFrom20.java @@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.world; import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.bausystem.utils.PlaceItemUtils; import de.steamwar.linkage.Linked; import de.steamwar.linkage.MinVersion; @@ -81,6 +82,7 @@ public class SignEditFrom20 implements Listener { } private void edit(Player player, Block block) { + if (!Permission.BUILD.hasPermission(player)) return; Sign sign = (Sign) block.getState(); Side side = signSide(player, block); SignSide signSide = sign.getSide(side); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java index 19184032..7aebd4e9 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SignEditUntil19.java @@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.world; import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; import de.steamwar.linkage.Linked; import de.steamwar.linkage.MaxVersion; import org.bukkit.Bukkit; @@ -68,6 +69,7 @@ public class SignEditUntil19 implements Listener { } private void edit(Player player, Block block) { + if (!Permission.BUILD.hasPermission(player)) return; Sign sign = (org.bukkit.block.Sign) block.getState(); String[] lines = sign.getLines(); for (int i = 0; i < lines.length; i++) { diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java new file mode 100644 index 00000000..5563f7a6 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/SpectatorListener.java @@ -0,0 +1,254 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.world; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.Permission; +import de.steamwar.bausystem.config.BauServer; +import de.steamwar.bausystem.utils.BauMemberUpdateEvent; +import de.steamwar.inventory.SWItem; +import de.steamwar.linkage.Linked; +import de.steamwar.sql.BauweltMember; +import de.steamwar.techhider.TechHider; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockCanBuildEvent; +import org.bukkit.event.block.BlockMultiPlaceEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.player.*; + +import java.util.HashSet; +import java.util.Set; + +@Linked +public class SpectatorListener implements Listener { + + private static final Set NO_TECHHIDER = new HashSet<>(); + + static { + Set materials = new HashSet<>(); + materials.add(Material.REDSTONE_WIRE); + materials.add(Material.REDSTONE_TORCH); + materials.add(Material.REDSTONE_BLOCK); + materials.add(Material.REPEATER); + materials.add(Material.COMPARATOR); + materials.add(Material.LEVER); + for (Material value : Material.values()) { + if (value.name().endsWith("_BUTTON")) { + materials.add(value); + } + if (value.name().endsWith("_PRESSURE_PLATE")) { + materials.add(value); + } + if (value.name().endsWith("_SIGN")) { + materials.add(value); + } + } + materials.add(SWItem.getMaterial("SCULK_SENSOR")); + materials.add(SWItem.getMaterial("CALIBRATED_SCULK_SENSOR")); + materials.add(SWItem.getMaterial("SCULK_SHRIEKER")); + materials.add(SWItem.getMaterial("AMETHYST_BLOCK")); + materials.add(SWItem.getMaterial("AMETHYST_CLUSTER")); + materials.add(SWItem.getMaterial("SMALL_AMETHYST_BUG")); + materials.add(SWItem.getMaterial("MEDIUM_AMETHYST_BUG")); + materials.add(SWItem.getMaterial("LARGE_AMETHYST_BUG")); + materials.add(Material.TRIPWIRE_HOOK); + materials.add(Material.TRIPWIRE); + materials.add(Material.DAYLIGHT_DETECTOR); + materials.add(SWItem.getMaterial("LIGHTNING_ROD")); + materials.add(Material.PISTON); + materials.add(Material.PISTON_HEAD); + materials.add(Material.MOVING_PISTON); + materials.add(Material.STICKY_PISTON); + materials.add(Material.SLIME_BLOCK); + materials.add(Material.HONEY_BLOCK); + materials.add(Material.OBSERVER); + materials.add(Material.RAIL); + materials.add(Material.POWERED_RAIL); + materials.add(Material.DETECTOR_RAIL); + materials.add(Material.ACTIVATOR_RAIL); + materials.add(Material.TNT); + materials.add(Material.REDSTONE_ORE); + materials.add(SWItem.getMaterial("SCAFFOLDING")); + materials.add(Material.WATER); + materials.remove(Material.BARRIER); + materials.remove(Material.STONE); + TechHider techHider = new TechHider((TechHider.LocationEvaluator) (player, i, i1) -> { + return Permission.BUILD.hasPermission(player) || Permission.isTempOnlySpectator(player) || NO_TECHHIDER.contains(player); + }, Material.END_STONE, materials, new HashSet<>()); + techHider.enable(); + } + + public static void toggleNoTechHider(Player player) { + if (NO_TECHHIDER.contains(player)) { + NO_TECHHIDER.remove(player); + } else { + NO_TECHHIDER.add(player); + } + resendChunks(player); + } + + private static void resendChunks(Player player) { + Location location = player.getLocation().clone(); + player.teleport(location.clone().add(16.0 * player.getClientViewDistance(), 0, 16.0 * player.getClientViewDistance())); + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + player.teleport(location); + }, 5); + } + + private boolean anySupervisorOnline(Player player) { + return Bukkit.getOnlinePlayers().stream().filter(p -> p != player).anyMatch(Permission.SUPERVISOR::hasPermission); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (event.getPlayer().getUniqueId().equals(BauServer.getInstance().getOwner())) { + return; + } + BauweltMember bauweltMember = BauweltMember.getBauMember(BauServer.getInstance().getOwner(), event.getPlayer().getUniqueId()); + if (bauweltMember == null) { + event.getPlayer().kickPlayer(""); + return; + } + if (Permission.SUPERVISOR.hasPermission(event.getPlayer())) { + return; + } + if (!anySupervisorOnline(null)) { + Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { + event.getPlayer().kickPlayer(""); + }, 1); + } + } + + @EventHandler + public void onBauMemberUpdate(BauMemberUpdateEvent event) { + if (!anySupervisorOnline(null)) { + Bukkit.getOnlinePlayers().forEach(player -> { + player.kickPlayer(""); + }); + return; + } + + event.getChanged().forEach(player -> { + NO_TECHHIDER.remove(player); + if (Permission.isTempOnlySpectator(player)) return; + resendChunks(player); + }); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + NO_TECHHIDER.remove(event.getPlayer()); + if (!anySupervisorOnline(event.getPlayer())) { + Bukkit.getOnlinePlayers().forEach(player -> { + player.kickPlayer(""); + }); + } + } + + @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 (!Permission.SUPERVISOR.hasPermission(event.getPlayer())) { + event.setCancelled(true); + event.setMessage("/"); + } + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockMultiPlace(BlockMultiPlaceEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockCanBuild(BlockCanBuildEvent event) { + if (event.getPlayer() == null) return; + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setBuildable(false); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerBucketEntity(PlayerBucketEntityEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerBucketFill(PlayerBucketFillEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onPlayerDropItem(PlayerDropItemEvent event) { + if (!Permission.BUILD.hasPermission(event.getPlayer())) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEntityPickupItem(EntityPickupItemEvent event) { + if (!(event.getEntity() instanceof Player)) return; + if (!Permission.BUILD.hasPermission((Player) event.getEntity())) { + event.setCancelled(true); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/StopCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/StopCommand.java index 4017e548..68f618db 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/StopCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/StopCommand.java @@ -51,14 +51,14 @@ public class StopCommand extends SWCommand { return true; } Player player = (Player) sender; - if (Permission.hasPermission(player, Permission.WORLD)) { + if (Permission.SUPERVISOR.hasPermission(player)) { return true; } SteamwarUser user = SteamwarUser.get(player.getUniqueId()); if (user.hasPerm(UserPerm.ADMINISTRATION)) { return true; } - messageSender.send("STOP_NO_PERMS"); + messageSender.send("NO_PERMISSION"); return false; }; } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java index 19dc6e09..a377db87 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java @@ -40,8 +40,8 @@ public class WorldEditListener implements Listener { if (!isWorldEditCommand(e.getMessage().split(" ")[0])) return; Player p = e.getPlayer(); - if (!Permission.hasPermission(p, Permission.WORLDEDIT)) { - BauSystem.MESSAGE.send("WORLD_EDIT_NO_PERMS", p); + if (!Permission.BUILD.hasPermission(e.getPlayer())) { + BauSystem.MESSAGE.send("NO_PERMISSION", p); e.setCancelled(true); e.setMessage("/"); } @@ -51,7 +51,12 @@ public class WorldEditListener implements Listener { commands.add(s); } + public static void addCommandExclusion(String s) { + commandExclusions.add(s); + } + private static final Set commands = new HashSet<>(); + private static final Set commandExclusions = new HashSet<>(); private static final String[] shortcutCommands = {"//1", "//2", "//90", "//-90", "//180", "//p", "//c", "//flopy", "//floppy", "//flopyp", "//floppyp", "//u", "//r"}; public static boolean isWorldEditCommand(String command) { @@ -61,6 +66,9 @@ public class WorldEditListener implements Listener { for (String s : commands) { if (command.startsWith(s)) return true; } + for (String s : commandExclusions) { + if (command.startsWith(s)) return false; + } return FlatteningWrapper.impl.isWorldEditCommand(command); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java index 010498a8..6b6659ba 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java @@ -63,7 +63,7 @@ public class ColorReplaceCommand extends SWCommand { @Register(description = "COLORREPLACE_HELP") @SneakyThrows - public void genericCommand(Player player, Pair from, Color to) { + public void genericCommand(@Validator Player player, Pair from, Color to) { if (from.getValue() == to) { BukkitAdapter.adapt(player).printInfo(TranslatableComponent.of("worldedit.replace.replaced", new Component[]{TextComponent.of(0)})); return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java index 0cc939d6..8013c92b 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java @@ -67,7 +67,7 @@ public class TypeReplaceCommand extends SWCommand { @Register(description = "TYPEREPLACE_HELP") @SneakyThrows - public void genericCommand(Player player, Pair from, Type to) { + public void genericCommand(@Validator Player player, Pair from, Type to) { if (from.getValue() == to) { BukkitAdapter.adapt(player).printInfo(TranslatableComponent.of("worldedit.replace.replaced", new Component[]{TextComponent.of(0)})); return; diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java index ef30fbcd..59e88ec5 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/xray/XrayCommand.java @@ -62,7 +62,7 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen public TechHiderCommand techHiderCommand; @Register(description = "XRAY_HELP") - public void toggleHider(Player player) { + public void toggleHider(@Validator Player player) { Region region = Region.getRegion(player.getLocation()); if (region.isGlobal()) { BauSystem.MESSAGE.send("XRAY_GLOBAL", player); @@ -148,7 +148,7 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen } private TechHider createXray(Region rg, Set obfuscate) { - TechHider current = new TechHider((p, cX, cY) -> { + TechHider current = new TechHider((TechHider.LocationEvaluator) (p, cX, cY) -> { if (rg.buildChunkOutside(cX, cY)) return true; return !hidden.get(rg).contains(p); }, Material.STRUCTURE_VOID, obfuscate, new HashSet<>()); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/BauMemberUpdateEvent.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/BauMemberUpdateEvent.java new file mode 100644 index 00000000..77f2ba3e --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/BauMemberUpdateEvent.java @@ -0,0 +1,60 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.utils; + +import lombok.Getter; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class BauMemberUpdateEvent extends Event { + + @Getter + private final Set changed; + + @Getter + private final Set newSpectator; + + @Getter + private final Set newBuilder; + + public BauMemberUpdateEvent(Set newSpectator, Set newBuilder) { + this.newSpectator = Collections.unmodifiableSet(newSpectator); + this.newBuilder = Collections.unmodifiableSet(newBuilder); + Set changed = new HashSet<>(); + changed.addAll(newSpectator); + changed.addAll(newBuilder); + this.changed = Collections.unmodifiableSet(changed); + } + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/TickEndEvent.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/TickEndEvent.java new file mode 100644 index 00000000..11b90f80 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/TickEndEvent.java @@ -0,0 +1,36 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.utils; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TickEndEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/TickListener.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/TickListener.java new file mode 100644 index 00000000..029a2e5c --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/TickListener.java @@ -0,0 +1,31 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.utils; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.core.VersionDependent; + +public interface TickListener { + + TickListener impl = VersionDependent.getVersionImpl(BauSystem.getInstance()); + + default void init() { + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/TickStartEvent.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/TickStartEvent.java new file mode 100644 index 00000000..1134a832 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/TickStartEvent.java @@ -0,0 +1,36 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.utils; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TickStartEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/SCRIPT.md b/SCRIPT.md index ae9cb181..c9ccb352 100644 --- a/SCRIPT.md +++ b/SCRIPT.md @@ -69,19 +69,34 @@ In den Scripten gibt es dazu noch folgende globale Variablen: - [`server`](#server) - [`storage`](#storage) - [`inventory`](#inventory) +- [`scoreboard`](#scoreboard) - `_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\) | Fragt den User nach einer Eingabe mit der Nachricht und called die zugehörige Funktion nach dieser | -| `delayed` | delayed(Number, Function\) | 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 | +| Name | Signature | Beschreibung | +|-----------|---------------------------------------|-------------------------------------------------------------------------------------------------------------------| +| `print` | print(String...) | @see chat(String...) | +| `input` | input(String, Function\) | Fragt den User nach einer Eingabe mit der Nachricht und called die zugehörige Funktion nach dieser | +| `delayed` | delayed(Number, Function\) | Wartet die angegebene Anzahl an Ticks und führt danach die zugehörige Funktion aus | +| `pos` | pos(Number, Number, Number): Position | 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 | + +Position besteht aus einer x, y und z Koordinate als auch aus folgenden Methoden: + +| Name | Signature | Beschreibung | +|-----------|------------------------------|--------------------------------------------------------------| +| add | add(Position): Position | Erstellt eine neue Position mit neuen X, Y und Z Koordinaten | +| addX | addX(Number): Position | Erstellt eine neue Position mit neuer X Koordinate | +| addY | addY(Number): Position | Erstellt eine neue Position mit neuer Y Koordinate | +| addZ | addZ(Number): Position | Erstellt eine neue Position mit neuer Z Koordinate | +| subtract | subtract(Position): Position | Erstellt eine neue Position mit neuen X, Y und Z Koordinaten | +| subtractX | subtractX(Number): Position | Erstellt eine neue Position mit neuer X Koordinate | +| subtractY | subtractY(Number): Position | Erstellt eine neue Position mit neuer Y Koordinate | +| subtractZ | subtractZ(Number): Position | Erstellt eine neue Position mit neuer Z Koordinate | +| blockPos | blockPos(): Position | Erstellt eine neue Position mit Block-Koordinaten | ### player Das `player`-Modul stellt Funktionen zur Verfügung, die den Spieler betreffen. @@ -92,6 +107,8 @@ Es gibt folgende Funktionen: | `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 | +| `pos` | pos() | Position of Player | +| `blockPos` | blockPos() | Block Position of Player | | `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 | @@ -167,12 +184,14 @@ Es gibt folgende Funktionen: 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`) | +| 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 | +| `onlinePlayerCount` | onlinePlayerCount(): Number | Gibt die Anzal der Spieler auf dem Server 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`) | +| `interactAt` | interactAt(Pos) | Interagiere mit einem Block in der Welt, als wenn dieser durch den Spieler gerechtsklicked wurde | Es gibt folgende weitere Module: @@ -255,6 +274,34 @@ Wenn eine Barrier statt des richtigen Items angezeigt wird, dann ist das angegeb ⚠️⚠️⚠️ ``` +## scoreboard +Das `scoreboard`-Modul stellt Funktionen zur Verfügung, um Zeilen im Scoreboard hinzuzufügen. +Es gibt folgende Funktionen: + +| Name | Signature | Beschreibung | +|-----------|----------------------------------------------------|-------------------------------------------------------------------------------------------| +| `group` | | Siehe: [Scoreboardgroups](#scoreboardgroups) | +| `element` | element(String, Group): ScoreboardElement | Erstellt ein ScoreboardElement, welche man nachfolgend befüllen kann | +| `element` | element(String, Group, Integer): ScoreboardElement | Erstellt ein ScoreboardElement, welche man nachfolgend befüllen kann mit einer Sortierung | + +Ein ScoreboardElement ist ein Objekt, womit du direkt auf einen Wert zugreifen kannst und es ändern kannst. +Es geht wie folgt: +```lua +key = scoreboard.element("key", scoreboard.group.OTHER) + +key("Hello World") -- Setzt im Bereich Other den Text "Hello World" unter allem anderen +key() -- Removed im Bereich Other den vorherigen Text "Hello World" +``` + +## Scoreboardgroups + +| Name | +|----------| +| `Header` | +| `Region` | +| `Other` | +| `Footer` | + # 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. @@ -333,6 +380,7 @@ Wenn `hasBlock` wahr ist, gibt es folgende Variablen: | `blockY` | Die Y-Koordinate des Blocks | | `blockZ` | Die Z-Koordinate des Blocks | | `blockFace` | Die Seite des Blocks die geklickt wurde | +| `blockType` | Das Material des Blocks | ### Position diff --git a/build.gradle b/build.gradle index 48c8df51..5b8a3f12 100644 --- a/build.gradle +++ b/build.gradle @@ -37,8 +37,8 @@ version '' compileJava.options.encoding = 'UTF-8' compileJava.options.compilerArgs << '-parameter' -sourceCompatibility = 11 -targetCompatibility = 11 +sourceCompatibility = 17 +targetCompatibility = 17 mainClassName = '' @@ -61,6 +61,10 @@ allprojects { maven { url = uri('https://libraries.minecraft.net') } + + maven { + url = uri("https://repo.papermc.io/repository/maven-public/") + } } } diff --git a/sw.def.lua b/sw.def.lua index d56a134e..2c5dbab8 100644 --- a/sw.def.lua +++ b/sw.def.lua @@ -18,9 +18,35 @@ --- --- 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 +--- Created by Chaoscaot and YoyoNow --- +scoreboard = {} + +---@param key string +---@param group ScoreboardGroup +---@return ScoreboardElement +function scoreboard.element(key, group) return nil end + +---@param key string +---@param group ScoreboardGroup +---@param order number +---@return ScoreboardElement +function scoreboard.element(key, group, order) return nil end + +---@class ScoreboardElement +---@overload fun(): void +---@overload fun(value: string): void + +---@class ScoreboardGroup +---@class group +---@field HEADER ScoreboardGroup +---@field REGION ScoreboardGroup +---@field OTHER ScoreboardGroup +---@field FOOTER ScoreboardGroup +local group = {} +scoreboard.group = group + inventory = {} ---@param title string @@ -66,6 +92,12 @@ function player.chat(...) end ---Send a message to the actionbar of the player. function player.actionbar(...) end +---@return Position +function player.pos() end + +---@return Position +function player.blockPos() end + ---@overload fun(): number ---@param newX number function player.x(newX) end @@ -153,6 +185,36 @@ 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 @@ -192,11 +254,6 @@ function region.get(name) return nil end ---@return iregion[] function region.list() return nil end ----@class Position ----@field x number ----@field y number ----@field z number - ---@class server ---@field tps tps server = {} @@ -207,14 +264,21 @@ function server.time() return nil end ---@return number function server.ticks() return nil end +---@return number +function server.onlinePlayerCount() return nil end + ---@param position Position ---@return string -function getBlockAt(position) return nil end +function server.getBlockAt(position) return nil end ---@param position Position ---@param material string ---@return void -function setBlockAt(position, material) return nil end +function server.setBlockAt(position, material) return nil end + +---@param position Position +---@return void +function server.interactAt(position) return nil end ---@class tps local tps = {} @@ -247,6 +311,7 @@ function tps.limit() return nil end storage = {} ---@class storageLib +---Any Primitive, Array or Table will be saved across restarts, everything else will be discarded local storageLib = {} ---@param key string @@ -301,6 +366,47 @@ function delayed(ticks, callback) end ---@return Position function pos(x, y, z) return nil end +---@class Position +---@field x number +---@field y number +---@field z number +local position = {} + +---@param pos Position +---@return Position +function position.add(pos) return nil end + +---@param pos Position +---@return Position +function position.subtract(pos) return nil end + +---@param x number +---@return Position +function position.addX(x) return nil end + +---@param y number +---@return Position +function position.addY(y) return nil end + +---@param z number +---@return Position +function position.addZ(z) return nil end + +---@param x number +---@return Position +function position.subtractX(x) return nil end + +---@param y number +---@return Position +function position.subtractY(y) return nil end + +---@param z number +---@return Position +function position.subtractZ(z) return nil end + +---@return Position +function position.blockPos() return nil end + ---@return void function exec(...) end