diff --git a/BauSystem_15/src/de/steamwar/bausystem/features/slaves/MaterialUtils_15.java b/BauSystem_15/src/de/steamwar/bausystem/features/slaves/MaterialUtils_15.java
new file mode 100644
index 00000000..d8a0df55
--- /dev/null
+++ b/BauSystem_15/src/de/steamwar/bausystem/features/slaves/MaterialUtils_15.java
@@ -0,0 +1,53 @@
+/*
+ * 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.slaves;
+
+import lombok.experimental.UtilityClass;
+import net.minecraft.server.v1_15_R1.WorldGenVines;
+import org.bukkit.Material;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+@UtilityClass
+public class MaterialUtils_15 {
+
+ private static Set unpushable = new HashSet<>(Arrays.asList(Material.BARRIER, Material.BEACON, Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK, Material.ENCHANTING_TABLE, Material.END_GATEWAY, Material.END_PORTAL, Material.ENDER_CHEST, Material.GRINDSTONE, Material.JIGSAW, Material.JUKEBOX, Material.NETHER_PORTAL, Material.OBSIDIAN, Material.STRUCTURE_VOID, Material.BARREL, Material.BEEHIVE, Material.BEE_NEST, Material.BLAST_FURNACE, Material.BREWING_STAND, Material.CHEST, Material.DAYLIGHT_DETECTOR, Material.DISPENSER, Material.DROPPER, Material.FURNACE, Material.HOPPER, Material.LECTERN, Material.SMOKER, Material.TRAPPED_CHEST));
+
+ // TODO: FLOWER
+ private static Set breaking = new HashSet<>(Arrays.asList(Material.BAMBOO, Material.CACTUS, Material.CAKE, Material.CARVED_PUMPKIN, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.COBWEB, Material.COCOA, Material.DRAGON_EGG, Material.FIRE, Material.FLOWER_POT, Material.JACK_O_LANTERN, Material.LADDER, Material.LAVA, Material.LAVA, Material.LEVER, Material.LILY_PAD, Material.MELON, Material.NETHER_WART, Material.PUMPKIN, Material.COMPARATOR, Material.REDSTONE_WIRE, Material.REPEATER, Material.TORCH, Material.STRUCTURE_VOID, Material.SCAFFOLDING, Material.SEA_PICKLE, Material.SNOW, Material.SUGAR_CANE, Material.TORCH, Material.TRIPWIRE, Material.TRIPWIRE_HOOK, Material.TURTLE_EGG, Material.VINE, Material.WATER, Material.WHEAT));
+
+ static boolean isUnpusheable(Material material) {
+ if (unpushable.contains(material)) {
+ return true;
+ }
+ String name = material.name();
+ return name.contains("BANNER") || name.contains("SIGN");
+ }
+
+ static boolean isBreakingOnPush(Material material) {
+ if (breaking.contains(material)) {
+ return true;
+ }
+ String name = material.name();
+ return name.contains("BED") || name.contains("BUTTON") || name.contains("CARPET") || (name.contains("DOOR") && !name.contains("TRAPDOOR")) || name.contains("HEAD") || name.contains("LEAVES") || name.contains("MUSHROOM") || name.contains("PRESSURE_PLATE") || name.contains("SHULKER_BOX");
+ }
+}
diff --git a/BauSystem_Main/build.gradle b/BauSystem_Main/build.gradle
index 9629d086..32d7760b 100644
--- a/BauSystem_Main/build.gradle
+++ b/BauSystem_Main/build.gradle
@@ -61,6 +61,5 @@ dependencies {
compileOnly files("${projectDir}/../lib/Spigot-1.15.jar")
compileOnly files("${projectDir}/../lib/WorldEdit-1.15.jar")
- compileOnly files("${projectDir}/../lib/ProtocolLib.jar")
compileOnly files("${projectDir}/../lib/SpigotCore.jar")
}
diff --git a/BauSystem_Main/src/BauSystem.properties b/BauSystem_Main/src/BauSystem.properties
index 31feca0d..4458cbf0 100644
--- a/BauSystem_Main/src/BauSystem.properties
+++ b/BauSystem_Main/src/BauSystem.properties
@@ -38,7 +38,6 @@ SCOREBOARD_LOADER = Loader
SCOREBOARD_TPS = TPS
SCOREBOARD_TRACE_TICKS = Ticks
-SCOREBOARD_TRACE_TNT-COUNT = Anzahl TNT
# Flags
FLAG_COLOR = Color
@@ -96,7 +95,7 @@ AUTOSTART_MESSAGE_NO-REGION = §cDu befindest dich derzeit in keiner Region
AUTOSTART_MESSAGE_RESET = §eDer AutostartTimer wurde zurückgesetzt
AUTOSTART_MESSAGE_START = §eAutostartTimer gestartet
AUTOSTART_MESSAGE_RESULT1 = §eZeit §7bis zur §eExplosion §7am Gegner§8:§e {0}
-AUTOSTART_MESSAGE_RESULT2 = §eZeitdifferenz in ticks §7bis 60 Sekunden§8:§e {0}
+AUTOSTART_MESSAGE_RESULT2 = §eZeitdifferenz in ticks §7bis {0} Sekunden§8:§e {1}
AUTOSTART_MESSAGE_RESULT3 = §7Positiv, wenn zu wenig, negativ wenn zu viel
# Backup
@@ -171,8 +170,8 @@ DETONATOR_AUTOSTART_ENABLE=§7Autostart beim detonate §aangeschaltet
DETONATOR_AUTOSTART_DISABLE=§7Autostart beim detonate §causgeschaltet
DETONATOR_POINT_ACT=§eEinen Punkt ausgelöst
DETONATOR_POINTS_ACT=§e{0} Punkte ausgelöst
-DETONATOR_INVALID_POINT=§cEin Punkt konnte nicht ausgeführt werden und wurde entfernt
-DETONATOR_INVALID_POINTS=§c{0} Punkte konnten nicht ausgeführt werden und wurden entfernt
+DETONATOR_INVALID_POINT=§cEin Punkt konnte nicht ausgeführt werden
+DETONATOR_INVALID_POINTS=§c{0} Punkte konnten nicht ausgeführt werden
DETONATOR_INVALID_BLOCK=§eDer Block konnte nicht hinzugefügt werden
# Hotbar
HOTBAR_SAVED=§7Deine Hotbar wurde als Standard gespeichert
@@ -199,6 +198,13 @@ GUI_EDITOR_ITEM_TRASH=§cTrashcan
GUI_EDITOR_ITEM_TRASH_LORE=§7Item hier rein Legen
GUI_EDITOR_ITEM_MORE=§eMehr Items
GUI_EDITOR_TITLE_MORE=Item auswählen
+
+# SmartPlace
+SMART_PLACE_HELP = §8/§esmartplace §8-§7 Toggled SmartPlace
+SMART_PLACE_INFO = §7Plaziert rotierbare Blöcke beim §esneaken§7 von dir §eweg§7.
+SMART_PLACE_ENABLE = §aSmartPlace aktiviert
+SMART_PLACE_DISABLE = §cSmartPlace deaktiviert
+
# Trace
TRACE_RECORD=§aan
TRACE_RECORD-AUTO=§aan
@@ -245,6 +251,18 @@ TRACE_SHOW_GUI_INTERPOLATE-XZ_ITEM = §eInterpolation §7XZ-Achse
TRACE_SHOW_GUI_INTERPOLATE-XZ_LORE1 = §7Zeigt die Interpolation
TRACE_SHOW_GUI_INTERPOLATE-XZ_LORE2 = §7auf der XZ-Achse.
+TRACE_GUI_TITLE = Trace GUI
+TRACE_GUI_ITEM_BACK = §eBack
+TRACE_GUI_ITEM = §eTrace §8- §e{0} §7TNT
+TRACE_GUI_CLEAR = §eTraces löschen
+TRACE_GUI_RECORD_ITEM = §eTNT §8- §e{0} §7Positionen
+TRACE_GUI_RECORD_CLEAR = §eTNT löschen
+TRACE_GUI_POSITION_ITEM = §ePosition
+TRACE_GUI_POSITION_X = §7X§8: §e{0}
+TRACE_GUI_POSITION_Y = §7Y§8: §e{0}
+TRACE_GUI_POSITION_Z = §7Z§8: §e{0}
+TRACE_GUI_POSITION_EXPLODED = §7Explodiert§8: §e{0}
+
# Loader
LOADER_OFF = §caus
LOADER_SETUP = §eSetup
@@ -365,9 +383,12 @@ OTHER_TELEPORT_SELF_4=§cFür eine solche Distanz?
OTHER_TIME_HELP_1=§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_WORLDSPAWN_HELP_1=§8/§eworldspawn §8-§e Teleportiere dich zum Spawn
# DebugStick
DEBUG-STICK_COMMAND_HELP=§8/§edebugstick §8-§7 Erhalte einen DebugStick
+# StructureVoid
+STRUCTURE-VOID_COMMAND_HELP=§8/§estructureVoid §8-§7 Erhalte ein StructureVoid
# NightVision
NIGHT-VISION_COMMAND_HELP=§8/§enightvision §8-§7 Schalte Nightvision an oder aus.
NIGHT-VISION_OFF=§eNightvision deaktiviert
@@ -383,12 +404,15 @@ MATERIAL_SEARCH_GRAVITY=§eFallend
MATERIAL_SEARCH_OCCLUDING=§eOccluding
MATERIAL_SEARCH_INTERACTEABLE=§eInterargierbar
MATERIAL_SEARCH_FLAMMABLE=§eFlammbar
+MATERIAL_SEARCH_BURNABLE=§eBrennbar
+MATERIAL_SEARCH_WATERLOGGABLE=§eWasserspeicherbar
MATERIAL_SEARCH_BLASTRESISTANCE=§eBlast Resistance
MATERIAL_SEARCH_BLASTRESISTANCE_MIN=§eBlast Resistance mindestens
MATERIAL_SEARCH_BLASTRESISTANCE_MAX=§eBlast Resistance maximal
MATERIAL_SEARCH_BLASTRESISTANCE_EXACT=§eBlast Resistance
MATERIAL_SEARCH_VALUE=§8: §e{0}
MATERIAL_BLAST-RESISTANCE=§8- §eBlast Resistance§8: §7{0}
+MATERIAL_HARDNESS=§8- §eHärte§8: §7{0}
MATERIAL_TNT_BREAKABLE=§8- §eZerstörbar durch TNT
MATERIAL_TNT_UNBREAKABLE=§8- §eNicht Zerstörbar durch TNT
MATERIAL_TRANSPARENT=§8- §eTransparenter Block
@@ -397,6 +421,8 @@ MATERIAL_GRAVITY=§8- §eFallender Block
MATERIAL_OCCLUDING=§8- §eOccluding Block
MATERIAL_INTERACT-ABLE=§8- §eInterargierbarer Block
MATERIAL_FLAMMABLE=§8- §eFlammbarer Block
+MATERIAL_BURNABLE=§8- §eBrennbarer Block
+MATERIAL_WATERLOGGABLE=§8- §eWasserspeicherbarer Block
# Redstonetester
RT_HELP_1=§8/§eredstonetester §8-§7 Gibt den RedstoneTester
RT_GIVEN=§7Messe die Zeit zwischen der Aktivierung zweier Redstone Komponenten
@@ -457,6 +483,7 @@ REGION_REGION_HELP_4=§8/§eregion §8[§7RegionsTyp§8] §8- §7Wähle einen Re
REGION_REGION_HELP_5=§8/§eregion §8[§7RegionsTyp§8] §8[§7Extension§8] §8- §7Wähle einen RegionsTyp aus mit oder ohne Extension
REGION_REGION_HELP_6=§8/§eregion color §8[§7Color§8] §8- §7Ändere die Regions Farbe
REGION_REGION_HELP_7=§8/§eregion copypoint §8- §7Teleportiere dich zum Regions Kopierpunkt
+REGION_REGION_HELP_8=§8/§eregion testblockpoint §8- §7Teleportiere dich zum Regions Testblockpunkt
REGION_REGION_NOTHING_UNDO=§cNichts zum rückgängig machen
REGION_REGION_UNDID=§7Letzte Aktion rückgangig gemacht
REGION_REGION_NOTHING_REDO=§cNichts zum wiederhohlen
@@ -468,6 +495,8 @@ REGION_REGION_COLORED_FAILED=§7Nutze §e/rg restore§7 um manuell die Farbe zu
REGION_REGION_FAILED_COLORED=§cFehler beim umfärben der Region
REGION_REGION_NO_SCHEM=§cSchematic nicht gefunden
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}
@@ -505,6 +534,18 @@ LOCK_SCHEM_LOCKED=§e{0} §7von §e{1} §7wurde von §e{2} §7auf §eNORMAL §7z
LOCK_SCHEM_HELP=§8/§eschemlock §8[§7Owner§8] [§7Schematic§8] [§7Grund§8] - §7Sperre eine Schematic
AFK_KICK_MESSAGE=§cAuf diesem Server ist seit 5 Minuten nichts passiert.
AFK_WARNING_MESSAGE=§cDieser Server wird bei weiterer Inaktivität in einer Minute gestoppt
+
+# Panzern
+PANZERN_HELP = §8/§epanzern §8[§7Block§8] §8[§7Slab§8] §8- §7Panzer deine WorldEdit Auswahl
+PANZERN_PREPARE1 = §71. Gucke nochmal nach, ob Läufe auch bis zur Panzergrenze führen.
+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
+
# Warp
WARP_EXISTS=§7Der Warp mit dem namen §e{0} §7existiert bereits
WARP_NAME_RESERVED=§7Du kannst nicht §c{0} §7als name für einen Warp nutzen
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
index 291d9aa6..3cbd13e5 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/BauSystem.java
@@ -19,12 +19,14 @@
package de.steamwar.bausystem;
+import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.config.ColorConfig;
import de.steamwar.bausystem.configplayer.Config;
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.ProtocolAPI;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.message.Message;
import de.steamwar.scoreboard.SWScoreboard;
@@ -87,6 +89,7 @@ public class BauSystem extends JavaPlugin implements Listener {
WorldData.write();
Config.getInstance().saveAll();
+ ProtocolAPI.tinyProtocol.close();
}
private void fixLogging() {
@@ -114,6 +117,7 @@ public class BauSystem extends JavaPlugin implements Listener {
int number = -1;
try {
String string = new File(world.getWorldFolder(), "sections.yml").getCanonicalPath();
+ if (string.endsWith("/sections2.yml")) number = 2;
if (string.endsWith("/sections3.yml")) number = 3;
if (string.endsWith("/sections4.yml")) number = 4;
} catch (IOException e) {
@@ -134,8 +138,8 @@ public class BauSystem extends JavaPlugin implements Listener {
private void createLink(String source, String destination) {
try {
- Bukkit.getLogger().log(Level.INFO, "Executing: ln -s /home/minecraft/backbone/server/Bau15/{0} {1}", new String[]{source, destination});
- ProcessBuilder processBuilder = new ProcessBuilder("ln", "-s", "/home/minecraft/backbone/server/Bau15/" + source, destination);
+ Bukkit.getLogger().log(Level.INFO, "Executing: ln -s /home/minecraft/server/Bau15/{0} {1}", new String[]{source, destination});
+ ProcessBuilder processBuilder = new ProcessBuilder("ln", "-s", "/home/minecraft/server/Bau15/" + source, destination);
processBuilder.directory(world.getWorldFolder());
processBuilder.inheritIO();
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 9f90799c..46c311ba 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java
@@ -104,7 +104,7 @@ public class AutostartListener implements Listener {
if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
long tickDiff = TPSUtils.currentTick.get() - regionStartTime.remove(region);
RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT1", new SimpleDateFormat("mm:ss SSSS").format(new Date(tickDiff * 50)));
- RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT2", (1200 - tickDiff));
+ RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT2", 30, (600 - tickDiff));
RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT3");
});
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java
index 599200c3..35a40af1 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/Detonator.java
@@ -109,7 +109,6 @@ public class Detonator {
SWUtils.sendToActionbar(p, BauSystem.MESSAGE.parse("DETONATOR_POINTS_ACT", p, s));
}
- invalid.forEach(detonator::removeLocation);
if (!invalid.isEmpty()) {
int invalidPoints = invalid.size();
if (invalidPoints == 1) {
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 c699211e..8b6b91da 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/detonator/DetonatorListener.java
@@ -19,17 +19,14 @@
package de.steamwar.bausystem.features.detonator;
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.events.PacketAdapter;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.SWUtils;
import de.steamwar.bausystem.features.detonator.storage.DetonatorStorage;
import de.steamwar.bausystem.features.detonator.storage.ItemStorage;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.bausystem.utils.ProtocolAPI;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -41,7 +38,6 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -49,30 +45,29 @@ import java.util.Set;
@Linked(LinkageType.LISTENER)
public class DetonatorListener implements Listener {
+ public static final Class> useEntity = Reflection.getClass("{nms}.PacketPlayInUseEntity");
+ private static final Reflection.FieldAccessor entityIdFieldAccessor = Reflection.getField(useEntity, int.class, 0);
+
private static final Set HAS_UPDATED = new HashSet<>();
public DetonatorListener() {
- ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(BauSystem.getInstance(), PacketType.Play.Client.USE_ENTITY) {
- @Override
- public void onPacketReceiving(PacketEvent event) {
- List entities = new ArrayList<>(Detonator.getDetoEntities(event.getPlayer()));
- if (entities.isEmpty()) {
- return;
- }
-
- PacketContainer container = event.getPacket();
- int entityId = container.getIntegers().read(0);
- entities.removeIf(abstractDetonatorEntity -> abstractDetonatorEntity.getId() != entityId);
-
- if (entities.isEmpty()) {
- return;
- }
- AbstractDetonatorEntity entity = entities.get(0);
- Location location = entity.getBukkitEntity().getLocation().getBlock().getLocation();
- addLocationToDetonator(location, event.getPlayer());
- HAS_UPDATED.add(event.getPlayer());
- event.setCancelled(true);
+ ProtocolAPI.setIncomingHandler(useEntity, (player, o) -> {
+ List entities = Detonator.getDetoEntities(player);
+ if (entities.isEmpty()) {
+ return o;
}
+
+ int entityId = entityIdFieldAccessor.get(o);
+ AbstractDetonatorEntity entity = entities.stream().filter(abstractDetonatorEntity -> abstractDetonatorEntity.getId() == entityId).findFirst().orElse(null);
+
+ if (entity == null) {
+ return o;
+ }
+
+ Location location = entity.getBukkitEntity().getLocation().getBlock().getLocation();
+ addLocationToDetonator(location, player);
+ HAS_UPDATED.add(player);
+ return null;
});
}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGuiListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGuiListener.java
index 5602f90d..e8c48493 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGuiListener.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/gui/BauGuiListener.java
@@ -19,38 +19,16 @@
package de.steamwar.bausystem.features.gui;
-import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.event.player.PlayerSwapHandItemsEvent;
-
-import java.util.HashSet;
-import java.util.Set;
@Linked(LinkageType.LISTENER)
public class BauGuiListener implements Listener {
- private static final Set LAST_FS = new HashSet<>();
-
- public BauGuiListener() {
- Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), LAST_FS::clear, 20, 20);
- }
-
- @EventHandler
- public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
- if (LAST_FS.contains(event.getPlayer())) {
- BauGUI.openBauGui(event.getPlayer());
- } else {
- LAST_FS.add(event.getPlayer());
- }
- }
-
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getItem() == null) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/other/NoClipCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/other/NoClipCommand.java
index 4d8d5f1f..ae2034b7 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/other/NoClipCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/other/NoClipCommand.java
@@ -19,23 +19,17 @@
package de.steamwar.bausystem.features.other;
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.events.PacketAdapter;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.events.PacketEvent;
-import com.comphenix.protocol.wrappers.EnumWrappers;
-import com.comphenix.protocol.wrappers.PlayerInfoData;
-import com.comphenix.protocol.wrappers.WrappedChatComponent;
-import com.comphenix.protocol.wrappers.WrappedGameProfile;
+import com.comphenix.tinyprotocol.Reflection;
+import com.mojang.authlib.GameProfile;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.bausystem.utils.ProtocolAPI;
import de.steamwar.command.SWCommand;
+import de.steamwar.core.Core;
import de.steamwar.core.VersionedRunnable;
import lombok.Getter;
-import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
@@ -46,42 +40,64 @@ import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
+import java.util.*;
+import java.util.function.BiFunction;
@Linked(LinkageType.COMMAND)
@Linked(LinkageType.LISTENER)
public class NoClipCommand extends SWCommand implements Listener {
+ private static final Class> playerInfoPacket = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo");
+ private static final Reflection.ConstructorInvoker playerInfoConstructor = Reflection.getConstructor(playerInfoPacket);
+ private static final Class> playerInfoActionClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$EnumPlayerInfoAction");
+ private static final Reflection.FieldAccessor> playerInfoAction = Reflection.getField(playerInfoPacket, playerInfoActionClass, 0);
+ private static final Object updateGamemode = playerInfoActionClass.getEnumConstants()[1];
+ private static final Reflection.FieldAccessor playerInfoData = Reflection.getField(playerInfoPacket, List.class, 0);
+ private static final Class> playerInfoDataClass = Reflection.getClass("{nms}.PacketPlayOutPlayerInfo$PlayerInfoData");
+ private static final Class> enumGamemode = Reflection.getClass("{nms}.EnumGamemode");
+ private static final Object spectator = enumGamemode.getEnumConstants()[4];
+ private static final Class> iChatBaseComponent = Reflection.getClass("{nms}.IChatBaseComponent");
+
+ private static final Reflection.ConstructorInvoker playerInfoDataConstructor = Reflection.getConstructor(playerInfoDataClass, playerInfoPacket, GameProfile.class, int.class, enumGamemode, iChatBaseComponent);
+
+ private static final Class> gameStateChange = Reflection.getClass("{nms}.PacketPlayOutGameStateChange");
+ private static final Reflection.FieldAccessor integerFieldAccessor = Reflection.getField(gameStateChange, int.class, 0);
+ private static final Reflection.FieldAccessor floatFieldAccessor = Reflection.getField(gameStateChange, float.class, 0);
+
+ private static final Class> position = Reflection.getClass("{nms}.PacketPlayInFlying$PacketPlayInPosition");
+ private static final Class> positionLook = Reflection.getClass("{nms}.PacketPlayInFlying$PacketPlayInPositionLook");
+ private static final Class> useItem = Reflection.getClass("{nms}.PacketPlayInUseItem");
+ private static final Class> blockDig = Reflection.getClass("{nms}.PacketPlayInBlockDig");
+ private static final Class> windowClick = Reflection.getClass("{nms}.PacketPlayInWindowClick");
+
@Getter
private static final List NOCLIPS = new ArrayList<>();
private static final Map LAST_TICKS = new HashMap<>();
protected NoClipCommand() {
super("noclip", "nc");
- ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(BauSystem.getInstance(), PacketType.Play.Client.POSITION, PacketType.Play.Client.POSITION_LOOK) {
- @Override
- public void onPacketReceiving(PacketEvent event) {
- if (NOCLIPS.contains(event.getPlayer())) {
- if (LAST_TICKS.getOrDefault(event.getPlayer(), -1L).equals(TPSUtils.currentTick.get())) return;
- VersionedRunnable.call(new VersionedRunnable(() -> NoClipCommand_15.setGameModeInternal(event.getPlayer(), GameMode.SPECTATOR), 15));
- LAST_TICKS.put(event.getPlayer(), TPSUtils.currentTick.get());
- }
+
+ BiFunction first = (player, o) -> {
+ if (NOCLIPS.contains(player)) {
+ if (LAST_TICKS.getOrDefault(player, -1L).equals(TPSUtils.currentTick.get())) return o;
+ VersionedRunnable.call(new VersionedRunnable(() -> NoClipCommand_15.setGameModeInternal(player, GameMode.SPECTATOR), 15));
+ LAST_TICKS.put(player, TPSUtils.currentTick.get());
}
- });
- ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(BauSystem.getInstance(), PacketType.Play.Client.USE_ITEM, PacketType.Play.Client.BLOCK_DIG, PacketType.Play.Client.WINDOW_CLICK) {
- @Override
- public void onPacketReceiving(PacketEvent event) {
- if (NOCLIPS.contains(event.getPlayer())) {
- VersionedRunnable.call(new VersionedRunnable(() -> NoClipCommand_15.setGameModeInternal(event.getPlayer(), GameMode.CREATIVE), 15));
- LAST_TICKS.put(event.getPlayer(), TPSUtils.currentTick.get());
- }
+ return o;
+ };
+ ProtocolAPI.setIncomingHandler(position, first);
+ ProtocolAPI.setIncomingHandler(positionLook, first);
+
+ BiFunction second = (player, o) -> {
+ if (NOCLIPS.contains(player)) {
+ VersionedRunnable.call(new VersionedRunnable(() -> NoClipCommand_15.setGameModeInternal(player, GameMode.CREATIVE), 15));
+ LAST_TICKS.put(player, TPSUtils.currentTick.get());
}
- });
+ return o;
+ };
+ ProtocolAPI.setIncomingHandler(useItem, second);
+ ProtocolAPI.setIncomingHandler(blockDig, second);
+ ProtocolAPI.setIncomingHandler(windowClick, second);
}
@Register(help = true)
@@ -93,23 +109,15 @@ public class NoClipCommand extends SWCommand implements Listener {
player.setGameMode(GameMode.SPECTATOR);
((CraftPlayer) player).getHandle().abilities.mayBuild = true;
((CraftPlayer) player).getHandle().abilities.canInstantlyBuild = true;
- PacketContainer gm3packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.PLAYER_INFO);
- gm3packet.getPlayerInfoAction().write(0, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE);
- List playerInfoActions = new ArrayList<>();
- playerInfoActions.add(new PlayerInfoData(WrappedGameProfile.fromPlayer(player), 1, EnumWrappers.NativeGameMode.SPECTATOR, WrappedChatComponent.fromText(player.getDisplayName())));
- gm3packet.getPlayerInfoDataLists().write(0, playerInfoActions);
- PacketContainer gm1packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.GAME_STATE_CHANGE);
- gm1packet.getIntegers().write(0, 3);
- gm1packet.getFloat().write(0, 1F);
+
+ Object gameStateChangeObject = Reflection.newInstance(gameStateChange);
+ integerFieldAccessor.set(gameStateChangeObject, 3);
+ floatFieldAccessor.set(gameStateChangeObject, 1F);
+
NOCLIPS.add(player);
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
- try {
- ProtocolLibrary.getProtocolManager().sendServerPacket(player, gm1packet);
- ProtocolLibrary.getProtocolManager().sendServerPacket(player, gm3packet);
- } catch (InvocationTargetException e) {
- Bukkit.getLogger().log(Level.SEVERE, "Invocation target exception", e);
- player.performCommand("noclip");
- }
+ ProtocolAPI.tinyProtocol.sendPacket(player, gameStateChangeObject);
+ pseudoSpectator(player);
}
}
@@ -145,4 +153,15 @@ public class NoClipCommand extends SWCommand implements Listener {
event.setCancelled(true);
}
}
+
+ private static void pseudoSpectator(Player player) {
+ ProtocolAPI.tinyProtocol.sendPacket(player, playerInfoPacket(updateGamemode, new GameProfile(player.getUniqueId(), player.getName()), spectator));
+ }
+
+ private static Object playerInfoPacket(Object action, GameProfile profile, Object mode) {
+ Object packet = playerInfoConstructor.invoke();
+ playerInfoAction.set(packet, action);
+ playerInfoData.set(packet, Collections.singletonList(playerInfoDataConstructor.invoke(packet, profile, 0, mode, null)));
+ return packet;
+ }
}
\ No newline at end of file
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/other/SlotCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/other/SlotCommand.java
index a741d763..0adb7f86 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/other/SlotCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/other/SlotCommand.java
@@ -40,6 +40,11 @@ public class SlotCommand extends SWCommand {
super("slot", "s");
}
+ @Register(help = true)
+ public void genericHelp(Player p, String... args) {
+ BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", p);
+ }
+
@Register
public void slotCommand(Player player, Integer slot) {
if (slot < 1 || slot > 9) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java
index f08cfc31..a946a9cd 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/other/TimeCommand.java
@@ -23,6 +23,7 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.command.CommandParseException;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
@@ -54,6 +55,7 @@ public class TimeCommand extends SWCommand {
return;
}
Bukkit.getWorlds().get(0).setTime(time.getValue());
+ BauSystem.MESSAGE.send("OTHER_TIME_RESULT", p);
}
@Register
@@ -67,6 +69,7 @@ public class TimeCommand extends SWCommand {
return;
}
Bukkit.getWorlds().get(0).setTime(time);
+ BauSystem.MESSAGE.send("OTHER_TIME_RESULT", p);
}
@ClassMapper(value = int.class, local = true)
@@ -75,7 +78,7 @@ public class TimeCommand extends SWCommand {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
- return 0;
+ return null;
}
}, s -> tabCompletions);
}
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 7126fc32..9e30068c 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/region/RegionCommand.java
@@ -82,6 +82,7 @@ public class RegionCommand extends SWCommand {
BauSystem.MESSAGE.sendPrefixless("REGION_REGION_HELP_5", player);
BauSystem.MESSAGE.sendPrefixless("REGION_REGION_HELP_6", player);
BauSystem.MESSAGE.sendPrefixless("REGION_REGION_HELP_7", player);
+ BauSystem.MESSAGE.sendPrefixless("REGION_REGION_HELP_8", player);
}
@Register("undo")
@@ -170,10 +171,29 @@ public class RegionCommand extends SWCommand {
if (checkGlobalRegion(region, p)) {
return;
}
+ if (region.getCopyPoint() == null) {
+ BauSystem.MESSAGE.send("REGION_REGION_TP_UNKNOWN", p);
+ return;
+ }
p.teleport(region.getCopyPoint().toLocation(p, 0.5, 0, 0.5), PlayerTeleportEvent.TeleportCause.COMMAND);
BauSystem.MESSAGE.send("REGION_REGION_TP_COPY", p);
}
+ @Register("testblockpoint")
+ @Register("tbpoint")
+ public void testBlockPointCommand(Player p) {
+ Region region = Region.getRegion(p.getLocation());
+ if (checkGlobalRegion(region, p)) {
+ return;
+ }
+ if (region.getTestBlockPoint() == null) {
+ BauSystem.MESSAGE.send("REGION_REGION_TP_UNKNOWN", p);
+ return;
+ }
+ p.teleport(region.getTestBlockPoint().toLocation(p, 0.5, 0, 0.5), PlayerTeleportEvent.TeleportCause.COMMAND);
+ BauSystem.MESSAGE.send("REGION_REGION_TP_TEST_BLOCK", p);
+ }
+
@Register("changetype")
@Register("type")
public void changeTypeCommand(Player p) {
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomCommandListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomCommandListener.java
deleted file mode 100644
index 9712ef4d..00000000
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomCommandListener.java
+++ /dev/null
@@ -1,137 +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.script;
-
-import de.steamwar.bausystem.features.script.variables.Value;
-import de.steamwar.bausystem.linkage.LinkageType;
-import de.steamwar.bausystem.linkage.Linked;
-import de.steamwar.core.VersionedCallable;
-import lombok.AccessLevel;
-import lombok.RequiredArgsConstructor;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.inventory.InventoryCloseEvent;
-import org.bukkit.event.player.PlayerCommandPreprocessEvent;
-import org.bukkit.event.player.PlayerJoinEvent;
-import org.bukkit.event.player.PlayerQuitEvent;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.BookMeta;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Linked(LinkageType.LISTENER)
-public class CustomCommandListener implements Listener {
-
- @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
- private static class CustomCommand {
- private final BookMeta bookMeta;
- private final String[] args;
-
- public boolean execute(String[] command, PlayerCommandPreprocessEvent e) {
- if (args.length != command.length) {
- return false;
- }
-
- if (!args[0].equals(command[0])) {
- return false;
- }
-
- Map arguments = new HashMap<>();
- for (int i = 1; i < args.length; i++) {
- String current = args[i];
- if (current.startsWith("<") && current.endsWith(">")) {
- arguments.put(current.substring(1, current.length() - 1), new Value.StringValue(command[i]));
- } else {
- if (!current.equals(command[i])) {
- return false;
- }
- }
- }
- e.setCancelled(true);
- new ScriptExecutor(bookMeta, e.getPlayer(), arguments);
- return true;
- }
- }
-
- private Map> playerMap = new HashMap<>();
-
- private void updateInventory(Player p) {
- playerMap.remove(p);
- for (ItemStack item : p.getInventory().getContents()) {
- if (item == null || isNoBook(item) || item.getItemMeta() == null) {
- continue;
- }
-
- BookMeta bookMeta = ((BookMeta) item.getItemMeta());
- if (bookMeta.getPageCount() == 0) {
- continue;
- }
- if (bookMeta.getPage(1).isEmpty()) {
- continue;
- }
- String s = bookMeta.getPage(1).split("\n")[0];
- if (!s.startsWith("#!CMD /")) {
- continue;
- }
- playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new CustomCommand(bookMeta, s.substring(6).split(" ")));
- }
- }
-
- @EventHandler
- public void onPlayerJoin(PlayerJoinEvent event) {
- updateInventory(event.getPlayer());
- }
-
- @EventHandler
- public void onPlayerQuit(PlayerQuitEvent e) {
- playerMap.remove(e.getPlayer());
- }
-
- @EventHandler
- public void onInventoryClose(InventoryCloseEvent e) {
- if (e.getPlayer() instanceof Player) {
- updateInventory((Player) e.getPlayer());
- }
- }
-
- @EventHandler
- public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent e) {
- if (e.getMessage().startsWith("/script:")) {
- e.setMessage("/" + e.getMessage().substring(8));
- return;
- }
-
- List customCommands = playerMap.get(e.getPlayer());
- if (customCommands == null) {
- return;
- }
-
- String[] command = e.getMessage().split(" ");
- customCommands.stream().map(customCommand -> customCommand.execute(command, e)).filter(b -> !b).findFirst();
- }
-
- private boolean isNoBook(ItemStack item) {
- return VersionedCallable.call(new VersionedCallable<>(() -> ScriptListener_15.isNoBook(item), 15));
- }
-}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScript.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScript.java
new file mode 100644
index 00000000..deb73c3e
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScript.java
@@ -0,0 +1,240 @@
+/*
+ * 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.script;
+
+import de.steamwar.bausystem.features.script.variables.Value;
+import de.steamwar.inventory.SWItem;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.UtilityClass;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.inventory.meta.BookMeta;
+import yapion.hierarchy.types.YAPIONArray;
+import yapion.hierarchy.types.YAPIONMap;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@UtilityClass
+public class CustomScript {
+
+ public interface Script {
+ }
+
+ public interface MenuScript {
+ void toYAPION(YAPIONMap yapionMap);
+ SWItem toItem();
+ }
+
+ public interface CustomEvent extends Script {
+ String eventName();
+ boolean execute(Event e, Player p, Map variables);
+ }
+
+ @RequiredArgsConstructor
+ public static class InventoryEvent implements CustomEvent {
+ public final BookMeta bookMeta;
+ public final String[] args;
+
+ @Override
+ public String eventName() {
+ return args[0];
+ }
+
+ @Override
+ public boolean execute(Event e, Player p, Map variables) {
+ new ScriptExecutor(bookMeta, p, variables);
+ return true;
+ }
+ }
+
+ @RequiredArgsConstructor
+ public static class MenuEvent implements CustomEvent, MenuScript {
+ public final List pages;
+ public final String[] args;
+
+ @Override
+ public String eventName() {
+ return args[0];
+ }
+
+ @Override
+ public boolean execute(Event e, Player p, Map variables) {
+ new ScriptExecutor(pages, p, variables);
+ return false;
+ }
+
+ @Override
+ public void toYAPION(YAPIONMap yapionMap) {
+ YAPIONArray yapionArray = new YAPIONArray();
+ pages.forEach(yapionArray::add);
+ yapionMap.put(String.join(" ", args), yapionArray);
+ }
+
+ @Override
+ public SWItem toItem() {
+ StringBuilder st = new StringBuilder();
+ for (int i = 0; i < args.length; i++) {
+ if (i != 0) st.append(" ");
+ if (i == 0) st.append("§e");
+ st.append(args[i]);
+ if (i == 0) st.append("§8 -§7");
+ }
+
+ SWItem swItem = new SWItem(Material.WRITABLE_BOOK, "§7Event§8: " + st);
+ BookMeta bookMeta = (BookMeta) swItem.getItemMeta();
+ bookMeta.setPages(pages.toArray(new String[0]));
+ swItem.setItemMeta(bookMeta);
+ return swItem;
+ }
+ }
+
+ public interface CustomCommand extends Script {
+ default Map check(String[] args, String[] command) {
+ if (args.length < command.length) {
+ return null;
+ }
+
+ if (!args[0].equals(command[0])) {
+ return null;
+ }
+
+ Map arguments = new HashMap<>();
+ if (!check(arguments, args, command, 0, 0)) {
+ return null;
+ }
+ return arguments;
+ }
+
+ default boolean check(Map arguments, String[] args, String[] command, int argsIndex, int commandIndex) {
+ if (command.length <= commandIndex) {
+ for (int i = argsIndex; i < args.length; i++) {
+ if (!(args[i].startsWith("(") && args[i].endsWith(")"))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (args.length <= argsIndex) return true;
+
+ String currentArg = args[argsIndex];
+ String currentCommand = command[commandIndex];
+
+ if (currentArg.startsWith("<") && currentArg.endsWith(">")) {
+ arguments.put(trim(currentArg, 1), new Value.StringValue(currentCommand));
+ return check(arguments, args, command, argsIndex + 1, commandIndex + 1);
+ } else if (currentArg.startsWith("(<") && currentArg.endsWith(">)")) {
+ arguments.put(trim(currentArg, 2), new Value.StringValue(currentCommand));
+ return check(arguments, args, command, argsIndex + 1, commandIndex + 1);
+ } else if (currentArg.startsWith("(") && currentArg.endsWith(")")) {
+ if (!trim(currentArg, 1).equals(currentCommand)) {
+ arguments.put(trim(currentArg, 1), new Value.BooleanValue(false));
+ return check(arguments, args, command, argsIndex + 1, commandIndex);
+ } else {
+ arguments.put(trim(currentArg, 1), new Value.BooleanValue(true));
+ return check(arguments, args, command, argsIndex + 1, commandIndex + 1);
+ }
+ } else {
+ if (!currentArg.equals(currentCommand)) return false;
+ return check(arguments, args, command, argsIndex + 1, commandIndex + 1);
+ }
+ }
+
+ default String trim(String s, int count) {
+ return s.substring(count, s.length() - count);
+ }
+
+ boolean execute(String[] command, PlayerCommandPreprocessEvent e);
+ }
+
+ @RequiredArgsConstructor
+ public static class InventoryCommand implements CustomCommand {
+ public final BookMeta bookMeta;
+ public final String[] args;
+
+ public boolean execute(String[] command, PlayerCommandPreprocessEvent e) {
+ Map arguments = check(args, command);
+ if (arguments == null) {
+ return false;
+ }
+
+ e.setCancelled(true);
+ new ScriptExecutor(bookMeta, e.getPlayer(), arguments);
+ return true;
+ }
+ }
+
+ @RequiredArgsConstructor
+ public static class MenuCommand implements CustomCommand, MenuScript {
+ public final List pages;
+ public final String[] args;
+
+ public boolean execute(String[] command, PlayerCommandPreprocessEvent e) {
+ Map arguments = check(args, command);
+ if (arguments == null) {
+ return false;
+ }
+
+ e.setCancelled(true);
+ new ScriptExecutor(pages, e.getPlayer(), arguments);
+ return true;
+ }
+
+ public boolean equals(MenuCommand menuCommand) {
+ if (menuCommand.args.length != args.length) {
+ return false;
+ }
+ for (int i = 0; i < args.length; i++) {
+ if (i == 0) continue;
+ String s1 = args[i];
+ String s2 = menuCommand.args[i];
+ if (s1.equals(s2)) {
+ return true;
+ }
+ if (s1.startsWith("<") && s1.endsWith(">") && s2.startsWith("<") && s2.endsWith(">")) {
+ return true;
+ }
+ if (s1.startsWith("(<") && s1.endsWith(">)") && s2.startsWith("(<") && s2.endsWith(">)")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void toYAPION(YAPIONMap yapionMap) {
+ YAPIONArray yapionArray = new YAPIONArray();
+ pages.forEach(yapionArray::add);
+ yapionMap.put(String.join(" ", args), yapionArray);
+ }
+
+ @Override
+ public SWItem toItem() {
+ SWItem swItem = new SWItem(Material.WRITABLE_BOOK, "§7Command§8: §e" + String.join(" ", args));
+ BookMeta bookMeta = (BookMeta) swItem.getItemMeta();
+ bookMeta.setPages(pages.toArray(new String[0]));
+ swItem.setItemMeta(bookMeta);
+ return swItem;
+ }
+ }
+}
diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScriptListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScriptListener.java
new file mode 100644
index 00000000..008ec820
--- /dev/null
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/CustomScriptListener.java
@@ -0,0 +1,404 @@
+/*
+ * 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.script;
+
+import de.steamwar.bausystem.BauSystem;
+import de.steamwar.bausystem.SWUtils;
+import de.steamwar.bausystem.features.script.variables.Value;
+import de.steamwar.bausystem.linkage.LinkageType;
+import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.bausystem.region.Region;
+import de.steamwar.core.VersionedCallable;
+import de.steamwar.inventory.SWItem;
+import de.steamwar.inventory.SWListInv;
+import de.steamwar.sql.UserConfig;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.entity.EntitySpawnEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.player.*;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.BookMeta;
+import yapion.hierarchy.output.LengthOutput;
+import yapion.hierarchy.output.StringOutput;
+import yapion.hierarchy.types.YAPIONArray;
+import yapion.hierarchy.types.YAPIONMap;
+import yapion.hierarchy.types.YAPIONObject;
+import yapion.hierarchy.types.YAPIONValue;
+import yapion.parser.YAPIONParser;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Linked(LinkageType.LISTENER)
+public class CustomScriptListener implements Listener {
+
+ private Map> playerMap = new HashMap<>();
+
+ private void updateInventory(Player p) {
+ playerMap.computeIfPresent(p, (player, customCommands) -> {
+ customCommands.removeIf(script -> !(script instanceof CustomScript.MenuScript));
+ return customCommands;
+ });
+ for (ItemStack item : p.getInventory().getContents()) {
+ if (item == null || isNoBook(item) || item.getItemMeta() == null) {
+ continue;
+ }
+
+ BookMeta bookMeta = ((BookMeta) item.getItemMeta());
+ if (bookMeta.getPageCount() == 0) {
+ continue;
+ }
+ if (bookMeta.getPage(1).isEmpty()) {
+ continue;
+ }
+ String s = bookMeta.getPage(1).split("\n")[0];
+ if (s.startsWith("#!CMD /")) {
+ playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new CustomScript.InventoryCommand(bookMeta, s.substring(6).split(" ")));
+ } else if (s.startsWith("#!EVENT ")) {
+ playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new CustomScript.InventoryEvent(bookMeta, s.substring(8).split(" ")));
+ }
+ }
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent e) {
+ Player p = e.getPlayer();
+ updateInventory(p);
+
+ String s = UserConfig.getConfig(p.getUniqueId(), "bausystem-scripts");
+ if (s == null) {
+ s = UserConfig.getConfig(p.getUniqueId(), "bausystem-commands");
+ UserConfig.removePlayerConfig(p.getUniqueId(), "bausystem-commands");
+ }
+ YAPIONObject yapionObject;
+ if (s == null) {
+ yapionObject = new YAPIONObject();
+ yapionObject.getYAPIONMapOrSetDefault("events", new YAPIONMap()).add("FF", new YAPIONArray().add("#!EVENT FF /gui Kürzel\ngui"));
+ } else {
+ yapionObject = YAPIONParser.parse(s);
+ if (yapionObject.containsKey("")) {
+ yapionObject.add("commands", yapionObject.getMap(""));
+ yapionObject.remove("");
+ yapionObject.getYAPIONMapOrSetDefault("events", new YAPIONMap()).add("FF", new YAPIONArray().add("#!EVENT FF /gui Kürzel\ngui"));
+ }
+ }
+
+ yapionObject.getYAPIONMapOrSetDefault("commands", new YAPIONMap()).forEach((key, value) -> {
+ String[] command = ((YAPIONValue) key).get().split(" ");
+ List pages = ((YAPIONArray) value).stream().map(YAPIONValue.class::cast).map(YAPIONValue::get).map(String.class::cast).collect(Collectors.toList());
+ playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new CustomScript.MenuCommand(pages, command));
+ });
+
+ yapionObject.getYAPIONMapOrSetDefault("events", new YAPIONMap()).forEach((key, value) -> {
+ String[] event = ((YAPIONValue) key).get().split(" ");
+ List pages = ((YAPIONArray) value).stream().map(YAPIONValue.class::cast).map(YAPIONValue::get).map(String.class::cast).collect(Collectors.toList());
+ playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(new CustomScript.MenuEvent(pages, event));
+ });
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent e) {
+ save(e.getPlayer());
+ playerMap.remove(e.getPlayer());
+ }
+
+ private YAPIONObject output(Player p) {
+ if (!playerMap.containsKey(p)) return new YAPIONObject();
+ YAPIONObject yapionObject = new YAPIONObject();
+ YAPIONMap commandsMap = new YAPIONMap();
+ yapionObject.add("commands", commandsMap);
+ playerMap.get(p).stream().filter(CustomScript.MenuCommand.class::isInstance).map(CustomScript.MenuCommand.class::cast).forEach(menuCommand -> {
+ menuCommand.toYAPION(commandsMap);
+ });
+ YAPIONMap eventsMap = new YAPIONMap();
+ yapionObject.add("events", eventsMap);
+ playerMap.get(p).stream().filter(CustomScript.MenuEvent.class::isInstance).map(CustomScript.MenuEvent.class::cast).forEach(menuCommand -> {
+ menuCommand.toYAPION(eventsMap);
+ });
+ return yapionObject;
+ }
+
+ private boolean save(Player p) {
+ if (!playerMap.containsKey(p)) {
+ UserConfig.removePlayerConfig(p.getUniqueId(), "bausystem-scripts");
+ return true;
+ }
+ YAPIONObject yapionObject = output(p);
+ if (yapionObject.toYAPION(new LengthOutput()).getLength() > 64 * 1024) {
+ return false;
+ }
+ UserConfig.updatePlayerConfig(p.getUniqueId(), "bausystem-scripts", yapionObject.toYAPION(new StringOutput()).getResult());
+ return true;
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent e) {
+ if (e.getPlayer() instanceof Player) {
+ updateInventory((Player) e.getPlayer());
+ }
+ }
+
+ private boolean isNoBook(ItemStack item) {
+ return VersionedCallable.call(new VersionedCallable<>(() -> ScriptListener_15.isNoBook(item), 15));
+ }
+
+ public void openCommandsMenu(Player p) {
+ List> menuCommands = new ArrayList<>();
+ playerMap.getOrDefault(p, new ArrayList<>()).stream().filter(CustomScript.MenuScript.class::isInstance).map(CustomScript.MenuScript.class::cast).forEach(menuItem -> {
+ SWItem swItem = menuItem.toItem();
+ ItemStack itemStack = swItem.getItemStack();
+ if (menuItem instanceof CustomScript.MenuEvent) {
+ itemStack.setType(Material.REPEATING_COMMAND_BLOCK);
+ } else {
+ itemStack.setType(Material.COMMAND_BLOCK);
+ }
+ swItem.setItemStack(itemStack);
+ swItem.setLore(Arrays.asList("§7Klicke zum rausnehmen", "§7Middle Klicke zum kopieren"));
+
+ menuCommands.add(new SWListInv.SWListEntry<>(swItem, menuItem));
+ });
+
+ int length = (int) output(p).toYAPION(new LengthOutput()).getLength();
+ StringBuilder menuName = new StringBuilder();
+ menuName.append("§eScript Commands ");
+ double percentage = ((int) ((length / 655336.0) * 1000)) / 10.0;
+ if (percentage > 99) {
+ menuName.append("§c");
+ } else if (percentage >= 75) {
+ menuName.append("§6");
+ } else {
+ menuName.append("§a");
+ }
+ menuName.append(percentage).append("§7%");
+
+ SWListInv menuCommandSWListInv = new SWListInv<>(p, menuName.toString(), false, menuCommands, (clickType, menuCommand) -> {
+ if (!clickType.isCreativeAction()) {
+ playerMap.get(p).removeIf(customCommand -> customCommand == menuCommand);
+ }
+ SWUtils.giveItemToPlayer(p, menuCommand.toItem().getItemStack());
+ p.closeInventory();
+ save(p);
+ });
+ menuCommandSWListInv.setItem(49, new SWItem(Material.HOPPER, "§eHinzufügen", Arrays.asList("§7Klicke mit einem Buch zum hinzufügen"), false, clickType -> {
+ ItemStack item = p.getItemOnCursor();
+ if (item.getType().isAir()) {
+ return;
+ }
+ if (isNoBook(item) || item.getItemMeta() == null) {
+ return;
+ }
+
+ BookMeta bookMeta = ((BookMeta) item.getItemMeta());
+ if (bookMeta.getPageCount() == 0) {
+ return;
+ }
+ if (bookMeta.getPage(1).isEmpty()) {
+ return;
+ }
+ String s = bookMeta.getPage(1).split("\n")[0];
+ if (s.startsWith("#!CMD /")) {
+ CustomScript.MenuCommand menuCommand = new CustomScript.MenuCommand(bookMeta.getPages(), s.substring(6).split(" "));
+ for (CustomScript.Script script : playerMap.computeIfAbsent(p, player -> new ArrayList<>())) {
+ if (!(script instanceof CustomScript.MenuCommand)) {
+ continue;
+ }
+ if (((CustomScript.MenuCommand) script).equals(menuCommand)) {
+ p.sendMessage("§cCommand '" + (String.join(" ", menuCommand.args)) + "' bereits definiert");
+ return;
+ }
+ }
+ scriptBookLimit(p, menuCommand);
+ } else if (s.startsWith("#!EVENT ")) {
+ CustomScript.MenuEvent menuEvent = new CustomScript.MenuEvent(bookMeta.getPages(), s.substring(8).split(" "));
+ try {
+ EventType.valueOf(menuEvent.eventName());
+ } catch (Exception e) {
+ p.sendMessage("§cEvent '" + menuEvent.eventName() + "' ist nicht definierbar");
+ return;
+ }
+ scriptBookLimit(p, menuEvent);
+ }
+ }));
+ menuCommandSWListInv.open();
+ }
+
+ private void scriptBookLimit(Player p, CustomScript.Script menuScript) {
+ playerMap.computeIfAbsent(p, player -> new ArrayList<>()).add(menuScript);
+ if (!save(p)) {
+ playerMap.get(p).removeIf(script -> script == menuScript);
+ p.closeInventory();
+ SWUtils.giveItemToPlayer(p, p.getItemOnCursor());
+ save(p);
+ p.sendMessage("§cScript-Buch Limit erreicht");
+ return;
+ }
+ p.setItemOnCursor(null);
+ openCommandsMenu(p);
+ }
+
+ @Getter
+ public enum EventType {
+ FF(PlayerSwapHandItemsEvent.class, event -> null),
+ PlaceBlock(BlockPlaceEvent.class, event -> {
+ Map valueMap = new HashMap<>();
+ valueMap.put("blockX", new Value.LongValue(event.getBlockPlaced().getX()));
+ valueMap.put("blockY", new Value.LongValue(event.getBlockPlaced().getY()));
+ valueMap.put("blockZ", new Value.LongValue(event.getBlockPlaced().getZ()));
+ valueMap.put("blockType", new Value.StringValue(event.getBlockPlaced().getType().name()));
+ return valueMap;
+ }),
+ BreakBlock(BlockBreakEvent.class, event -> {
+ Map valueMap = new HashMap<>();
+ valueMap.put("blockX", new Value.LongValue(event.getBlock().getX()));
+ valueMap.put("blockY", new Value.LongValue(event.getBlock().getY()));
+ valueMap.put("blockZ", new Value.LongValue(event.getBlock().getZ()));
+ valueMap.put("blockType", new Value.StringValue(event.getBlock().getType().name()));
+ return valueMap;
+ }),
+ RightClick(PlayerInteractEvent.class, event -> {
+ Map valueMap = new HashMap<>();
+ valueMap.put("blockInHand", new Value.BooleanValue(event.isBlockInHand()));
+ return valueMap;
+ }),
+ LeftClick(PlayerInteractEvent.class, event -> {
+ Map valueMap = new HashMap<>();
+ valueMap.put("blockInHand", new Value.BooleanValue(event.isBlockInHand()));
+ return valueMap;
+ }),
+ TNTSpawn(EntitySpawnEvent.class, event -> null);
+
+ private Class extends Event> eventType;
+ private Function> eventValues;
+
+ EventType(Class eventType, Function> eventValues) {
+ this.eventType = eventType;
+ this.eventValues = event -> eventValues.apply((T) event);
+ }
+ }
+
+ private void callEvent(EventType eventType, Player p, Event e) {
+ if (!eventType.getEventType().equals(e.getClass())) {
+ return;
+ }
+
+ List customEvents = playerMap.getOrDefault(p, new ArrayList<>()).stream().filter(CustomScript.CustomEvent.class::isInstance).map(CustomScript.CustomEvent.class::cast).collect(Collectors.toList());
+ for (CustomScript.CustomEvent customEvent : customEvents) {
+ if (customEvent.eventName().equals(eventType.name())) {
+ Map variables = eventType.getEventValues().apply(e);
+ if (variables == null) {
+ variables = new HashMap<>();
+ }
+ if (e instanceof Cancellable) {
+ variables.put("cancel", new Value.BooleanValue(false));
+ }
+ customEvent.execute(e, p, variables);
+ if (variables.containsKey("cancel")) {
+ Value value = variables.get("cancel");
+ if (value.asBoolean()) {
+ ((Cancellable) e).setCancelled(true);
+ }
+ }
+ }
+ }
+ }
+
+ // EventListener for Commands as well as Events
+
+ // Event Command
+ @EventHandler
+ public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent e) {
+ if (e.getMessage().startsWith("/script:")) {
+ e.setMessage("/" + e.getMessage().substring(8));
+ return;
+ }
+
+ List customCommands = playerMap.getOrDefault(e.getPlayer(), new ArrayList<>()).stream().filter(CustomScript.CustomCommand.class::isInstance).map(CustomScript.CustomCommand.class::cast).collect(Collectors.toList());
+ String[] command = e.getMessage().split(" ");
+ for (CustomScript.CustomCommand customCommand : customCommands) {
+ if (customCommand.execute(command, e)) {
+ return;
+ }
+ }
+ }
+
+ // Event FF
+ private static final Set LAST_FS = new HashSet<>();
+
+ {
+ Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), LAST_FS::clear, 20, 20);
+ }
+
+ @EventHandler
+ public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
+ if (LAST_FS.contains(event.getPlayer())) {
+ callEvent(EventType.FF, event.getPlayer(), event);
+ } else {
+ LAST_FS.add(event.getPlayer());
+ }
+ }
+
+ @EventHandler
+ public void onBlockPlace(BlockPlaceEvent event) {
+ callEvent(EventType.PlaceBlock, event.getPlayer(), event);
+ }
+
+ @EventHandler
+ public void onBlockBreak(BlockBreakEvent event) {
+ callEvent(EventType.BreakBlock, event.getPlayer(), event);
+ }
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
+ callEvent(EventType.RightClick, event.getPlayer(), event);
+ }
+ if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
+ callEvent(EventType.LeftClick, event.getPlayer(), event);
+ }
+ }
+
+ @EventHandler
+ public void onEntitySpawn(EntitySpawnEvent event) {
+ if (event.getEntityType() != EntityType.PRIMED_TNT) {
+ return;
+ }
+ Region tntRegion = Region.getRegion(event.getLocation());
+
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ Region region = Region.getRegion(player.getLocation());
+ if (region == tntRegion) {
+ callEvent(EventType.TNTSpawn, player, event);
+ }
+ }
+ }
+}
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 2c2b886c..0880f4ae 100644
--- a/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java
+++ b/BauSystem_Main/src/de/steamwar/bausystem/features/script/ScriptCommand.java
@@ -1,8 +1,8 @@
package de.steamwar.bausystem.features.script;
-import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.linkage.LinkageType;
import de.steamwar.bausystem.linkage.Linked;
+import de.steamwar.bausystem.linkage.LinkedInstance;
import de.steamwar.command.SWCommand;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
@@ -23,23 +23,31 @@ public class ScriptCommand extends SWCommand {
super("script");
}
- private static List> swItems = new ArrayList<>();
+ @LinkedInstance
+ private CustomScriptListener customScriptListener = null;
+
+ private static List> swItems = new ArrayList<>();
@Register(help = true)
public void genericHelp(Player p, String... args) {
- p.sendMessage("§8/§escript §8- §7Gibt das Script Buch");
+ p.sendMessage("§8/§escript §8- §7Öffnet die ScriptGUI");
+ p.sendMessage("§8/§escript menu §8- §7Öffnet die ScriptMenuGUI für Custom Command b auübergreifend");
}
@Register
- public void giveCommand(Player p) {
+ public void menuCommand(Player p) {
if (swItems.isEmpty()) {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 3; i++) {
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", new ArrayList<>(), false, clickType -> {
}), null));
}
- swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.BOOK, "§eCustom Commands", Arrays.asList("§7Schreibe§8: §7#!CMD 'COMMAND'", "§7an den Anfang eines Script Buches um", "§7ein Custom Command zu nutzen. Der", "§7Befehl startet immer mit / und kann dann so", "§7aufgebaut sein wie du willst. Alles was in Spitzen", "§7Klammern steht (<>) wird als Parameter und somit", "§7als Variable gewertet."), false, clickType -> {
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.BOOK, "§eCustom Commands", Arrays.asList("§7Schreibe§8: §7#!CMD 'COMMAND'", "§7an den Anfang eines Script Buches um", "§7ein Custom Command zu nutzen. Der", "§7Befehl startet immer mit / und kann dann so", "§7aufgebaut sein wie du willst. Alles was in Spitzen", "§7Klammern steht '<>' wird als Parameter und somit", "§7als Variable gewertet.", "§7Parameter, welche in runden Klammern", "§7stehen sind Optional. Einfache", "§7Texte als Parameter bekommen", "§7eine gleichnamige Variable mit", "§7true/false als Wert je nachdem", "§7ob dieser angegeben wurde oder nicht"), false, clickType -> {
}), null));
- for (int i = 0; i < 4; i++) {
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.BOOK, "§eCustom Events", Arrays.asList("§7Schreibe§8: §7#!EVENT 'EventName'", "§7an den Anfang eines Script Buches um", "§7ein Custom Event zu nutzen. Jedes Event kann durch", "§7'var cancel true' gecancelt werden.", "§7Hinter dem Event Namen stehen die Variablen,", "§7welche im Script durch das Event nutztbar sind.", "§7Nutzbare Events sind:", "§eFF", "§ePlaceBlock §8-§7 blockX, blockY, blockZ, blockType", "§eBreakBlock §8-§7 blockX, blockY, blockZ, blockType", "§eRightClick §8-§7 blockInHand", "§eLeftClick §8-§7 blockInHand", "§eTNTSpawn"), false, clickType -> {
+ }), null));
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.BOOK, "§eOther", Arrays.asList("§7Kommentare fangen mit §e#§7 an.", "§7Jump_Points fangen mit §e.§7 an.", "§7Eine Variablen Namen in '<>'", "§7eingeschlossen wird ersetzt, bis zu zwei mal.", "§7Eine Variable in '<>' kann mit 'const.'", "§7oder 'local.' oder 'global.' prefixed werden", "§7für den genauen type wo nach geguckt werden soll"), false, clickType -> {
+ }), null));
+ for (int i = 0; i < 3; i++) {
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", new ArrayList<>(), false, clickType -> {
}), null));
}
@@ -69,14 +77,10 @@ public class ScriptCommand extends SWCommand {
}
SWItem swItem = new SWItem(specialCommand.material(), "§7Command: §e" + specialCommand.command(), strings, false, clickType -> {
- p.sendMessage("§eScript Command§8: §e" + specialCommand.command());
- for (String s : specialCommand.description()) {
- p.sendMessage("§7" + s);
- }
});
- swItems.add(new SWListInv.SWListEntry<>(swItem, null));
+ swItems.add(new SWListInv.SWListEntry<>(swItem, specialCommand));
});
- for (int i = 0; i < 9 + 4; i++) {
+ for (int i = 0; i < 9 + 3; i++) {
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", new ArrayList<>(), false, clickType -> {
}), null));
}
@@ -92,31 +96,52 @@ public class ScriptCommand extends SWCommand {
}), null));
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.TNT, "§7Constant §etnt", Arrays.asList("§etrue§7 wenn TNT nicht ausgeschaltet ist."), false, clickType -> {
}), null));
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.TNT, "§7Constant §etnt-onlytb", Arrays.asList("§etrue§7 wenn TNT Nur Testblock an ist."), false, clickType -> {
+ }), null));
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GUNPOWDER, "§7Constant §efreeze", Arrays.asList("§etrue§7 wenn Freeze nicht ausgeschaltet ist."), false, clickType -> {
}), null));
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.FIRE_CHARGE, "§7Constant §efire", Arrays.asList("§etrue§7 wenn Fire nicht ausgeschaltet ist."), false, clickType -> {
}), null));
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.OBSIDIAN, "§7Constant §eprotect", Arrays.asList("§etrue§7 wenn Protect angeschaltet ist."), false, clickType -> {
}), null));
- swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.PLAYER_HEAD, "§7Constant §ex", Arrays.asList("§ex§7 Position des Spielers."), false, clickType -> {
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.PLAYER_HEAD, "§7Constant §ex", Arrays.asList("§ex§7 Position des Spielers.", "§eÜberschreibbar"), false, clickType -> {
}), null));
- swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.PLAYER_HEAD, "§7Constant §ey", Arrays.asList("§ey§7 Position des Spielers."), false, clickType -> {
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.PLAYER_HEAD, "§7Constant §ey", Arrays.asList("§ey§7 Position des Spielers.", "§eÜberschreibbar"), false, clickType -> {
}), null));
- swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.PLAYER_HEAD, "§7Constant §ez", Arrays.asList("§ez§7 Position des Spielers."), false, clickType -> {
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.PLAYER_HEAD, "§7Constant §ez", Arrays.asList("§ez§7 Position des Spielers.", "§eÜberschreibbar"), false, clickType -> {
}), null));
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.NAME_TAG, "§7Constant §ename", Arrays.asList("§eDisplay§7 Name des Spielers."), false, clickType -> {
}), null));
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.IRON_BOOTS, "§7Constant §esneak", Arrays.asList("§etrue§7 wenn der Spieler gerade sneakt."), false, clickType -> {
}), null));
- for (int i = 0; i < 7 + 2 * 9; i++) {
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.DIAMOND_BOOTS, "§7Constant §esprinting", Arrays.asList("§etrue§7 wenn der Spieler gerade rennt."), false, clickType -> {
+ }), null));
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.ARROW, "§7Constant §eslot", Arrays.asList("§e0-8§7 für den ausgewählten slot.", "§eÜberschreibbar"), false, clickType -> {
+ }), null));
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRASS_BLOCK, "§7Constant §eslotmaterial", Arrays.asList("§eMaterial§7 des Items im Slot"), false, clickType -> {
+ }), null));
+ swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.IRON_BLOCK, "§7Constant §eoffhandmaterial", Arrays.asList("§eMaterial§7 des Items in oder Off Hand"), false, clickType -> {
+ }), null));
+ for (int i = 0; i < 2 + 2 * 9; i++) {
swItems.add(new SWListInv.SWListEntry<>(new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", new ArrayList<>(), false, clickType -> {
}), null));
}
}
- SWListInv