Add FixedRegionDataUtils

This commit is contained in:
2025-12-22 16:08:17 +01:00
parent 1533f16f09
commit a580087df8
12 changed files with 145 additions and 87 deletions
@@ -33,7 +33,7 @@ import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Stream; import java.util.stream.Stream;
public interface Region { public interface Region extends RegionDataStore {
static Stream<Region> getRegions() { static Stream<Region> getRegions() {
return RegionSystem.INSTANCE.getRegions(); return RegionSystem.INSTANCE.getRegions();
@@ -41,7 +41,7 @@ public interface RegionBackups {
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
abstract class Backup implements Comparable<Backup> { abstract class Backup implements RegionDataStore, Comparable<Backup> {
@NonNull @NonNull
private final BackupType type; private final BackupType type;
@@ -22,8 +22,6 @@ package de.steamwar.bausystem.region;
import de.steamwar.bausystem.region.flags.Flag; import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter;
import yapion.hierarchy.types.YAPIONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -33,33 +31,22 @@ import java.util.function.Function;
public abstract class RegionData { public abstract class RegionData {
@Setter
protected RegionDataStore store; protected RegionDataStore store;
private final List<Property<?, ?>> properties = new ArrayList<>(); private final List<Property<?, ?>> properties = new ArrayList<>();
protected final YAPIONObject data;
protected final YAPIONObject flagData;
protected final Runnable onChange;
protected final Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>(); protected final Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>();
private Property<SchematicNode, Integer> testblockSchematic = new Property<>("testblockSchematic", SchematicNode::byId, SchematicNode::getId); protected final Property<SchematicNode, Integer> testblockSchematic = new Property<>("testblockSchematic", SchematicNode::byId, SchematicNode::getId);
protected RegionData(YAPIONObject data, Runnable onChange) { protected RegionData(RegionDataStore store) {
this.data = data; this.store = store;
this.flagData = data.getObjectOrSetDefault("flagStorage", new YAPIONObject());
this.onChange = onChange;
initialize(); initialize();
for (final Flag flag : Flag.getFlags()) { store.loadRegionData(this);
if (!has(flag).isWritable()) continue; }
try {
String s = flagData.getPlainValue(flag.name()); public void setStore(RegionDataStore store) {
flagMap.put(flag, flag.valueOfValue(s)); this.store = store;
} catch (Exception e) { store.loadRegionData(this);
flagMap.put(flag, (Flag.Value<?>) flag.getDefaultValue());
}
}
properties.forEach(Property::load);
} }
protected void initialize() { protected void initialize() {
@@ -74,8 +61,7 @@ public abstract class RegionData {
public final <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) { public final <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
if (has(flag).isWritable()) { if (has(flag).isWritable()) {
if (flagMap.put(flag, value) != value) { if (flagMap.put(flag, value) != value) {
flagData.put(flag.name(), value.name()); store.saveRegionData(this);
onChange.run();
return true; return true;
} }
} }
@@ -91,24 +77,27 @@ public abstract class RegionData {
for (Flag flag : Flag.getFlags()) { for (Flag flag : Flag.getFlags()) {
if (has(flag).isWritable()) { if (has(flag).isWritable()) {
flagMap.remove(flag); flagMap.remove(flag);
flagData.remove(flag.name());
} }
} }
properties.forEach(property -> property.set(null)); properties.forEach(property -> property.set(null));
onChange.run(); store.saveRegionData(this);
} }
public final Map<Flag<?>, Flag.Value<?>> getBackedMap() { public final Map<Flag<?>, Flag.Value<?>> getBackedMap() {
return flagMap; return flagMap;
} }
public final List<Property<Object, Object>> getBackedProperties() {
return (List) properties;
}
public SchematicNode getTestblockSchematic() { public SchematicNode getTestblockSchematic() {
return testblockSchematic.get(); return testblockSchematic.get();
} }
public void setTestblockSchematic(SchematicNode schematic) { public void setTestblockSchematic(SchematicNode schematic) {
testblockSchematic.set(schematic); testblockSchematic.set(schematic);
onChange.run(); store.saveRegionData(this);
} }
@Override @Override
@@ -123,39 +112,26 @@ public abstract class RegionData {
return st.toString(); return st.toString();
} }
private final class Property<T, K> { public final class Property<T, K> {
private final String field; public final String field;
private final Function<K, T> loader; public final Function<K, T> loader;
private final Function<T, K> writer; public final Function<T, K> writer;
private T value; private T value;
public Property(String field, Function<K, T> loader, Function<T, K> writer) { private Property(String field, Function<K, T> loader, Function<T, K> writer) {
this.field = field; this.field = field;
this.loader = loader; this.loader = loader;
this.writer = writer; this.writer = writer;
properties.add(this); properties.add(this);
} }
public void load() {
if (flagData.containsKey(field)) {
value = loader.apply(flagData.getPlainValue(field));
} else {
value = null;
}
}
public T get() { public T get() {
return value; return value;
} }
public void set(T value) { public void set(T value) {
this.value = value; this.value = value;
if (value == null) {
flagData.remove(field);
} else {
flagData.put(field, writer.apply(value));
}
} }
@Override @Override
@@ -86,7 +86,7 @@ public class GlobalRegion implements Region {
} }
}; };
private static final GlobalRegionData REGION_DATA = new GlobalRegionData(); private static final GlobalRegionData REGION_DATA = new GlobalRegionData(INSTANCE);
@Override @Override
public @NonNull UUID getID() { public @NonNull UUID getID() {
@@ -132,4 +132,14 @@ public class GlobalRegion implements Region {
public @NonNull RegionBackups getBackups() { public @NonNull RegionBackups getBackups() {
return RegionBackups.EMPTY; return RegionBackups.EMPTY;
} }
@Override
public void saveRegionData(@NonNull RegionData regionData) {
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
}
} }
@@ -31,8 +31,8 @@ import yapion.hierarchy.types.YAPIONObject;
public class GlobalRegionData extends RegionData { public class GlobalRegionData extends RegionData {
public GlobalRegionData() { public GlobalRegionData(GlobalRegion globalRegion) {
super(new YAPIONObject(), () -> {}); // TODO: Implement loading of data and saving! super(globalRegion);
} }
@Override @Override
@@ -44,7 +44,7 @@ public class GlobalRegionData extends RegionData {
@Override @Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) { public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR)) { if (flag.oneOf(Flag.COLOR, Flag.PROTECT)) {
return RegionFlagPolicy.READ_ONLY; return RegionFlagPolicy.READ_ONLY;
} }
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) { if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
@@ -21,12 +21,15 @@ package de.steamwar.bausystem.region.fixed;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.bausystem.region.*; import de.steamwar.bausystem.region.*;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.utils.PasteBuilder; import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.sql.GameModeConfig; import de.steamwar.sql.GameModeConfig;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import yapion.hierarchy.types.YAPIONObject;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.File; import java.io.File;
@@ -137,4 +140,14 @@ public final class FixedGlobalRegion implements Region {
public @NonNull RegionBackups getBackups() { public @NonNull RegionBackups getBackups() {
return RegionBackups.EMPTY; return RegionBackups.EMPTY;
} }
@Override
public void saveRegionData(@NonNull RegionData regionData) {
FixedRegionDataUtils.saveRegionData("global", regionData);
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
FixedRegionDataUtils.loadRegionData("global", regionData);
}
} }
@@ -20,18 +20,18 @@
package de.steamwar.bausystem.region.fixed; package de.steamwar.bausystem.region.fixed;
import de.steamwar.bausystem.region.RegionData; import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionDataStore;
import de.steamwar.bausystem.region.RegionFlagPolicy; import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.ColorMode; import de.steamwar.bausystem.region.flags.ColorMode;
import de.steamwar.bausystem.region.flags.Flag; import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ProtectMode; import de.steamwar.bausystem.region.flags.ProtectMode;
import de.steamwar.bausystem.region.flags.TNTMode; import de.steamwar.bausystem.region.flags.TNTMode;
import lombok.NonNull; import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class FixedGlobalRegionData extends RegionData { public class FixedGlobalRegionData extends RegionData {
public FixedGlobalRegionData(YAPIONObject data, Runnable onChange) { public FixedGlobalRegionData(RegionDataStore store) {
super(data, onChange); super(store);
} }
@Override @Override
@@ -142,12 +142,20 @@ public class FixedRegion implements Region {
public long getCreationTime() { public long getCreationTime() {
return file.lastModified(); return file.lastModified();
} }
@Override
public void saveRegionData(@NonNull RegionData regionData) {
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
}
} }
public FixedRegion(String name, FixedRegionData flagStorage, Prototype prototype, YAPIONObject regionConfig, YAPIONObject regionData) { public FixedRegion(String name, Prototype prototype, YAPIONObject regionConfig) {
this.name = name; this.name = name;
uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8)); uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
this.flagStorage = flagStorage; this.flagStorage = new FixedRegionData(this);
this.prototype = prototype; this.prototype = prototype;
this.skin = prototype.getDefaultSkin(); this.skin = prototype.getDefaultSkin();
@@ -392,4 +400,14 @@ public class FixedRegion implements Region {
public @NonNull RegionBackups getBackups() { public @NonNull RegionBackups getBackups() {
return regionBackups; return regionBackups;
} }
@Override
public void saveRegionData(@NonNull RegionData regionData) {
FixedRegionDataUtils.saveRegionData(name, regionData);
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
FixedRegionDataUtils.loadRegionData(name, regionData);
}
} }
@@ -20,15 +20,15 @@
package de.steamwar.bausystem.region.fixed; package de.steamwar.bausystem.region.fixed;
import de.steamwar.bausystem.region.RegionData; import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionDataStore;
import de.steamwar.bausystem.region.RegionFlagPolicy; import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.Flag; import de.steamwar.bausystem.region.flags.Flag;
import lombok.NonNull; import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class FixedRegionData extends RegionData { public class FixedRegionData extends RegionData {
public FixedRegionData(YAPIONObject data, Runnable onChange) { public FixedRegionData(RegionDataStore store) {
super(data, onChange); super(store);
} }
@Override @Override
@@ -0,0 +1,64 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 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.fixed;
import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.worlddata.WorldData;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import yapion.hierarchy.types.YAPIONObject;
@UtilityClass
public class FixedRegionDataUtils {
public void saveRegionData(@NonNull String identifier, @NonNull RegionData regionData) {
YAPIONObject yapionObject = new YAPIONObject();
YAPIONObject flagData = yapionObject.getOrSetDefault("flagStorage", new YAPIONObject());
regionData.getBackedMap().forEach((flag, value) -> {
flagData.put(flag.name(), value.name());
});
regionData.getBackedProperties().forEach(property -> {
yapionObject.put(property.field, property.writer.apply(property.get()));
});
WorldData.getRegionsData().put(identifier, yapionObject);
WorldData.write();
}
public void loadRegionData(@NonNull String identifier, @NonNull RegionData regionData) {
YAPIONObject values = WorldData.getRegionsData().getObject(identifier);
if (values == null) return;
YAPIONObject flagData = values.getObjectOrDefault("flagStorage", new YAPIONObject());
for (final Flag flag : Flag.getFlags()) {
if (!regionData.has(flag).isWritable()) continue;
try {
String s = flagData.getPlainValue(flag.name());
regionData.getBackedMap().put(flag, flag.valueOfValue(s));
} catch (Exception e) {
regionData.getBackedMap().put(flag, (Flag.Value<?>) flag.getDefaultValue());
}
}
regionData.getBackedProperties().forEach(property -> {
Object object = values.getPlainValue(property.field);
property.set(property.loader.apply(object));
});
}
}
@@ -210,14 +210,8 @@ public class Prototype {
} }
} }
public static void generateRegion(String name, YAPIONObject regionConfig, YAPIONObject regionData) { public static void generateRegion(String name, YAPIONObject regionConfig) {
Prototype prototype; Prototype prototype = PROTOTYPE_MAP.get(regionConfig.getPlainValue("prototype"));
if (regionData.containsKey("prototype", String.class)) { FixedRegionSystem.addRegion(new FixedRegion(name, prototype, regionConfig));
prototype = PROTOTYPE_MAP.get(regionData.getPlainValue("prototype"));
} else {
prototype = PROTOTYPE_MAP.get(regionConfig.getPlainValue("prototype"));
}
FixedRegionData flagStorage = new FixedRegionData(regionData, WorldData::write);
FixedRegionSystem.addRegion(new FixedRegion(name, flagStorage, prototype, regionConfig, regionData));
} }
} }
@@ -22,13 +22,11 @@ package de.steamwar.bausystem.region.fixed.loader;
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion; import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData; import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
import de.steamwar.bausystem.region.fixed.Prototype; import de.steamwar.bausystem.region.fixed.Prototype;
import de.steamwar.bausystem.worlddata.WorldData;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import yapion.hierarchy.diff.DiffChange; import yapion.hierarchy.diff.DiffChange;
import yapion.hierarchy.diff.YAPIONDiff; import yapion.hierarchy.diff.YAPIONDiff;
import yapion.hierarchy.types.YAPIONObject; import yapion.hierarchy.types.YAPIONObject;
import yapion.hierarchy.types.YAPIONType;
import yapion.parser.YAPIONParser; import yapion.parser.YAPIONParser;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@@ -55,7 +53,6 @@ public class RegionLoader {
} }
loaded = yapionObject; loaded = yapionObject;
YAPIONObject optionsYapionObject = WorldData.getRegionsData();
yapionObject.forEach((key, yapionAnyType) -> { yapionObject.forEach((key, yapionAnyType) -> {
if (key.equals("global")) { if (key.equals("global")) {
return; return;
@@ -63,23 +60,9 @@ public class RegionLoader {
if (!(yapionAnyType instanceof YAPIONObject)) { if (!(yapionAnyType instanceof YAPIONObject)) {
return; return;
} }
Prototype.generateRegion(key, (YAPIONObject) yapionAnyType);
YAPIONObject regionConfig = (YAPIONObject) yapionAnyType;
YAPIONObject regionData = new YAPIONObject();
if (optionsYapionObject.containsKey(key, YAPIONType.OBJECT)) {
regionData = optionsYapionObject.getObject(key);
} else {
optionsYapionObject.add(key, regionData);
}
Prototype.generateRegion(key, regionConfig, regionData);
}); });
YAPIONObject globalOptions = optionsYapionObject.getObject("global"); FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(FixedGlobalRegion.INSTANCE));
if (globalOptions == null) {
globalOptions = new YAPIONObject();
optionsYapionObject.add("global", globalOptions);
}
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(globalOptions, WorldData::write));
} }
} }