34 Commits

Author SHA1 Message Date
ec41111054 Start Logging
Some checks failed
SteamWarCI Build failed
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-28 20:44:05 +01:00
361c698323 Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 10:07:26 +01:00
db4ea2d69d Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 10:05:17 +01:00
3cecc58bce Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 10:03:14 +01:00
ce3d50fcb7 Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 10:01:36 +01:00
61bd28150b Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 09:59:22 +01:00
bb9caa28a3 Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 09:57:18 +01:00
4b2970d243 Check why StaticMessageChannel does not work?
All checks were successful
SteamWarCI Build successful
2026-01-09 09:53:34 +01:00
834767edbe Fix API
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-04 12:35:11 +01:00
4bea077d36 Fix Kits
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-03 02:25:52 +01:00
74d6ccc24f Fix Kits
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-03 02:22:55 +01:00
d9f905d957 Fix Kits
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-02 14:24:49 +01:00
663a745d8f Fix Kits
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-02 14:08:49 +01:00
1f64c3383d Fix HotbarKitListener
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2026-01-01 17:04:09 +01:00
Lixfel
e4676d5eba Test hotpatch kit
All checks were successful
SteamWarCI Build successful
2026-01-01 15:08:37 +01:00
ebb2ec817d Fix Windcharge Damage on Arena
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-27 19:18:31 +01:00
b6445ce2e9 Merge pull request 'Change Bug Button to Link' (#263) from update-bug-button into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #263
Reviewed-by: YoyoNow <yoyonow@noreply.localhost>
2025-12-25 21:09:37 +01:00
a454da6da8 Change Bug Button to Link
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-25 21:07:53 +01:00
a87cc94700 Pot fix for WinconditionBasePercent
All checks were successful
SteamWarCI Build successful
2025-12-23 12:27:48 +01:00
31dac93698 Remove UnrankCommand
All checks were successful
SteamWarCI Build successful
2025-12-23 10:40:53 +01:00
1f568f3d8b Remove UnrankCommand
Some checks failed
SteamWarCI Build failed
2025-12-22 21:25:40 +01:00
b8b8dd1ba0 Update UserPerm.kt
All checks were successful
SteamWarCI Build successful
2025-12-21 13:25:30 +01:00
99f864d889 Hotfix SteamwarUser and ServerStarter
All checks were successful
SteamWarCI Build successful
2025-12-21 12:27:55 +01:00
711a21b634 Merge pull request 'Remove SchemElo and UserElo' (#256) from RemoveElo into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #256
2025-12-21 12:04:27 +01:00
9a85e8b442 Merge branch 'main' into RemoveElo
All checks were successful
SteamWarCI Build successful
2025-12-21 12:03:33 +01:00
8358203cd4 Fix kits frfrfrfrfrfr
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-20 22:15:30 +01:00
6a619c2fd1 Fix kits frfrfrfrfr?
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-20 22:12:48 +01:00
d348e4a480 Fix kits frfrfrfr?
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-20 22:10:25 +01:00
1269e4d971 Fix kits frfrfr
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-20 22:03:09 +01:00
feac17d732 Fix kits frfr
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-20 21:58:44 +01:00
975b2bb8e6 Fix Kits and Maybe? Locale
All checks were successful
SteamWarCI Build successful
Signed-off-by: Chaoscaot <max@maxsp.de>
2025-12-20 21:35:34 +01:00
a1add4f997 Remove SchemElo and UserElo
All checks were successful
SteamWarCI Build successful
2025-12-20 21:28:00 +01:00
b517fe3ad0 Remove SchemElo and UserElo
All checks were successful
SteamWarCI Build successful
2025-12-20 21:26:42 +01:00
ac5dda58a1 Remove SchemElo and UserElo
All checks were successful
SteamWarCI Build successful
2025-12-20 21:19:20 +01:00
112 changed files with 391 additions and 4942 deletions

3
.gitignore vendored
View File

@@ -20,4 +20,5 @@ lib
/WebsiteBackend/data
/WebsiteBackend/logs
/WebsiteBackend/skins
/WebsiteBackend/config.json
/WebsiteBackend/config.json
/WebsiteBackend/sessions

View File

@@ -39,7 +39,6 @@ import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
@@ -115,9 +114,6 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
@Override
public Clipboard loadSchematic(File file) {
if (file == null) {
return null;
}
Clipboard clipboard;
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
clipboard = reader.read();
@@ -171,18 +167,13 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
ClipboardHolder ch = new ClipboardHolder(clipboard);
BlockVector3 dimensions = clipboard.getDimensions();
BlockVector3 v;
BlockVector3 v = BlockVector3.at(pasteBuilder.getPastPoint().getX(), pasteBuilder.getPastPoint().getY(), pasteBuilder.getPastPoint().getZ());
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
if (pasteBuilder.getPastPoint() != null) {
v = pasteBuilder.getPastPoint().toBlockVector3();
if (pasteBuilder.isRotate()) {
ch.setTransform(new AffineTransform().rotateY(180));
v = v.add(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset.multiply(-1, 1, -1)).subtract(0, 0, 1);
} else {
v = v.subtract(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset);
}
if (pasteBuilder.isRotate()) {
ch.setTransform(new AffineTransform().rotateY(180));
v = v.add(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset.multiply(-1, 1, -1)).subtract(0, 0, 1);
} else {
v = pasteBuilder.getMinPoint().toBlockVector3().subtract(offset);
v = v.subtract(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset);
}
pastePoint.set(v);
@@ -192,7 +183,6 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
}
}
e.setSideEffectApplier(SideEffectSet.none());
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
return e;
} catch (WorldEditException e) {

View File

@@ -56,7 +56,6 @@ public class BauInfoBauGuiItem extends BauGuiItem {
Region region = Region.getRegion(player.getLocation());
List<String> stringList = new ArrayList<>();
for (Flag flag : Flag.getFlags()) {
if (flag == Flag.CHANGED) continue;
if (!region.getRegionData().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getRegionData().get(flag);
if (value.isPresent()) {

View File

@@ -30,7 +30,6 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.util.SelectCommand;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.shared.Pair;
@@ -72,10 +71,7 @@ public class RegionCommand extends SWCommand {
@Register(value = "undo", description = "REGION_REGION_HELP_UNDO")
public void undoCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (region.getHistory() == RegionHistory.EMPTY) {
BauSystem.MESSAGE.send("REGION_REGION_NO_REGION", p);
return;
}
if (checkGlobalRegion(region, p)) return;
if (region.getHistory().undo()) {
RegionUtils.message(region, "REGION_REGION_UNDID");
@@ -87,8 +83,7 @@ public class RegionCommand extends SWCommand {
@Register(value = "redo", description = "REGION_REGION_HELP_REDO")
public void redoCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (region.getHistory() == RegionHistory.EMPTY) {
BauSystem.MESSAGE.send("REGION_REGION_NO_REGION", p);
if (checkGlobalRegion(region, p)) {
return;
}

View File

@@ -21,11 +21,9 @@ package de.steamwar.bausystem.features.region;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.config.BauServer;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.TestblockMode;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.command.PreviousArguments;
@@ -175,17 +173,6 @@ public class TestblockCommand extends SWCommand {
private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation());
if (region.getRegionData().has(Flag.TESTBLOCK).isWritable() && region.getRegionData().get(Flag.TESTBLOCK).isWithDefault(TestblockMode.NO_VALUE)) {
Point minPoint = region.getArea().getMinPoint(false);
Point maxPoint = region.getArea().getMaxPoint(false);
// TODO: Check if empty!
int half = minPoint.getZ() + (maxPoint.getZ() - minPoint.getZ()) / 2;
if (player.getLocation().getBlockZ() <= half) {
region.getRegionData().set(Flag.TESTBLOCK, TestblockMode.SOUTH);
} else {
region.getRegionData().set(Flag.TESTBLOCK, TestblockMode.NORTH);
}
}
if (region.getTestblockArea().isEmpty()) {
BauSystem.MESSAGE.send("REGION_TB_NO_REGION", player);
return null;

View File

@@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.warp;
import de.steamwar.bausystem.region.RegionSystem;
import de.steamwar.bausystem.worlddata.WorldData;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
@@ -36,20 +35,14 @@ public class Warp {
private static Map<String, Warp> warpMap = new HashMap<>();
public static void enable() {
Warp worldSpawn = new Warp("WorldSpawn") {
@Override
public Location getLocation() {
return RegionSystem.INSTANCE.getWorldSpawn();
}
};
Warp worldSpawn = new Warp("WorldSpawn");
worldSpawn.setLocation(RegionSystem.INSTANCE.getWorldSpawn());
worldSpawn.setMat(Material.NETHER_STAR);
warpMap.put("WorldSpawn", worldSpawn);
}
private String name;
@Setter
private Location location;
@Setter
private Material mat;
private Warp(String name) {
@@ -98,13 +91,21 @@ public class Warp {
return warpMap.get(name);
}
public void setMat(Material mat) {
this.mat = mat;
}
public void setLocation(Location location) {
this.location = location;
}
public void delete() {
warpMap.remove(name);
WorldData.getWarpData().remove(name);
}
public void teleport(Player player) {
player.teleport(getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
player.playSound(getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1, 1);
player.teleport(location, PlayerTeleportEvent.TeleportCause.PLUGIN);
player.playSound(location, Sound.ENTITY_ENDERMAN_TELEPORT, SoundCategory.PLAYERS, 1, 1);
}
}

View File

@@ -122,7 +122,7 @@ public class BauScoreboard implements Listener {
if (region.getType().isGlobal()) return "§eSteam§8War";
String colorCode = "§e";
if (region.getRegionData().has(Flag.COLOR).isReadable()) {
colorCode = "§" + region.getRegionData().get(Flag.COLOR).getWithDefault().getColorCode();
colorCode = "§" + region.getRegionData().get(Flag.COLOR).orElse(ColorMode.PINK).getColorCode();
}
return colorCode + "■ §eSteam§8War " + colorCode + ""; // ■
}

View File

@@ -33,7 +33,7 @@ import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.stream.Stream;
public interface Region extends RegionDataStore {
public interface Region {
static Stream<Region> getRegions() {
return RegionSystem.INSTANCE.getRegions();
@@ -65,12 +65,6 @@ public interface Region extends RegionDataStore {
@NonNull
Area getTestblockArea();
default int getFloorLevel() {
Point p1 = getBuildArea().getMinPoint(true);
Point p2 = getTestblockArea().getMinPoint(true);
return Math.min(p1.getY(), p2.getY());
}
@NonNull
GameModeConfig<Material, String> getGameModeConfig();
@@ -154,14 +148,6 @@ public interface Region extends RegionDataStore {
return true;
}
default boolean inRegion(int x, int z, boolean extension) {
Point minPoint = getMinPoint(extension);
Point maxPoint = getMaxPoint(extension);
if (x < minPoint.getX() || x > maxPoint.getX()) return false;
if (z < minPoint.getZ() || z > maxPoint.getZ()) return false;
return true;
}
@Nullable
default Clipboard copy(boolean extension) {
return FlatteningWrapper.impl.copy(getMinPoint(extension), getMaxPoint(extension), getCopyPoint());

View File

@@ -41,7 +41,7 @@ public interface RegionBackups {
@RequiredArgsConstructor
@Getter
abstract class Backup implements RegionDataStore, Comparable<Backup> {
abstract class Backup {
@NonNull
private final BackupType type;
@@ -55,13 +55,6 @@ public interface RegionBackups {
public abstract boolean load();
public abstract void delete();
public abstract long getCreationTime();
@Override
public int compareTo(Backup o) {
return Long.compare(getCreationTime(), o.getCreationTime());
}
}
@CheckReturnValue

View File

@@ -22,6 +22,7 @@ package de.steamwar.bausystem.region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.sql.SchematicNode;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
import java.util.ArrayList;
import java.util.HashMap;
@@ -31,22 +32,66 @@ import java.util.function.Function;
public abstract class RegionData {
protected RegionDataStore store;
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 Property<SchematicNode, Integer> testblockSchematic = new Property<>("testblockSchematic", SchematicNode::byId, SchematicNode::getId);
protected RegionData(RegionDataStore store) {
this.store = store;
initialize();
store.loadRegionData(this);
private final class Property<T, K> {
private final String field;
private final Function<K, T> loader;
private final Function<T, K> writer;
private T value;
public Property(String field, Function<K, T> loader, Function<T, K> writer) {
this.field = field;
this.loader = loader;
this.writer = writer;
properties.add(this);
}
public void load() {
if (flagData.containsKey(field)) {
value = loader.apply(flagData.getPlainValue(field));
} else {
value = null;
}
}
public T get() {
return value;
}
public void set(T value) {
this.value = value;
if (value == null) {
flagData.remove(field);
} else {
flagData.put(field, writer.apply(value));
}
}
}
public void setStore(RegionDataStore store) {
this.store = store;
store.loadRegionData(this);
private Property<SchematicNode, Integer> testblockSchematic = new Property<>("testblockSchematic", SchematicNode::byId, SchematicNode::getId);
protected RegionData(YAPIONObject data, Runnable onChange) {
this.data = data;
this.flagData = data.getObjectOrSetDefault("flagStorage", new YAPIONObject());
this.onChange = onChange;
initialize();
for (final Flag flag : Flag.getFlags()) {
if (!has(flag).isWritable()) continue;
try {
String s = flagData.getPlainValue(flag.name());
flagMap.put(flag, flag.valueOfValue(s));
} catch (Exception e) {
flagMap.put(flag, (Flag.Value<?>) flag.getDefaultValue());
}
}
properties.forEach(Property::load);
}
protected void initialize() {
@@ -61,7 +106,8 @@ public abstract class RegionData {
public final <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
if (has(flag).isWritable()) {
if (flagMap.put(flag, value) != value) {
store.saveRegionData(this);
flagData.put(flag.name(), value.name());
onChange.run();
return true;
}
}
@@ -77,68 +123,30 @@ public abstract class RegionData {
for (Flag flag : Flag.getFlags()) {
if (has(flag).isWritable()) {
flagMap.remove(flag);
flagData.remove(flag.name());
}
}
properties.forEach(property -> property.set(null));
store.saveRegionData(this);
onChange.run();
}
public final Map<Flag<?>, Flag.Value<?>> getBackedMap() {
return flagMap;
}
public final List<Property<Object, Object>> getBackedProperties() {
return (List) properties;
}
public SchematicNode getTestblockSchematic() {
return testblockSchematic.get();
}
public void setTestblockSchematic(SchematicNode schematic) {
testblockSchematic.set(schematic);
store.saveRegionData(this);
onChange.run();
}
@Override
public final String toString() {
StringBuilder st = new StringBuilder();
st.append(getClass().getSimpleName()).append("{");
st.append("flagMap=").append(flagMap);
for (Property<?, ?> p : properties) {
st.append(p);
}
st.append("}");
return st.toString();
}
public final class Property<T, K> {
public final String field;
public final Function<K, T> loader;
public final Function<T, K> writer;
private T value;
private Property(String field, Function<K, T> loader, Function<T, K> writer) {
this.field = field;
this.loader = loader;
this.writer = writer;
properties.add(this);
}
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
@Override
public String toString() {
Object value = this.value;
if (value != null) value = writer.apply((T) value);
return ", " + field + "=" + value;
}
return getClass().getSimpleName() + "{" +
"flagMap=" + flagMap +
'}';
}
}

View File

@@ -19,7 +19,6 @@
package de.steamwar.bausystem.region;
import de.steamwar.core.Core;
import lombok.NonNull;
import org.bukkit.Location;
@@ -31,8 +30,6 @@ import java.util.stream.Stream;
public interface RegionSystem {
UUID GLOBAL_REGION_ID = new UUID(0, 0);
RegionSystem INSTANCE = init();
/**
@@ -40,6 +37,11 @@ public interface RegionSystem {
*/
void load();
/**
* Saves anything that should be written to file on either CRIUSleepEvent or plugin disable.
*/
void save();
/**
* Returns the Location to teleport players to when they first join or Warp to "WorldSpawn"
*/
@@ -73,51 +75,46 @@ public interface RegionSystem {
Stream<Region> getRegions();
private static RegionSystem init() {
if (Core.getVersion() >= 21) {
// TODO: Add some kind of detection if the DynamicRegionSystem should be used!
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 |
InvocationTargetException e) {
// Ignore
return new RegionSystem() {
@Override
public void load() {
throw new UnsupportedOperationException();
}
@Override
public void save() {
throw new UnsupportedOperationException();
}
@Override
public @NonNull Location getWorldSpawn() {
throw new UnsupportedOperationException();
}
@Override
public Region getGlobalRegion() {
throw new UnsupportedOperationException();
}
@Override
public Region get(Location location) {
throw new UnsupportedOperationException();
}
@Override
public Optional<Region> getRegion(UUID id) {
throw new UnsupportedOperationException();
}
@Override
public Stream<Region> getRegions() {
throw new UnsupportedOperationException();
}
};
}
return new RegionSystem() {
@Override
public void load() {
throw new UnsupportedOperationException();
}
@Override
public @NonNull Location getWorldSpawn() {
throw new UnsupportedOperationException();
}
@Override
public Region getGlobalRegion() {
throw new UnsupportedOperationException();
}
@Override
public Region get(Location location) {
throw new UnsupportedOperationException();
}
@Override
public Optional<Region> getRegion(UUID id) {
throw new UnsupportedOperationException();
}
@Override
public Stream<Region> getRegions() {
throw new UnsupportedOperationException();
}
};
}
}

View File

@@ -26,31 +26,9 @@ import lombok.RequiredArgsConstructor;
@Getter
public enum RegionType {
GLOBAL(true, false, true, ConnectionType.Global),
/**
* This should not be used by the DynamicRegionSystem
*/
NORMAL(false, true, false, ConnectionType.Closed),
SPAWN(false, false, true, ConnectionType.Closed),
SPAWN_PATH(false, false, true, ConnectionType.Path),
SPAWN_EXTENSION(false, false, false, ConnectionType.Closed),
PATH(false, false, false, ConnectionType.Path),
DRY(false, true, false, ConnectionType.Closed),
DRY_SPECIAL(false, false, false, ConnectionType.Closed),
WET(false, true, false, ConnectionType.Water),
WET_SPECIAL(false, false, false, ConnectionType.Water),
GLOBAL(true),
NORMAL(false),
;
private final boolean global;
private final boolean createBackup;
private final boolean cannotDelete;
private final ConnectionType connectionType;
public enum ConnectionType {
Closed,
Path,
Water,
Global
}
}

View File

@@ -28,7 +28,6 @@ import org.bukkit.entity.Player;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
@UtilityClass
public class RegionUtils {
@@ -59,12 +58,10 @@ public class RegionUtils {
}
public void forEachInRegion(Region region, Consumer<Player> consumer) {
Stream<? extends Player> players = Bukkit.getOnlinePlayers().stream();
if (region.getType().isGlobal()) {
players = players.filter(player -> Region.getRegion(player.getLocation()).getType().isGlobal());
} else {
players = players.filter(player -> region.getArea().inRegion(player.getLocation(), false));
}
players.forEach(consumer);
Bukkit.getOnlinePlayers()
.stream()
.filter(player -> region.getArea().inRegion(player.getLocation(), false))
.filter(player -> !region.getType().isGlobal() || Region.getRegion(player.getLocation()).getType().isGlobal())
.forEach(consumer);
}
}

View File

@@ -57,19 +57,6 @@ public class PasteBuilder {
this.clipboardProvider = clipboardProvider;
}
public PasteBuilder with(ClipboardProvider clipboardProvider) {
return new PasteBuilder(clipboardProvider)
.pastePoint(pastPoint)
.rotate(rotate)
.ignoreAir(ignoreAir)
.reset(reset)
.minPoint(minPoint)
.maxPoint(maxPoint)
.waterLevel(waterLevel)
.predicates(predicates)
.mappers(mappers);
}
public PasteBuilder pastePoint(Point point) {
this.pastPoint = point;
return this;
@@ -105,16 +92,6 @@ public class PasteBuilder {
return this;
}
private PasteBuilder predicates(List<BiPredicate<BaseBlock, String>> predicates) {
this.predicates = predicates;
return this;
}
public PasteBuilder mappers(List<BiConsumer<Clipboard, BlockVector3>> mappers) {
this.mappers = mappers;
return this;
}
public PasteBuilder only(BiPredicate<BaseBlock, String> predicate) {
predicates.add(predicate);
return this;
@@ -205,10 +182,10 @@ public class PasteBuilder {
}
public EditSession run() {
if (pastPoint != null || minPoint != null) {
return FlatteningWrapper.impl.paste(this);
if (pastPoint == null) {
throw new IllegalStateException("pastePoint is null");
}
throw new IllegalStateException("pastePoint is null");
return FlatteningWrapper.impl.paste(this);
}
public interface ClipboardProvider {

View File

@@ -1,48 +0,0 @@
/*
* 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(libs.classindex)
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)
}

View File

@@ -1,164 +0,0 @@
/*
* 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.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.Tile;
import de.steamwar.bausystem.region.dynamic.global.GlobalRegion;
import lombok.NonNull;
import org.bukkit.Location;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Stream;
public class DynamicRegionSystem implements RegionSystem {
public static DynamicRegionSystem INSTANCE;
private static final Map<Long, Region> regionCache = new LinkedHashMap<>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<Long, Region> eldest) {
return size() > 8192; // Tweak this number if needed!
}
}; // Will be cleared on region add/delete/remove!
private static final Map<UUID, Region> regionMap = new HashMap<>();
private static final Map<RegionType, Set<Region>> regionTypeMap = new EnumMap<>(RegionType.class);
public void add(DynamicRegion region) {
regionCache.clear();
regionMap.put(region.getID(), region);
regionTypeMap.computeIfAbsent(region.getType(), __ -> new HashSet<>()).add(region);
}
public void remove(DynamicRegion region) {
regionCache.clear();
regionMap.remove(region.getId());
regionTypeMap.getOrDefault(region.getType(), Collections.emptySet()).remove(region);
}
@Override
public void load() {
INSTANCE = this;
new BufferedReader(new InputStreamReader(BauSystem.getInstance().getClass().getResourceAsStream("/META-INF/annotations/de.steamwar.bausystem.region.dynamic.RegionConstructorData")))
.lines()
.map(s -> {
try {
return Class.forName(s, false, BauSystem.getInstance().getClass().getClassLoader());
} catch (ClassNotFoundException | NoClassDefFoundError e) {
throw new SecurityException(e.getMessage(), e);
}
})
.forEach(clazz -> {
RegionConstructorData regionConstructorData = clazz.getAnnotation(RegionConstructorData.class);
if (regionConstructorData == null) return;
// TODO: Save regionConstructorData together with clazz
});
}
@Override
public @NonNull Location getWorldSpawn() {
return null;
}
@Override
public @NonNull Region getGlobalRegion() {
return GlobalRegion.INSTANCE;
}
private Region get(int x, int z, boolean fastCache, Collection<Region> regions) {
Tile tile = Tile.fromXZ(x, z).orElse(null);
if (tile == null) {
return getGlobalRegion();
}
if (regionCache.containsKey(tile.getId())) {
Region region = regionCache.get(tile.getId());
if (fastCache || regions.contains(region)) return region;
}
Region region = regions.stream()
.filter(rg -> rg.getArea().inRegion(x, z, false))
.findFirst()
.orElseGet(this::getGlobalRegion);
regionCache.put(tile.getId(), region);
return region;
}
@Override
public @NonNull Region get(@NonNull Location location) {
return get(location.getBlockX(), location.getBlockZ(), true, regionMap.values());
}
@Override
public Optional<Region> getRegion(@NonNull UUID id) {
return Optional.ofNullable(regionMap.get(id));
}
@Override
public @NonNull Stream<Region> getRegions() {
return regionMap.values().stream();
}
private Stream<Region> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection<Region> regions) {
Point minPoint = region.getArea().getMinPoint(false).subtract(18, 0, 18);
Point maxPoint = region.getArea().getMaxPoint(false).add(19, 0, 19);
Set<Region> neighbours = new HashSet<>();
for (int x = minPoint.getX() + (noCorners ? 18 : 0); x <= maxPoint.getX() - (noCorners ? 19 : 0); x += 19) {
int minZ = minPoint.getZ();
int maxZ = maxPoint.getZ();
neighbours.add(get(x, minZ, fastCache, regions));
neighbours.add(get(x, maxZ, fastCache, regions));
}
for (int z = minPoint.getZ() + 18; z <= maxPoint.getZ() - 19; z += 19) {
int minX = minPoint.getX();
int maxX = maxPoint.getX();
neighbours.add(get(minX, z, fastCache, regions));
neighbours.add(get(maxX, z, fastCache, regions));
}
neighbours.remove(getGlobalRegion());
return neighbours.stream();
}
public Stream<Region> getNeighbours(Region region) {
return getNeighbours(region, false, true, regionMap.values());
}
public Stream<Region> getConnectedRegions(Region region) {
Set<Region> regions = regionTypeMap.get(region.getType());
Set<Region> connected = new HashSet<>();
LinkedHashSet<Region> current = new LinkedHashSet<>();
current.add(region);
while (!current.isEmpty()) {
Region r = current.removeFirst();
if (!connected.add(r)) continue;
getNeighbours(r, true, false, regions).forEach(current::add);
}
return connected.stream();
}
}

View File

@@ -1,55 +0,0 @@
/*
* 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.dynamic;
import de.steamwar.bausystem.region.DynamicRegionSystem;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionData;
import lombok.Getter;
import lombok.NonNull;
import java.util.UUID;
public abstract class DynamicRegion implements Region {
@Getter
protected final UUID id;
protected final int minX;
protected final int minZ;
protected DynamicRegion(UUID id, int minX, int minZ) {
this.id = id;
this.minX = minX;
this.minZ = minZ;
DynamicRegionSystem.INSTANCE.add(this);
// TODO: Implement further
}
public void update(DynamicRegion updateFrom) {
}
public abstract void setRegionData(@NonNull RegionData regionData);
public void delete() {
if (getType().isCannotDelete()) return;
DynamicRegionSystem.INSTANCE.remove(this);
// TODO: Implement!
}
}

View File

@@ -1,38 +0,0 @@
/*
* 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.dynamic;
import de.steamwar.bausystem.region.RegionData;
import org.atteo.classindex.IndexAnnotated;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@IndexAnnotated
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RegionConstructorData {
int widthX();
int widthZ();
boolean placeable() default true;
Class<? extends RegionData> regionDataClass();
}

View File

@@ -1,92 +0,0 @@
/*
* 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.dynamic;
import org.bukkit.Location;
import java.util.Optional;
public class Tile {
public static final int tileSize = 19;
public static final int maxTile = 1023;
public static final int minTile = -maxTile;
public static final int tilesPerAxis = maxTile * 2 + 1;
private final int tileX;
private final int tileZ;
private Tile(int tileX, int tileZ) {
this.tileX = tileX;
this.tileZ = tileZ;
}
public static Optional<Tile> fromTile(int tileX, int tileZ) {
if (tileX < minTile || tileZ < minTile) return Optional.empty();
if (tileX > maxTile || tileZ > maxTile) return Optional.empty();
return Optional.of(new Tile(tileX, tileZ));
}
public static Optional<Tile> fromLocation(Location location) {
return fromXZ(location.getBlockX(), location.getBlockZ());
}
public static Optional<Tile> fromXZ(int x, int z) {
x = (int) Math.floor((x + 9) / (double) tileSize);
z = (int) Math.floor((z + 9) / (double) tileSize);
return fromTile(x, z);
}
public static int getMinX(int tileX) {
return tileX * tileSize - 9;
}
public int getMinX() {
return getMinX(tileX);
}
public static int getMinZ(int tileZ) {
return tileZ * tileSize - 9;
}
public int getMinZ() {
return getMinZ(tileZ);
}
public static Location getMinLocation(int tileX, int tileZ) {
return new Location(null, getMinX(tileX), 0, getMinZ(tileZ));
}
public Location getMinLocation() {
return getMinLocation(tileX, tileZ);
}
public Optional<Tile> add(int offsetX, int offsetZ) {
return fromTile(tileX + offsetX, tileZ + offsetZ);
}
public static long getID(int tileX, int tileZ) {
return (tileX + maxTile) * tilesPerAxis + tileZ + maxTile;
}
public long getId() {
return getID(tileX, tileZ);
}
}

View File

@@ -1,145 +0,0 @@
/*
* 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.dynamic.global;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.bausystem.region.*;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.sql.GameModeConfig;
import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.Material;
import javax.annotation.Nullable;
import java.io.File;
import java.util.UUID;
import java.util.function.BiConsumer;
public class GlobalRegion implements Region {
public static final GlobalRegion INSTANCE = new GlobalRegion();
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 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 GlobalRegionData REGION_DATA = new GlobalRegionData(INSTANCE);
@Override
public @NonNull UUID getID() {
return RegionSystem.GLOBAL_REGION_ID;
}
@Override
public @NonNull RegionType getType() {
return RegionType.GLOBAL;
}
@Override
public @NonNull RegionData getRegionData() {
return REGION_DATA;
}
@Override
public @NonNull Area getArea() {
return GLOBAL_AREA;
}
@Override
public @NonNull Area getBuildArea() {
return Area.EMPTY;
}
@Override
public @NonNull Area getTestblockArea() {
return Area.EMPTY;
}
@Override
public @NonNull GameModeConfig<Material, String> getGameModeConfig() {
return GameModeConfig.getDefaults();
}
@Override
public @NonNull RegionHistory getHistory() {
return RegionHistory.EMPTY;
}
@Override
public @NonNull RegionBackups getBackups() {
return RegionBackups.EMPTY;
}
@Override
public void saveRegionData(@NonNull RegionData regionData) {
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
}
}

View File

@@ -1,58 +0,0 @@
/*
* 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.dynamic.global;
import de.steamwar.bausystem.region.RegionData;
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.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class GlobalRegionData extends RegionData {
public GlobalRegionData(GlobalRegion globalRegion) {
super(globalRegion);
}
@Override
protected void initialize() {
flagMap.put(Flag.TNT, TNTMode.DENY);
flagMap.put(Flag.COLOR, ColorMode.YELLOW);
flagMap.put(Flag.PROTECT, ProtectMode.INACTIVE);
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR, Flag.PROTECT)) {
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;
}
}

View File

@@ -1,46 +0,0 @@
/*
* 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)
}

View File

@@ -1,131 +0,0 @@
/*
* 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.features.region.RegionCommand;
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.TileUtils;
import de.steamwar.bausystem.region.dynamic.normal.display.MicroWarGear21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.display.MiniWarGear21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.display.WarGear21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.display.WarShip21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.MicroWarGear21WorkRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.MiniWarGear21WorkRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.WarGear21WorkRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.WarShip21WorkRegion;
import de.steamwar.bausystem.region.dynamic.path.PathRegion;
import de.steamwar.bausystem.region.dynamic.special.DrySpecialRegion;
import de.steamwar.bausystem.region.dynamic.special.WetSpecialRegion;
import de.steamwar.bausystem.shared.Pair;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.command.AbstractSWCommand;
import de.steamwar.command.SWCommand;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
@AbstractSWCommand.PartOf(RegionCommand.class)
public class DynamicRegionCommand extends SWCommand {
public DynamicRegionCommand() {
super("");
}
@Register({"dynamic", "place"})
public void placeRegion(Player player, Placement placement) {
Region region = DynamicRegionSystem.INSTANCE.get(player.getLocation());
if (!region.getType().isGlobal()) return;
Pair<Integer, Integer> tile = TileUtils.fromLocation(player.getLocation());
Pair<Integer, Integer> placePosition = placePosition(tile, placement);
if (placePosition == null) return;
Pair<Integer, Integer> min = TileUtils.toMinLocation(placePosition);
DynamicRegion dynamicRegion = placement.constructor.apply(min.getKey(), min.getValue());
dynamicRegion.getArea().reset(new PasteBuilder(new PasteBuilder.FileProvider(dynamicRegion.getArea().getResetFile())), false);
DynamicRegionSystem.INSTANCE.getNeighbours(dynamicRegion).collect(Collectors.toList())
.forEach(r -> r.update(dynamicRegion));
}
private Pair<Integer, Integer> placePosition(Pair<Integer, Integer> sourceTile, Placement placement) {
Map<Pair<Integer, Integer>, Region> regionCache = new HashMap<>();
Set<Pair<Integer, Integer>> seen = new HashSet<>();
LinkedHashSet<Pair<Integer, Integer>> currentTile = new LinkedHashSet<>();
currentTile.add(sourceTile);
while (!currentTile.isEmpty() && currentTile.size() < (placement.widthX * 2 / 19) * (placement.widthZ * 2 / 19)) {
Pair<Integer, Integer> tile = currentTile.removeFirst();
if (!seen.add(tile)) continue;
if (canPlace(tile, placement, regionCache)) {
return tile;
}
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (dx == 0 && dz == 0) continue;
Pair<Integer, Integer> nextTile = new Pair<>(tile.getKey() + dx, tile.getValue() + dz);
Region region = regionCache.computeIfAbsent(nextTile, tilePair -> Region.getRegion(TileUtils.toMinLocation(tilePair.getKey(), tilePair.getValue())));
if (region.getType().isGlobal()) currentTile.add(nextTile);
}
}
}
return null;
}
private boolean canPlace(Pair<Integer, Integer> tile, Placement placement, Map<Pair<Integer, Integer>, Region> regionCache) {
for (int x = tile.getKey(); x < tile.getKey() + placement.widthX / TileUtils.tileSize; x++) {
for (int z = tile.getValue(); z < tile.getValue() + placement.widthZ / TileUtils.tileSize; z++) {
Region region = regionCache.computeIfAbsent(new Pair<>(x, z), tilePair -> Region.getRegion(TileUtils.toMinLocation(tilePair.getKey(), tilePair.getValue())));
if (region.getType().isGlobal()) continue;
return false;
}
}
return true;
}
@RequiredArgsConstructor
public enum Placement {
Path(PathRegion::new, 19, 19),
WetSpecial(WetSpecialRegion::new, 19, 19),
DrySpecial(DrySpecialRegion::new, 19, 19),
WarGearWork21(WarGear21WorkRegion::new, WarGear21WorkRegion.widthX, WarGear21WorkRegion.widthZ),
WarGearDisplay21(WarGear21DisplayRegion::new, WarGear21DisplayRegion.widthX, WarGear21DisplayRegion.widthZ),
MiniWarGearWork21(MiniWarGear21WorkRegion::new, MiniWarGear21WorkRegion.widthX, MiniWarGear21WorkRegion.widthZ),
MiniWarGearDisplay21(MiniWarGear21DisplayRegion::new, MiniWarGear21DisplayRegion.widthX, MiniWarGear21DisplayRegion.widthZ),
WarShipWork21(WarShip21WorkRegion::new, WarShip21WorkRegion.widthX, WarShip21WorkRegion.widthZ),
WarShipDisplay21(WarShip21DisplayRegion::new, WarShip21DisplayRegion.widthX, WarShip21DisplayRegion.widthZ),
MicroWarGearWork21(MicroWarGear21WorkRegion::new, MicroWarGear21WorkRegion.widthX, MicroWarGear21WorkRegion.widthZ),
MicroWarGearDisplay21(MicroWarGear21DisplayRegion::new, MicroWarGear21DisplayRegion.widthX, MicroWarGear21DisplayRegion.widthZ),
;
private final BiFunction<Integer, Integer, DynamicRegion> constructor;
private final int widthX;
private final int widthZ;
}
@Register({"dynamic", "delete"})
public void deleteRegion(Player player) {
Region region = DynamicRegionSystem.INSTANCE.get(player.getLocation());
if (region.getType().isCannotDelete()) return;
((DynamicRegion) region).delete();
}
}

View File

@@ -1,154 +0,0 @@
/*
* 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.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.MovementListener;
import de.steamwar.bausystem.region.dynamic.RegionDataRepository;
import de.steamwar.bausystem.region.dynamic.global.GlobalRegion;
import de.steamwar.bausystem.region.dynamic.path.PathRegion;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnPathRegion;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnResetter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DynamicRegionSystem implements RegionSystem {
public static DynamicRegionSystem INSTANCE;
private static final World WORLD = Bukkit.getWorlds().get(0);
private static Map<UUID, Region> regionMap = new HashMap<>();
@Override
public void load() {
INSTANCE = this;
new DynamicRegionCommand();
RegionDataRepository.loadRegions();
Bukkit.getPluginManager().registerEvents(new MovementListener(), BauSystem.getInstance());
if (regionMap.isEmpty()) { // TODO: Implement this in default region!
new SpawnRegion(-9, -9);
new SpawnPathRegion(-9, -28);
new SpawnPathRegion(-9, 10);
new SpawnPathRegion(-28, -9);
new SpawnPathRegion(10, -9);
new PathRegion(-28, -28);
new PathRegion(-28, 10);
new PathRegion(10, -28);
new PathRegion(10, 10);
}
}
public void add(DynamicRegion region) {
regionMap.put(region.getID(), region);
}
public void delete(DynamicRegion region) {
regionMap.remove(region.getID());
}
@Override
public @NonNull Location getWorldSpawn() {
if (SpawnResetter.isBigSpawn()) {
return SpawnResetter.BIG_WORLD_SPAWN;
} else {
return SpawnResetter.SMALL_WORLD_SPAWN;
}
}
@Override
public @NonNull Region getGlobalRegion() {
return GlobalRegion.INSTANCE;
}
// TODO: Optimize later on!
private Region get(Location location, Collection<Region> regions) {
return regions.stream()
.filter(region -> region.getArea().inRegion(location, false))
.findFirst()
.orElse(GlobalRegion.INSTANCE);
}
@Override
public @NonNull Region get(@NonNull Location location) {
return get(location, regionMap.values());
}
@Override
public Optional<Region> getRegion(@NonNull UUID id) {
return Optional.ofNullable(regionMap.get(id));
}
@Override
public @NonNull Stream<Region> getRegions() {
return regionMap.values().stream();
}
private Stream<DynamicRegion> getNeighbours(Region region, boolean noCorners, Collection<Region> regions) {
Point minPoint = region.getArea().getMinPoint(false).subtract(18, 0, 18);
Point maxPoint = region.getArea().getMaxPoint(false).add(19, 0, 19);
Set<Region> neighbours = new HashSet<>();
for (int x = minPoint.getX() + (noCorners ? 18 : 0); x <= maxPoint.getX() - (noCorners ? 19 : 0); x += 19) {
int minZ = minPoint.getZ();
int maxZ = maxPoint.getZ();
neighbours.add(get(new Location(WORLD, x, 0, minZ), regions));
neighbours.add(get(new Location(WORLD, x, 0, maxZ), regions));
}
for (int z = minPoint.getZ() + 18; z <= maxPoint.getZ() - 19; z += 19) {
int minX = minPoint.getX();
int maxX = maxPoint.getX();
neighbours.add(get(new Location(WORLD, minX, 0, z), regions));
neighbours.add(get(new Location(WORLD, maxX, 0, z), regions));
}
neighbours.remove(GlobalRegion.INSTANCE);
return ((Set<DynamicRegion>) (Set) neighbours).stream();
}
public Stream<DynamicRegion> getNeighbours(Region region) {
return getNeighbours(region, false, regionMap.values());
}
public Stream<DynamicRegion> getConnectedRegions(DynamicRegion region) {
Set<Region> regions = regionMap.values()
.stream()
.filter(r -> r.getType() == region.getType())
.collect(Collectors.toSet());
Set<DynamicRegion> connectedRegions = new HashSet<>();
LinkedHashSet<DynamicRegion> current = new LinkedHashSet<>();
current.add(region);
while (!current.isEmpty()) {
DynamicRegion r = current.removeFirst();
if (!connectedRegions.add(r)) continue;
getNeighbours(r, true, regions).forEach(current::add);
}
return connectedRegions.stream();
}
}

View File

@@ -1,66 +0,0 @@
/*
* 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.FlagOptional;
import de.steamwar.bausystem.region.FlagStorage;
import de.steamwar.bausystem.region.flags.Flag;
import lombok.NonNull;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public abstract class DefaultFlagStorage implements FlagStorage {
protected Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>();
private Consumer<FlagStorage> operation;
@Override
public <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
if (has(flag).isWritable()) {
boolean result = flagMap.put(flag, value) != value;
if (operation != null) {
operation.accept(this);
}
return result;
} else {
return false;
}
}
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> FlagOptional<T> get(@NonNull Flag<T> flag) {
return FlagOptional.of(flag, (T) flagMap.get(flag));
}
@Override
public Map<Flag<?>, Flag.Value<?>> getBackedMap() {
return flagMap;
}
public void setSaveOperation(Consumer<FlagStorage> operation) {
this.operation = operation;
}
public void save() {
operation.accept(this);
}
}

View File

@@ -1,104 +0,0 @@
/*
* 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 com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.bausystem.region.DynamicRegionSystem;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionBackups;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.util.UUID;
import java.util.stream.Collectors;
public abstract class DynamicRegion implements Region {
@Getter
protected final UUID ID;
protected final int minX;
protected final int minZ;
@Getter
protected final RegionBackups backups;
protected DynamicRegion(int minX, int minZ) {
this.ID = UUID.randomUUID();
this.minX = minX;
this.minZ = minZ;
backups = RegionDataRepository.getBackups(this);
RegionDataRepository.saveRegion(this);
DynamicRegionSystem.INSTANCE.add(this);
}
protected DynamicRegion(RegionConstructorData regionConstructorData) {
this.ID = regionConstructorData.uuid;
this.minX = regionConstructorData.minX;
this.minZ = regionConstructorData.minZ;
backups = RegionDataRepository.getBackups(this);
RegionDataRepository.saveRegion(this);
DynamicRegionSystem.INSTANCE.add(this);
}
public RegionConstructorData getRegionConstructorData() {
return new RegionConstructorData.RegionConstructorDataBuilder()
.regionClass(this.getClass().getSimpleName())
.uuid(ID)
.minX(minX)
.minZ(minZ)
.build();
}
public abstract void update(DynamicRegion updateFrom);
public abstract void setFlags(DefaultFlagStorage flags);
@Override
public abstract @NonNull DefaultFlagStorage getFlags();
public void delete() {
if (getType().isCannotDelete()) return;
DynamicRegionSystem.INSTANCE.delete(this);
RegionDataRepository.deleteRegion(this);
Point minPoint = getArea().getMinPoint(false);
Point maxPoint = getArea().getMaxPoint(false);
EditSession editSession = WorldEdit.getInstance()
.newEditSessionBuilder()
.world(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)))
.checkMemory(false)
.allowedRegionsEverywhere()
.limitUnlimited()
.changeSetNull()
.build();
editSession.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(minPoint.toBlockVector3(), maxPoint.toBlockVector3()), BlockTypes.AIR.getDefaultState());
editSession.close();
DynamicRegionSystem.INSTANCE.getNeighbours(this).collect(Collectors.toList())
.forEach(region -> region.update(this));
}
}

View File

@@ -1,42 +0,0 @@
/*
* 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 de.steamwar.bausystem.shared.Pair;
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;
public class MovementListener implements Listener {
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
Pair<Integer, Integer> tile = TileUtils.fromLocation(event.getTo());
Region region = Region.getRegion(event.getTo());
if (tile != null) {
event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(tile.getKey() + " : " + tile.getValue() + " " + region.getType()));
} else {
event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("NONE " + region.getType()));
}
}
}

View File

@@ -1,63 +0,0 @@
/*
* 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.FlagOptional;
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.core.Core;
import lombok.NonNull;
import lombok.ToString;
@ToString
public class NonNormalFlagStorage extends DefaultFlagStorage {
public NonNormalFlagStorage() {
flagMap.put(Flag.TNT, TNTMode.DENY);
}
@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 @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 super.get(flag);
}
}

View File

@@ -1,60 +0,0 @@
/*
* 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 com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Cleanup;
import lombok.SneakyThrows;
import java.io.File;
import java.io.FileWriter;
import java.util.UUID;
@Builder
@AllArgsConstructor
public class RegionConstructorData {
public final String regionClass;
public final UUID uuid;
public final int minX;
public final int minZ;
public RegionConstructorData(JsonObject jsonObject, UUID uuid) {
regionClass = jsonObject.get("regionClass").getAsString();
this.uuid = uuid;
minX = jsonObject.get("minX").getAsInt();
minZ = jsonObject.get("minZ").getAsInt();
}
@SneakyThrows
public void write(File file) {
@Cleanup
JsonWriter writer = new JsonWriter(new FileWriter(file));
writer.setIndent(" ");
writer.beginObject();
writer.name("regionClass").value(regionClass);
writer.name("minX").value(minX);
writer.name("minZ").value(minZ);
writer.endObject();
}
}

View File

@@ -1,321 +0,0 @@
/*
* 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 com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonWriter;
import com.sk89q.worldedit.EditSession;
import de.steamwar.bausystem.region.FlagStorage;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionBackups;
import de.steamwar.bausystem.region.dynamic.normal.NormalFlagStorage;
import de.steamwar.bausystem.region.dynamic.normal.display.MicroWarGear21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.display.MiniWarGear21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.display.WarGear21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.display.WarShip21DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.MicroWarGear21WorkRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.MiniWarGear21WorkRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.WarGear21WorkRegion;
import de.steamwar.bausystem.region.dynamic.normal.work.WarShip21WorkRegion;
import de.steamwar.bausystem.region.dynamic.path.PathRegion;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnPathRegion;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnRegion;
import de.steamwar.bausystem.region.dynamic.special.DrySpecialRegion;
import de.steamwar.bausystem.region.dynamic.special.WetSpecialRegion;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.Cleanup;
import lombok.NonNull;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import javax.annotation.Nullable;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
@UtilityClass
public class RegionDataRepository {
public static final String META_FILE_NAME = "meta.json";
public static final String FLAGS_FILE_NAME = "flags.json";
public static final String REGION_SCHEM_FILE_NAME = "region.schem";
public static final String BACKUP_DIRECTORY = "backup";
private static File regionDataFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "regions");
private static Map<String, Function<RegionConstructorData, DynamicRegion>> regionCreators = new HashMap<>();
static {
regionCreators.put(SpawnRegion.class.getSimpleName(), SpawnRegion::new);
regionCreators.put(SpawnPathRegion.class.getSimpleName(), SpawnPathRegion::new);
regionCreators.put(PathRegion.class.getSimpleName(), PathRegion::new);
regionCreators.put(DrySpecialRegion.class.getSimpleName(), DrySpecialRegion::new);
regionCreators.put(WetSpecialRegion.class.getSimpleName(), WetSpecialRegion::new);
regionCreators.put(WarGear21WorkRegion.class.getSimpleName(), WarGear21WorkRegion::new);
regionCreators.put(WarGear21DisplayRegion.class.getSimpleName(), WarGear21DisplayRegion::new);
regionCreators.put("WarGear21Region", WarGear21WorkRegion::new); // TODO: Legacy because of rename
regionCreators.put(MiniWarGear21WorkRegion.class.getSimpleName(), MiniWarGear21WorkRegion::new);
regionCreators.put(MiniWarGear21DisplayRegion.class.getSimpleName(), MiniWarGear21DisplayRegion::new);
regionCreators.put("MiniWarGear21Region", MiniWarGear21WorkRegion::new); // TODO: Legacy because of rename
regionCreators.put(WarShip21WorkRegion.class.getSimpleName(), WarShip21WorkRegion::new);
regionCreators.put(WarShip21DisplayRegion.class.getSimpleName(), WarShip21DisplayRegion::new);
regionCreators.put("WarShip21Region", WarShip21WorkRegion::new); // TODO: Legacy because of rename
regionCreators.put(MicroWarGear21WorkRegion.class.getSimpleName(), MicroWarGear21WorkRegion::new);
regionCreators.put(MicroWarGear21DisplayRegion.class.getSimpleName(), MicroWarGear21DisplayRegion::new);
regionCreators.put("MicroWarGear21Region", MicroWarGear21WorkRegion::new); // TODO: Legacy because of rename
}
static {
regionDataFolder.mkdirs();
}
private File getRegionDirectory(Region region) {
File file = new File(regionDataFolder, region.getID().toString());
file.mkdirs();
return file;
}
@SneakyThrows
public List<DynamicRegion> loadRegions() {
File[] files = regionDataFolder.listFiles();
List<DynamicRegion> regions = new ArrayList<>();
for (File file : files) {
File metaFile = new File(file, META_FILE_NAME);
if (!metaFile.exists()) continue;
JsonObject jsonObject = JsonParser.parseReader(new FileReader(metaFile)).getAsJsonObject();
RegionConstructorData regionConstructorData = new RegionConstructorData(jsonObject, UUID.fromString(file.getName()));
Function<RegionConstructorData, DynamicRegion> constructor = regionCreators.get(regionConstructorData.regionClass);
if (constructor == null) continue;
regions.add(constructor.apply(regionConstructorData));
}
return regions;
}
public void saveRegion(DynamicRegion region) {
File file = getRegionDirectory(region);
file = new File(file, META_FILE_NAME);
region.getRegionConstructorData()
.write(file);
}
public void deleteRegion(DynamicRegion region) {
deleteDir(getRegionDirectory(region));
}
public void loadFlagStorage(Region region, DefaultFlagStorage storage) {
File file = getRegionDirectory(region);
file = new File(file, FLAGS_FILE_NAME);
loadFlagStorage(file, storage);
if (!file.exists()) saveFlagStorage(region, storage);
storage.setSaveOperation(currentStorage -> {
saveFlagStorage(region, currentStorage);
});
}
@SneakyThrows
private void loadFlagStorage(File file, FlagStorage storage) {
if (file == null || !file.exists()) return;
JsonObject jsonObject = JsonParser.parseReader(new FileReader(file)).getAsJsonObject();
for (Flag flag : Flag.getFlags()) {
if (!jsonObject.has(flag.name())) continue;
Flag.Value<?> value;
try {
value = flag.valueOfValue(jsonObject.get(flag.name()).getAsString());
} catch (IllegalArgumentException e) {
continue;
}
storage.getBackedMap().put(flag, value);
}
}
private void saveFlagStorage(Region region, FlagStorage storage) {
File file = getRegionDirectory(region);
file = new File(file, FLAGS_FILE_NAME);
saveFlagStorage(file, storage);
}
@SneakyThrows
public void saveFlagStorage(File file, FlagStorage storage) {
file.getParentFile().mkdirs();
@Cleanup
JsonWriter jsonWriter = new JsonWriter(new FileWriter(file));
jsonWriter.setIndent(" ");
jsonWriter.beginObject();
for (Map.Entry<Flag<?>, Flag.Value<?>> entry : storage.getBackedMap().entrySet()) {
if (entry.getKey() == Flag.CHANGED) continue;
jsonWriter.name(entry.getKey().name());
jsonWriter.value(entry.getValue().name());
}
jsonWriter.endObject();
}
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd'_'HH:mm:ss");
public RegionBackups getBackups(DynamicRegion region) {
if (!region.getType().isCreateBackup()) {
return RegionBackups.EMPTY;
}
File directory = new File(getRegionDirectory(region), BACKUP_DIRECTORY);
directory.mkdirs();
return new RegionBackups() {
private List<Backup> backups = new ArrayList<>();
{
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
backups.add(new BackupImpl(file, region));
}
}
backups.sort(null);
}
@Override
@SneakyThrows
public Optional<Backup> create(BackupType backupType) {
String name = LocalDateTime.now().format(formatter);
File backupDirectory = new File(directory, name);
backupDirectory.mkdirs();
Point minPoint = region.getArea().getMinPoint(false);
Point maxPoint = region.getArea().getMaxPoint(false);
boolean success = FlatteningWrapper.impl.backup(minPoint, maxPoint, new File(backupDirectory, REGION_SCHEM_FILE_NAME));
if (!success) {
deleteDir(backupDirectory);
return Optional.empty();
}
int count = 0;
for (int i = backups.size() - 1; i >= 0; i--) {
Backup backup = backups.get(i);
if (backup.getType() == backupType) {
if (count >= backupType.maxBackups - 1) {
backup.delete();
backups.remove(i);
continue;
}
count++;
}
}
new File(backupDirectory, backupType.name()).createNewFile();
saveFlagStorage(new File(backupDirectory, FLAGS_FILE_NAME), region.getFlags());
Backup backup = new BackupImpl(backupDirectory, region);
backups.add(backup);
return Optional.of(backup);
}
@Override
public @NonNull List<Backup> list() {
return backups;
}
@Nullable
@Override
public Backup get(String name) {
for (Backup backup : backups) {
if (backup.getName().equals(name)) {
return backup;
}
}
return null;
}
};
}
private static class BackupImpl extends RegionBackups.Backup {
private final File file;
private final DynamicRegion region;
public BackupImpl(File file, DynamicRegion region) {
super(getType(file), file.getName(), getFlags(file));
this.file = file;
this.region = region;
}
private static RegionBackups.BackupType getType(File file) {
for (RegionBackups.BackupType type : RegionBackups.BackupType.values()) {
if (new File(file, type.name()).exists()) return type;
}
throw new IllegalArgumentException("Unknown backup type");
}
private static FlagStorage getFlags(File file) {
NormalFlagStorage storage = new NormalFlagStorage();
loadFlagStorage(new File(file, FLAGS_FILE_NAME), storage);
return storage;
}
@Override
public boolean load() {
if (!file.exists()) return false;
EditSession editSession = new PasteBuilder(new PasteBuilder.FileProvider(new File(file, REGION_SCHEM_FILE_NAME)))
.pastePoint(region.getArea().getMinPoint(false))
.minPoint(region.getArea().getMinPoint(false))
.maxPoint(region.getArea().getMaxPoint(false))
.run();
region.getHistory().remember(editSession);
region.getFlags().setSaveOperation(null);
region.setFlags((DefaultFlagStorage) getFlags());
region.getFlags().setSaveOperation(storage -> saveFlagStorage(region, storage));
return true;
}
@Override
public void delete() {
deleteDir(file);
}
@Override
public long getCreationTime() {
return file.lastModified();
}
}
@SneakyThrows
private static void deleteDir(File file) {
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
}

View File

@@ -1,48 +0,0 @@
/*
* 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.shared.Pair;
import lombok.experimental.UtilityClass;
import org.bukkit.Location;
@UtilityClass
public class TileUtils {
public static final int tileSize = 19;
public static final int minTile = -1023;
public static final int maxTile = 1023;
public Pair<Integer, Integer> fromLocation(Location location) {
int x = (int) Math.floor((location.getBlockX() + 9) / (double) tileSize);
int z = (int) Math.floor((location.getBlockZ() + 9) / (double) tileSize);
if (x < minTile || z < minTile) return null;
if (x > maxTile || z > maxTile) return null;
return new Pair<>(x, z);
}
public Pair<Integer, Integer> toMinLocation(Pair<Integer, Integer> tile) {
return new Pair<>(tile.getKey() * tileSize - 9, tile.getValue() * tileSize - 9);
}
public Location toMinLocation(int tileX, int tileZ) {
return new Location(null, tileX * tileSize - 9, 0, tileZ * tileSize - 9);
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.NonNull;
import java.io.File;
import java.time.LocalDate;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
public interface VariantSelector {
Optional<File> selectVariant(int minX, int minZ);
default VariantSelector or(VariantSelector other) {
return (minX, minZ) -> selectVariant(minX, minZ).or(() -> other.selectVariant(minX, minZ));
}
static VariantSelector AtDate(int day, int month, File file) {
return (minX, minZ) -> {
LocalDate date = LocalDate.now();
if (date.getDayOfMonth() == day && date.getMonthValue() == month) {
return Optional.of(file);
} else {
return Optional.empty();
}
};
}
static VariantSelector File(@NonNull File file) {
return (minX, minZ) -> Optional.of(file);
}
static VariantSelector StableVariants(@NonNull File directory) {
File[] files = directory.listFiles();
Random rand = new Random();
return (minX, minZ) -> {
rand.setSeed(Objects.hash(minX, minZ));
return Optional.of(files[rand.nextInt(files.length)]);
};
}
static VariantSelector RandomVariants(@NonNull File directory) {
File[] files = directory.listFiles();
Random rand = new Random();
return (minX, minZ) -> {
return Optional.of(files[rand.nextInt(files.length)]);
};
}
}

View File

@@ -1,143 +0,0 @@
/*
* 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.DefaultFlagStorage;
import de.steamwar.bausystem.region.dynamic.NonNormalFlagStorage;
import de.steamwar.bausystem.region.dynamic.RegionDataRepository;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.sql.GameModeConfig;
import lombok.NonNull;
import org.bukkit.Location;
import javax.annotation.Nullable;
import java.io.File;
import java.util.UUID;
import java.util.function.BiConsumer;
public class GlobalRegion implements Region {
public static final GlobalRegion INSTANCE = new GlobalRegion();
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 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 DefaultFlagStorage FLAG_STORAGE = new NonNormalFlagStorage();
static {
RegionDataRepository.loadFlagStorage(INSTANCE, FLAG_STORAGE);
}
private GlobalRegion() {
}
@Override
public RegionType getType() {
return RegionType.GLOBAL;
}
@Override
public @NonNull UUID getID() {
return RegionSystem.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 GameModeConfig getGameModeConfig() {
return GameModeConfig.EMPTY;
}
@Override
public @NonNull RegionHistory getHistory() {
return RegionHistory.EMPTY;
}
@Override
public @NonNull RegionBackups getBackups() {
return RegionBackups.EMPTY;
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.normal;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.dynamic.DefaultFlagStorage;
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.RegionDataRepository;
import lombok.Getter;
import lombok.NonNull;
public abstract class DisplayRegion extends DynamicRegion {
@Getter
private DefaultFlagStorage flags = new NormalFlagStorage();
@Getter
protected NormalArea area = NormalArea.EMPTY;
@Getter
private final RegionHistory history = new RegionHistory.Impl(20);
protected DisplayRegion(int minX, int minZ) {
super(minX, minZ);
RegionDataRepository.loadFlagStorage(this, flags);
}
protected DisplayRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
RegionDataRepository.loadFlagStorage(this, flags);
}
@Override
public void update(DynamicRegion updateFrom) {
}
@Override
public void setFlags(DefaultFlagStorage flags) {
this.flags = flags;
}
@Override
public @NonNull Area getBuildArea() {
return Area.EMPTY;
}
@Override
public @NonNull Area getTestblockArea() {
return Area.EMPTY;
}
}

View File

@@ -1,126 +0,0 @@
/*
* 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.normal;
import com.sk89q.worldedit.EditSession;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.NonNull;
import org.bukkit.Location;
import javax.annotation.Nullable;
import java.io.File;
import java.util.function.BiConsumer;
public class NormalArea implements Region.Area {
public static final NormalArea EMPTY = new NormalArea(0, 0, 0, 0, 0, 0, null, false, null) {
@Override
public void reset(PasteBuilder pasteBuilder, boolean extension) {
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean inRegion(Location location, boolean extension) {
return false;
}
@Override
public void forEachChunk(BiConsumer<Integer, Integer> executor) {
}
@Override
public boolean isChunkOutside(int chunkX, int chunkZ) {
return true;
}
};
private final int minX;
private final int minY;
private final int minZ;
private final int widthX;
private final int widthY;
private final int widthZ;
private VariantSelector variantSelector;
private final Point minPoint;
private final Point maxPoint;
private final Point copyPoint;
private final boolean rotate;
private final Region region;
public NormalArea(int minX, int minY, int minZ, int widthX, int widthY, int widthZ, VariantSelector variantSelector, boolean rotate, Region region) {
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.widthX = widthX;
this.widthY = widthY;
this.widthZ = widthZ;
this.variantSelector = variantSelector;
this.rotate = rotate;
this.region = region;
minPoint = new Point(minX, minY, minZ);
maxPoint = new Point(minX + widthX - 1, minY + widthY - 1, minZ + widthZ - 1);
copyPoint = minPoint.add(widthX / 2, widthY, widthZ / 2);
}
@Override
public @NonNull Point getMinPoint(boolean extension) {
return minPoint;
}
@Override
public @NonNull Point getMaxPoint(boolean extension) {
return maxPoint;
}
@Override
public @NonNull Point getCopyPoint() {
return copyPoint;
}
public NormalArea setResetFile(VariantSelector variantSelector) {
this.variantSelector = variantSelector;
return this;
}
@Nullable
@Override
public File getResetFile() {
return variantSelector.selectVariant(minX, minZ).orElseThrow();
}
@Override
public void reset(PasteBuilder pasteBuilder, boolean extension) {
EditSession editSession = pasteBuilder.minPoint(minPoint)
.maxPoint(maxPoint)
.rotate(rotate)
.color(region.getFlags().get(Flag.COLOR).getWithDefault())
.run();
region.getHistory().remember(editSession);
}
}

View File

@@ -1,42 +0,0 @@
/*
* 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.normal;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.dynamic.DefaultFlagStorage;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.core.Core;
import lombok.NonNull;
import lombok.ToString;
@ToString
public class NormalFlagStorage extends DefaultFlagStorage {
@Override
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.TESTBLOCK, Flag.CHANGED)) {
return RegionFlagPolicy.WRITABLE;
}
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
return RegionFlagPolicy.WRITABLE;
}
return RegionFlagPolicy.NOT_APPLICABLE;
}
}

View File

@@ -1,90 +0,0 @@
/*
* 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.normal;
import de.steamwar.bausystem.region.FlagOptional;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.dynamic.*;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.TestblockMode;
import lombok.Getter;
import lombok.NonNull;
public abstract class WorkRegion extends DynamicRegion {
@Getter
private DefaultFlagStorage flags = new NormalFlagStorage();
@Getter
protected NormalArea area = NormalArea.EMPTY;
protected NormalArea northArea = NormalArea.EMPTY;
protected NormalArea southArea = NormalArea.EMPTY;
protected VariantSelector frame;
protected VariantSelector testblock;
@Getter
private final RegionHistory history = new RegionHistory.Impl(20);
protected WorkRegion(int minX, int minZ) {
super(minX, minZ);
RegionDataRepository.loadFlagStorage(this, flags);
}
protected WorkRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
RegionDataRepository.loadFlagStorage(this, flags);
}
@Override
public void update(DynamicRegion updateFrom) {
}
@Override
public void setFlags(DefaultFlagStorage flags) {
this.flags = flags;
}
@Override
public @NonNull Area getBuildArea() {
FlagOptional<TestblockMode> testblock = flags.get(Flag.TESTBLOCK);
if (testblock.isWithDefault(TestblockMode.NO_VALUE)) {
return Area.EMPTY;
}
if (testblock.isWithDefault(TestblockMode.SOUTH)) {
return northArea.setResetFile(this.frame);
} else {
return southArea.setResetFile(this.frame);
}
}
@Override
public @NonNull Area getTestblockArea() {
FlagOptional<TestblockMode> testblock = flags.get(Flag.TESTBLOCK);
if (testblock.isWithDefault(TestblockMode.NO_VALUE)) {
return Area.EMPTY;
}
if (testblock.isWithDefault(TestblockMode.SOUTH)) {
return southArea.setResetFile(this.testblock);
} else {
return northArea.setResetFile(this.testblock);
}
}
}

View File

@@ -1,59 +0,0 @@
/*
* 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.normal.display;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class MicroWarGear21DisplayRegion extends DisplayRegion {
public static final int widthX = 57;
public static final int widthZ = 57;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/microwargear21/");
private static final File REGION_FILE = new File(MODE_DIR, "Display.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public MicroWarGear21DisplayRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
public MicroWarGear21DisplayRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,59 +0,0 @@
/*
* 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.normal.display;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class MiniWarGear21DisplayRegion extends DisplayRegion {
public static final int widthX = 57;
public static final int widthZ = 38;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/miniwargear21/");
private static final File REGION_FILE = new File(MODE_DIR, "Display.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public MiniWarGear21DisplayRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
public MiniWarGear21DisplayRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,59 +0,0 @@
/*
* 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.normal.display;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class WarGear21DisplayRegion extends DisplayRegion {
public static final int widthX = 133;
public static final int widthZ = 95;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/wargear21/");
private static final File REGION_FILE = new File(MODE_DIR, "Display.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public WarGear21DisplayRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
public WarGear21DisplayRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,59 +0,0 @@
/*
* 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.normal.display;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.DisplayRegion;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class WarShip21DisplayRegion extends DisplayRegion {
public static final int widthX = 266;
public static final int widthZ = 95;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/warship21/");
private static final File REGION_FILE = new File(MODE_DIR, "Display.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public WarShip21DisplayRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
public WarShip21DisplayRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.normal.work;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import de.steamwar.bausystem.region.dynamic.normal.WorkRegion;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class MicroWarGear21WorkRegion extends WorkRegion {
public static final int widthX = 57;
public static final int widthZ = 114;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/microwargear21/");
private static final File REGION_FILE = new File(MODE_DIR, "Work.schem");
private static final File FRAME_FILE = new File(MODE_DIR, "Frame.schem");
private static final File TESTBLOCK_FILE = new File(MODE_DIR, "Testblock.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public MicroWarGear21WorkRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 25, 32, minZ + 25, 7, 7, 7, null, false, this);
southArea = new NormalArea(minX + 25, 32, minZ + 82, 7, 7, 7, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
public MicroWarGear21WorkRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 25, 32, minZ + 25, 7, 7, 7, null, false, this);
southArea = new NormalArea(minX + 25, 32, minZ + 82, 7, 7, 7, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.normal.work;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import de.steamwar.bausystem.region.dynamic.normal.WorkRegion;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class MiniWarGear21WorkRegion extends WorkRegion {
public static final int widthX = 95;
public static final int widthZ = 152;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/miniwargear21/");
private static final File REGION_FILE = new File(MODE_DIR, "Work.schem");
private static final File FRAME_FILE = new File(MODE_DIR, "Frame.schem");
private static final File TESTBLOCK_FILE = new File(MODE_DIR, "Testblock.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public MiniWarGear21WorkRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 29, 32, minZ + 29, 37, 26, 22, null, false, this);
southArea = new NormalArea(minX + 29, 32, minZ + 101, 37, 26, 22, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
public MiniWarGear21WorkRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 29, 32, minZ + 29, 37, 26, 22, null, false, this);
southArea = new NormalArea(minX + 29, 32, minZ + 101, 37, 26, 22, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.normal.work;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import de.steamwar.bausystem.region.dynamic.normal.WorkRegion;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class WarGear21WorkRegion extends WorkRegion {
public static final int widthX = 133;
public static final int widthZ = 228;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/wargear21/");
private static final File REGION_FILE = new File(MODE_DIR, "Work.schem");
private static final File FRAME_FILE = new File(MODE_DIR, "Frame.schem");
private static final File TESTBLOCK_FILE = new File(MODE_DIR, "Testblock.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public WarGear21WorkRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 33, 32, minZ + 42, 67, 41, 47, null, false, this);
southArea = new NormalArea(minX + 33, 32, minZ + 139, 67, 41, 47, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
public WarGear21WorkRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 33, 32, minZ + 42, 67, 41, 47, null, false, this);
southArea = new NormalArea(minX + 33, 32, minZ + 139, 67, 41, 47, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY;
}
}

View File

@@ -1,69 +0,0 @@
/*
* 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.normal.work;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.region.dynamic.normal.NormalArea;
import de.steamwar.bausystem.region.dynamic.normal.WorkRegion;
import lombok.Getter;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class WarShip21WorkRegion extends WorkRegion {
public static final int widthX = 285;
public static final int widthZ = 228;
private static final File MODE_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/regions/warship21/");
private static final File REGION_FILE = new File(MODE_DIR, "Work.schem");
private static final File FRAME_FILE = new File(MODE_DIR, "Frame.schem");
private static final File TESTBLOCK_FILE = new File(MODE_DIR, "Testblock.schem");
@Getter
private final GameModeConfig gameModeConfig = new GameModeConfig(null); // TODO: Implement
public WarShip21WorkRegion(int minX, int minZ) {
super(minX, minZ);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 28, 19, minZ + 25, 230, 58, 43, null, false, this);
southArea = new NormalArea(minX + 28, 19, minZ + 160, 230, 58, 43, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
public WarShip21WorkRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new NormalArea(minX, 0, minZ, widthX, 255, widthZ, VariantSelector.File(REGION_FILE), false, this);
northArea = new NormalArea(minX + 28, 19, minZ + 25, 230, 58, 43, null, false, this);
southArea = new NormalArea(minX + 28, 19, minZ + 160, 230, 58, 43, null, true, this);
frame = VariantSelector.File(FRAME_FILE);
testblock = VariantSelector.File(TESTBLOCK_FILE);
}
@Override
public @NonNull RegionType getType() {
return RegionType.WET;
}
}

View File

@@ -1,162 +0,0 @@
/*
* 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.path;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionSystem;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.World;
import javax.annotation.Nullable;
import java.io.File;
import java.util.function.Function;
public class PathAreaTile implements Region.Area { // TODO: Change to VariantSelector
private static final File PATH_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections/path");
private static final File PATH_CENTER = new File(PATH_DIR, "PathCenter.schem");
@RequiredArgsConstructor
private enum Path {
North(0, -18, 5, 0, 0),
South(0, 19, 5, 0, 180),
West(-18, 0, 5, 0, 90),
East(19, 0, 5, 0, 270),
;
private final int checkX;
private final int checkZ;
private final int pasteX;
private final int pasteZ;
private final int rotate;
private static final Function<RegionType.ConnectionType, File> function = connectionType -> {
return new File(PATH_DIR, "PathEdge" + connectionType.name() + ".schem");
};
}
@RequiredArgsConstructor
private enum PathCorner {
NorthEast(Path.North, Path.East, 14, 0, 0),
EastSouth(Path.East, Path.South, 14, 0, 270),
SouthWest(Path.South, Path.West, 14, 0, 180),
WestNorth(Path.West, Path.North, 14, 0, 90),
;
private final Path check1;
private final Path check2;
private final int pasteX;
private final int pasteZ;
private final int rotate;
private static final TriFunction<RegionType.ConnectionType, RegionType.ConnectionType, RegionType.ConnectionType, File> function = (connectionType1, connectionType2, connectionTypeCorner) -> {
return new File(PATH_DIR, "PathCorner" + connectionType1.name() + connectionType2.name() + connectionTypeCorner.name() + ".schem");
};
private interface TriFunction<T, U, V, W> {
W apply(T t, U u, V v);
}
}
private final int minX;
private final int minZ;
private final Point minPoint;
private final Point maxPoint;
private final Point copyPoint;
private final Region region;
public PathAreaTile(int minX, int minZ, Region region) {
this.minX = minX;
this.minZ = minZ;
minPoint = new Point(minX, 0, minZ);
maxPoint = new Point(minX + 18, 255, minZ + 18);
copyPoint = new Point(minX + 9, 0, minZ + 9);
this.region = region;
}
@Override
public @NonNull Point getMinPoint(boolean extension) {
return minPoint;
}
@Override
public @NonNull Point getMaxPoint(boolean extension) {
return maxPoint;
}
@Override
public @NonNull Point getCopyPoint() {
return copyPoint;
}
@Nullable
@Override
public File getResetFile() {
return null; // I know what I do!
}
@Override
public void reset(PasteBuilder pasteBuilder, boolean extension) {
Point minPoint = getMinPoint(false);
paste(PATH_CENTER, minPoint.add(5, 0, 5), 0);
for (Path path : Path.values()) {
RegionType.ConnectionType connectionType = RegionSystem.INSTANCE.get(minPoint.add(path.checkX, 0, path.checkZ).toLocation((World) null)).getType().getConnectionType();
File schem = path.function.apply(connectionType);
if (schem.exists()) {
paste(schem, minPoint.add(path.pasteX, 0, path.pasteZ), path.rotate);
}
}
for (PathCorner corner : PathCorner.values()) {
RegionType.ConnectionType connectionType1 = RegionSystem.INSTANCE.get(minPoint.add(corner.check1.checkX, 0, corner.check1.checkZ).toLocation((World) null)).getType().getConnectionType();
RegionType.ConnectionType connectionType2 = RegionSystem.INSTANCE.get(minPoint.add(corner.check2.checkX, 0, corner.check2.checkZ).toLocation((World) null)).getType().getConnectionType();
RegionType.ConnectionType connectionTypeCorner = RegionSystem.INSTANCE.get(minPoint.add(corner.check1.checkX + corner.check2.checkX, 0, corner.check1.checkZ + corner.check2.checkZ).toLocation((World) null)).getType().getConnectionType();
File schem = corner.function.apply(connectionType1, connectionType2, connectionTypeCorner);
if (schem.exists()) {
System.out.println(connectionType1 + " " + connectionType2 + " " + connectionTypeCorner + " " + schem);
paste(schem, minPoint.add(corner.pasteX, 0, corner.pasteZ), corner.rotate);
} else {
System.out.println(connectionType1 + " " + connectionType2 + " " + connectionTypeCorner + " " + PATH_DIR.getAbsolutePath() + "/PathCornerUnknown.schem");
paste(new File(PATH_DIR, "PathCornerUnknown.schem"), minPoint.add(corner.pasteX, 0, corner.pasteZ), corner.rotate);
}
}
}
private void paste(File file, Point minPoint, int rotate) {
Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(file);
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
BlockVector3 to = minPoint.toBlockVector3().subtract(offset);
clipboard.paste(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)), to, false, true, new AffineTransform().rotateY(rotate));
}
}

View File

@@ -1,109 +0,0 @@
/*
* 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.path;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.*;
import de.steamwar.bausystem.region.dynamic.spawn.SpawnAreaTile;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class PathRegion extends DynamicRegion {
private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections");
private static final File RESET_FILE = new File(SECTIONS_DIR, "path/Path.schem"); // Temp
private DefaultFlagStorage flagStorage = new NonNormalFlagStorage();
private final Area area;
public PathRegion(int minX, int minZ) {
super(minX, minZ);
RegionDataRepository.loadFlagStorage(this, flagStorage);
if (minX >= -28 && minX <= 10 && minZ >= -28 && minZ <= 10) {
area = new SpawnAreaTile(minX, minZ, VariantSelector.File(RESET_FILE), this);
} else {
area = new PathAreaTile(minX, minZ, this);
}
}
public PathRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
RegionDataRepository.loadFlagStorage(this, flagStorage);
if (minX >= -28 && minX <= 10 && minZ >= -28 && minZ <= 10) {
area = new SpawnAreaTile(minX, minZ, VariantSelector.File(RESET_FILE), this);
} else {
area = new PathAreaTile(minX, minZ, this);
}
}
@Override
public void update(DynamicRegion updateFrom) {
if (area instanceof PathAreaTile) {
area.reset(null, false);
}
}
@Override
public void setFlags(DefaultFlagStorage flags) {
}
@Override
public @NonNull RegionType getType() {
if (area instanceof SpawnAreaTile) {
return RegionType.SPAWN_EXTENSION;
} else {
return RegionType.PATH;
}
}
@Override
public @NonNull DefaultFlagStorage getFlags() {
return flagStorage;
}
@Override
public @NonNull Area getArea() {
return area;
}
@Override
public @NonNull Area getBuildArea() {
return Area.EMPTY;
}
@Override
public @NonNull Area getTestblockArea() {
return Area.EMPTY;
}
@Override
public @NonNull GameModeConfig getGameModeConfig() {
return GameModeConfig.EMPTY;
}
@Override
public @NonNull RegionHistory getHistory() {
return RegionHistory.EMPTY;
}
}

View File

@@ -1,78 +0,0 @@
/*
* 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.spawn;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.NonNull;
import javax.annotation.Nullable;
import java.io.File;
public class SpawnAreaTile implements Region.Area {
private final int minX;
private final int minZ;
private final VariantSelector variantSelector;
private final Point minPoint;
private final Point maxPoint;
private final Point copyPoint;
private final Region region;
public SpawnAreaTile(int minX, int minZ, VariantSelector variantSelector, Region region) {
this.minX = minX;
this.minZ = minZ;
this.variantSelector = variantSelector;
minPoint = new Point(minX, 0, minZ);
maxPoint = new Point(minX + 18, 255, minZ + 18);
copyPoint = new Point(minX + 9, 0, minZ + 9);
this.region = region;
}
@Override
public @NonNull Point getMinPoint(boolean extension) {
return minPoint;
}
@Override
public @NonNull Point getMaxPoint(boolean extension) {
return maxPoint;
}
@Override
public @NonNull Point getCopyPoint() {
return copyPoint;
}
@Nullable
@Override
public File getResetFile() {
return variantSelector.selectVariant(minX, minZ).orElseThrow();
}
@Override
public void reset(PasteBuilder pasteBuilder, boolean extension) {
SpawnResetter.reset(region);
}
}

View File

@@ -1,110 +0,0 @@
/*
* 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.spawn;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.*;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class SpawnPathRegion extends DynamicRegion {
private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections");
private static final File RESET_FILE_NORTH = new File(SECTIONS_DIR, "spawn/SpawnNorth.schem");
private static final File RESET_FILE_SOUTH = new File(SECTIONS_DIR, "spawn/SpawnSouth.schem");
private static final File RESET_FILE_WEST = new File(SECTIONS_DIR, "spawn/SpawnWest.schem");
private static final File RESET_FILE_EAST = new File(SECTIONS_DIR, "spawn/SpawnEast.schem");
private DefaultFlagStorage flagStorage = new NonNormalFlagStorage();
private final Area area;
public SpawnPathRegion(int minX, int minZ) {
super(minX, minZ);
RegionDataRepository.loadFlagStorage(this, flagStorage);
area = new SpawnAreaTile(minX, minZ, getResetFile(minX, minZ), this);
}
public SpawnPathRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
RegionDataRepository.loadFlagStorage(this, flagStorage);
area = new SpawnAreaTile(minX, minZ, getResetFile(minX, minZ), this);
}
private static VariantSelector getResetFile(int minX, int minZ) {
if (minX == -28) {
return VariantSelector.File(RESET_FILE_WEST);
} else if (minX == 10) {
return VariantSelector.File(RESET_FILE_EAST);
} else if (minZ == -28) {
return VariantSelector.File(RESET_FILE_NORTH);
} else if (minZ == 10) {
return VariantSelector.File(RESET_FILE_SOUTH);
}
throw new IllegalArgumentException("Invalid minX: " + minX + ", minZ: " + minZ);
}
@Override
public void update(DynamicRegion updateFrom) {
// TODO: Implement
}
@Override
public void setFlags(DefaultFlagStorage flags) {
}
@Override
public @NonNull RegionType getType() {
return RegionType.SPAWN_PATH;
}
@Override
public @NonNull DefaultFlagStorage getFlags() {
return flagStorage;
}
@Override
public @NonNull Area getArea() {
return area;
}
@Override
public @NonNull Area getBuildArea() {
return Area.EMPTY;
}
@Override
public @NonNull Area getTestblockArea() {
return Area.EMPTY;
}
@Override
public @NonNull GameModeConfig getGameModeConfig() {
return GameModeConfig.EMPTY;
}
@Override
public @NonNull RegionHistory getHistory() {
return RegionHistory.EMPTY;
}
}

View File

@@ -1,94 +0,0 @@
/*
* 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.spawn;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.*;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class SpawnRegion extends DynamicRegion {
private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections");
private static final File RESET_FILE = new File(SECTIONS_DIR, "spawn/SpawnMiddle.schem");
private DefaultFlagStorage flagStorage = new NonNormalFlagStorage();
private final Area area;
public SpawnRegion(int minX, int minZ) {
super(minX, minZ);
RegionDataRepository.loadFlagStorage(this, flagStorage);
area = new SpawnAreaTile(minX, minZ, VariantSelector.File(RESET_FILE), this);
}
public SpawnRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
RegionDataRepository.loadFlagStorage(this, flagStorage);
area = new SpawnAreaTile(minX, minZ, VariantSelector.File(RESET_FILE), this);
}
@Override
public void update(DynamicRegion updateFrom) {
SpawnResetter.reset(null);
}
@Override
public void setFlags(DefaultFlagStorage flags) {
}
@Override
public @NonNull RegionType getType() {
return RegionType.SPAWN;
}
@Override
public @NonNull DefaultFlagStorage getFlags() {
return flagStorage;
}
@Override
public @NonNull Area getArea() {
return area;
}
@Override
public @NonNull Area getBuildArea() {
return Area.EMPTY;
}
@Override
public @NonNull Area getTestblockArea() {
return Area.EMPTY;
}
@Override
public @NonNull GameModeConfig getGameModeConfig() {
return GameModeConfig.EMPTY;
}
@Override
public @NonNull RegionHistory getHistory() {
return RegionHistory.EMPTY;
}
}

View File

@@ -1,99 +0,0 @@
/*
* 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.spawn;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import de.steamwar.bausystem.region.*;
import de.steamwar.bausystem.utils.FlatteningWrapper;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
@UtilityClass
public class SpawnResetter {
private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections");
private static final File RESET_FILE = new File(SECTIONS_DIR, "spawn/SpawnBig.schem");
public static final Location BIG_WORLD_SPAWN = new Location(Bukkit.getWorlds().get(0), 0.5, 26, 0.5);
public static final Location SMALL_WORLD_SPAWN = new Location(Bukkit.getWorlds().get(0), 0.5, 32, 0.5);
private static final Location LOCATION = new Location(null, 0, 0, 0);
public boolean isBigSpawn() {
Region spawnRegion = DynamicRegionSystem.INSTANCE.get(LOCATION);
List<Region> neighbours = DynamicRegionSystem.INSTANCE.getNeighbours(spawnRegion)
.filter(r -> r.getType() == RegionType.PATH || r.getType() == RegionType.SPAWN_EXTENSION || r.getType() == RegionType.SPAWN_PATH)
.collect(Collectors.toList());
return neighbours.size() == 8;
}
public void reset(Region region) {
Region spawnRegion = DynamicRegionSystem.INSTANCE.get(LOCATION);
List<Region> neighbours = DynamicRegionSystem.INSTANCE.getNeighbours(spawnRegion)
.filter(r -> r.getType() == RegionType.PATH || r.getType() == RegionType.SPAWN_EXTENSION || r.getType() == RegionType.SPAWN_PATH)
.collect(Collectors.toList());
if (neighbours.size() == 8) {
Bukkit.getWorlds().get(0).setSpawnLocation(BIG_WORLD_SPAWN);
Region.Area area = spawnRegion.getArea();
Point minPoint = area.getMinPoint(false).subtract(19, 0, 19);
Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(RESET_FILE);
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
BlockVector3 to = minPoint.toBlockVector3().subtract(offset);
clipboard.paste(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)), to);
if (spawnRegion != region) {
RegionUtils.message(spawnRegion, "REGION_RESET_RESETED");
}
neighbours.forEach(r -> {
if (r != region) {
RegionUtils.message(r, "REGION_RESET_RESETED");
}
});
return;
} else {
Bukkit.getWorlds().get(0).setSpawnLocation(SMALL_WORLD_SPAWN);
}
internalReset(spawnRegion, spawnRegion != region);
DynamicRegionSystem.INSTANCE.getNeighbours(spawnRegion)
.forEach(r -> internalReset(r, r != region));
}
private void internalReset(Region region, boolean message) {
Region.Area area = region.getArea();
Point minPoint = area.getMinPoint(false);
Clipboard clipboard = FlatteningWrapper.impl.loadSchematic(area.getResetFile());
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
BlockVector3 to = minPoint.toBlockVector3().subtract(offset);
clipboard.paste(BukkitAdapter.adapt(Bukkit.getWorlds().get(0)), to);
if (message) {
RegionUtils.message(region, "REGION_RESET_RESETED");
}
}
}

View File

@@ -1,54 +0,0 @@
/*
* 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.special;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class DrySpecialRegion extends SpecialRegion {
private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections");
private static final File RESET_FILE = new File(SECTIONS_DIR, "special/DryRegion.schem");
public DrySpecialRegion(int minX, int minZ) {
super(minX, minZ);
area = new SpecialAreaTile(minX, minZ, VariantSelector.File(RESET_FILE));
}
public DrySpecialRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new SpecialAreaTile(minX, minZ, VariantSelector.File(RESET_FILE));
}
@Override
public @NonNull RegionType getType() {
return RegionType.DRY_SPECIAL;
}
@Override
public int getFloorLevel() {
return 32;
}
}

View File

@@ -1,78 +0,0 @@
/*
* 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.special;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import de.steamwar.bausystem.utils.PasteBuilder;
import lombok.NonNull;
import javax.annotation.Nullable;
import java.io.File;
public class SpecialAreaTile implements Region.Area {
private final int minX;
private final int minZ;
private final VariantSelector variantSelector;
private final Point minPoint;
private final Point maxPoint;
private final Point copyPoint;
public SpecialAreaTile(int minX, int minZ, VariantSelector variantSelector) {
this.minX = minX;
this.minZ = minZ;
this.variantSelector = variantSelector;
minPoint = new Point(minX, 0, minZ);
maxPoint = new Point(minX + 18, 255, minZ + 18);
copyPoint = new Point(minX + 9, 0, minZ + 9);
}
@Override
public @NonNull Point getMinPoint(boolean extension) {
return minPoint;
}
@Override
public @NonNull Point getMaxPoint(boolean extension) {
return maxPoint;
}
@Override
public @NonNull Point getCopyPoint() {
return copyPoint;
}
@Nullable
@Override
public File getResetFile() {
return variantSelector.selectVariant(minX, minZ).orElseThrow();
}
@Override
public void reset(PasteBuilder pasteBuilder, boolean extension) {
pasteBuilder.minPoint(minPoint)
.maxPoint(maxPoint)
.run();
}
}

View File

@@ -1,47 +0,0 @@
/*
* 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.special;
import de.steamwar.bausystem.region.DynamicRegionSystem;
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.normal.NormalFlagStorage;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.TNTMode;
import lombok.NonNull;
public class SpecialFlagStorage extends NormalFlagStorage {
private DynamicRegion region;
public SpecialFlagStorage(DynamicRegion region) {
this.region = region;
flagMap.put(Flag.TNT, TNTMode.DENY);
}
@Override
public <T extends Enum<T> & Flag.Value<T>> boolean set(@NonNull Flag<T> flag, @NonNull T value) {
boolean result = super.set(flag, value);
DynamicRegionSystem.INSTANCE.getConnectedRegions(region).forEach(other -> {
other.getFlags().getBackedMap().put(flag, value);
other.getFlags().save();
});
return result;
}
}

View File

@@ -1,77 +0,0 @@
/*
* 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.special;
import de.steamwar.bausystem.region.GameModeConfig;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.dynamic.DefaultFlagStorage;
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.RegionDataRepository;
import lombok.Getter;
import lombok.NonNull;
public abstract class SpecialRegion extends DynamicRegion {
@Getter
private DefaultFlagStorage flags = new SpecialFlagStorage(this);
@Getter
protected SpecialAreaTile area;
protected SpecialRegion(int minX, int minZ) {
super(minX, minZ);
RegionDataRepository.loadFlagStorage(this, flags);
}
protected SpecialRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
RegionDataRepository.loadFlagStorage(this, flags);
}
@Override
public void update(DynamicRegion updateFrom) {
}
@Override
public void setFlags(DefaultFlagStorage flags) {
this.flags = flags;
}
@Override
public @NonNull Area getBuildArea() {
return Area.EMPTY;
}
@Override
public @NonNull Area getTestblockArea() {
return Area.EMPTY;
}
@Override
public @NonNull GameModeConfig getGameModeConfig() {
return GameModeConfig.EMPTY;
}
@Override
public @NonNull RegionHistory getHistory() {
return RegionHistory.EMPTY;
}
}

View File

@@ -1,49 +0,0 @@
/*
* 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.special;
import de.steamwar.bausystem.region.RegionType;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.VariantSelector;
import lombok.NonNull;
import org.bukkit.Bukkit;
import java.io.File;
public class WetSpecialRegion extends SpecialRegion {
private static final File SECTIONS_DIR = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "sections");
private static final File RESET_FILE = new File(SECTIONS_DIR, "special/WetRegion.schem");
public WetSpecialRegion(int minX, int minZ) {
super(minX, minZ);
area = new SpecialAreaTile(minX, minZ, VariantSelector.File(RESET_FILE));
}
public WetSpecialRegion(RegionConstructorData regionConstructorData) {
super(regionConstructorData);
area = new SpecialAreaTile(minX, minZ, VariantSelector.File(RESET_FILE));
}
@Override
public @NonNull RegionType getType() {
return RegionType.WET_SPECIAL;
}
}

View File

@@ -46,6 +46,10 @@ public class FixedRegionSystem implements RegionSystem {
RegionLoader.load();
}
@Override
public void save() {
}
@Override
public @NonNull Location getWorldSpawn() {
Location spawnLocation = Bukkit.getWorlds().get(0).getSpawnLocation();

View File

@@ -21,15 +21,12 @@ package de.steamwar.bausystem.region.fixed;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.bausystem.region.*;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.sql.GameModeConfig;
import lombok.NonNull;
import lombok.Setter;
import org.bukkit.Location;
import org.bukkit.Material;
import yapion.hierarchy.types.YAPIONObject;
import javax.annotation.Nullable;
import java.io.File;
@@ -46,6 +43,8 @@ public final class FixedGlobalRegion implements Region {
@Setter
private static RegionData FLAG_STORAGE;
private static final UUID GLOBAL_REGION_ID = new UUID(0, 0);
private static final Area GLOBAL_AREA = new Area() {
@Override
public @NonNull Point getMinPoint(boolean extension) {
@@ -103,7 +102,7 @@ public final class FixedGlobalRegion implements Region {
@Override
public @NonNull UUID getID() {
return RegionSystem.GLOBAL_REGION_ID;
return GLOBAL_REGION_ID;
}
@Override
@@ -140,14 +139,4 @@ public final class FixedGlobalRegion implements Region {
public @NonNull RegionBackups getBackups() {
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);
}
}

View File

@@ -20,7 +20,6 @@
package de.steamwar.bausystem.region.fixed;
import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionDataStore;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.ColorMode;
import de.steamwar.bausystem.region.flags.Flag;
@@ -28,11 +27,12 @@ import de.steamwar.bausystem.region.flags.ProtectMode;
import de.steamwar.bausystem.region.flags.TNTMode;
import de.steamwar.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class FixedGlobalRegionData extends RegionData {
public FixedGlobalRegionData(RegionDataStore store) {
super(store);
public FixedGlobalRegionData(YAPIONObject data, Runnable onChange) {
super(data, onChange);
}
@Override

View File

@@ -137,25 +137,12 @@ public class FixedRegion implements Region {
public void delete() {
file.delete();
}
@Override
public long getCreationTime() {
return file.lastModified();
}
@Override
public void saveRegionData(@NonNull RegionData regionData) {
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
}
}
public FixedRegion(String name, Prototype prototype, YAPIONObject regionConfig) {
public FixedRegion(String name, FixedRegionData flagStorage, Prototype prototype, YAPIONObject regionConfig, YAPIONObject regionData) {
this.name = name;
uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
this.flagStorage = new FixedRegionData(this);
this.flagStorage = flagStorage;
this.prototype = prototype;
this.skin = prototype.getDefaultSkin();
@@ -400,14 +387,4 @@ public class FixedRegion implements Region {
public @NonNull RegionBackups getBackups() {
return regionBackups;
}
@Override
public void saveRegionData(@NonNull RegionData regionData) {
FixedRegionDataUtils.saveRegionData(name, regionData);
}
@Override
public void loadRegionData(@NonNull RegionData regionData) {
FixedRegionDataUtils.loadRegionData(name, regionData);
}
}

View File

@@ -20,16 +20,16 @@
package de.steamwar.bausystem.region.fixed;
import de.steamwar.bausystem.region.RegionData;
import de.steamwar.bausystem.region.RegionDataStore;
import de.steamwar.bausystem.region.RegionFlagPolicy;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.core.Core;
import lombok.NonNull;
import yapion.hierarchy.types.YAPIONObject;
public class FixedRegionData extends RegionData {
public FixedRegionData(RegionDataStore store) {
super(store);
public FixedRegionData(YAPIONObject data, Runnable onChange) {
super(data, onChange);
}
@Override

View File

@@ -1,64 +0,0 @@
/*
* 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));
});
}
}

View File

@@ -210,8 +210,14 @@ public class Prototype {
}
}
public static void generateRegion(String name, YAPIONObject regionConfig) {
Prototype prototype = PROTOTYPE_MAP.get(regionConfig.getPlainValue("prototype"));
FixedRegionSystem.addRegion(new FixedRegion(name, prototype, regionConfig));
public static void generateRegion(String name, YAPIONObject regionConfig, YAPIONObject regionData) {
Prototype prototype;
if (regionData.containsKey("prototype", String.class)) {
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));
}
}

View File

@@ -19,14 +19,16 @@
package de.steamwar.bausystem.region.fixed.loader;
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
import de.steamwar.bausystem.region.fixed.Prototype;
import de.steamwar.bausystem.worlddata.WorldData;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import yapion.hierarchy.diff.DiffChange;
import yapion.hierarchy.diff.YAPIONDiff;
import yapion.hierarchy.types.YAPIONObject;
import yapion.hierarchy.types.YAPIONType;
import yapion.parser.YAPIONParser;
import java.io.BufferedInputStream;
@@ -53,6 +55,7 @@ public class RegionLoader {
}
loaded = yapionObject;
YAPIONObject optionsYapionObject = WorldData.getRegionsData();
yapionObject.forEach((key, yapionAnyType) -> {
if (key.equals("global")) {
return;
@@ -60,9 +63,23 @@ public class RegionLoader {
if (!(yapionAnyType instanceof YAPIONObject)) {
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);
});
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(FixedGlobalRegion.INSTANCE));
YAPIONObject globalOptions = optionsYapionObject.getObject("global");
if (globalOptions == null) {
globalOptions = new YAPIONObject();
optionsYapionObject.add("global", globalOptions);
}
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(globalOptions, WorldData::write));
}
}

View File

@@ -28,7 +28,6 @@ tasks.build {
dependencies {
implementation(project(":BauSystem:BauSystem_RegionFixed"))
implementation(project(":BauSystem:BauSystem_RegionDynamic"))
implementation(project(":BauSystem:BauSystem_Main"))
implementation(project(":BauSystem:BauSystem_15"))
implementation(project(":BauSystem:BauSystem_18"))
@@ -54,12 +53,3 @@ tasks.register<DevServer>("DevBau21") {
dependsOn(":SchematicSystem:shadowJar")
template = "Bau21"
}
tasks.register<DevServer>("DevBau21Dynamic") {
group = "run"
description = "Run a 1.21 Dynamic Dev Bau"
dependsOn(":BauSystem:shadowJar")
dependsOn(":SchematicSystem:shadowJar")
template = "Bau21-Dynamic"
jar = "/jars/paper-1.21.6.jar"
}

View File

@@ -24,4 +24,5 @@ plugins {
dependencies {
testImplementation(libs.junit)
testImplementation(libs.hamcrest)
compileOnly(project(":CommonCore:SQL"))
}

View File

@@ -1,7 +1,7 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
* Copyright (C) 2026 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
@@ -17,14 +17,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.region.dynamic;
package de.steamwar
import de.steamwar.bausystem.region.RegionData;
import yapion.hierarchy.types.YAPIONObject;
public abstract class DefaultRegionData extends RegionData {
protected DefaultRegionData(YAPIONObject data, Runnable onChange) {
super(data, onChange);
}
}
data class ServerInfo(val name: String, val version: Int, val checkpointed: Boolean)

View File

@@ -0,0 +1,71 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2026 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.logger
import de.steamwar.sql.AuditLog
import de.steamwar.sql.AuditLogTable
import de.steamwar.sql.SQLWrapper
import de.steamwar.sql.SteamwarUser
import de.steamwar.sql.internal.useDb
import org.jetbrains.exposed.v1.jdbc.insertIgnore
class LogEntry(val type: AuditLog.Type, val user: SteamwarUser) {
private val start = System.currentTimeMillis()
var text: String = ""
var arguments: String = ""
private var exceptionType: String? = null
private var exceptionText: String? = null
private var exceptionStacktrace: String? = null
private var owner: SteamwarUser? = null
fun addException(e: Throwable) {
exceptionType = e.javaClass.name
exceptionText = e.message
exceptionStacktrace = e.stackTraceToString()
}
fun addServerOwner(owner: SteamwarUser) {
this.owner = owner
}
fun finish() {
val end = System.currentTimeMillis()
val info = SQLWrapper.impl.serverInfo
useDb {
AuditLogTable.insertIgnore {
it[this.action] = type
it[this.actor] = user.getId()
it[this.actionText] = text
it[this.actionArguments] = arguments
it[this.duration] = end - start
it[this.errorType] = exceptionType
it[this.errorText] = exceptionText
it[this.stackTrace] = exceptionStacktrace
it[this.server] = info.name
it[this.checkpointed] = info.checkpointed
it[this.duration] = end - start
it[this.serverOwner] = owner?.getId()
}
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2025 SteamWar.de-Serverteam
* Copyright (C) 2026 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
@@ -17,11 +17,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.region;
package de.steamwar.logger
import lombok.NonNull;
import de.steamwar.sql.AuditLog
import de.steamwar.sql.SteamwarUser
public interface RegionDataStore {
void saveRegionData(@NonNull RegionData regionData);
void loadRegionData(@NonNull RegionData regionData);
}
object SWLogger {
fun startCommand(user: SteamwarUser) = LogEntry(AuditLog.Type.COMMAND, user)
}

View File

@@ -19,94 +19,47 @@
package de.steamwar.sql
import de.steamwar.sql.internal.useDb
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.dao.id.IntIdTable
import org.jetbrains.exposed.v1.dao.IntEntity
import org.jetbrains.exposed.v1.dao.IntEntityClass
import org.jetbrains.exposed.v1.javatime.timestamp
import java.time.Instant
object AuditLogTable: IntIdTable("AuditLog", "AuditLogId") {
val time = timestamp("Time")
val server = varchar("ServerName", 255)
val serverOwner = reference("ServerOwner", SteamwarUserTable).nullable()
val serverType = varchar("ServerType", 255)
val serverOwner = optReference("ServerOwner", SteamwarUserTable)
val checkpointed = bool("Checkpointed")
val actor = reference("Actor", SteamwarUserTable)
val action = enumerationByName("ActionType", 255, AuditLog.Type::class)
val actionText = text("ActionText")
val actionArguments = text("ActionArguments")
val duration = long("Duration")
val errorType = text("ErrorType").nullable()
val errorText = text("ErrorText").nullable()
val stackTrace = text("StackTrace").nullable()
}
class AuditLog(id: EntityID<Int>): IntEntity(id) {
companion object: IntEntityClass<AuditLog>(AuditLogTable) {
const val SERVER_NAME_VELOCITY: String = "Velocity"
private fun create(
serverName: String,
serverOwner: SteamwarUser?,
actor: SteamwarUser,
actionType: Type,
text: String = ""
) = useDb {
new {
this.time = Instant.now()
this.server = serverName
this.serverOwner = serverOwner?.id
this.actor = actor.id
this.action = actionType
this.actionText = text
}
}
@JvmStatic
fun createJoin(jointServerName: String, serverOwner: SteamwarUser?, joinedPlayer: SteamwarUser) = create(jointServerName, serverOwner, joinedPlayer, Type.JOIN)
@JvmStatic
fun createLeave(leftServerName: String, serverOwner: SteamwarUser?, joinedPlayer: SteamwarUser) = create(leftServerName, serverOwner, joinedPlayer, Type.LEAVE)
@JvmStatic
fun createCommand(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser?, command: String) = player?.let { create(serverName, serverOwner, it, Type.COMMAND, command) }
@JvmStatic
fun createSensitiveCommand(
serverName: String,
serverOwner: SteamwarUser?,
player: SteamwarUser?,
command: String
) = player?.let { create(serverName, serverOwner, it, Type.SENSITIVE_COMMAND, command) }
@JvmStatic
fun createChat(serverName: String, serverOwner: SteamwarUser?, chatter: SteamwarUser, chat: String) = create(serverName, serverOwner, chatter, Type.CHAT, chat)
@JvmStatic
fun createGuiOpen(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser, guiName: String) = create(serverName, serverOwner, player, Type.GUI_OPEN, guiName)
@JvmStatic
fun createGuiClick(
serverName: String,
serverOwner: SteamwarUser?,
player: SteamwarUser,
guiName: String,
clickType: String,
slot: Int,
itemName: String
) = create(
serverName,
serverOwner,
player,
Type.GUI_CLICK,
"Gui: $guiName\nSlot: $slot\nClickType: $clickType\nItemName: $itemName"
)
@JvmStatic
fun createGuiClose(serverName: String, serverOwner: SteamwarUser?, player: SteamwarUser, guiName: String) = create(serverName, serverOwner, player, Type.GUI_CLOSE, guiName)
@JvmField
val SERVER_NAME_VELOCITY: String = "Velocity"
}
var time by AuditLogTable.time
var server by AuditLogTable.server
val serverType by AuditLogTable.serverType
var serverOwner by AuditLogTable.serverOwner
var actor by AuditLogTable.actor
var checkpointed by AuditLogTable.checkpointed
var action by AuditLogTable.action
var actionText by AuditLogTable.actionText
var actionArguments by AuditLogTable.actionArguments
var duration by AuditLogTable.duration
var errorType by AuditLogTable.errorType
var errorText by AuditLogTable.errorText
var stackTrace by AuditLogTable.stackTrace
enum class Type {
JOIN,

View File

@@ -33,8 +33,8 @@ object PersonalKitTable: CompositeIdTable("PersonalKit") {
val userId = reference("UserId", SteamwarUserTable)
val gamemode = varchar("Gamemode", 64).entityId()
val kitName = varchar("Name", 64).entityId()
val inventory = text("Inventory")
val armor = text("Armor")
val inventory = text("Inventory", eagerLoading = true)
val armor = text("Armor", eagerLoading = true)
val inUse = bool("InUse")
override val primaryKey = PrimaryKey(userId, gamemode, kitName)
@@ -54,7 +54,7 @@ class InternalKit(id: EntityID<CompositeID>): CompositeEntity(id) {
@JvmStatic
fun get(userId: Int, gamemode: String, kitName: String) = useDb {
get(CompositeID {
findById(CompositeID {
it[PersonalKitTable.userId] = EntityID(userId, SteamwarUserTable)
it[PersonalKitTable.gamemode] = gamemode
it[PersonalKitTable.kitName] = kitName
@@ -70,10 +70,10 @@ class InternalKit(id: EntityID<CompositeID>): CompositeEntity(id) {
it[PersonalKitTable.kitName] = kitName
}
) {
this.inventory = rawInventory
this.armor = rawArmor
this.inUse = true
}
this.rawInventory = rawInventory
this.rawArmor = rawArmor
this.inUse = false
}.also { it.setDefault() }
}
@JvmStatic
@@ -110,6 +110,7 @@ class InternalKit(id: EntityID<CompositeID>): CompositeEntity(id) {
fun setDefault() = useDb {
find { PersonalKitTable.userId eq userID and (PersonalKitTable.gamemode eq gameMode) and (PersonalKitTable.inUse eq true) }
.filter { it.id.value != this@InternalKit.id.value }
.forEach { it.inUse = false }
inUse = true
}

View File

@@ -20,6 +20,7 @@
package de.steamwar.sql;
import de.steamwar.ImplementationProvider;
import de.steamwar.ServerInfo;
import java.io.File;
import java.util.Collections;
@@ -40,4 +41,6 @@ public interface SQLWrapper<M> {
}
void additionalExceptionMetadata(StringBuilder builder);
ServerInfo getServerInfo();
}

View File

@@ -36,6 +36,8 @@ object ExceptionTable: IntIdTable("Exception") {
class SWException {
companion object {
private val exceptionCache = HashSet<String>()
val cwd = System.getProperty("user.dir")
val serverName = File(cwd).name
@@ -43,7 +45,9 @@ class SWException {
fun init() = Unit
@JvmStatic
fun log(message: String, stacktrace: String) = useDb {
fun log(message: String, stacktrace: String) = if (exceptionCache.contains(stacktrace)) Unit else useDb {
exceptionCache.add(stacktrace)
ExceptionTable.insert {
it[ExceptionTable.server] = serverName
it[ExceptionTable.message] = generateMessage(message)

View File

@@ -1,74 +0,0 @@
/*
* 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.sql
import de.steamwar.sql.internal.useDb
import org.jetbrains.exposed.v1.core.and
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.dao.CompositeEntity
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
import org.jetbrains.exposed.v1.jdbc.insertIgnore
object SchemEloTable: CompositeIdTable("SchemElo") {
val schemId = reference("SchemId", SchematicNodeTable)
val season = integer("Season").entityId()
val elo = integer("Elo")
override val primaryKey = PrimaryKey(schemId, season)
init {
addIdColumn(schemId)
}
}
class SchemElo(id: EntityID<CompositeID>): CompositeEntity(id) {
companion object: CompositeEntityClass<SchemElo>(SchemEloTable) {
@JvmStatic
fun getElo(node: SchematicNode, season: Int, defaultElo: Int = 0) = useDb {
find { (SchemEloTable.schemId eq node.id) and (SchemEloTable.season eq season) }.firstOrNull()?.elo ?: defaultElo
}
@JvmStatic
fun getCurrentElo(schemId: Int) = getElo(SchematicNode.byId(schemId)!!, Season.getSeason())
@JvmStatic
fun setElo(node: Int, elo: Int) = useDb {
findByIdAndUpdate(CompositeID {
it[SchemEloTable.schemId] = node
it[SchemEloTable.season] = Season.getSeason()
}) {
it.elo = elo
} ?: SchemEloTable.insertIgnore {
it[SchemEloTable.schemId] = node
it[SchemEloTable.season] = Season.getSeason()
it[SchemEloTable.elo] = elo
}
return@useDb
}
}
var node by SchemEloTable.schemId
var season by SchemEloTable.season
var elo by SchemEloTable.elo
}

View File

@@ -116,7 +116,7 @@ class SchematicNode(id: EntityID<Int>) : IntEntity(id) {
@JvmStatic
fun schematicAccessibleForUser(user: SteamwarUser, schematicId: Int?) = fromSql(
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeId = ?",
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE SN.NodeId = ?",
listOf(
IntegerColumnType() to user.getId(),
IntegerColumnType() to user.getId(),
@@ -365,8 +365,6 @@ class SchematicNode(id: EntityID<Int>) : IntEntity(id) {
}
}
fun getElo(season: Int) = SchemElo.getElo(this, season)
override fun delete() = useDb {
super.delete()
}

View File

@@ -1,61 +0,0 @@
/*
* 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.sql;
import java.util.Calendar;
public class Season {
private Season() {}
public static int getSeason() {
Calendar calendar = Calendar.getInstance();
int yearIndex = calendar.get(Calendar.MONTH) / 4;
return (calendar.get(Calendar.YEAR) * 3 + yearIndex);
}
public static String getSeasonStart() {
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH);
if (month <= 3) {
return calendar.get(Calendar.YEAR) + "-1-1";
} else if (month <= 7) {
return calendar.get(Calendar.YEAR) + "-5-1";
} else {
return calendar.get(Calendar.YEAR) + "-9-1";
}
}
public static String convertSeasonToString(int season){
if (season == -1) return "";
int yearSeason = season % 3;
int year = (season - yearSeason) / 3;
return String.format("%d-%d", year, yearSeason + 1);
}
public static int convertSeasonToNumber(String season){
if (season.isEmpty()) return -1;
String[] split = season.split("-");
try {
return Integer.parseInt(split[0]) * 3 + Integer.parseInt(split[1]) - 1;
} catch (NumberFormatException e) {
return -1;
}
}
}

View File

@@ -170,7 +170,7 @@ class SteamwarUser(id: EntityID<Int>): IntEntity(id) {
fun isLeader() = leader
var locale: Locale by SteamwarUserTable.locale
.transform({ it.toLanguageTag() }, { it?.let { Locale.forLanguageTag(it) } ?: Locale.getDefault()})
.transform({ it.toLanguageTag() }, { it?.let { Locale.forLanguageTag(it) } ?: Locale.ENGLISH })
var manualLocale by SteamwarUserTable.manualLocale
var bedrock by SteamwarUserTable.bedrock
private var passwordInternal by SteamwarUserTable.password

View File

@@ -1,170 +0,0 @@
/*
* 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.sql
import de.steamwar.sql.internal.useDb
import org.jetbrains.exposed.v1.core.*
import org.jetbrains.exposed.v1.core.dao.id.CompositeID
import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable
import org.jetbrains.exposed.v1.core.dao.id.EntityID
import org.jetbrains.exposed.v1.dao.CompositeEntity
import org.jetbrains.exposed.v1.dao.CompositeEntityClass
import org.jetbrains.exposed.v1.jdbc.insertIgnore
import org.jetbrains.exposed.v1.jdbc.select
import java.util.concurrent.ConcurrentHashMap
object UserEloTable : CompositeIdTable("UserElo") {
val season = integer("Season").entityId()
val gameMode = varchar("GameMode", 16).entityId()
val userId = reference("UserID", SteamwarUserTable)
val elo = integer("Elo")
override val primaryKey = PrimaryKey(season, gameMode, userId)
init {
addIdColumn(season)
addIdColumn(gameMode)
}
}
class UserElo(id: EntityID<CompositeID>) : CompositeEntity(id) {
companion object : CompositeEntityClass<UserElo>(UserEloTable) {
private const val ELO_DEFAULT = 0
private val gameModeUserEloCache: MutableMap<String, MutableMap<Int, Int?>> = ConcurrentHashMap()
private val emblemCache: MutableMap<Int, String> = ConcurrentHashMap()
@JvmStatic
fun clear() {
gameModeUserEloCache.clear()
emblemCache.clear()
}
@JvmStatic
fun getEloOrDefault(userId: Int, gameMode: String) =
getElo(userId, gameMode) ?: ELO_DEFAULT
@JvmStatic
fun getElo(userId: Int, gameMode: String) =
gameModeUserEloCache.getOrPut(gameMode) { mutableMapOf() }
.getOrPut(userId) { getEloFromDb(userId, gameMode)?.elo }
private fun getEloFromDb(userId: Int, gameMode: String) = useDb {
find { (UserEloTable.userId eq userId) and (UserEloTable.gameMode eq gameMode) and (UserEloTable.season eq Season.getSeason()) }.firstOrNull()
}
@JvmStatic
fun getFightsOfSeason(userId: Int, gamemode: String) = useDb {
exec(
"SELECT COUNT(*) AS Fights FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode = ? AND UNIX_TIMESTAMP(StartTime) + Duration >= UNIX_TIMESTAMP(?)",
args = listOf(
IntegerColumnType() to userId,
VarCharColumnType() to gamemode,
VarCharColumnType() to Season.getSeasonStart()
)
) {
return@exec if (it.next()) {
it.getInt("Fights")
} else {
0
}
} ?: 0
}
@JvmStatic
fun setElo(userId: Int, gameMode: String, elo: Int) {
emblemCache.remove(userId)
gameModeUserEloCache.getOrDefault(gameMode, mutableMapOf()).remove(userId)
useDb {
findByIdAndUpdate(CompositeID {
it[UserEloTable.userId] = userId
it[UserEloTable.gameMode] = gameMode
it[UserEloTable.season] = Season.getSeason()
}) {
it.elo = elo
} ?: UserEloTable.insertIgnore {
it[UserEloTable.userId] = userId
it[UserEloTable.gameMode] = gameMode
it[UserEloTable.season] = Season.getSeason()
it[UserEloTable.elo] = elo
}
}
}
@JvmStatic
fun getPlacement(elo: Int, gamemode: String) = useDb {
UserEloTable.select(UserEloTable.userId.count()).where {
(UserEloTable.gameMode eq gamemode) and (UserEloTable.elo greater elo) and (UserEloTable.season eq Season.getSeason())
}.firstOrNull()?.get(UserEloTable.userId.count())?.let { it + 1 }?.toInt() ?: -1
}
@JvmStatic
fun getEmblem(user: SteamwarUser, rankedModes: List<String>) =
emblemCache.getOrPut(user.id.value) {
var emblemProgression = -1
for (mode in rankedModes) {
if (getFightsOfSeason(user.id.value, mode) == 0) continue
val progression = getProgression(user.id.value, mode)
if (progression > emblemProgression) {
emblemProgression = progression
}
}
return toEmblem(emblemProgression)
}
@JvmStatic
fun getEmblemProgression(gameMode: String, userId: Int): String =
when (getProgression(userId, gameMode)) {
-1 -> "§8❱❱❱❱ ❂"
0 -> "§e❱§8❱❱❱ ❂"
1 -> "§e❱❱§8❱❱ ❂"
2 -> "§e❱❱❱§8❱ ❂"
3 -> "§e❱❱❱❱§8 ❂"
4 -> "§8❱❱❱❱ §5❂"
else -> throw SecurityException("Progression is not in range")
}
@JvmStatic
fun getProgression(userId: Int, gameMode: String) = useDb { getElo(userId, gameMode) ?: -1 }.let {
when {
it < 0 -> -1
it < 150 -> 0
it < 350 -> 1
it < 600 -> 2
it < 900 -> 3
else -> 4
}
}
@JvmStatic
fun toEmblem(progression: Int) = when (progression) {
-1 -> ""
0 -> "§e❱ "
1 -> "§e❱❱ "
2 -> "§e❱❱❱ "
3 -> "§e❱❱❱❱ "
4 -> "§5❂ "
else -> throw SecurityException("Progression out of range")
}
}
var elo by UserEloTable.elo
}

View File

@@ -60,7 +60,7 @@ enum class UserPerm {
@JvmField
val prefixes = mapOf(
PREFIX_NONE to emptyPrefix,
PREFIX_YOUTUBER to Prefix("§7", "YT"),
PREFIX_YOUTUBER to Prefix("§x§8§A§2§B§E§5", "CC"), // 8A2BE5
PREFIX_GUIDE to Prefix("§x§e§7§6§2§e§d", "Guide"), // E762ED
PREFIX_SUPPORTER to Prefix("§x§6§0§9§5§F§B", "Sup"), // 6095FB
PREFIX_MODERATOR to Prefix("§x§F§F§A§2§5§C", "Mod"), // FFA25C

View File

@@ -23,6 +23,7 @@ import org.intellij.lang.annotations.Language
import org.jetbrains.exposed.v1.core.ColumnType
import org.jetbrains.exposed.v1.core.Expression
import org.jetbrains.exposed.v1.core.ResultRow
import org.jetbrains.exposed.v1.core.StdOutSqlLogger
import org.jetbrains.exposed.v1.core.statements.StatementType
import org.jetbrains.exposed.v1.dao.IntEntity
import org.jetbrains.exposed.v1.dao.IntEntityClass

View File

@@ -19,11 +19,27 @@
package de.steamwar.fightsystem.utils;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.datacomponent.DataComponentTypes;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashSet;
import java.util.Set;
public class ReflectionWrapper21 implements ReflectionWrapper {
private static final Set<DataComponentType> FORBIDDEN_TYPES = new HashSet<>();
static {
FORBIDDEN_TYPES.add(DataComponentTypes.CUSTOM_NAME);
FORBIDDEN_TYPES.add(DataComponentTypes.PROFILE);
FORBIDDEN_TYPES.add(DataComponentTypes.UNBREAKABLE);
FORBIDDEN_TYPES.add(DataComponentTypes.BLOCK_DATA);
FORBIDDEN_TYPES.add(DataComponentTypes.BLOCKS_ATTACKS);
FORBIDDEN_TYPES.add(DataComponentTypes.BUNDLE_CONTENTS);
FORBIDDEN_TYPES.add(DataComponentTypes.CUSTOM_MODEL_DATA);
}
@Override
public Object explosionHider(Player player, Object packet, PacketHiderFunction packetHiderFunction) {
return packet;
@@ -31,6 +47,7 @@ public class ReflectionWrapper21 implements ReflectionWrapper {
@Override
public boolean hasItems(ItemStack stack) {
return stack.getDataTypes().stream().anyMatch(dataComponentType -> dataComponentType != DataComponentTypes.ENCHANTMENTS || dataComponentType != DataComponentTypes.DAMAGE);
FORBIDDEN_TYPES.forEach(stack::resetData);
return false;
}
}

View File

@@ -44,7 +44,6 @@ REMOVE_HELP=§8/§eremove §8[§eplayer§8]
NOT_FIGHTLEADER=§cYou are not the fight leader
WIN_HELP=§8/§7win §8[§eteam §8or §etie§8]
INFO_RANKED=§7Ranked§8: §e{0}
INFO_LEADER=§7Leader {0}§8: {1}
INFO_SCHEMATIC=§7Schematic {0}§8: §e{1} §7from {2}, Rank: {3}
@@ -167,7 +166,6 @@ TPS_WARNING=§c{0} §7TPS
UI_PRE_RUNNING=§7Kits distributed
UI_RUNNING=§aFight started
UI_SKIP=§7Skipping to next event
UI_UNRANKED=§7Unranked match
UI_PLAYER_JOINS=§a§l» {0}{1}
UI_PLAYER_LEAVES=§c§l« {0}{1}
UI_LEADER_JOINS=§a§l» {0}Leader {1}

View File

@@ -154,7 +154,6 @@ COMMAND_CURRENTLY_UNAVAILABLE=§cDieser Befehl ist zu diesem Kampfzeitpunkt nich
UI_PRE_RUNNING=§7Kits verteilt
UI_RUNNING=§aArena freigegeben
UI_SKIP=§7Sprung zum nächsten Ereignis
UI_UNRANKED=§7Ungewerteter Kampf
UI_LEADER_JOINS=§a§l» {0}Leader {1}
UI_PLAYER_DEATH={0}{1} §7ist gestorben
UI_PLAYER_LEAVE={0}{1} §7hat den Kampf verlassen

View File

@@ -37,7 +37,6 @@ public class DummyAI extends AI {
public DummyAI(FightTeam team) {
super(team, SteamwarUser.get("public"));
FightStatistics.unrank();
getEntity().setInvulnerable(true);
}

View File

@@ -182,7 +182,7 @@ public class GUI {
}
Kit prototype = Kit.getAvailableKits(Fight.getFightPlayer(p).isLeader()).get(0);
PersonalKit kit = PersonalKit.create(user.getId(), Config.GameModeConfig.Schematic.Type.toDB(), s, prototype.getInventory(), prototype.getArmor());
PersonalKitCreator.openKitCreator(p, kit);
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), () -> PersonalKitCreator.openKitCreator(p, kit));
});
anvilInv.open();
});

View File

@@ -51,7 +51,6 @@ public class InfoCommand implements CommandExecutor {
if(!SteamwarUser.get(player.getUniqueId()).hasPerm(UserPerm.CHECK))
return false;
FightSystem.getMessage().send("INFO_RANKED", player, !FightStatistics.isUnranked());
for(FightTeam team : Fight.teams()) {
if(!team.isLeaderless())
FightSystem.getMessage().send("INFO_LEADER", player, team.getColoredName(), team.getLeader().getEntity().getName());

View File

@@ -1,51 +0,0 @@
/*
* 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.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import de.steamwar.fightsystem.utils.FightStatistics;
import de.steamwar.linkage.Linked;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Linked
public class UnrankCommand implements CommandExecutor {
public UnrankCommand () {
new StateDependentCommand(ArenaMode.VariableTeams, FightState.Setup, "unrank", this);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(!(sender instanceof Player))
return false;
Player player = (Player) sender;
if(Commands.checkGetLeader(player) == null)
return false;
FightStatistics.unrank();
return false;
}
}

View File

@@ -393,7 +393,6 @@ public class FightTeam {
public void pasteSchem(SchematicNode schematic){
if(schematic.getSchemtype().check()) {
FightStatistics.unrank();
FightSystem.getMessage().broadcast("SCHEMATIC_UNCHECKED", getColoredName());
}

View File

@@ -34,6 +34,7 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.PlayerInventory;
import java.util.HashSet;
import java.util.Set;
@@ -62,6 +63,7 @@ public class HotbarKitListener implements Listener {
public void onInventoryClick(InventoryClickEvent event) {
int slot = event.getSlot();
if (slot < 0 || slot >= HotbarKit.HOTBAR_SIZE) return;
if (!(event.getClickedInventory() instanceof PlayerInventory)) return;
Player player = (Player) event.getWhoClicked();
click(player, slot, event);

View File

@@ -117,7 +117,7 @@ public class Kit {
if(kit.isList("Armor"))
armor = Objects.requireNonNull(kit.getList("Armor")).toArray(new ItemStack[0]);
else
armor = null;
armor = new ItemStack[]{ null, null, null, null};
leaderAllowed = kit.getBoolean("LeaderAllowed");
memberAllowed = kit.getBoolean("MemberAllowed");
if(kit.isList("Effects"))
@@ -261,7 +261,7 @@ public class Kit {
player.getInventory().setContents(inventory);
if(armor != null)
player.getInventory().setArmorContents(armor);
player.updateInventory();
player.updateInventory(); //TODO issue in 1.21.6?
if(effects != null)
player.addPotionEffects(effects);
}

View File

@@ -35,6 +35,7 @@ import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -180,6 +181,7 @@ public class Permanent implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onExplosion(EntityExplodeEvent e) {
if (!(e.getEntity() instanceof TNTPrimed)) return;
e.blockList().removeIf(block -> {
if(block.getType() == Material.TNT) {
return false;

View File

@@ -32,20 +32,16 @@ import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.winconditions.Wincondition;
import de.steamwar.linkage.Linked;
import de.steamwar.network.NetworkSender;
import de.steamwar.network.packets.common.FightEndsPacket;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.EventRelation;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Bukkit;
import java.nio.file.Files;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static de.steamwar.sql.Fight.create;
import static de.steamwar.sql.Fight.markReplayAvailable;
@@ -53,14 +49,6 @@ import static de.steamwar.sql.Fight.markReplayAvailable;
@Linked
public class FightStatistics {
@Getter
private static boolean unranked = false;
public static void unrank() {
unranked = true;
FightUI.addSubtitle("UI_UNRANKED");
}
private Timestamp starttime = Timestamp.from(Instant.now());
public FightStatistics() {
@@ -145,12 +133,6 @@ public class FightStatistics {
} catch (Exception e) {
Bukkit.getLogger().log(Level.SEVERE, "Failed to save statistics", e);
}
if (!Bukkit.getOnlinePlayers().isEmpty() && !unranked) {
NetworkSender.send(new FightEndsPacket((byte) win, blueSchem == null ? 0 : blueSchem, redSchem == null ? 0 : redSchem, Fight.getBlueTeam().getPlayers().stream().map(FightPlayer::getUser).map(SteamwarUser::getId).collect(Collectors.toList()), Fight.getRedTeam().getPlayers().stream().map(FightPlayer::getUser).map(SteamwarUser::getId).collect(Collectors.toList()), gameMode, (int)(endTime.getEpochSecond() - starttime.toInstant().getEpochSecond())));
}
unranked = false;
}
private int getLeader(FightTeam team) {

View File

@@ -91,7 +91,7 @@ public abstract class WinconditionBasePercent extends Wincondition implements Pr
@EventHandler
public void onEntityExplode(EntityExplodeEvent event) {
if (
event.getEntityType() == EntityType.FIREBALL ||
event.getEntityType() != EntityType.PRIMED_TNT ||
!team.getExtendRegion().inRegion(event.getEntity().getLocation()) ||
(!Config.GameModeConfig.WinConditionParams.PercentEntern && !Config.GameModeConfig.EnterStages.isEmpty() && Config.GameModeConfig.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft())
) {

View File

@@ -59,7 +59,6 @@ UTIL_INFO_TYPE_DIR=§eDIR
UTIL_INFO_RANK=§7Rank: §e{0}
UTIL_INFO_COLOR=§7Color translation: {0}
UTIL_INFO_REPLAY=§7Replay playback: {0}
UTIL_INFO_ELO=§7Elo: §e{0}
UTIL_INFO_FORMAT=§7Format: §e{0}
UTIL_INFO_STATUS=§cState: §c{0}: {1}
UTIL_INFO_MEMBER=§7Members: §e{0}

View File

@@ -248,7 +248,6 @@ public class SchematicCommandUtils {
if (node.getSchemtype().fightType()) {
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_COLOR", player, SchematicSystem.MESSAGE.parse(node.replaceColor() ? "ON" : "OFF", player));
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_REPLAY", player, SchematicSystem.MESSAGE.parse(node.allowReplay() ? "ON" : "OFF", player));
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_ELO", player, node.getElo(Season.getSeason()));
}
SchematicSystem.MESSAGE.sendPrefixless("UTIL_INFO_FORMAT", player, node.getFileEnding());

View File

@@ -157,7 +157,23 @@ public final class Reflection {
} else if(MAJOR_VERSION < 21 || MINOR_VERSION < 4) {
return Class.forName(spigotClassnames.getOrDefault(name, name));
} else {
return Class.forName(name);
Class<?> clazz = null;
try {
clazz = Class.forName(name);
} catch (ClassNotFoundException e) {}
if (clazz != null && clazz.getName().equals(name)) {
return clazz;
}
try {
return Core.class.getClassLoader().getParent().loadClass(name);
} catch (ClassNotFoundException e) {
if (clazz == null) {
throw e;
}
return clazz;
}
}
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Cannot find " + name, e);

View File

@@ -19,9 +19,14 @@
package de.steamwar.core;
import lombok.Getter;
public class CheckpointUtils {
private CheckpointUtils() {}
@Getter
private static boolean restored = false;
public static void signalHandler() {
try {
CheckpointUtilsJ9.signalHandler();
@@ -33,6 +38,7 @@ public class CheckpointUtils {
public static void freeze() {
try {
CheckpointUtilsJ9.freeze();
restored = true;
} catch (NoClassDefFoundError e) {
//ignore
}

View File

@@ -55,7 +55,7 @@ public class PersonalKit {
public ItemStack[] getArmor(){
YamlConfiguration config = YamlConfiguration.loadConfiguration(new StringReader(getRawArmor()));
return Objects.requireNonNull(config.getList("Armor")).toArray(new ItemStack[0]);
return Objects.requireNonNull(config.getList("Armor")).toArray(new ItemStack[4]);
}
public void setInUse() {

View File

@@ -19,6 +19,8 @@
package de.steamwar.sql;
import de.steamwar.ServerInfo;
import de.steamwar.core.CheckpointUtils;
import de.steamwar.core.Core;
import de.steamwar.data.GameModeConfigUtils;
import org.bukkit.Bukkit;
@@ -68,4 +70,9 @@ public class SQLWrapperImpl implements SQLWrapper<Material> {
builder.append(world.getName()).append(" ");
builder.append("\nServer: ").append(SERVER_VERSION);
}
@Override
public ServerInfo getServerInfo() {
return new ServerInfo(Core.getServerName(), Core.getVersion(), CheckpointUtils.isRestored());
}
}

Some files were not shown because too many files have changed in this diff Show More