forked from SteamWar/SteamWar
Add Unified GameModeConfig
This commit is contained in:
@@ -22,4 +22,5 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":CommonCore:SQL"))
|
||||
}
|
||||
@@ -0,0 +1,821 @@
|
||||
/*
|
||||
* 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.data;
|
||||
|
||||
import de.steamwar.sql.SchematicType;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ToString
|
||||
public final class GameModeConfig<M, ST, W> {
|
||||
|
||||
private static final Random random = new Random();
|
||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm");
|
||||
|
||||
public final boolean loaded;
|
||||
public final File configFile;
|
||||
|
||||
public final Server Server;
|
||||
|
||||
/**
|
||||
* Submission deadline for schematics in 'dd.MM.yyyy HH:mm' format
|
||||
* @implSpec {@code null} by default
|
||||
*/
|
||||
public final Date Deadline;
|
||||
|
||||
/**
|
||||
* The questions that have to be answered to accept the schematic
|
||||
*
|
||||
* @implSpec Disables check schem type if missing
|
||||
*/
|
||||
public final List<String> CheckQuestions;
|
||||
public final Times Times;
|
||||
public final Arena Arena;
|
||||
public final Schematic<M, ST> Schematic;
|
||||
|
||||
/**
|
||||
* The name of the game mode presented to the players
|
||||
*
|
||||
* @implSpec {@code YMLWrapper.getDefaultGameName()} by default
|
||||
*/
|
||||
public final String GameName;
|
||||
|
||||
/**
|
||||
* The months this game mode should be active and playable<br/>
|
||||
* The empty List means all of them
|
||||
*
|
||||
* @implNote 1 is January - 12 is December
|
||||
*/
|
||||
public final List<Integer> ActiveMonths;
|
||||
|
||||
/**
|
||||
* The prefix used for team chats
|
||||
*
|
||||
* @implSpec {@code +} by default
|
||||
*/
|
||||
public final String TeamChatPrefix;
|
||||
public final Blue Blue;
|
||||
public final Red Red;
|
||||
|
||||
/**
|
||||
* The list of active win conditions
|
||||
*/
|
||||
public final List<W> WinConditions;
|
||||
public final WinConditionParams<M> WinConditionParams;
|
||||
public final Kits<M> Kits;
|
||||
|
||||
/**
|
||||
* A list of integers containing the waiting time of this enter stage in the fight
|
||||
*/
|
||||
public final List<Integer> EnterStages;
|
||||
public final Techhider<M> Techhider;
|
||||
|
||||
public GameModeConfig(YMLWrapper<M, ST, W> loader) {
|
||||
configFile = loader.getFile();
|
||||
loaded = loader.canLoad();
|
||||
Server = new Server(loader.with("Server"));
|
||||
|
||||
String deadlineString = loader.getString("Deadline", null);
|
||||
if (deadlineString != null) {
|
||||
Date Deadline = null;
|
||||
try {
|
||||
Deadline = DATE_FORMAT.parse(deadlineString);
|
||||
} catch (ParseException e) {
|
||||
Deadline = null;
|
||||
}
|
||||
this.Deadline = Deadline;
|
||||
} else {
|
||||
Deadline = null;
|
||||
}
|
||||
|
||||
CheckQuestions = loader.getStringList("CheckQuestions");
|
||||
Times = new Times(loader.with("Times"));
|
||||
// Arena would be here to be in config order but needs Schematic.Size and EnterStages loaded afterwards
|
||||
Schematic = new Schematic<>(loader.with("Schematic"));
|
||||
GameName = loader.getString("GameName", loader.getDefaultGameName());
|
||||
ActiveMonths = loader.getIntList("ActiveMonths");
|
||||
TeamChatPrefix = loader.getString("TeamChatPrefix", "+");
|
||||
Blue = new Blue(loader.with("Blue"));
|
||||
Red = new Red(loader.with("Red"));
|
||||
WinConditions = Collections.unmodifiableList(loader.getStringList("WinConditions").stream().map(loader.winconditionMapper).collect(Collectors.toList()));
|
||||
WinConditionParams = new WinConditionParams<>(loader.with("WinConditionParams"));
|
||||
Kits = new Kits<>(loader.with("Kits"));
|
||||
EnterStages = loader.getIntList("EnterStages");
|
||||
Techhider = new Techhider<>(loader.with("Techhider"));
|
||||
|
||||
Arena = new Arena(loader.with("Arena"), Schematic.Size, EnterStages);
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Server {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* Base server folder
|
||||
*/
|
||||
public final String Folder;
|
||||
|
||||
/**
|
||||
* Server java archive
|
||||
*/
|
||||
public final String ServerJar;
|
||||
|
||||
/**
|
||||
* Available arenas
|
||||
*/
|
||||
public final List<String> Maps;
|
||||
|
||||
/**
|
||||
* Names to address the game mode in the chat interface
|
||||
*/
|
||||
public final List<String> ChatNames;
|
||||
|
||||
/**
|
||||
* If the Server is a Spigot server
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean Spigot;
|
||||
|
||||
/**
|
||||
* If the game mode should be marked as a historic game mode
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean Historic;
|
||||
|
||||
/**
|
||||
* If ranked matches should be available for the game mode
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean Ranked;
|
||||
|
||||
private Server(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
Folder = loader.getString("Folder", null);
|
||||
ServerJar = loader.getString("ServerJar", null);
|
||||
Maps = loader.getStringList("Maps");
|
||||
ChatNames = loader.getStringList("ChatNames");
|
||||
Spigot = loader.getBoolean("Spigot", false);
|
||||
Historic = loader.getBoolean("Historic", false);
|
||||
Ranked = loader.getBoolean("Ranked", false);
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Times {
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* Time in seconds the server stops after starting if nobody joins
|
||||
*
|
||||
* @implSpec {@code 300} by default
|
||||
*/
|
||||
public final int NoPlayersOnlineDuration;
|
||||
|
||||
/**
|
||||
* Time in seconds the team leaders have to choose their schematic
|
||||
*
|
||||
* @implSpec {@code 120} by default
|
||||
*/
|
||||
public final int PreSchemPasteDuration;
|
||||
|
||||
/**
|
||||
* Time in seconds for preparing
|
||||
*
|
||||
* @implSpec {@code 300} by default
|
||||
*/
|
||||
public final int SetupDuration;
|
||||
|
||||
/**
|
||||
* Time in seconds the final countdown is long
|
||||
*
|
||||
* @implSpec {@code 30} by default
|
||||
*/
|
||||
public final int PreFightDuration;
|
||||
|
||||
/**
|
||||
* Time in seconds to spectate the arena after the fight
|
||||
*
|
||||
* @implSpec {@code 30} by default
|
||||
*/
|
||||
public final int SpectatorDuration;
|
||||
|
||||
private Times(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
NoPlayersOnlineDuration = loader.getInt("NoPlayersOnlineDuration", 300);
|
||||
PreSchemPasteDuration = loader.getInt("PreSchemPasteDuration", 120);
|
||||
SetupDuration = loader.getInt("SetupDuration", 300);
|
||||
PreFightDuration = loader.getInt("PreFightDuration", 30);
|
||||
SpectatorDuration = loader.getInt("SpectatorDuration", 60);
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Arena {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* The amount of blocks the schematics should be pasted under the surface
|
||||
*
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int WaterDepth;
|
||||
|
||||
/**
|
||||
* The outer border of the arena, measured in blocks around the schematic areas
|
||||
*/
|
||||
public final Schem2Border Schem2Border;
|
||||
|
||||
/**
|
||||
* The offset the teams spawn relative to the center of their area
|
||||
*/
|
||||
public final SpawnOffset SpawnOffset;
|
||||
|
||||
/**
|
||||
* The size of the team areas are expanded around the schematics
|
||||
*
|
||||
* @implSpec {@code 12} by default
|
||||
*/
|
||||
public final int BorderFromSchematic;
|
||||
|
||||
/**
|
||||
* If ground walkable, teams can walk below the lower arena border during setup
|
||||
*
|
||||
* @implSpec {@code true} by default
|
||||
*/
|
||||
public final boolean GroundWalkable;
|
||||
|
||||
/**
|
||||
* Disable snow and ice melting
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean DisableSnowMelt;
|
||||
|
||||
/**
|
||||
* Allow leaving the arena area as spectator
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean Leaveable;
|
||||
|
||||
/**
|
||||
* Allow missiles to fly to the enemy and not stop at the schem border.
|
||||
*
|
||||
* @implSpec {@code !EnterStages.isEmpty()} by default
|
||||
*/
|
||||
public final boolean AllowMissiles;
|
||||
|
||||
/**
|
||||
* Denotes that there is no floor for this GameMode
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean NoFloor;
|
||||
|
||||
private Arena(YMLWrapper loader, Schematic.Size Size, List<Integer> EnterStages) {
|
||||
loaded = loader.canLoad();
|
||||
WaterDepth = loader.getInt("WaterDepth", 0);
|
||||
Schem2Border = new Schem2Border(loader.with("Schem2Border"));
|
||||
SpawnOffset = new SpawnOffset(loader.with("SpawnOffset"), Size);
|
||||
BorderFromSchematic = loader.getInt("BorderFromSchematic", 21);
|
||||
GroundWalkable = loader.getBoolean("GroundWalkable", true);
|
||||
DisableSnowMelt = loader.getBoolean("DisableSnowMelt", false);
|
||||
Leaveable = loader.getBoolean("Leaveable", false);
|
||||
AllowMissiles = loader.getBoolean("AllowMissiles", !EnterStages.isEmpty());
|
||||
NoFloor = loader.getBoolean("NoFloor", false);
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Schem2Border {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 24} by default
|
||||
*/
|
||||
public final int x;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 24} by default
|
||||
*/
|
||||
public final int z;
|
||||
|
||||
private Schem2Border(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
x = loader.getInt("x", 24);
|
||||
z = loader.getInt("z", 24);
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class SpawnOffset {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final double x;
|
||||
|
||||
/**
|
||||
* @implSpec {@code Schematic.Size.y} by default
|
||||
*/
|
||||
public final double y;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final double z;
|
||||
|
||||
private SpawnOffset(YMLWrapper loader, Schematic.Size Size) {
|
||||
loaded = loader.canLoad();
|
||||
x = loader.getDouble("x", 0);
|
||||
y = loader.getDouble("y", Size.y);
|
||||
z = loader.getDouble("z", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Schematic<M, ST> {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* The size of the schematics
|
||||
*/
|
||||
public final Size Size;
|
||||
|
||||
/**
|
||||
* Used for GameModes with a technic area
|
||||
*/
|
||||
public final Inset Inset;
|
||||
|
||||
/**
|
||||
* The schematic type that can be chosen in this arena
|
||||
*
|
||||
* @implSpec {@code Normal} by default
|
||||
*/
|
||||
public final ST Type;
|
||||
|
||||
/**
|
||||
* The schematic types that are also allowed to be chosen in this arena
|
||||
*/
|
||||
public final List<ST> SubTypes;
|
||||
|
||||
/**
|
||||
* Shortcut of the schematic type
|
||||
*
|
||||
* @implSpec {@code ""} by default
|
||||
*/
|
||||
public final String Shortcut;
|
||||
|
||||
/**
|
||||
* Spigot (1.8) material for GUIs
|
||||
*
|
||||
* @implSpec {@code STONE_BUTTON} by default
|
||||
*/
|
||||
public final M Material;
|
||||
|
||||
/**
|
||||
* Manual check of schematic necessary
|
||||
*
|
||||
* @implSpec {@code true} by default
|
||||
*/
|
||||
public final boolean ManualCheck;
|
||||
|
||||
/**
|
||||
* If the schematics should be rotated during pasting
|
||||
*
|
||||
* @implSpec {@code true} by default
|
||||
*/
|
||||
public final boolean Rotate;
|
||||
|
||||
/**
|
||||
* If the schematics should be pasted aligned to the borders instead of centered
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean PasteAligned;
|
||||
|
||||
/**
|
||||
* If only public schematics are allowed
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean OnlyPublicSchematics;
|
||||
|
||||
/**
|
||||
* If the public only force should be completely disabled
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean IgnorePublicOnly;
|
||||
|
||||
/**
|
||||
* If obsidian and bedrock should be replaced during PRE_RUNNING
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean ReplaceObsidianBedrock;
|
||||
|
||||
/**
|
||||
* If the replacement should happen with block updates
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean ReplaceWithBlockupdates;
|
||||
|
||||
/**
|
||||
* If the schematic perparation arena mode is time limited
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean UnlimitedPrepare;
|
||||
|
||||
/**
|
||||
* Maximal amount of blocks allowed in the schematic
|
||||
*
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int MaxBlocks;
|
||||
|
||||
/**
|
||||
* Maximal amount of items per dispenser
|
||||
*
|
||||
* @implSpec {@code 128} by default
|
||||
*/
|
||||
public final int MaxDispenserItems;
|
||||
|
||||
/**
|
||||
* Maximal blast resistance for the design blocks
|
||||
*
|
||||
* @implSpec {@code Double.MAX_VALUE} by default
|
||||
*/
|
||||
public final double MaxDesignBlastResistance;
|
||||
|
||||
/**
|
||||
* List of limited material (combinations)<br/>
|
||||
* List contains tags Amount (integer) and Materials (List of material names in Spigot 1.12 AND Spigot 1.15 format)
|
||||
*/
|
||||
public final Map<Set<M>, Integer> Limited;
|
||||
|
||||
private Schematic(YMLWrapper<M, ST, ?> loader) {
|
||||
loaded = loader.canLoad();
|
||||
Size = new Size(loader.with("Size"));
|
||||
Inset = new Inset(loader.with("Inset"));
|
||||
Type = loader.getSchematicType("Type", "Normal");
|
||||
SubTypes = loader.getSchematicTypeList("SubTypes");
|
||||
Shortcut = loader.getString("Shortcut", "");
|
||||
Material = loader.getMaterial("Material", "STONE_BUTTON");
|
||||
ManualCheck = loader.getBoolean("ManualCheck", true);
|
||||
Rotate = loader.getBoolean("Rotate", true);
|
||||
PasteAligned = loader.getBoolean("PasteAligned", false);
|
||||
OnlyPublicSchematics = loader.getBoolean("OnlyPublicSchematics", false);
|
||||
IgnorePublicOnly = loader.getBoolean("IgnorePublicOnly", false);
|
||||
ReplaceObsidianBedrock = loader.getBoolean("ReplaceObsidianBedrock", false);
|
||||
ReplaceWithBlockupdates = loader.getBoolean("ReplaceWithBlockupdates", false);
|
||||
UnlimitedPrepare = loader.getBoolean("UnlimitedPrepare", false);
|
||||
MaxBlocks = loader.getInt("MaxBlocks", 0);
|
||||
MaxDispenserItems = loader.getInt("MaxDispenserItems", 128);
|
||||
MaxDesignBlastResistance = loader.getDouble("MaxDesignBlastResistance", Double.MAX_VALUE);
|
||||
|
||||
Map<Set<M>, Integer> Limited = new HashMap<>();
|
||||
for (Map<?, ?> entry : loader.getMapList("Limited")) {
|
||||
int amount = (Integer) entry.get("Amount");
|
||||
Set<String> materials = new HashSet<>((List<String>) entry.get("Materials"));
|
||||
if (amount == 0) {
|
||||
materials.forEach(material -> {
|
||||
Limited.put(Collections.singleton(loader.materialMapper.apply(material.toUpperCase())), 0);
|
||||
});
|
||||
} else {
|
||||
Limited.put(Collections.unmodifiableSet(materials.stream().map(String::toUpperCase).map(loader.materialMapper).collect(Collectors.toSet())), amount);
|
||||
}
|
||||
}
|
||||
this.Limited = Collections.unmodifiableMap(Limited);
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Size {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int x;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int y;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int z;
|
||||
|
||||
private Size(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
x = loader.getInt("x", 0);
|
||||
y = loader.getInt("y", 0);
|
||||
z = loader.getInt("z", 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Inset {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int x;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int z;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int top;
|
||||
|
||||
/**
|
||||
* @implSpec {@code 0} by default
|
||||
*/
|
||||
public final int bottom;
|
||||
|
||||
private Inset(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
x = loader.getInt("x", 0);
|
||||
z = loader.getInt("z", 0);
|
||||
top = loader.getInt("top", 0);
|
||||
bottom = loader.getInt("bottom", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Blue {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* @implSpec {@code Blau} by default
|
||||
*/
|
||||
public final String Name;
|
||||
|
||||
/**
|
||||
* @implSpec {@code §3} by default
|
||||
*/
|
||||
public final String Prefix;
|
||||
|
||||
private Blue(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
Name = loader.getString("Name", "Blau");
|
||||
Prefix = loader.getString("Prefix", "§3");
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Red {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* @implSpec {@code Rot} by default
|
||||
*/
|
||||
public final String Name;
|
||||
|
||||
/**
|
||||
* @implSpec {@code §c} by default
|
||||
*/
|
||||
public final String Prefix;
|
||||
|
||||
private Red(YMLWrapper loader) {
|
||||
loaded = loader.canLoad();
|
||||
Name = loader.getString("Name", "Rot");
|
||||
Prefix = loader.getString("Prefix", "§c");
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class WinConditionParams<M> {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* The time of any of the timeout win conditions in seconds
|
||||
*
|
||||
* @implSpec {@code 1200} by default
|
||||
*/
|
||||
public final int TimeoutTime;
|
||||
|
||||
/**
|
||||
* The percentage when any of the percent win conditions limits or triggers a win
|
||||
*
|
||||
* @implSpec {@code 7.0} by default
|
||||
*/
|
||||
public final double PercentWin;
|
||||
|
||||
/**
|
||||
* Does the percentage still change after the start of the enter phase
|
||||
*
|
||||
* @implSpec {@code true} by default
|
||||
*/
|
||||
public final boolean PercentEntern;
|
||||
|
||||
/**
|
||||
* Is Blocks a whitelist (true) or blacklist (false)
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean BlocksWhitelist;
|
||||
|
||||
/**
|
||||
* Special Blocks (Valid spigot material values) used by the percent win conditions
|
||||
*/
|
||||
public final List<M> Blocks;
|
||||
|
||||
/**
|
||||
* Time for being declared TechKo without a shot given.
|
||||
*
|
||||
* @implSpec {@code 90} by default
|
||||
*/
|
||||
public final int TechKoTime;
|
||||
|
||||
private WinConditionParams(YMLWrapper<M, ?, ?> loader) {
|
||||
loaded = loader.canLoad();
|
||||
TimeoutTime = loader.getInt("TimeoutTime", 1200);
|
||||
PercentWin = loader.getDouble("PercentWin", 7.0);
|
||||
PercentEntern = loader.getBoolean("PercentEntern", true);
|
||||
BlocksWhitelist = loader.getBoolean("BlocksWhitelist", false);
|
||||
Blocks = loader.getMaterialList("Blocks");
|
||||
TechKoTime = loader.getInt("TechKoTime", 90);
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Kits<M> {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* The kit file for this configuration
|
||||
*
|
||||
* @implSpec {@code kits.yml} by default
|
||||
*/
|
||||
public final String File;
|
||||
|
||||
/**
|
||||
* The default kit for team members
|
||||
*
|
||||
* @implSpec {@code default} by default
|
||||
*/
|
||||
public final String MemberDefault;
|
||||
|
||||
/**
|
||||
* The default kit for team leaders
|
||||
*
|
||||
* @implSpec {@code default} by default
|
||||
*/
|
||||
public final String LeaderDefault;
|
||||
|
||||
/**
|
||||
* If the personal kit system is active
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean PersonalKits;
|
||||
|
||||
/**
|
||||
* Items (Valid spigot material values) that are not allowed in the personal kit
|
||||
*/
|
||||
public final List<M> ForbiddenItems;
|
||||
|
||||
private Kits(YMLWrapper<M, ?, ?> loader) {
|
||||
loaded = loader.canLoad();
|
||||
File = loader.getString("File", "kits.yml");
|
||||
MemberDefault = loader.getString("MemberDefault", "default");
|
||||
LeaderDefault = loader.getString("LeaderDefault", "default");
|
||||
PersonalKits = loader.getBoolean("PersonalKits", false);
|
||||
ForbiddenItems = loader.getMaterialList("ForbiddenItems");
|
||||
}
|
||||
}
|
||||
|
||||
@ToString
|
||||
public static final class Techhider<M> {
|
||||
|
||||
public final boolean loaded;
|
||||
|
||||
/**
|
||||
* Activates the tech hider
|
||||
*
|
||||
* @implSpec {@code false} by default
|
||||
*/
|
||||
public final boolean Active;
|
||||
|
||||
/**
|
||||
* Which block the tech hider replaces to.
|
||||
*
|
||||
* @implSpec {@code end_stone} by default
|
||||
*/
|
||||
public final M ObfuscateWith;
|
||||
|
||||
/**
|
||||
* A list of all hidden blocks. "water" results in the hiding of all waterlogged blocks as well.
|
||||
*/
|
||||
public final Set<M> HiddenBlocks;
|
||||
|
||||
/**
|
||||
* The block entity contents that are hidden (here with minecraft:nametag)
|
||||
*/
|
||||
public final Set<String> HiddenBlockEntities;
|
||||
|
||||
private Techhider(YMLWrapper<M, ?, ?> loader) {
|
||||
loaded = loader.canLoad();
|
||||
Active = loader.getBoolean("Active", false);
|
||||
ObfuscateWith = loader.getMaterial("ObfuscateWith", "end_stone");
|
||||
HiddenBlocks = Collections.unmodifiableSet(new HashSet<>(loader.getMaterialList("HiddenBlocks")));
|
||||
HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(loader.getStringList("HiddenBlockEntities")));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAfterDeadline() {
|
||||
return Deadline != null && Deadline.before(Date.from(Instant.now()));
|
||||
}
|
||||
|
||||
public String hasMap(String map) {
|
||||
for (String m : Server.Maps) {
|
||||
if (m.equalsIgnoreCase(map))
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRandomMap() {
|
||||
return Server.Maps.get(random.nextInt(Server.Maps.size()));
|
||||
}
|
||||
|
||||
public String convertToRealMapName(String map) {
|
||||
for (String m : Server.Maps) {
|
||||
if (m.equalsIgnoreCase(map))
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getChatName() {
|
||||
return Server.ChatNames.get(0);
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
if (Server.ChatNames.isEmpty()) return false;
|
||||
if (ActiveMonths.isEmpty()) return true;
|
||||
return ActiveMonths.contains(LocalDateTime.now().getMonth().getValue());
|
||||
}
|
||||
|
||||
public String getSchemTypeOrInternalName() {
|
||||
if (Schematic.loaded) {
|
||||
ST type = Schematic.Type;
|
||||
if (type instanceof SchematicType) {
|
||||
return ((SchematicType) type).toDB();
|
||||
} else if (type instanceof String) {
|
||||
return (String) type;
|
||||
}
|
||||
}
|
||||
return configFile.getName().replace(".yml", "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.data;
|
||||
|
||||
import de.steamwar.sql.SchematicType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class YMLWrapper<M, ST, W> {
|
||||
|
||||
public static final Function<String, String> ToString = Function.identity();
|
||||
public static final Function<String, SchematicType> ToSchematicType = SchematicType::fromDB;
|
||||
|
||||
protected final File file;
|
||||
public final Function<String, M> materialMapper;
|
||||
public final Function<String, ST> schematicTypeMapper;
|
||||
public final Function<String, W> winconditionMapper;
|
||||
|
||||
protected YMLWrapper(File file, Function<String, M> materialMapper, Function<String, ST> schematicTypeMapper, Function<String, W> winconditionMapper) {
|
||||
this.file = file;
|
||||
this.materialMapper = materialMapper;
|
||||
this.schematicTypeMapper = schematicTypeMapper;
|
||||
this.winconditionMapper = winconditionMapper;
|
||||
}
|
||||
|
||||
public final File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public abstract boolean canLoad();
|
||||
|
||||
public abstract YMLWrapper<M, ST, W> with(String path);
|
||||
|
||||
public abstract String getDefaultGameName();
|
||||
|
||||
public abstract String getString(String path, String defaultValue);
|
||||
|
||||
public abstract int getInt(String path, int defaultValue);
|
||||
|
||||
public abstract double getDouble(String path, double defaultValue);
|
||||
|
||||
public abstract boolean getBoolean(String path, boolean defaultValue);
|
||||
|
||||
public final ST getSchematicType(String path, String defaultValue) {
|
||||
String schematicType = getString(path, defaultValue);
|
||||
return schematicTypeMapper.apply(schematicType);
|
||||
}
|
||||
|
||||
public final M getMaterial(String path, String defaultValue) {
|
||||
return materialMapper.apply(getString(path, defaultValue).toUpperCase());
|
||||
}
|
||||
|
||||
public abstract List<String> getStringList(String path);
|
||||
|
||||
public abstract List<Integer> getIntList(String path);
|
||||
|
||||
public final List<ST> getSchematicTypeList(String path) {
|
||||
List<String> list = getStringList(path);
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Collections.unmodifiableList(list.stream().map(schematicTypeMapper).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
public final List<M> getMaterialList(String path) {
|
||||
List<String> list = getStringList(path);
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Collections.unmodifiableList(list.stream().map(String::toUpperCase).map(materialMapper).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract List<Map<?, ?>> getMapList(String path);
|
||||
}
|
||||
@@ -21,9 +21,11 @@ package de.steamwar.sql;
|
||||
|
||||
import de.steamwar.sql.internal.SqlTypeMapper;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class SchematicType {
|
||||
|
||||
public static final SchematicType Normal = new SchematicType("Normal", "", Type.NORMAL, null, "STONE_BUTTON", false);
|
||||
@@ -38,7 +40,10 @@ public class SchematicType {
|
||||
tmpTypes.add(Normal);
|
||||
tmpFromDB.put(Normal.name().toLowerCase(), Normal);
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
SQLWrapper.impl.loadSchemTypes(tmpTypes, tmpFromDB);
|
||||
time = System.currentTimeMillis() - time;
|
||||
log.info("Loaded {} Schematic Types in {}ms", tmpTypes.size(), time);
|
||||
|
||||
fromDB = Collections.unmodifiableMap(tmpFromDB);
|
||||
types = Collections.unmodifiableList(tmpTypes);
|
||||
|
||||
Reference in New Issue
Block a user