Add DynamicRegionSystem

This commit is contained in:
2025-08-02 22:15:42 +02:00
parent aead25650e
commit 30f0d9cec8
10 changed files with 531 additions and 0 deletions
@@ -75,6 +75,12 @@ public interface RegionSystem {
Stream<Region> 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 |
@@ -0,0 +1,47 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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"))
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Tile, UUID> tileMap = new HashMap<>();
private static Map<UUID, Region> 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 = 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<Region> getRegion(@NonNull UUID id) {
return Optional.ofNullable(regionMap.get(id));
}
@Override
public @NonNull Stream<Region> getRegions() {
return regionMap.values().stream();
}
@Override
public boolean isModular() {
return true;
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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 = 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()));
}
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Tile> 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<Tile> getNeighbors() {
List<Tile> 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;
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<?>, 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 <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> 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 <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> 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 <T extends Enum<T> & Flag.Value<T>> FlagOptional<T> get(@NonNull Flag<T> 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<?>, Flag.Value<?>> getBackedMap() {
return flagMap;
}
@Override
public String toString() {
return "FixedGlobalFlagStorage{" +
"flagMap=" + flagMap +
'}';
}
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Integer, Integer> 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;
}
}
+1
View File
@@ -28,6 +28,7 @@ tasks.build {
dependencies {
implementation(project(":BauSystem:BauSystem_RegionFixed"))
implementation(project(":BauSystem:BauSystem_RegionDynamic"))
implementation(project(":BauSystem:BauSystem_Main"))
}
+1
View File
@@ -165,6 +165,7 @@ dependencyResolutionManagement {
include(
"BauSystem",
"BauSystem:BauSystem_Main",
"BauSystem:BauSystem_RegionDynamic",
"BauSystem:BauSystem_RegionFixed"
)