From 30f0d9cec851a00be5c41f05107532e7e2db9eff Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Sat, 2 Aug 2025 22:15:42 +0200 Subject: [PATCH] Add DynamicRegionSystem --- .../bausystem/region/RegionSystem.java | 6 + .../BauSystem_RegionDynamic/build.gradle.kts | 47 ++++++ .../bausystem/region/DynamicRegionSystem.java | 88 +++++++++++ .../region/dynamic/DynamicRegion.java | 29 ++++ .../region/dynamic/MovementListener.java | 43 ++++++ .../bausystem/region/dynamic/Tile.java | 66 ++++++++ .../global/DynamicGlobalFlagStorage.java | 108 +++++++++++++ .../dynamic/global/DynamicGlobalRegion.java | 142 ++++++++++++++++++ BauSystem/build.gradle.kts | 1 + settings.gradle.kts | 1 + 10 files changed, 531 insertions(+) create mode 100644 BauSystem/BauSystem_RegionDynamic/build.gradle.kts create mode 100644 BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java create mode 100644 BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java create mode 100644 BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java create mode 100644 BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java create mode 100644 BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalFlagStorage.java create mode 100644 BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalRegion.java diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionSystem.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionSystem.java index 0a657a84..77fd02e6 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionSystem.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/region/RegionSystem.java @@ -75,6 +75,12 @@ public interface RegionSystem { Stream getRegions(); private static RegionSystem init() { + try { + return (RegionSystem) Class.forName("de.steamwar.bausystem.region.DynamicRegionSystem").getConstructor().newInstance(); + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { + // Ignore + } try { return (RegionSystem) Class.forName("de.steamwar.bausystem.region.FixedRegionSystem").getConstructor().newInstance(); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | diff --git a/BauSystem/BauSystem_RegionDynamic/build.gradle.kts b/BauSystem/BauSystem_RegionDynamic/build.gradle.kts new file mode 100644 index 00000000..b33f5f0a --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/build.gradle.kts @@ -0,0 +1,47 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +plugins { + steamwar.java +} + +tasks.compileJava { + options.isWarnings = false +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +dependencies { + compileOnly(project(":BauSystem:BauSystem_Main", "default")) + compileOnly(project(":SpigotCore", "default")) + + compileOnly(libs.spigotapi) + compileOnly(libs.axiom) + compileOnly(libs.authlib) + compileOnly(libs.viaapi) + + compileOnly(libs.nms20) + compileOnly(libs.fawe18) + + implementation(libs.luaj) + implementation(files("$projectDir/../libs/YAPION-SNAPSHOT.jar")) +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java new file mode 100644 index 00000000..e9d8a972 --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/DynamicRegionSystem.java @@ -0,0 +1,88 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.region; + +import de.steamwar.bausystem.BauSystem; +import de.steamwar.bausystem.region.dynamic.MovementListener; +import de.steamwar.bausystem.region.dynamic.Tile; +import de.steamwar.bausystem.region.dynamic.global.DynamicGlobalRegion; +import lombok.NonNull; +import org.bukkit.Bukkit; +import org.bukkit.Location; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; + +public class DynamicRegionSystem implements RegionSystem { + + public static DynamicRegionSystem INSTANCE; + + private static Map tileMap = new HashMap<>(); + private static Map regionMap = new HashMap<>(); + + @Override + public void load() { + INSTANCE = this; + Bukkit.getPluginManager().registerEvents(new MovementListener(), BauSystem.getInstance()); + } + + @Override + public void save() { + } + + @Override + public @NonNull Location getWorldSpawn() { + return new Location(Bukkit.getWorlds().get(0), 0, 0, 0); + } + + @Override + public @NonNull Region getGlobalRegion() { + return DynamicGlobalRegion.INSTANCE; + } + + @Override + public @NonNull Region get(@NonNull Location location) { + Optional tile = Tile.fromLocation(location); + if (tile.isEmpty()) return DynamicGlobalRegion.INSTANCE; + UUID uuid = tileMap.get(tile.get()); + if (uuid == null) return DynamicGlobalRegion.INSTANCE; + Region region = regionMap.get(uuid); + if (region == null) return DynamicGlobalRegion.INSTANCE; + return region; + } + + @Override + public Optional getRegion(@NonNull UUID id) { + return Optional.ofNullable(regionMap.get(id)); + } + + @Override + public @NonNull Stream getRegions() { + return regionMap.values().stream(); + } + + @Override + public boolean isModular() { + return true; + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java new file mode 100644 index 00000000..b4ed994b --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/DynamicRegion.java @@ -0,0 +1,29 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.region.dynamic; + +import de.steamwar.bausystem.region.Region; + +public interface DynamicRegion extends Region { + + default void update(Tile updateFrom) { + System.out.println("Updating from " + updateFrom); + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java new file mode 100644 index 00000000..0f337190 --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/MovementListener.java @@ -0,0 +1,43 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.region.dynamic; + +import de.steamwar.bausystem.region.Region; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.Optional; + +public class MovementListener implements Listener { + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + Optional tile = Tile.fromLocation(event.getTo()); + Region region = Region.getRegion(event.getTo()); + if (tile.isPresent()) { + event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(region.getType() + " " + tile.get() + " " + region.getType())); + } else { + event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(region.getType() + " NONE " + region.getType())); + } + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java new file mode 100644 index 00000000..f29b5405 --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/Tile.java @@ -0,0 +1,66 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.region.dynamic; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import org.bukkit.Location; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class Tile { + + private static final int tileSize = 19; + private static final int minTile = -1023; + private static final int maxTile = 1023; + + public static Optional fromLocation(Location location) { + int x = (location.getBlockX() + 9) / tileSize; + int z = (location.getBlockZ() + 9) / tileSize; + if (location.getX() < -9) x--; + if (location.getZ() < -9) z--; + if (x < minTile || z < minTile) return Optional.empty(); + if (x > maxTile || z > maxTile) return Optional.empty(); + return Optional.of(new Tile(x, z)); + } + + private int x; + private int z; + + public String toString() { + return x + " : " + z; + } + + public List getNeighbors() { + List neighbors = new ArrayList<>(); + for (int x = -1; x <= 1; x++) { + for (int z = -1; z <= 1; z++) { + if (x == 0 && z == 0) continue; + if (this.x + x < minTile || this.z + z < minTile) continue; + if (this.x + x > maxTile || this.z + z > maxTile) continue; + neighbors.add(new Tile(this.x + x, this.z + z)); + } + } + return neighbors; + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalFlagStorage.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalFlagStorage.java new file mode 100644 index 00000000..a794a2ef --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalFlagStorage.java @@ -0,0 +1,108 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.region.dynamic.global; + +import de.steamwar.bausystem.region.FlagOptional; +import de.steamwar.bausystem.region.FlagStorage; +import de.steamwar.bausystem.region.RegionFlagPolicy; +import de.steamwar.bausystem.region.flags.ColorMode; +import de.steamwar.bausystem.region.flags.Flag; +import de.steamwar.bausystem.region.flags.ProtectMode; +import de.steamwar.bausystem.region.flags.TNTMode; +import de.steamwar.bausystem.worlddata.WorldData; +import de.steamwar.core.Core; +import lombok.NonNull; +import yapion.hierarchy.types.YAPIONObject; + +import java.util.HashMap; +import java.util.Map; + +public class DynamicGlobalFlagStorage implements FlagStorage { + + private Map, Flag.Value> flagMap = new HashMap<>(); + private YAPIONObject data; + + public DynamicGlobalFlagStorage(YAPIONObject data) { + flagMap.put(Flag.TNT, TNTMode.DENY); + this.data = data; + for (final Flag flag : Flag.getFlags()) { + if (!has(flag).isWritable()) continue; + try { + String s = data.getPlainValue(flag.name()); + flagMap.put(flag, flag.valueOfValue(s)); + } catch (Exception e) { + flagMap.put(flag, (Flag.Value) flag.getDefaultValue()); + } + } + } + + @Override + public @NonNull & Flag.Value> RegionFlagPolicy has(@NonNull Flag flag) { + if (flag.oneOf(Flag.COLOR)) { + return RegionFlagPolicy.READ_ONLY; + } + if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) { + return RegionFlagPolicy.WRITABLE; + } + if (flag.oneOf(Flag.TNT, Flag.FIRE, Flag.FREEZE)) { + return RegionFlagPolicy.WRITABLE; + } + return RegionFlagPolicy.NOT_APPLICABLE; + } + + @Override + public & Flag.Value> boolean set(@NonNull Flag flag, @NonNull T value) { + if (has(flag).isWritable()) { + data.put(flag.name(), value.name()); + WorldData.write(); + return flagMap.put(flag, value) != value; + } else { + return false; + } + } + + @Override + public @NonNull & Flag.Value> FlagOptional get(@NonNull Flag flag) { + if (flag.oneOf(Flag.COLOR)) { + return FlagOptional.of((Flag) flag, ColorMode.YELLOW); + } + if (flag.oneOf(Flag.PROTECT)) { + return FlagOptional.of((Flag) flag, ProtectMode.INACTIVE); + } + return FlagOptional.of(flag, (T) flagMap.get(flag)); + } + + @Override + public void clear() { + flagMap.clear(); + } + + @Override + public Map, Flag.Value> getBackedMap() { + return flagMap; + } + + @Override + public String toString() { + return "FixedGlobalFlagStorage{" + + "flagMap=" + flagMap + + '}'; + } +} diff --git a/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalRegion.java b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalRegion.java new file mode 100644 index 00000000..8b11f0bc --- /dev/null +++ b/BauSystem/BauSystem_RegionDynamic/src/de/steamwar/bausystem/region/dynamic/global/DynamicGlobalRegion.java @@ -0,0 +1,142 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.region.dynamic.global; + +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import de.steamwar.bausystem.region.*; +import de.steamwar.bausystem.region.dynamic.DynamicRegion; +import de.steamwar.bausystem.utils.PasteBuilder; +import lombok.NonNull; +import org.bukkit.Location; +import yapion.hierarchy.types.YAPIONObject; + +import javax.annotation.Nullable; +import java.io.File; +import java.util.UUID; +import java.util.function.BiConsumer; + +public class DynamicGlobalRegion implements DynamicRegion { + + public static final DynamicGlobalRegion INSTANCE = new DynamicGlobalRegion(); + + private static final Point MIN_POINT = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + private static final Point MAX_POINT = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + + private static FlagStorage FLAG_STORAGE = new DynamicGlobalFlagStorage(new YAPIONObject()); + + private static final UUID GLOBAL_REGION_ID = new UUID(0, 0); + + private static final Region.Area GLOBAL_AREA = new Region.Area() { + @Override + public @NonNull Point getMinPoint(boolean extension) { + return MIN_POINT; + } + + @Override + public @NonNull Point getMaxPoint(boolean extension) { + return MAX_POINT; + } + + @Override + public @NonNull Point getCopyPoint() { + return Point.ZERO; + } + + @Override + public boolean inRegion(Location location, boolean extension) { + return true; + } + + @Nullable + @Override + public Clipboard copy(boolean extension) { + return null; + } + + @Nullable + @Override + public File getResetFile() { + return null; + } + + @Override + public void reset(PasteBuilder pasteBuilder, boolean extension) { + } + + @Override + public void forEachChunk(BiConsumer executor) { + } + + @Override + public boolean isChunkOutside(int chunkX, int chunkZ) { + return false; + } + }; + + private static final RegionConfig GLOBAL_CONFIG = new RegionConfig(null); + + private DynamicGlobalRegion() { + } + + @Override + public RegionType getType() { + return RegionType.GLOBAL; + } + + @Override + public @NonNull UUID getID() { + return GLOBAL_REGION_ID; + } + + @Override + public @NonNull FlagStorage getFlags() { + return FLAG_STORAGE; + } + + @Override + public @NonNull Region.Area getArea() { + return GLOBAL_AREA; + } + + @Override + public @NonNull Region.Area getBuildArea() { + return Region.Area.EMPTY; + } + + @Override + public @NonNull Region.Area getTestblockArea() { + return Region.Area.EMPTY; + } + + @Override + public @NonNull RegionConfig getGameModeConfig() { + return GLOBAL_CONFIG; + } + + @Override + public @NonNull RegionHistory getHistory() { + return RegionHistory.EMPTY; + } + + @Override + public @NonNull RegionBackups getBackups() { + return RegionBackups.EMPTY; + } +} diff --git a/BauSystem/build.gradle.kts b/BauSystem/build.gradle.kts index de9fe1b8..d6fbd005 100644 --- a/BauSystem/build.gradle.kts +++ b/BauSystem/build.gradle.kts @@ -28,6 +28,7 @@ tasks.build { dependencies { implementation(project(":BauSystem:BauSystem_RegionFixed")) + implementation(project(":BauSystem:BauSystem_RegionDynamic")) implementation(project(":BauSystem:BauSystem_Main")) } diff --git a/settings.gradle.kts b/settings.gradle.kts index c9103d0a..5de418b8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -165,6 +165,7 @@ dependencyResolutionManagement { include( "BauSystem", "BauSystem:BauSystem_Main", + "BauSystem:BauSystem_RegionDynamic", "BauSystem:BauSystem_RegionFixed" )