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 232962a1..7da0fea1 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/autostart/AutostartListener.java @@ -31,6 +31,8 @@ import de.steamwar.linkage.Linked; import lombok.Getter; import org.bukkit.Material; import org.bukkit.block.data.type.Chest; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -39,11 +41,9 @@ import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; +import java.io.File; import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; +import java.util.*; @Linked public class AutostartListener implements Listener { @@ -117,15 +117,24 @@ public class AutostartListener implements Listener { if (regionStartTime.isEmpty()) { return; } + event.blockList().forEach(block -> { Region region = Region.getRegion(block.getLocation()); if (!regionStartTime.containsKey(region)) return; if (!region.hasType(RegionType.TESTBLOCK)) return; if (!region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return; long tickDiff = TPSUtils.currentRealTick.get() - regionStartTime.remove(region); + long preFightDurationInSeconds = getPreFightDurationInSeconds(region); RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT1", tickDiff); - RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT2", 30, (600 - tickDiff)); + RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT2", preFightDurationInSeconds, ((preFightDurationInSeconds * 20) - tickDiff)); RegionUtils.message(region, "AUTOSTART_MESSAGE_RESULT3"); }); } + + private int getPreFightDurationInSeconds(Region region) { + File file = region.gameModeConfig(); + if (file == null) return 30; + FileConfiguration config = YamlConfiguration.loadConfiguration(file); + return config.getInt("Times.PreFightDuration", 30); + } } 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..b2bf51cc 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 @@ -31,6 +31,7 @@ import de.steamwar.bausystem.features.world.WorldEditListener; import de.steamwar.bausystem.utils.WorldEditUtils; import de.steamwar.inventory.SWAnvilInv; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -192,7 +193,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..d4895693 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 @@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.script.lua.libs; 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; @@ -93,7 +94,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 +108,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 f6c35f9f..07554a68 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 @@ -81,6 +81,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/StorageLib.java b/BauSystem_Main/src/de/steamwar/bausystem/features/script/lua/libs/StorageLib.java index 033c5f98..8967951d 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,13 @@ package de.steamwar.bausystem.features.script.lua.libs; +import com.google.gson.*; import de.steamwar.bausystem.region.Region; 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 +34,171 @@ 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 (!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 (!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 +253,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 +298,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/smartplace/SmartPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index 07748a98..f3ab68bf 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -67,6 +67,7 @@ public class SmartPlaceListener implements Plain, Listener { } } CONTAINERS.add(Material.GRINDSTONE); + CONTAINERS.remove(Material.COMPARATOR); state.update(true, false); IGNORED.add(Material.TNT); 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/world/WorldEditListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java index 19dc6e09..ba9d6d9e 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/world/WorldEditListener.java @@ -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/sw.def.lua b/sw.def.lua index d56a134e..613437a1 100644 --- a/sw.def.lua +++ b/sw.def.lua @@ -153,6 +153,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 @@ -247,6 +277,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