forked from SteamWar/SteamWar
Compare commits
162
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b42f0d13c | ||
|
|
4306fe7bc9 | ||
|
|
58df6087f0 | ||
|
|
b9b7869124 | ||
|
|
1e85b14667 | ||
|
|
35c27923aa | ||
|
|
c3b3e3e60f | ||
|
|
3aa1bf7ffd | ||
|
|
5a02a58437 | ||
|
|
6209b86149 | ||
|
|
6f1403df9c | ||
|
|
0113788da2 | ||
|
|
8a7f65e000 | ||
|
|
8401f67b24 | ||
|
|
362468e756 | ||
|
|
ece12df0bc | ||
|
|
f35c07ab5b | ||
|
|
549f7e555c | ||
|
|
859238d7fa | ||
|
|
a79b00f78f | ||
|
|
105eda32e6 | ||
|
|
b4487b8079 | ||
|
|
ea3aad3bd2 | ||
|
|
d307f890e2 | ||
|
|
97c1da1b2a | ||
|
|
8a53aecfac | ||
|
|
5236afba17 | ||
|
|
d3c8b6e1c6 | ||
|
|
00ea792eee | ||
|
|
38e845b0e4 | ||
|
|
c60a8caed8 | ||
|
|
2e390286b2 | ||
|
|
6476125a3f | ||
|
|
311437d451 | ||
|
|
5a52771ec1 | ||
|
|
72b70a62e1 | ||
|
|
8575dcac33 | ||
|
|
cb744f6aa0 | ||
|
|
227f63c9ff | ||
|
|
397b10c319 | ||
|
|
32569f19d9 | ||
|
|
f19e4158e7 | ||
|
|
6c46b5b2a2 | ||
|
|
58516448d9 | ||
|
|
683236bb59 | ||
|
|
8dc101639d | ||
|
|
792620804a | ||
|
|
4aa7c99a6e | ||
|
|
cce18124f2 | ||
|
|
18ad0ad90c | ||
|
|
a58de898bb | ||
|
|
507b7c2569 | ||
|
|
a18098b8f4 | ||
|
|
97773f292d | ||
|
|
5fdfc03587 | ||
|
|
493e66cc98 | ||
|
|
2be3a136ae | ||
|
|
c62a566447 | ||
|
|
0684765a76 | ||
|
|
c40f29c3c1 | ||
|
|
72dc4eee9e | ||
|
|
c7a949322e | ||
|
|
9d5b7893f1 | ||
|
|
ae898e14c2 | ||
|
|
726f73cc45 | ||
|
|
badff1c70f | ||
|
|
1d2ac4f705 | ||
|
|
b48c75ef74 | ||
|
|
8b6ea12a08 | ||
|
|
801678ddd3 | ||
|
|
e5cc874834 | ||
|
|
95119fc93f | ||
|
|
d84ca3547a | ||
|
|
25ab79abc0 | ||
|
|
582d6a62e3 | ||
|
|
5eec792aff
|
||
|
|
e0f26c3e8d
|
||
|
|
a59e9b4343 | ||
|
|
64e627514d | ||
|
|
a8c68864d8 | ||
|
|
c0668723d7 | ||
|
|
5bc2daf37a | ||
|
|
e6d39da36b | ||
|
|
390d388692 | ||
|
|
9a60ac228c | ||
|
|
dab443b989 | ||
|
|
bf3c65c630 | ||
|
|
b488c4ed7c | ||
|
|
2e795aaf8e | ||
|
|
7a601235f5 | ||
|
|
3a247de43d
|
||
|
|
62e855ec1b
|
||
|
|
9e7311934f | ||
|
|
6fd3e6f690
|
||
|
|
7acd51fd61
|
||
|
|
b278ca15f3
|
||
|
|
029249c2b0
|
||
|
|
1ceb10439b
|
||
|
|
a5dfe6ab7e
|
||
|
|
c8a5f567eb | ||
|
|
47fb4da85b
|
||
|
|
0eef22aab0 | ||
|
|
013d18614f | ||
|
|
c7c1ab64e0 | ||
|
|
b68a27fbb6 | ||
|
|
7038dc2aa5
|
||
|
|
7af586ec16
|
||
|
|
b04e99ce54 | ||
|
|
524702fbb9 | ||
|
|
e07298e748 | ||
|
|
e1df793e9f | ||
|
|
806a1affea | ||
|
|
c538cdbbd2 | ||
|
|
d7ba19049a | ||
|
|
47909b6f07 | ||
|
|
48846a698f | ||
|
|
b771c95b99 | ||
|
|
d0aada2b00 | ||
|
|
6522fc77f2 | ||
|
|
27e01a56ae | ||
|
|
ed89770c0f | ||
|
|
3ec3c90f04 | ||
|
|
73d4ed26c8 | ||
|
|
256bcfb1bf | ||
|
|
28ce288815 | ||
|
|
6599dd026a | ||
|
|
03052b677f | ||
|
|
f76a6fa79d | ||
|
|
7fb7f46ca7 | ||
|
|
1269b7f00a | ||
|
|
91a0685724 | ||
|
|
72dd2ef59a | ||
|
|
54a1549973 | ||
|
|
fd5f5b92b4 | ||
|
|
60dc5e4442 | ||
|
|
4cdaf759af | ||
|
|
6e919d9148 | ||
|
|
a20ec8c93d | ||
|
|
18b65a2984 | ||
|
|
669235709e | ||
|
|
796e154c1c | ||
|
|
9efe35fe0d | ||
|
|
e0aaacd66a | ||
|
|
7adb1e8b4a | ||
|
|
b88e592e79 | ||
|
|
914134600e | ||
|
|
27877938bc
|
||
|
|
70c8678c60
|
||
|
|
997292d58e | ||
|
|
8050f51424
|
||
|
|
a6681ffaf6
|
||
|
|
a23530074c
|
||
|
|
e88a4c624b
|
||
|
|
105beaf7a6 | ||
|
|
5f7ab3cd7b
|
||
|
|
5ce69e6b7a
|
||
|
|
9e43d5cd1b | ||
|
|
2ad9ae3c7f | ||
|
|
847eb3fe5d | ||
|
|
8fa9f7b0d3 | ||
|
|
559cae2b6d | ||
|
|
5dbf3638d0 |
@@ -15,6 +15,11 @@ bin/
|
||||
.vscode
|
||||
.settings
|
||||
|
||||
# Language Server
|
||||
**/.project
|
||||
**/.factorypath
|
||||
**/.classpath
|
||||
|
||||
# Other
|
||||
lib
|
||||
/WebsiteBackend/data
|
||||
|
||||
@@ -35,6 +35,7 @@ dependencies {
|
||||
compileOnly(libs.classindex)
|
||||
annotationProcessor(libs.classindex)
|
||||
compileOnly(project(":SpigotCore", "default"))
|
||||
compileOnly(project(":KotlinCore", "default"))
|
||||
|
||||
compileOnly(libs.axiom)
|
||||
compileOnly(libs.authlib)
|
||||
@@ -46,7 +47,7 @@ dependencies {
|
||||
compileOnly(libs.netty)
|
||||
|
||||
implementation(libs.luaj)
|
||||
implementation(files("$projectDir/../libs/YAPION-SNAPSHOT.jar"))
|
||||
// implementation(files("$projectDir/../libs/YAPION-SNAPSHOT.jar"))
|
||||
}
|
||||
|
||||
widener {
|
||||
|
||||
@@ -20,27 +20,28 @@
|
||||
package de.steamwar.bausystem;
|
||||
|
||||
import de.steamwar.bausystem.config.BauServer;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.bausystem.configplayer.ConfigConverter;
|
||||
import de.steamwar.bausystem.config.ConfigStore;
|
||||
import de.steamwar.bausystem.features.gui.BauGUI;
|
||||
import de.steamwar.bausystem.features.script.lua.SteamWarLuaPlugin;
|
||||
import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.panzern.Panzern;
|
||||
import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.features.world.BauScoreboard;
|
||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.RegionSystem;
|
||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||
import de.steamwar.bausystem.utils.TickManager;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import de.steamwar.command.AbstractValidator;
|
||||
import de.steamwar.command.SWCommandUtils;
|
||||
import de.steamwar.core.CRIUSleepEvent;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.WorldEditRendererCUIEditor;
|
||||
import de.steamwar.core.WorldIdentifier;
|
||||
import de.steamwar.core.worldedit.SteamEdit;
|
||||
import de.steamwar.core.worldedit.WorldEditRendererCUIEditor;
|
||||
import de.steamwar.linkage.AbstractLinker;
|
||||
import de.steamwar.linkage.SpigotLinker;
|
||||
import de.steamwar.message.Message;
|
||||
@@ -48,6 +49,7 @@ import de.steamwar.providers.BauServerInfo;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -108,8 +110,8 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
if (any instanceof PanzernAlgorithm) {
|
||||
Panzern.add((PanzernAlgorithm) any);
|
||||
}
|
||||
if (any instanceof ConfigConverter) {
|
||||
Config.addConfigConverter((ConfigConverter) any);
|
||||
if (any instanceof BoundingBoxLoader) {
|
||||
((BoundingBoxLoader) any).load();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -125,7 +127,19 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
TraceManager.instance.init();
|
||||
TraceRecorder.instance.init();
|
||||
|
||||
new WorldEditRendererCUIEditor();
|
||||
SteamEdit.init();
|
||||
SteamEdit.ADJACENT_FILTERS = location -> {
|
||||
Region region = Region.getRegion(location);
|
||||
Region.Area area;
|
||||
if (region.getBuildArea().inRegion(location, true)) {
|
||||
area = region.getBuildArea();
|
||||
} else if (region.getTestblockArea().inRegion(location, true)) {
|
||||
area = region.getTestblockArea();
|
||||
} else {
|
||||
return SteamEdit.AdjacentFilter.ALWAYS;
|
||||
}
|
||||
return (x, y, z) -> area.inRegion(new Location(null, x, y, z), true);
|
||||
};
|
||||
|
||||
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
|
||||
|
||||
@@ -141,9 +155,8 @@ public class BauSystem extends JavaPlugin implements Listener {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
linker.unlink();
|
||||
WorldData.write();
|
||||
RegionSystem.INSTANCE.save();
|
||||
Config.getInstance().saveAll();
|
||||
ConfigStore.saveAll();
|
||||
}
|
||||
|
||||
private <T extends CommandSender> AbstractValidator<T, ?> validator(Permission permission) {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
/**
|
||||
* Converts a config of one version into the next version, e.g. ConfigV1 to
|
||||
* ConfigV2. The converter for the second newest version converts into the
|
||||
* current version. Converters are registered in the {@link ConfigStore}
|
||||
* of the config.
|
||||
*
|
||||
* @param <F> the config version to convert from
|
||||
* @param <T> the config version to convert to
|
||||
*/
|
||||
public interface ConfigConverter<F extends VersionedConfig, T extends VersionedConfig> {
|
||||
|
||||
/**
|
||||
* @return the version this converter converts from
|
||||
*/
|
||||
int version();
|
||||
|
||||
/**
|
||||
* Converts the config to the next version. If anything goes wrong do not
|
||||
* silently exit this method, throw an Exception. The {@link ConfigStore}
|
||||
* will deal with it.
|
||||
*
|
||||
* @param config the config to convert
|
||||
* @return the converted config
|
||||
*/
|
||||
T convert(F config);
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* 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.bausystem.config;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import de.steamwar.sql.UserConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Loads, converts and saves a versioned config stored as JSON. Older versions
|
||||
* are converted with the registered {@link ConfigConverter}s, legacy formats
|
||||
* that are not JSON can be read with {@link #legacy(Predicate, Function)}.
|
||||
* <p>
|
||||
* A store can be bound to where the config is stored:
|
||||
* <ul>
|
||||
* <li>{@link #userConfig(String)}: one config per player in the {@link UserConfig}, use {@link #get(Player)}</li>
|
||||
* <li>{@link #file(File)}: one config in a file, use {@link #get()}</li>
|
||||
* <li>unbound: use {@link #load(File)} and {@link #save(File, VersionedConfig)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param <T> the current config version
|
||||
*/
|
||||
public class ConfigStore<T extends VersionedConfig> {
|
||||
|
||||
private static final List<ConfigStore<?>> STORES = new ArrayList<>();
|
||||
|
||||
private final Class<T> type;
|
||||
private final int version;
|
||||
private final Supplier<T> defaultConfig;
|
||||
|
||||
private final Map<Integer, Class<? extends VersionedConfig>> jsonVersions = new HashMap<>();
|
||||
private final Map<Integer, ConfigConverter<?, ?>> converters = new HashMap<>();
|
||||
private final List<LegacyFormat> legacyFormats = new ArrayList<>();
|
||||
private Gson gson = new Gson();
|
||||
private Integer unversionedVersion = null;
|
||||
|
||||
private String userConfigKey = null;
|
||||
private Predicate<T> removeIf = config -> false;
|
||||
private final Map<UUID, T> playerConfigs = new ConcurrentHashMap<>();
|
||||
|
||||
private File file = null;
|
||||
private File legacyFile = null;
|
||||
private Function<String, ? extends VersionedConfig> legacyFileReader = null;
|
||||
private T fileConfig = null;
|
||||
|
||||
private record LegacyFormat(Predicate<String> matches, Function<String, ? extends VersionedConfig> reader) {
|
||||
}
|
||||
|
||||
public ConfigStore(Class<T> type, int version, Supplier<T> defaultConfig) {
|
||||
this.type = type;
|
||||
this.version = version;
|
||||
this.defaultConfig = defaultConfig;
|
||||
jsonVersions.put(version, type);
|
||||
STORES.add(this);
|
||||
}
|
||||
|
||||
public ConfigStore<T> gson(Gson gson) {
|
||||
this.gson = gson;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an older config version that is stored as JSON.
|
||||
*/
|
||||
public ConfigStore<T> jsonVersion(int version, Class<? extends VersionedConfig> type) {
|
||||
jsonVersions.put(version, type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigStore<T> converter(ConfigConverter<?, ?> converter) {
|
||||
if (converters.putIfAbsent(converter.version(), converter) != null) {
|
||||
throw new IllegalStateException("Duplicate converter for version " + converter.version() + " of " + type.getSimpleName());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a legacy format that is not JSON, stored strings matching the predicate are read by the reader.
|
||||
*/
|
||||
public ConfigStore<T> legacy(Predicate<String> matches, Function<String, ? extends VersionedConfig> reader) {
|
||||
legacyFormats.add(new LegacyFormat(matches, reader));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of stored JSON without a version field.
|
||||
*/
|
||||
public ConfigStore<T> unversioned(int version) {
|
||||
this.unversionedVersion = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds this store to the {@link UserConfig} with the given key, one config per player.
|
||||
*/
|
||||
public ConfigStore<T> userConfig(String key) {
|
||||
this.userConfigKey = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the config from the {@link UserConfig} instead of saving it, if the predicate matches.
|
||||
*/
|
||||
public ConfigStore<T> removeIf(Predicate<T> removeIf) {
|
||||
this.removeIf = removeIf;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds this store to a single file.
|
||||
*/
|
||||
public ConfigStore<T> file(File file) {
|
||||
this.file = file;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy file to read, if the file of this store does not exist yet.
|
||||
*/
|
||||
public ConfigStore<T> legacyFile(File legacyFile, Function<String, ? extends VersionedConfig> reader) {
|
||||
this.legacyFile = legacyFile;
|
||||
this.legacyFileReader = reader;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a stored config and converts it to the current version.
|
||||
*
|
||||
* @throws RuntimeException if the config could not be read or converted
|
||||
*/
|
||||
public T read(String stored) {
|
||||
for (LegacyFormat legacyFormat : legacyFormats) {
|
||||
if (legacyFormat.matches().test(stored)) {
|
||||
return update(legacyFormat.reader().apply(stored));
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject json = JsonParser.parseString(stored).getAsJsonObject();
|
||||
int storedVersion;
|
||||
if (json.has("version")) {
|
||||
storedVersion = json.get("version").getAsInt();
|
||||
} else if (unversionedVersion != null) {
|
||||
storedVersion = unversionedVersion;
|
||||
json.addProperty("version", storedVersion);
|
||||
} else {
|
||||
throw new IllegalStateException("Missing version of " + type.getSimpleName());
|
||||
}
|
||||
Class<? extends VersionedConfig> storedType = jsonVersions.get(storedVersion);
|
||||
if (storedType == null) {
|
||||
throw new IllegalStateException("Unknown version " + storedVersion + " of " + type.getSimpleName());
|
||||
}
|
||||
return update(gson.fromJson(json, storedType));
|
||||
}
|
||||
|
||||
public String write(T config) {
|
||||
return gson.toJson(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a config to the current version.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public T update(VersionedConfig config) {
|
||||
while (config.getVersion() < version) {
|
||||
ConfigConverter converter = converters.get(config.getVersion());
|
||||
if (converter == null) {
|
||||
throw new IllegalStateException("No converter found for version " + config.getVersion() + " of " + type.getSimpleName());
|
||||
}
|
||||
VersionedConfig converted = converter.convert(config);
|
||||
if (converted.getVersion() <= config.getVersion()) {
|
||||
throw new IllegalStateException("Version did not increase after conversion of version " + config.getVersion() + " of " + type.getSimpleName());
|
||||
}
|
||||
config = converted;
|
||||
}
|
||||
if (!type.isInstance(config)) {
|
||||
throw new IllegalStateException("Version " + config.getVersion() + " is not the current version of " + type.getSimpleName());
|
||||
}
|
||||
return type.cast(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the config stored in the file, or the default config if the file is missing or empty
|
||||
* @throws RuntimeException if the config could not be read or converted
|
||||
*/
|
||||
public T load(File file) throws IOException {
|
||||
if (file.length() == 0) {
|
||||
return defaultConfig.get();
|
||||
}
|
||||
return read(Files.readString(file.toPath(), StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public void save(File file, T config) throws IOException {
|
||||
Files.writeString(file.toPath(), write(config), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config of a player, loads it from the {@link UserConfig} and converts it if necessary.
|
||||
*/
|
||||
public T get(Player player) {
|
||||
requireUserConfig();
|
||||
return playerConfigs.computeIfAbsent(player.getUniqueId(), this::loadPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the config of a player, this does not unload the config.
|
||||
*/
|
||||
public void save(Player player) {
|
||||
requireUserConfig();
|
||||
T config = playerConfigs.get(player.getUniqueId());
|
||||
if (config != null) {
|
||||
savePlayer(player.getUniqueId(), config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save and unload the config of a player.
|
||||
*/
|
||||
public void unload(Player player) {
|
||||
if (userConfigKey == null) return;
|
||||
T config = playerConfigs.remove(player.getUniqueId());
|
||||
if (config != null) {
|
||||
savePlayer(player.getUniqueId(), config);
|
||||
}
|
||||
}
|
||||
|
||||
private T loadPlayer(UUID uuid) {
|
||||
String stored = UserConfig.getConfig(uuid, userConfigKey);
|
||||
if (stored == null) {
|
||||
return defaultConfig.get();
|
||||
}
|
||||
try {
|
||||
return read(stored);
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not load " + type.getSimpleName() + " of " + uuid, e);
|
||||
return defaultConfig.get();
|
||||
}
|
||||
}
|
||||
|
||||
private void savePlayer(UUID uuid, T config) {
|
||||
if (removeIf.test(config)) {
|
||||
UserConfig.removePlayerConfig(uuid, userConfigKey);
|
||||
} else {
|
||||
UserConfig.updatePlayerConfig(uuid, userConfigKey, write(config));
|
||||
}
|
||||
}
|
||||
|
||||
private void requireUserConfig() {
|
||||
if (userConfigKey == null) {
|
||||
throw new IllegalStateException(type.getSimpleName() + " is not stored in the UserConfig");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config of the file of this store, loads it and converts it if necessary.
|
||||
*/
|
||||
public T get() {
|
||||
requireFile();
|
||||
if (fileConfig == null) {
|
||||
fileConfig = loadFile();
|
||||
save();
|
||||
}
|
||||
return fileConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the config to the file of this store, if it was loaded.
|
||||
*/
|
||||
public void save() {
|
||||
requireFile();
|
||||
if (fileConfig == null) return;
|
||||
try {
|
||||
save(file, fileConfig);
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not write " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
private T loadFile() {
|
||||
try {
|
||||
if (file.length() != 0) {
|
||||
return load(file);
|
||||
}
|
||||
if (legacyFile != null && legacyFile.length() != 0) {
|
||||
return update(legacyFileReader.apply(Files.readString(legacyFile.toPath(), StandardCharsets.UTF_8)));
|
||||
}
|
||||
return defaultConfig.get();
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not load " + file + ", using default " + type.getSimpleName(), e);
|
||||
backupBrokenFile();
|
||||
return defaultConfig.get();
|
||||
}
|
||||
}
|
||||
|
||||
private void backupBrokenFile() {
|
||||
if (file.length() == 0) return;
|
||||
try {
|
||||
Files.copy(file.toPath(), new File(file.getParentFile(), file.getName() + ".broken").toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Could not backup broken " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void requireFile() {
|
||||
if (file == null) {
|
||||
throw new IllegalStateException(type.getSimpleName() + " is not bound to a file");
|
||||
}
|
||||
}
|
||||
|
||||
static void unloadAll(Player player) {
|
||||
STORES.forEach(store -> store.unload(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves every loaded config and unloads the configs of the players.
|
||||
*/
|
||||
public static void saveAll() {
|
||||
for (ConfigStore<?> store : STORES) {
|
||||
if (store.userConfigKey != null) {
|
||||
store.playerConfigs.forEach((uuid, config) -> saveUnchecked(store, uuid, config));
|
||||
store.playerConfigs.clear();
|
||||
}
|
||||
if (store.file != null) {
|
||||
store.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends VersionedConfig> void saveUnchecked(ConfigStore<T> store, UUID uuid, Object config) {
|
||||
store.savePlayer(uuid, (T) config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.bausystem.config;
|
||||
|
||||
import de.steamwar.core.CRIUSleepEvent;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
/**
|
||||
* Saves and unloads the configs of the {@link ConfigStore}s bound to the UserConfig
|
||||
* when a player quits, configs are loaded on first use.
|
||||
*/
|
||||
@Linked
|
||||
public class ConfigStoreListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
ConfigStore.unloadAll(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCRIUSleep(CRIUSleepEvent event) {
|
||||
ConfigStore.saveAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.bausystem.config;
|
||||
|
||||
/**
|
||||
* Common interface of every version of a config stored by a {@link ConfigStore},
|
||||
* the current version (e.g. Config) and every older version (ConfigV1, ConfigV2, ...).
|
||||
*/
|
||||
public interface VersionedConfig {
|
||||
|
||||
int getVersion();
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.bausystem.config.legacy;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Deserializes {@link ItemStack}s that were serialized by YAPION, read with {@link YapionReader}.
|
||||
*/
|
||||
@UtilityClass
|
||||
@Deprecated
|
||||
public class YapionItemDeserializer {
|
||||
|
||||
private static final String TYPE_IDENTIFIER = "@type";
|
||||
|
||||
public ItemStack deserializeItem(Object yapion) {
|
||||
if (yapion == null) return null;
|
||||
Object result = deserialize(yapion);
|
||||
if (result instanceof ItemStack itemStack) return itemStack;
|
||||
throw new IllegalArgumentException("Not an ItemStack: " + result);
|
||||
}
|
||||
|
||||
private Object deserialize(Object yapion) {
|
||||
if (yapion instanceof List<?> list) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
list.forEach(o -> result.add(deserialize(o)));
|
||||
return result;
|
||||
}
|
||||
if (yapion instanceof YapionReader.YapionMap map) {
|
||||
Map<Object, Object> result = new LinkedHashMap<>();
|
||||
map.entries().forEach((key, value) -> result.put(deserialize(key), deserialize(value)));
|
||||
return result;
|
||||
}
|
||||
if (yapion instanceof Map<?, ?> object) {
|
||||
return deserializeObject(object);
|
||||
}
|
||||
return yapion;
|
||||
}
|
||||
|
||||
private Object deserializeObject(Map<?, ?> object) {
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
object.forEach((key, value) -> {
|
||||
if (!TYPE_IDENTIFIER.equals(key)) data.put((String) key, deserialize(value));
|
||||
});
|
||||
|
||||
if (!(object.get(TYPE_IDENTIFIER) instanceof String type)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
Class<?> javaType = javaUtilClass(type);
|
||||
if (javaType != null && Collection.class.isAssignableFrom(javaType)) {
|
||||
return data.getOrDefault("values", new ArrayList<>());
|
||||
}
|
||||
if (javaType != null && Map.class.isAssignableFrom(javaType)) {
|
||||
return data.containsKey("values") ? data.get("values") : data;
|
||||
}
|
||||
|
||||
data.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, type.equals("org.bukkit.inventory.meta.ItemMeta") ? "ItemMeta" : type);
|
||||
return ConfigurationSerialization.deserializeObject(data);
|
||||
}
|
||||
|
||||
private Class<?> javaUtilClass(String type) {
|
||||
if (!type.startsWith("java.util.")) return null;
|
||||
try {
|
||||
return Class.forName(type);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 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.bausystem.config.legacy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Minimal reader for the legacy YAPION format, only used to migrate old data.
|
||||
* <p>
|
||||
* The result is built from plain java objects:
|
||||
* <ul>
|
||||
* <li>YAPION objects {@code {key(value)}} become a {@link LinkedHashMap} of String to value</li>
|
||||
* <li>YAPION arrays {@code [a,b]} become a {@link List}</li>
|
||||
* <li>YAPION maps {@code <(a):(b)>} become a {@link YapionMap}</li>
|
||||
* <li>YAPION values {@code (value)} become null, Boolean, Number or String</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Deprecated
|
||||
public class YapionReader {
|
||||
|
||||
private static final Pattern INTEGER = Pattern.compile("[-+]?\\d+");
|
||||
private static final Pattern DECIMAL = Pattern.compile("[-+]?(\\d+\\.\\d*|\\.\\d+|\\d+)([eE][-+]?\\d+)?");
|
||||
|
||||
public record YapionMap(Map<Object, Object> entries) {
|
||||
}
|
||||
|
||||
public static Map<String, Object> parse(String yapion) {
|
||||
YapionReader reader = new YapionReader(yapion);
|
||||
reader.skipWhitespace();
|
||||
Map<String, Object> result = reader.readObject();
|
||||
reader.skipWhitespace();
|
||||
if (reader.index != yapion.length()) {
|
||||
throw reader.error("Unexpected trailing content");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double getDouble(Map<?, ?> object, String key, double defaultValue) {
|
||||
return object.get(key) instanceof Number value ? value.doubleValue() : defaultValue;
|
||||
}
|
||||
|
||||
public static int getInt(Map<?, ?> object, String key, int defaultValue) {
|
||||
return object.get(key) instanceof Number value ? value.intValue() : defaultValue;
|
||||
}
|
||||
|
||||
public static boolean getBoolean(Map<?, ?> object, String key, boolean defaultValue) {
|
||||
return object.get(key) instanceof Boolean value ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static String getString(Map<?, ?> object, String key, String defaultValue) {
|
||||
return object.get(key) instanceof String value ? value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entries of the array that are YAPION objects
|
||||
*/
|
||||
public static List<Map<?, ?>> getObjects(Map<?, ?> object, String key) {
|
||||
List<Map<?, ?>> objects = new ArrayList<>();
|
||||
if (object.get(key) instanceof List<?> array) {
|
||||
array.forEach(o -> {
|
||||
if (o instanceof Map<?, ?> map) objects.add(map);
|
||||
});
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
private final String input;
|
||||
private int index = 0;
|
||||
|
||||
private YapionReader(String input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
private Object readAny() {
|
||||
return switch (peek()) {
|
||||
case '{' -> readObject();
|
||||
case '[' -> readArray();
|
||||
case '<' -> readMap();
|
||||
case '(' -> readValue();
|
||||
default -> throw error("Expected '{', '[', '<' or '('");
|
||||
};
|
||||
}
|
||||
|
||||
private Map<String, Object> readObject() {
|
||||
expect('{');
|
||||
Map<String, Object> object = new LinkedHashMap<>();
|
||||
while (true) {
|
||||
skipWhitespace();
|
||||
if (peek() == '}') {
|
||||
index++;
|
||||
return object;
|
||||
}
|
||||
StringBuilder key = new StringBuilder();
|
||||
while (true) {
|
||||
char c = peek();
|
||||
if (c == '(' || c == '{' || c == '[' || c == '<') break;
|
||||
if (c == '}') throw error("Key without value");
|
||||
key.append(readChar());
|
||||
}
|
||||
object.put(key.toString(), readAny());
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> readArray() {
|
||||
expect('[');
|
||||
List<Object> array = new ArrayList<>();
|
||||
skipWhitespace();
|
||||
if (peek() == ']') {
|
||||
index++;
|
||||
return array;
|
||||
}
|
||||
while (true) {
|
||||
int start = index;
|
||||
skipWhitespace();
|
||||
char c = peek();
|
||||
if (c == '{' || c == '[' || c == '<' || c == '(') {
|
||||
array.add(readAny());
|
||||
skipWhitespace();
|
||||
} else {
|
||||
// Whitespace is part of plain values
|
||||
index = start;
|
||||
StringBuilder value = new StringBuilder();
|
||||
while (peek() != ',' && peek() != ']') {
|
||||
value.append(readChar());
|
||||
}
|
||||
array.add(typed(value.toString()));
|
||||
}
|
||||
char separator = input.charAt(index++);
|
||||
if (separator == ']') return array;
|
||||
if (separator != ',') throw error("Expected ',' or ']'");
|
||||
}
|
||||
}
|
||||
|
||||
private YapionMap readMap() {
|
||||
expect('<');
|
||||
Map<Object, Object> map = new LinkedHashMap<>();
|
||||
while (true) {
|
||||
skipWhitespace();
|
||||
if (peek() == '>') {
|
||||
index++;
|
||||
return new YapionMap(map);
|
||||
}
|
||||
Object key = readAny();
|
||||
skipWhitespace();
|
||||
expect(':');
|
||||
skipWhitespace();
|
||||
map.put(key, readAny());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* YAPION does not escape parentheses in values, balanced parentheses are part of the value.
|
||||
* A backslash only escapes a backslash, a unicode sequence or a control character, otherwise it is kept.
|
||||
*/
|
||||
private Object readValue() {
|
||||
expect('(');
|
||||
StringBuilder value = new StringBuilder();
|
||||
int depth = 0;
|
||||
while (true) {
|
||||
char c = peek();
|
||||
if (c == '\\') {
|
||||
value.append(readValueEscape());
|
||||
continue;
|
||||
}
|
||||
index++;
|
||||
if (c == '(') {
|
||||
depth++;
|
||||
} else if (c == ')') {
|
||||
if (depth == 0) break;
|
||||
depth--;
|
||||
}
|
||||
value.append(c);
|
||||
}
|
||||
return typed(value.toString());
|
||||
}
|
||||
|
||||
private String readValueEscape() {
|
||||
index++;
|
||||
if (index >= input.length()) return "\\";
|
||||
char escaped = input.charAt(index);
|
||||
switch (escaped) {
|
||||
case '\\', '(', ')':
|
||||
index++;
|
||||
return String.valueOf(escaped);
|
||||
case 'n':
|
||||
index++;
|
||||
return "\n";
|
||||
case 't':
|
||||
index++;
|
||||
return "\t";
|
||||
case 'r':
|
||||
index++;
|
||||
return "\r";
|
||||
case 'u':
|
||||
if (index + 5 <= input.length() && input.substring(index + 1, index + 5).matches("[0-9a-fA-F]{4}")) {
|
||||
char unicode = (char) Integer.parseInt(input.substring(index + 1, index + 5), 16);
|
||||
index += 5;
|
||||
return String.valueOf(unicode);
|
||||
}
|
||||
return "\\";
|
||||
default:
|
||||
return "\\";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one character of a key or plain array value, resolving backslash escapes.
|
||||
* A backslash that does not escape anything is kept, as the old player config
|
||||
* collapsed escaped backslashes into a single one.
|
||||
*/
|
||||
private char readChar() {
|
||||
char c = input.charAt(index++);
|
||||
if (c != '\\') return c;
|
||||
if (index >= input.length()) throw error("Unterminated escape");
|
||||
char escaped = input.charAt(index);
|
||||
switch (escaped) {
|
||||
case 'n':
|
||||
index++;
|
||||
return '\n';
|
||||
case 't':
|
||||
index++;
|
||||
return '\t';
|
||||
case 'r':
|
||||
index++;
|
||||
return '\r';
|
||||
case 'u':
|
||||
if (index + 5 <= input.length() && input.substring(index + 1, index + 5).matches("[0-9a-fA-F]{4}")) {
|
||||
char unicode = (char) Integer.parseInt(input.substring(index + 1, index + 5), 16);
|
||||
index += 5;
|
||||
return unicode;
|
||||
}
|
||||
return '\\';
|
||||
case '\\', ',', ' ', '(', ')', '{', '}', '[', ']', '<', '>', '"', ':', '@':
|
||||
index++;
|
||||
return escaped;
|
||||
default:
|
||||
return '\\';
|
||||
}
|
||||
}
|
||||
|
||||
private static Object typed(String value) {
|
||||
if (value.equals("null")) return null;
|
||||
if (value.equals("true")) return true;
|
||||
if (value.equals("false")) return false;
|
||||
if (value.length() >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
|
||||
return value.substring(1, value.length() - 1);
|
||||
}
|
||||
try {
|
||||
if (INTEGER.matcher(value).matches()) {
|
||||
long l = Long.parseLong(value);
|
||||
if (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE) return (int) l;
|
||||
return l;
|
||||
}
|
||||
if (value.length() > 1) {
|
||||
String number = value.substring(0, value.length() - 1);
|
||||
switch (value.charAt(value.length() - 1)) {
|
||||
case 'L':
|
||||
if (INTEGER.matcher(number).matches()) return Long.parseLong(number);
|
||||
break;
|
||||
case 'S':
|
||||
if (INTEGER.matcher(number).matches()) return Short.parseShort(number);
|
||||
break;
|
||||
case 'B':
|
||||
if (INTEGER.matcher(number).matches()) return Byte.parseByte(number);
|
||||
break;
|
||||
case 'F':
|
||||
if (DECIMAL.matcher(number).matches()) return Float.parseFloat(number);
|
||||
break;
|
||||
case 'D':
|
||||
if (DECIMAL.matcher(number).matches()) return Double.parseDouble(number);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (DECIMAL.matcher(value).matches()) return Double.parseDouble(value);
|
||||
} catch (NumberFormatException e) {
|
||||
// Not a number, fall through to String
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private void skipWhitespace() {
|
||||
while (index < input.length() && Character.isWhitespace(input.charAt(index))) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private char peek() {
|
||||
if (index >= input.length()) throw error("Unexpected end of input");
|
||||
return input.charAt(index);
|
||||
}
|
||||
|
||||
private void expect(char c) {
|
||||
if (peek() != c) throw error("Expected '" + c + "'");
|
||||
index++;
|
||||
}
|
||||
|
||||
private IllegalArgumentException error(String message) {
|
||||
return new IllegalArgumentException(message + " at index " + index);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.bausystem.config.serializer;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Stores an {@link ItemStack} as Base64 of {@link ItemStack#serializeAsBytes()}, which
|
||||
* contains the data version and gets upgraded on newer Minecraft versions.
|
||||
* Empty items are stored as null, items that can't be read are deserialized as null.
|
||||
*/
|
||||
public class ItemStackTypeAdapter extends TypeAdapter<ItemStack> {
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, ItemStack itemStack) throws IOException {
|
||||
if (itemStack == null || itemStack.isEmpty()) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.value(Base64.getEncoder().encodeToString(itemStack.serializeAsBytes()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack read(JsonReader in) throws IOException {
|
||||
if (in.peek() == JsonToken.NULL) {
|
||||
in.nextNull();
|
||||
return null;
|
||||
}
|
||||
String value = in.nextString();
|
||||
try {
|
||||
return ItemStack.deserializeBytes(Base64.getDecoder().decode(value));
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not deserialize ItemStack", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -19,129 +19,77 @@
|
||||
|
||||
package de.steamwar.bausystem.configplayer;
|
||||
|
||||
import de.steamwar.bausystem.configplayer.serializer.ConfigurationSerializableSerializer;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import de.steamwar.sql.UserConfig;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import de.steamwar.bausystem.config.ConfigConverter;
|
||||
import de.steamwar.bausystem.config.ConfigStore;
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import de.steamwar.bausystem.config.serializer.ItemStackTypeAdapter;
|
||||
import de.steamwar.bausystem.configplayer.converter.ConfigV1ToV2Converter;
|
||||
import de.steamwar.bausystem.features.hotbar.DefaultHotbar;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import yapion.hierarchy.output.StringOutput;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.YAPIONParser;
|
||||
import yapion.serializing.SerializeManager;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@Linked
|
||||
public class Config implements Listener {
|
||||
/**
|
||||
* The current player config. It is stored as JSON, fields missing in the
|
||||
* stored JSON keep the default value of their initializer, so adding a new
|
||||
* field does not need a new version.
|
||||
* <p>
|
||||
* When a field gets removed, renamed or its meaning changes, copy this class
|
||||
* to ConfigV{@link #VERSION} (without the {@link #STORE}), increase {@link #VERSION},
|
||||
* write a {@link ConfigConverter} from the copy to this class and register it in the {@link #STORE}.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class Config implements VersionedConfig {
|
||||
|
||||
static {
|
||||
SerializeManager.add(new ConfigurationSerializableSerializer());
|
||||
}
|
||||
public static final int VERSION = 2;
|
||||
|
||||
@Getter
|
||||
private static Config instance;
|
||||
public static final ConfigStore<Config> STORE = new ConfigStore<>(Config.class, VERSION, Config::new)
|
||||
.gson(new GsonBuilder().registerTypeHierarchyAdapter(ItemStack.class, new ItemStackTypeAdapter()).create())
|
||||
.legacy(s -> s.startsWith("{@version(1)"), ConfigV1::parse)
|
||||
.converter(new ConfigV1ToV2Converter())
|
||||
.userConfig("bausystem");
|
||||
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private final Map<UUID, YAPIONObject> playerConfigurations = new HashMap<>();
|
||||
|
||||
private static final Map<Integer, ConfigConverter> CONFIG_CONVERTER_MAP = new HashMap<>();
|
||||
|
||||
public static void addConfigConverter(ConfigConverter configConverter) {
|
||||
CONFIG_CONVERTER_MAP.putIfAbsent(configConverter.version(), configConverter);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
get(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
save(event.getPlayer());
|
||||
playerConfigurations.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
/**
|
||||
* Get a PlayerConfig, optionally loads it from the DataBase and migrates it if necessary.
|
||||
*
|
||||
* @param player the player from whom to get the config.
|
||||
* @return the config object
|
||||
* BauGui item id to inventory slot
|
||||
*/
|
||||
public YAPIONObject get(Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (!playerConfigurations.containsKey(uuid)) {
|
||||
String s = UserConfig.getConfig(uuid, "bausystem");
|
||||
YAPIONObject yapionObject;
|
||||
if (s == null) {
|
||||
yapionObject = ConfigCreator.createDefaultConfig();
|
||||
} else {
|
||||
yapionObject = YAPIONParser.parse(s);
|
||||
}
|
||||
yapionObject = update(yapionObject);
|
||||
playerConfigurations.put(uuid, yapionObject);
|
||||
return yapionObject;
|
||||
}
|
||||
return playerConfigurations.get(uuid);
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
playerConfigurations.forEach((uuid, yapionObject) -> {
|
||||
String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\+", "\\");
|
||||
UserConfig.updatePlayerConfig(uuid, "bausystem", string);
|
||||
});
|
||||
playerConfigurations.clear();
|
||||
}
|
||||
protected Map<Integer, Integer> bauGui = defaultBauGui();
|
||||
protected int bauGuiSize = 45;
|
||||
|
||||
/**
|
||||
* Save a PlayerConfig, this does not remove the key value mapping from the map.
|
||||
*
|
||||
* @param player the player to save the config.
|
||||
* Slots 0-8 are the hotbar, slots 9-12 the armor contents
|
||||
*/
|
||||
public void save(Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
if (playerConfigurations.containsKey(uuid)) {
|
||||
YAPIONObject yapionObject = playerConfigurations.get(uuid);
|
||||
String string = yapionObject.toYAPION(new StringOutput()).getResult().replaceAll("\\\\+", "\\\\");
|
||||
UserConfig.updatePlayerConfig(uuid, "bausystem", string);
|
||||
}
|
||||
}
|
||||
protected ItemStack[] hotbar = DefaultHotbar.defaultHotbar();
|
||||
|
||||
private YAPIONObject update(YAPIONObject yapionObject) {
|
||||
int version = yapionObject.getPlainValue("@version");
|
||||
while (version < ConfigCreator.currentVersion) {
|
||||
ConfigConverter configConverter = CONFIG_CONVERTER_MAP.getOrDefault(version, null);
|
||||
if (configConverter == null) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "No updater found for version " + version);
|
||||
return ConfigCreator.createDefaultConfig();
|
||||
}
|
||||
try {
|
||||
configConverter.update(yapionObject);
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
return ConfigCreator.createDefaultConfig();
|
||||
}
|
||||
int newVersion = yapionObject.getPlainValue("@version");
|
||||
if (version == newVersion) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Version Tag was the same after conversion");
|
||||
return ConfigCreator.createDefaultConfig();
|
||||
}
|
||||
if (newVersion < version) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Version Tag was earlier after conversion");
|
||||
return ConfigCreator.createDefaultConfig();
|
||||
}
|
||||
version = newVersion;
|
||||
}
|
||||
return yapionObject;
|
||||
protected boolean nightVision = false;
|
||||
protected boolean tntClickDetails = true;
|
||||
protected boolean detonatorAutostart = false;
|
||||
protected boolean inventoryFill = false;
|
||||
protected boolean rayVisualizer = false;
|
||||
protected boolean smartPlace = false;
|
||||
protected boolean blockCounter = false;
|
||||
protected boolean depthMessage = true;
|
||||
|
||||
public static Map<Integer, Integer> defaultBauGui() {
|
||||
// 0: ? | 1: ? | 2: 10 | 3: 3 | 4: 7 | 5: 17 | 6: 15 | 7: ? | 8: ?
|
||||
// 9: 5 | 10: ? | 11: ? | 12: ? | 13: ? | 14: ? | 15: ? | 16: ? | 17: 16
|
||||
// 18: 4 | 19: ? | 20: 19 | 21: 21 | 22: 9 | 23: 0 | 24: 1 | 25: ? | 26: 11
|
||||
// 27: 6 | 28: ? | 29: ? | 30: ? | 31: ? | 32: ? | 33: ? | 34: ? | 35: 18
|
||||
// 36: ? | 37: 23 | 38: 20 | 39: 8 | 40: 22 | 41: 26 | 42: 12 | 43: 14 | 44: ?
|
||||
Map<Integer, Integer> bauGui = new HashMap<>();
|
||||
bauGui.put(10, 2); bauGui.put(3, 3); bauGui.put(7, 4); bauGui.put(17, 5); bauGui.put(15, 6);
|
||||
bauGui.put(5, 9); bauGui.put(4, 18); bauGui.put(6, 27);
|
||||
bauGui.put(16, 17); bauGui.put(11, 26); bauGui.put(18, 35);
|
||||
bauGui.put(19, 20); bauGui.put(21, 21); bauGui.put(9, 22); bauGui.put(0, 23); bauGui.put(1, 24);
|
||||
bauGui.put(23, 37); bauGui.put(20, 38); bauGui.put(8, 39); bauGui.put(22, 40); bauGui.put(26, 41); bauGui.put(12, 42); bauGui.put(14, 43);
|
||||
return bauGui;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +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.configplayer;
|
||||
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
/**
|
||||
* A new {@link ConfigConverter} should be written when you remove anything
|
||||
* from the Config or modify any mayor part. When you move anything from
|
||||
* any key to any other key you should write a new {@link ConfigConverter}.
|
||||
* For adding any new key you should be able to get the default without
|
||||
* having it in the Config. Anything you need to change you should also
|
||||
* change the {@link ConfigCreator} accordingly, to produce the new Config.
|
||||
*/
|
||||
public interface ConfigConverter {
|
||||
|
||||
/**
|
||||
* This describes the version this Converter can convert from. The version
|
||||
* it should convert to is the version 1 above this number. But this is not
|
||||
* a necessity. In the config Object as parameter given in {@link #update(YAPIONObject)}
|
||||
* you should update the <b>@version</b> variable in the root object to the
|
||||
* new version this converter produced.
|
||||
*
|
||||
* @return the version number
|
||||
*/
|
||||
int version();
|
||||
|
||||
/**
|
||||
* This method should update everything needed to go from a lower config
|
||||
* version to a higher. It should update the <b>@version</b> variable
|
||||
* accordingly. Anything else is up the implementation. If anything goes wrong
|
||||
* do not silently exit this method, throw an Exception. The updater Code will
|
||||
* deal with it. Never leave the inputted object in a corrupted state.
|
||||
*
|
||||
* @param config the config object to update
|
||||
*/
|
||||
void update(YAPIONObject config);
|
||||
|
||||
}
|
||||
@@ -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.bausystem.configplayer;
|
||||
|
||||
import de.steamwar.bausystem.features.hotbar.DefaultHotbar;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
@UtilityClass
|
||||
public class ConfigCreator {
|
||||
|
||||
public static final int currentVersion = 1;
|
||||
|
||||
public YAPIONObject createDefaultConfig() {
|
||||
YAPIONObject yapionObject = new YAPIONObject();
|
||||
// This call should never be touched
|
||||
yapionObject.add("@version", currentVersion);
|
||||
|
||||
// Any initialising goes into here
|
||||
yapionObject.add("baugui", defaultBauGui());
|
||||
|
||||
// Default Hotbar Gui
|
||||
yapionObject.add("hotbar", DefaultHotbar.defaultHotbar());
|
||||
return yapionObject;
|
||||
}
|
||||
|
||||
private YAPIONObject defaultBauGui() {
|
||||
YAPIONObject yapionObject = new YAPIONObject();
|
||||
|
||||
// 0: ? | 1: ? | 2: 10 | 3: 3 | 4: 7 | 5: 17 | 6: 15 | 7: ? | 8: ?
|
||||
// 9: 5 | 10: ? | 11: ? | 12: ? | 13: ? | 14: ? | 15: ? | 16: ? | 17: 16
|
||||
// 18: 4 | 19: ? | 20: 19 | 21: 21 | 22: 9 | 23: 0 | 24: 1 | 25: ? | 26: 11
|
||||
// 27: 6 | 28: ? | 29: ? | 30: ? | 31: ? | 32: ? | 33: ? | 34: ? | 35: 18
|
||||
// 36: ? | 37: 23 | 38: 20 | 39: 8 | 40: 22 | 41: 26 | 42: 12 | 43: 14 | 44: ?
|
||||
|
||||
yapionObject.add("10", 2).add("3", 3).add("7", 4).add("17", 5).add("15", 6);
|
||||
yapionObject.add("5", 9).add("4", 18).add("6", 27);
|
||||
yapionObject.add("16", 17).add("11", 26).add("18", 35);
|
||||
yapionObject.add("19", 20).add("21", 21).add("9", 22).add("0", 23).add("1", 24);
|
||||
yapionObject.add("23", 37).add("20", 38).add("8", 39).add("22", 40).add("26", 41).add("12", 42).add("14", 43);
|
||||
yapionObject.add("size", 45);
|
||||
return yapionObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.bausystem.configplayer;
|
||||
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import de.steamwar.bausystem.config.legacy.YapionReader;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The legacy config that was stored in the YAPION format.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ConfigV1 implements VersionedConfig {
|
||||
|
||||
public static final int VERSION = 1;
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
/**
|
||||
* BauGui item id to inventory slot
|
||||
*/
|
||||
protected Map<Integer, Integer> bauGui = new HashMap<>();
|
||||
protected int bauGuiSize = 45;
|
||||
|
||||
/**
|
||||
* Minecraft version to the hotbar serialized by YAPION, read with {@link YapionReader}.
|
||||
* Use {@link de.steamwar.bausystem.config.legacy.YapionItemDeserializer} to get the items.
|
||||
*/
|
||||
protected Map<Integer, List<?>> hotbars = new HashMap<>();
|
||||
|
||||
protected boolean nightVision = false;
|
||||
protected boolean tntClickDetails = true;
|
||||
protected boolean detonatorAutostart = false;
|
||||
protected boolean inventoryFill = false;
|
||||
protected boolean rayVisualizer = false;
|
||||
protected boolean smartPlace = false;
|
||||
protected boolean blockCounter = false;
|
||||
protected boolean depthMessage = true;
|
||||
|
||||
public static ConfigV1 parse(String yapion) {
|
||||
Map<String, Object> object = YapionReader.parse(yapion);
|
||||
ConfigV1 config = new ConfigV1();
|
||||
config.version = (Integer) object.get("@version");
|
||||
|
||||
if (object.get("baugui") instanceof Map<?, ?> bauGui) {
|
||||
bauGui.forEach((key, value) -> {
|
||||
if (key.equals("size")) {
|
||||
config.bauGuiSize = (Integer) value;
|
||||
} else {
|
||||
config.bauGui.put(Integer.parseInt((String) key), (Integer) value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
object.forEach((key, value) -> {
|
||||
if (!(value instanceof List<?> hotbar)) return;
|
||||
if (key.equals("hotbar")) {
|
||||
// Hotbars were stored without version prior to 1.19
|
||||
config.hotbars.putIfAbsent(19, hotbar);
|
||||
} else if (key.startsWith("hotbar-")) {
|
||||
config.hotbars.put(Integer.parseInt(key.substring("hotbar-".length())), hotbar);
|
||||
}
|
||||
});
|
||||
|
||||
config.nightVision = getBoolean(object, "nightvision", config.nightVision);
|
||||
config.tntClickDetails = getBoolean(object, "tnt_click_details", config.tntClickDetails);
|
||||
config.detonatorAutostart = getBoolean(object, "detonator-autostart", config.detonatorAutostart);
|
||||
config.inventoryFill = getBoolean(object, "inventoryfill", config.inventoryFill);
|
||||
config.rayVisualizer = getBoolean(object, "rayvisualizer", config.rayVisualizer);
|
||||
config.smartPlace = getBoolean(object, "smartPlace", config.smartPlace);
|
||||
config.blockCounter = getBoolean(object, "blockCounter", config.blockCounter);
|
||||
config.depthMessage = getBoolean(object, "depth_message", config.depthMessage);
|
||||
return config;
|
||||
}
|
||||
|
||||
private static boolean getBoolean(Map<String, Object> object, String key, boolean defaultValue) {
|
||||
return object.get(key) instanceof Boolean value ? value : defaultValue;
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.bausystem.configplayer.converter;
|
||||
|
||||
import de.steamwar.bausystem.config.ConfigConverter;
|
||||
import de.steamwar.bausystem.config.legacy.YapionItemDeserializer;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.bausystem.configplayer.ConfigV1;
|
||||
import de.steamwar.core.Core;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@Deprecated
|
||||
public class ConfigV1ToV2Converter implements ConfigConverter<ConfigV1, Config> {
|
||||
|
||||
@Override
|
||||
public int version() {
|
||||
return ConfigV1.VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Config convert(ConfigV1 old) {
|
||||
Config config = new Config();
|
||||
config.setBauGui(new HashMap<>(old.getBauGui()));
|
||||
config.setBauGuiSize(old.getBauGuiSize());
|
||||
|
||||
List<?> hotbar = old.getHotbars().get(Core.getVersion());
|
||||
if (hotbar != null) {
|
||||
config.setHotbar(convertHotbar(hotbar));
|
||||
}
|
||||
|
||||
config.setNightVision(old.isNightVision());
|
||||
config.setTntClickDetails(old.isTntClickDetails());
|
||||
config.setDetonatorAutostart(old.isDetonatorAutostart());
|
||||
config.setInventoryFill(old.isInventoryFill());
|
||||
config.setRayVisualizer(old.isRayVisualizer());
|
||||
config.setSmartPlace(old.isSmartPlace());
|
||||
config.setBlockCounter(old.isBlockCounter());
|
||||
config.setDepthMessage(old.isDepthMessage());
|
||||
return config;
|
||||
}
|
||||
|
||||
private ItemStack[] convertHotbar(List<?> hotbar) {
|
||||
ItemStack[] items = new ItemStack[13];
|
||||
for (int i = 0; i < Math.min(hotbar.size(), items.length); i++) {
|
||||
try {
|
||||
items[i] = YapionItemDeserializer.deserializeItem(hotbar.get(i));
|
||||
} catch (Exception e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not convert hotbar item " + i, e);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
-90
@@ -1,90 +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.configplayer.serializer;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import yapion.hierarchy.api.groups.YAPIONAnyType;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.serializing.api.SerializerObject;
|
||||
import yapion.serializing.data.DeserializeData;
|
||||
import yapion.serializing.data.SerializeData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static yapion.utils.IdentifierUtils.TYPE_IDENTIFIER;
|
||||
|
||||
public class ConfigurationSerializableSerializer extends SerializerObject<ConfigurationSerializable> {
|
||||
|
||||
@Override
|
||||
public Class<ConfigurationSerializable> type() {
|
||||
return ConfigurationSerializable.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public YAPIONObject serialize(SerializeData<ConfigurationSerializable> serializeData) {
|
||||
YAPIONObject yapionObject = new YAPIONObject();
|
||||
yapionObject.add(TYPE_IDENTIFIER, serializeData.object.getClass().getTypeName());
|
||||
if (serializeData.object instanceof ItemStack) {
|
||||
yapionObject.add(TYPE_IDENTIFIER, ItemStack.class.getTypeName());
|
||||
}
|
||||
if (serializeData.object instanceof ItemMeta) {
|
||||
yapionObject.add(TYPE_IDENTIFIER, ItemMeta.class.getTypeName());
|
||||
}
|
||||
Map<String, Object> serializeDataMap = serializeData.object.serialize();
|
||||
serializeDataMap.forEach((s, o) -> {
|
||||
YAPIONAnyType yapionAnyType = serializeData.serialize(o);
|
||||
if (yapionAnyType instanceof YAPIONObject) {
|
||||
YAPIONObject object = (YAPIONObject) yapionAnyType;
|
||||
if (object.containsKey(TYPE_IDENTIFIER) && object.getPlainValue(TYPE_IDENTIFIER).equals("com.google.common.collect.RegularImmutableList")) {
|
||||
object.put(TYPE_IDENTIFIER, ArrayList.class.getTypeName());
|
||||
}
|
||||
}
|
||||
yapionObject.add(s, yapionAnyType);
|
||||
});
|
||||
return yapionObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSerializable deserialize(DeserializeData<YAPIONObject> deserializeData) {
|
||||
Map<String, Object> deserializeDataMap = new HashMap<>();
|
||||
deserializeData.object.forEach((s, yapionAnyType) -> {
|
||||
if (s.equals(TYPE_IDENTIFIER)) {
|
||||
if (yapionAnyType.toString().equals("(org.bukkit.inventory.meta.ItemMeta)")) {
|
||||
deserializeDataMap.put("==", "ItemMeta");
|
||||
} else {
|
||||
deserializeDataMap.put("==", deserializeData.deserialize(yapionAnyType));
|
||||
}
|
||||
return;
|
||||
}
|
||||
deserializeDataMap.put(s, deserializeData.deserialize(yapionAnyType));
|
||||
});
|
||||
return ConfigurationSerialization.deserializeObject(deserializeDataMap);
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class Depth {
|
||||
dimensions.setZ(Math.abs(dimensions.getZ()));
|
||||
|
||||
RegionUtils.message(region, player -> {
|
||||
if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
|
||||
if (Config.STORE.get(player).isDepthMessage()) {
|
||||
player.spigot().sendMessage(getMessage(player, dimensions.getBlockX() + 1, dimensions.getBlockY() + 1, dimensions.getBlockZ() + 1, tntCount));
|
||||
}
|
||||
});
|
||||
|
||||
+3
-3
@@ -34,11 +34,11 @@ public class DepthCommand extends SWCommand {
|
||||
|
||||
@Register
|
||||
public void toggle(Player player) {
|
||||
if (Config.getInstance().get(player).getPlainValueOrDefault("depth_message", true)) {
|
||||
Config.getInstance().get(player).put("depth_message", false);
|
||||
if (Config.STORE.get(player).isDepthMessage()) {
|
||||
Config.STORE.get(player).setDepthMessage(false);
|
||||
BauSystem.MESSAGE.send("DEPTH_COUNTER_DISABLE", player);
|
||||
} else {
|
||||
Config.getInstance().get(player).put("depth_message", true);
|
||||
Config.STORE.get(player).setDepthMessage(true);
|
||||
BauSystem.MESSAGE.send("DEPTH_COUNTER_ENABLE", player);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ public class Detonator {
|
||||
|
||||
public static void activateDetonator(DetonatorStorage detonator) {
|
||||
Player p = detonator.getPlayer();
|
||||
if (Config.getInstance().get(p).getPlainValueOrDefault("detonator-autostart", false)) {
|
||||
if (Config.STORE.get(p).isDetonatorAutostart()) {
|
||||
AutostartListener.instance.activate(p);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -76,8 +76,8 @@ public class DetonatorCommand extends SWCommand {
|
||||
|
||||
@Register(value = "autostart", description = "DETONATOR_HELP_AUTOSTART")
|
||||
public void toggleAutostartTimer(Player p) {
|
||||
boolean current = Config.getInstance().get(p).getPlainValueOrDefault("detonator-autostart", false);
|
||||
Config.getInstance().get(p).put("detonator-autostart", !current);
|
||||
boolean current = Config.STORE.get(p).isDetonatorAutostart();
|
||||
Config.STORE.get(p).setDetonatorAutostart(!current);
|
||||
if (!current) {
|
||||
BauSystem.MESSAGE.send("DETONATOR_AUTOSTART_ENABLE", p);
|
||||
} else {
|
||||
|
||||
+15
-16
@@ -28,7 +28,6 @@ import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -52,15 +51,15 @@ public class BauGuiMapping {
|
||||
}
|
||||
|
||||
@Getter
|
||||
private final YAPIONObject object;
|
||||
private final Config config;
|
||||
@Getter
|
||||
private final Player owner;
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean saved;
|
||||
|
||||
protected BauGuiMapping(YAPIONObject object, Player p) {
|
||||
this.object = object;
|
||||
protected BauGuiMapping(Config config, Player p) {
|
||||
this.config = config;
|
||||
this.owner = p;
|
||||
fromUUID.put(p.getUniqueId(), this);
|
||||
mappings.add(this);
|
||||
@@ -70,19 +69,18 @@ public class BauGuiMapping {
|
||||
BauGuiMapping mapping = fromUUID.get(p.getUniqueId());
|
||||
|
||||
if (mapping == null) {
|
||||
YAPIONObject yapionObject = Config.getInstance().get(p);
|
||||
mapping = new BauGuiMapping(yapionObject.getObject("baugui"), p);
|
||||
mapping = new BauGuiMapping(Config.STORE.get(p), p);
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public boolean isShown(int id) {
|
||||
return object.getPlainValueOrDefault(Integer.toString(id), -1) >= 0;
|
||||
return config.getBauGui().getOrDefault(id, -1) >= 0;
|
||||
}
|
||||
|
||||
public int getSlot(int id) {
|
||||
return object.getPlainValue(Integer.toString(id));
|
||||
return config.getBauGui().get(id);
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getMapping() {
|
||||
@@ -94,7 +92,7 @@ public class BauGuiMapping {
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return object.getPlainValueOrDefault("size", 45);
|
||||
return config.getBauGuiSize();
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
@@ -102,7 +100,7 @@ public class BauGuiMapping {
|
||||
return;
|
||||
}
|
||||
|
||||
object.add("size", size);
|
||||
config.setBauGuiSize(size);
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
@@ -111,16 +109,17 @@ public class BauGuiMapping {
|
||||
|
||||
public void save() {
|
||||
if (saved) return;
|
||||
YAPIONObject config = Config.getInstance().get(owner);
|
||||
config.add("baugui", object);
|
||||
Config.getInstance().save(owner);
|
||||
Config current = Config.STORE.get(owner);
|
||||
current.setBauGui(config.getBauGui());
|
||||
current.setBauGuiSize(config.getBauGuiSize());
|
||||
Config.STORE.save(owner);
|
||||
saved = true;
|
||||
}
|
||||
|
||||
private Map<Integer, Integer> internalReadMap() {
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
for (Map.Entry<Integer, BauGuiItem> e : BauGUI.getITEMS().entrySet()) {
|
||||
Integer value = object.getPlainValueOrDefault(e.getKey().toString(), -1);
|
||||
Integer value = config.getBauGui().getOrDefault(e.getKey(), -1);
|
||||
if (value == -1) continue;
|
||||
map.put(e.getKey(), value);
|
||||
}
|
||||
@@ -129,10 +128,10 @@ public class BauGuiMapping {
|
||||
|
||||
private void internalWriteMap(Map<Integer, Integer> map) {
|
||||
for (Map.Entry<Integer, BauGuiItem> e : BauGUI.getITEMS().entrySet()) {
|
||||
object.remove(e.getKey().toString());
|
||||
config.getBauGui().remove(e.getKey());
|
||||
Integer value = map.getOrDefault(e.getKey(), -1);
|
||||
if (value == -1) continue;
|
||||
object.add(e.getKey().toString(), value);
|
||||
config.getBauGui().put(e.getKey(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+30
-40
@@ -20,39 +20,23 @@
|
||||
package de.steamwar.bausystem.features.hotbar;
|
||||
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.core.Core;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import yapion.hierarchy.types.YAPIONArray;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.hierarchy.types.YAPIONValue;
|
||||
import yapion.parser.YAPIONParser;
|
||||
import yapion.serializing.YAPIONDeserializer;
|
||||
import yapion.serializing.YAPIONSerializer;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class DefaultHotbar {
|
||||
|
||||
private final YAPIONArray DEFAULT_HOTBAR = YAPIONParser.parse("{[{@type(org.bukkit.inventory.ItemStack)v(2230)type(WOODEN_AXE)meta{@type(org.bukkit.inventory.meta.ItemMeta)meta-type(UNSPECIFIC)display-name(WorldEdit Wand)lore{@type(java.util.ArrayList)values[Left click: select pos #1,Right click: select pos #2]}}},{@type(org.bukkit.inventory.ItemStack)v(2230)type(COMPASS)meta{@type(org.bukkit.inventory.meta.ItemMeta)meta-type(UNSPECIFIC)display-name(Navigation Wand)lore{@type(java.util.ArrayList)values[Left click: jump to location,Right click: pass through walls]}}},null,null,null,null,null,null,{@type(org.bukkit.inventory.ItemStack)v(2230)type(NETHER_STAR)meta{@type(org.bukkit.inventory.meta.ItemMeta)meta-type(UNSPECIFIC)display-name(§eBau GUI)}},null,null,{@type(org.bukkit.inventory.ItemStack)v(3117)type(ELYTRA)},null]}").getArray("");
|
||||
|
||||
public void updateHotbar(Player p) {
|
||||
ItemStack[] hotbar = new ItemStack[13];
|
||||
System.arraycopy(p.getInventory().getContents(), 0, hotbar, 0, 9);
|
||||
System.arraycopy(p.getInventory().getArmorContents(), 0, hotbar, 9, 4);
|
||||
YAPIONArray yapionArray = new YAPIONArray();
|
||||
for (ItemStack itemStack : hotbar) {
|
||||
if (itemStack != null) {
|
||||
yapionArray.add(YAPIONSerializer.serialize(itemStack));
|
||||
} else {
|
||||
yapionArray.add(new YAPIONValue<>(null));
|
||||
}
|
||||
}
|
||||
Config.getInstance().get(p).add("hotbar-" + Core.getVersion(), yapionArray);
|
||||
Config.getInstance().save(p);
|
||||
Config.STORE.get(p).setHotbar(copy(hotbar));
|
||||
Config.STORE.save(p);
|
||||
}
|
||||
|
||||
public void setHotbar(Player p) {
|
||||
@@ -66,28 +50,34 @@ public class DefaultHotbar {
|
||||
}
|
||||
|
||||
public ItemStack[] getItems(Player p) {
|
||||
Config.getInstance().get(p).remap("hotbar", "hotbar-19");
|
||||
YAPIONArray yapionArray = Config.getInstance().get(p).getYAPIONArrayOrSetDefault("hotbar-" + Core.getVersion(), defaultHotbar());
|
||||
return copy(Config.STORE.get(p).getHotbar());
|
||||
}
|
||||
|
||||
public ItemStack[] defaultHotbar() {
|
||||
ItemStack[] hotbar = new ItemStack[13];
|
||||
Set<Integer> invalid = new HashSet<>();
|
||||
yapionArray.forEach((integer, yapionAnyType) -> {
|
||||
if (yapionAnyType instanceof YAPIONValue) {
|
||||
hotbar[integer] = null;
|
||||
} else {
|
||||
try {
|
||||
hotbar[integer] = YAPIONDeserializer.deserialize((YAPIONObject) yapionAnyType);
|
||||
} catch (Exception e) {
|
||||
invalid.add(integer);
|
||||
hotbar[integer] = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
invalid.forEach(i -> yapionArray.set(i, new YAPIONValue<>(null)));
|
||||
if (!invalid.isEmpty()) Config.getInstance().save(p);
|
||||
hotbar[0] = item(Material.WOODEN_AXE, "WorldEdit Wand", "Left click: select pos #1", "Right click: select pos #2");
|
||||
hotbar[1] = item(Material.COMPASS, "Navigation Wand", "Left click: jump to location", "Right click: pass through walls");
|
||||
hotbar[8] = item(Material.NETHER_STAR, "§eBau GUI");
|
||||
hotbar[11] = new ItemStack(Material.ELYTRA);
|
||||
return hotbar;
|
||||
}
|
||||
|
||||
public YAPIONArray defaultHotbar() {
|
||||
return DEFAULT_HOTBAR;
|
||||
private ItemStack item(Material material, String name, String... lore) {
|
||||
ItemStack itemStack = new ItemStack(material);
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
meta.setDisplayName(name);
|
||||
if (lore.length > 0) {
|
||||
meta.setLore(List.of(lore));
|
||||
}
|
||||
itemStack.setItemMeta(meta);
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
private ItemStack[] copy(ItemStack[] hotbar) {
|
||||
ItemStack[] copy = new ItemStack[13];
|
||||
for (int i = 0; i < Math.min(hotbar.length, copy.length); i++) {
|
||||
copy[i] = hotbar[i] == null ? null : hotbar[i].clone();
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class InventoryFillBauGuiItem extends BauGuiItem {
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(Player player) {
|
||||
String loreKey = Config.getInstance().get(player).getPlainValueOrDefault("inventoryfill", false) ? "OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE" : "OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE";
|
||||
String loreKey = Config.STORE.get(player).isInventoryFill() ? "OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE" : "OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE";
|
||||
return new SWItem(Material.HOPPER, BauSystem.MESSAGE.parse("OTHER_ITEMS_INVENTORY_FILL_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse(loreKey, player)), false, clickType -> {
|
||||
}).getItemStack();
|
||||
}
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@ public class InventoryFiller implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
|
||||
if (!Config.STORE.get(event.getPlayer()).isInventoryFill()) return;
|
||||
if (!event.getPlayer().isSneaking()) return;
|
||||
Block block = event.getPlayer().getTargetBlockExact(5);
|
||||
if (block == null) return;
|
||||
@@ -62,7 +62,7 @@ public class InventoryFiller implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
|
||||
if (!Config.STORE.get(event.getPlayer()).isInventoryFill()) return;
|
||||
if (!event.getPlayer().isSneaking()) return;
|
||||
ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand();
|
||||
if (itemStack.getType() == Material.AIR) return;
|
||||
|
||||
+2
-2
@@ -68,8 +68,8 @@ public class InventoryFillerCommand extends SWCommand {
|
||||
|
||||
@Register(description = {"INVENTORY_FILL_HELP", "INVENTORY_FILL_INFO"})
|
||||
public void toggle(Player player) {
|
||||
boolean inventoryFill = Config.getInstance().get(player).getPlainValueOrDefault("inventoryfill", false);
|
||||
Config.getInstance().get(player).put("inventoryfill", !inventoryFill);
|
||||
boolean inventoryFill = Config.STORE.get(player).isInventoryFill();
|
||||
Config.STORE.get(player).setInventoryFill(!inventoryFill);
|
||||
if (!inventoryFill) {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("INVENTORY_FILL_ENABLE", player));
|
||||
BauSystem.MESSAGE.send("INVENTORY_FILL_INFO", player);
|
||||
|
||||
+1
-1
@@ -290,7 +290,7 @@ public class KillcheckerVisualizer {
|
||||
}
|
||||
rEntities.get(point).die();
|
||||
}
|
||||
RBlockDisplay entity = new RBlockDisplay(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5));
|
||||
RBlockDisplay entity = new RBlockDisplay(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0, 0, 0));
|
||||
entity.setBlock(MATERIALS[Math.min(count - 1, MATERIALS.length) - 1].createBlockData());
|
||||
rEntities.put(point, entity);
|
||||
if (outlinePoints.contains(point)) outlinePointsCache.add(point);
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class ObserverTracerListener implements Listener {
|
||||
public ObserverTracerListener() {
|
||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
||||
if (pair.getPlayer().getGameMode() != GameMode.SPECTATOR) return;
|
||||
if (pair.getSwPlayer().getPlayer().getGameMode() != GameMode.SPECTATOR) return;
|
||||
pair.getComponent().show();
|
||||
});
|
||||
}, 15L, 15L);
|
||||
|
||||
+4
-4
@@ -167,7 +167,7 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
boolean rayvisualizer = Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("rayvisualizer", false);
|
||||
boolean rayvisualizer = Config.STORE.get(event.getPlayer()).isRayVisualizer();
|
||||
if (rayvisualizer) server.addPlayer(event.getPlayer());
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (Permission.BUILD.hasPermission(player)) {
|
||||
boolean rayvisualizer = Config.getInstance().get(player).getPlainValueOrDefault("rayvisualizer", false);
|
||||
boolean rayvisualizer = Config.STORE.get(player).isRayVisualizer();
|
||||
if (rayvisualizer) server.addPlayer(player);
|
||||
} else {
|
||||
server.removePlayer(player);
|
||||
@@ -192,8 +192,8 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
|
||||
|
||||
@Register
|
||||
public void toggle(@Validator Player player) {
|
||||
boolean rayvisualizer = Config.getInstance().get(player).getPlainValueOrDefault("rayvisualizer", false);
|
||||
Config.getInstance().get(player).put("rayvisualizer", !rayvisualizer);
|
||||
boolean rayvisualizer = Config.STORE.get(player).isRayVisualizer();
|
||||
Config.STORE.get(player).setRayVisualizer(!rayvisualizer);
|
||||
if (!rayvisualizer) {
|
||||
SWUtils.sendToActionbar(player, BauSystem.MESSAGE.parse("RAY_VISUALIZER_ENABLE", player));
|
||||
server.addPlayer(player);
|
||||
|
||||
+4
-5
@@ -185,17 +185,16 @@ public class TestblockCommand extends SWCommand {
|
||||
return new TypeMapper<SchematicNode>() {
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
List<String> stringList = new ArrayList<>(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
|
||||
List<String> stringList = new ArrayList<>();
|
||||
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.byId(0), s));
|
||||
stringList.addAll(SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s));
|
||||
return stringList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchematicNode map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
|
||||
if (node == null) {
|
||||
node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
|
||||
}
|
||||
SchematicNode node = SchematicNode.getNodeFromPath(SteamwarUser.byId(0), s);
|
||||
if (node == null) node = SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
+11
-1
@@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.bausystem.features.simulator;
|
||||
|
||||
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.SWUtils;
|
||||
@@ -77,8 +78,16 @@ public class SimulatorCursor implements Listener {
|
||||
return isSimulatorItem(player.getInventory().getItemInMainHand()) || isSimulatorItem(player.getInventory().getItemInOffHand());
|
||||
}
|
||||
|
||||
private static Set<Player> scheduledUpdates = new HashSet<>();
|
||||
|
||||
private static void scheduleCursorUpdate(Player player) {
|
||||
BauSystem.runTaskLater(BauSystem.getInstance(), () -> calcCursor(player), 1);
|
||||
scheduledUpdates.add(player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerTickEnd(ServerTickEndEvent event) {
|
||||
scheduledUpdates.forEach(SimulatorCursor::calcCursor);
|
||||
scheduledUpdates.clear();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -122,6 +131,7 @@ public class SimulatorCursor implements Listener {
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
cursorType.remove(event.getPlayer());
|
||||
removeCursor(event.getPlayer());
|
||||
scheduledUpdates.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
private static final Map<Player, Long> LAST_SNEAKS = new HashMap<>();
|
||||
|
||||
+3
-3
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.simulator.data;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||
import de.steamwar.inventory.InvCallback;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import lombok.Getter;
|
||||
@@ -28,7 +29,6 @@ import lombok.Setter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
@@ -121,9 +121,9 @@ public abstract class SimulatorElement<T extends SimulatorPhase> {
|
||||
|
||||
public abstract String getType();
|
||||
|
||||
public void saveExtra(YAPIONObject elementObject) {
|
||||
public void saveExtra(SimulatorConfig.Element element) {
|
||||
}
|
||||
|
||||
public void loadExtra(YAPIONObject elementObject) {
|
||||
public void loadExtra(SimulatorConfig.Element element) {
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -20,10 +20,10 @@
|
||||
package de.steamwar.bausystem.features.simulator.data;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@@ -38,9 +38,9 @@ public abstract class SimulatorPhase {
|
||||
|
||||
public abstract void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd);
|
||||
|
||||
public void saveExtra(YAPIONObject phaseObject) {
|
||||
public void saveExtra(SimulatorConfig.Phase phase) {
|
||||
}
|
||||
|
||||
public void loadExtra(YAPIONObject phaseObject) {
|
||||
public void loadExtra(SimulatorConfig.Phase phase) {
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.simulator.data.observer;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
@@ -31,7 +32,6 @@ import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.type.Observer;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@@ -70,12 +70,12 @@ public final class ObserverPhase extends SimulatorPhase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveExtra(YAPIONObject phaseObject) {
|
||||
phaseObject.add("orientation", orientation.name());
|
||||
public void saveExtra(SimulatorConfig.Phase phase) {
|
||||
phase.setOrientation(orientation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadExtra(YAPIONObject phaseObject) {
|
||||
orientation = BlockFace.valueOf(phaseObject.getPlainValue("orientation"));
|
||||
public void loadExtra(SimulatorConfig.Phase phase) {
|
||||
if (phase.getOrientation() != null) orientation = phase.getOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -24,13 +24,13 @@ import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.gui.SimulatorTNTGui;
|
||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||
import de.steamwar.inventory.InvCallback;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
public final class TNTElement extends SimulatorElement<TNTPhase> {
|
||||
|
||||
@@ -100,14 +100,14 @@ public final class TNTElement extends SimulatorElement<TNTPhase> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveExtra(YAPIONObject elementObject) {
|
||||
elementObject.add("alignmentX", alignment.getX());
|
||||
elementObject.add("alignmentZ", alignment.getZ());
|
||||
public void saveExtra(SimulatorConfig.Element element) {
|
||||
element.setAlignmentX(alignment.getX());
|
||||
element.setAlignmentZ(alignment.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadExtra(YAPIONObject elementObject) {
|
||||
alignment.setX(elementObject.getDoubleOrSetDefault("alignmentX", 0));
|
||||
alignment.setZ(elementObject.getDoubleOrSetDefault("alignmentZ", 0));
|
||||
public void loadExtra(SimulatorConfig.Element element) {
|
||||
alignment.setX(element.getAlignmentX() != null ? element.getAlignmentX() : 0);
|
||||
alignment.setZ(element.getAlignmentZ() != null ? element.getAlignmentZ() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.simulator.data.tnt;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||
import de.steamwar.bausystem.features.simulator.storage.SimulatorConfig;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.FreezeMode;
|
||||
@@ -31,7 +32,6 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@@ -83,18 +83,18 @@ public final class TNTPhase extends SimulatorPhase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveExtra(YAPIONObject phaseObject) {
|
||||
phaseObject.add("count", count);
|
||||
phaseObject.add("xJump", xJump);
|
||||
phaseObject.add("yJump", yJump);
|
||||
phaseObject.add("zJump", zJump);
|
||||
public void saveExtra(SimulatorConfig.Phase phase) {
|
||||
phase.setCount(count);
|
||||
phase.setXJump(xJump);
|
||||
phase.setYJump(yJump);
|
||||
phase.setZJump(zJump);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadExtra(YAPIONObject phaseObject) {
|
||||
count = phaseObject.getPlainValue("count");
|
||||
xJump = phaseObject.getPlainValue("xJump");
|
||||
yJump = phaseObject.getPlainValue("yJump");
|
||||
zJump = phaseObject.getPlainValue("zJump");
|
||||
public void loadExtra(SimulatorConfig.Phase phase) {
|
||||
if (phase.getCount() != null) count = phase.getCount();
|
||||
if (phase.getXJump() != null) xJump = phase.getXJump();
|
||||
if (phase.getYJump() != null) yJump = phase.getYJump();
|
||||
if (phase.getZJump() != null) zJump = phase.getZJump();
|
||||
}
|
||||
}
|
||||
|
||||
+29
-37
@@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.storage;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
@@ -29,12 +30,7 @@ import de.steamwar.bausystem.features.simulator.data.redstone.RedstoneElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.redstone.RedstonePhase;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.exceptions.YAPIONException;
|
||||
import yapion.hierarchy.types.YAPIONArray;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.YAPIONParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -51,44 +47,41 @@ public class SimFormatSimulatorLoader implements SimulatorLoader {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
YAPIONObject yapionObject;
|
||||
SimulatorConfig config;
|
||||
try {
|
||||
yapionObject = YAPIONParser.parse(file);
|
||||
} catch (YAPIONException | IOException e) {
|
||||
config = SimulatorConfig.STORE.load(file);
|
||||
} catch (JsonParseException | IllegalStateException | IOException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String name = file.getName().substring(0, file.getName().length() - ".sim".length());
|
||||
|
||||
Simulator simulator = new Simulator(name);
|
||||
loadSimulator(yapionObject, simulator);
|
||||
loadSimulator(config, simulator);
|
||||
return Optional.of(Collections.singletonList(simulator));
|
||||
}
|
||||
|
||||
private void loadSimulator(YAPIONObject simulatorObject, Simulator simulator) {
|
||||
simulator.setMaterial(Material.valueOf(simulatorObject.getPlainValue("material")));
|
||||
simulator.setAutoTrace(simulatorObject.getPlainValue("autoTrace"));
|
||||
simulator.setAutoTestblock(simulatorObject.getPlainValueOrDefault("autoTestblock", false));
|
||||
private void loadSimulator(SimulatorConfig config, Simulator simulator) {
|
||||
if (config.getMaterial() != null) simulator.setMaterial(config.getMaterial());
|
||||
simulator.setAutoTrace(config.isAutoTrace());
|
||||
simulator.setAutoTestblock(config.isAutoTestblock());
|
||||
|
||||
YAPIONArray groups = simulatorObject.getArray("groups");
|
||||
groups.streamObject().forEach(groupObject -> {
|
||||
config.getGroups().forEach(groupConfig -> {
|
||||
SimulatorGroup simulatorGroup = new SimulatorGroup();
|
||||
loadGroup(groupObject, simulatorGroup);
|
||||
loadGroup(groupConfig, simulatorGroup);
|
||||
simulator.add(simulatorGroup);
|
||||
});
|
||||
}
|
||||
|
||||
private void loadGroup(YAPIONObject groupObject, SimulatorGroup group) {
|
||||
group.setMaterial(Material.valueOf(groupObject.getPlainValue("material")));
|
||||
group.setDisabled(groupObject.getPlainValue("disabled"));
|
||||
private void loadGroup(SimulatorConfig.Group groupConfig, SimulatorGroup group) {
|
||||
if (groupConfig.getMaterial() != null) group.setMaterial(groupConfig.getMaterial());
|
||||
group.setDisabled(groupConfig.isDisabled());
|
||||
|
||||
YAPIONArray elements = groupObject.getArray("elements");
|
||||
elements.streamObject().forEach(elementObject -> {
|
||||
groupConfig.getElements().forEach(elementConfig -> {
|
||||
SimulatorElement<?> element;
|
||||
Supplier<SimulatorPhase> phaseConstructor;
|
||||
Vector position = new Vector(elementObject.getDouble("x"), elementObject.getDouble("y"), elementObject.getDouble("z"));
|
||||
String type = elementObject.getPlainValue("type");
|
||||
switch (type) {
|
||||
Vector position = new Vector(elementConfig.getX(), elementConfig.getY(), elementConfig.getZ());
|
||||
switch (String.valueOf(elementConfig.getType())) {
|
||||
case "TNT":
|
||||
element = new TNTElement(position);
|
||||
phaseConstructor = TNTPhase::new;
|
||||
@@ -109,28 +102,27 @@ public class SimFormatSimulatorLoader implements SimulatorLoader {
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
loadElement(elementObject, element, phaseConstructor);
|
||||
loadElement(elementConfig, element, phaseConstructor);
|
||||
group.add(element);
|
||||
});
|
||||
}
|
||||
|
||||
private void loadElement(YAPIONObject elementObject, SimulatorElement<?> element, Supplier<SimulatorPhase> phaseConstructor) {
|
||||
element.setMaterial(Material.valueOf(elementObject.getPlainValue("material")));
|
||||
element.setDisabled(elementObject.getPlainValue("disabled"));
|
||||
element.loadExtra(elementObject);
|
||||
private void loadElement(SimulatorConfig.Element elementConfig, SimulatorElement<?> element, Supplier<SimulatorPhase> phaseConstructor) {
|
||||
if (elementConfig.getMaterial() != null) element.setMaterial(elementConfig.getMaterial());
|
||||
element.setDisabled(elementConfig.isDisabled());
|
||||
element.loadExtra(elementConfig);
|
||||
|
||||
YAPIONArray phases = elementObject.getArray("phases");
|
||||
phases.streamObject().forEach(phaseObject -> {
|
||||
elementConfig.getPhases().forEach(phaseConfig -> {
|
||||
SimulatorPhase phase = phaseConstructor.get();
|
||||
loadPhase(phaseObject, phase);
|
||||
loadPhase(phaseConfig, phase);
|
||||
((SimulatorElement) element).add(phase);
|
||||
});
|
||||
}
|
||||
|
||||
private void loadPhase(YAPIONObject phaseObject, SimulatorPhase phase) {
|
||||
phase.setTickOffset(phaseObject.getPlainValue("tickOffset"));
|
||||
phase.setLifetime(phaseObject.getPlainValue("lifetime"));
|
||||
phase.setOrder(phaseObject.getPlainValue("order"));
|
||||
phase.loadExtra(phaseObject);
|
||||
private void loadPhase(SimulatorConfig.Phase phaseConfig, SimulatorPhase phase) {
|
||||
phase.setTickOffset(phaseConfig.getTickOffset());
|
||||
phase.setLifetime(phaseConfig.getLifetime());
|
||||
phase.setOrder(phaseConfig.getOrder());
|
||||
phase.loadExtra(phaseConfig);
|
||||
}
|
||||
}
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.bausystem.features.simulator.storage;
|
||||
|
||||
import de.steamwar.bausystem.config.ConfigStore;
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The current stored form of a simulator, saved as JSON in a .sim file. Files
|
||||
* saved before the version was stored have no version and are version 1.
|
||||
* Fields missing in the stored JSON keep the default value of their initializer,
|
||||
* so adding a new field does not need a new version.
|
||||
* <p>
|
||||
* When a field gets removed, renamed or its meaning changes, copy this class
|
||||
* to SimulatorConfigV{@link #VERSION} (without the {@link #STORE}), increase {@link #VERSION}, write a
|
||||
* {@link de.steamwar.bausystem.config.ConfigConverter} from the copy to
|
||||
* this class and register it in the {@link #STORE}.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class SimulatorConfig implements VersionedConfig {
|
||||
|
||||
public static final int VERSION = 1;
|
||||
|
||||
/**
|
||||
* Files saved before the version was stored are version 1
|
||||
*/
|
||||
public static final ConfigStore<SimulatorConfig> STORE = new ConfigStore<>(SimulatorConfig.class, VERSION, SimulatorConfig::new)
|
||||
.unversioned(1);
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
protected Material material = Material.BARREL;
|
||||
protected boolean autoTrace = false;
|
||||
protected boolean autoTestblock = false;
|
||||
protected List<Group> groups = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Group {
|
||||
|
||||
protected Material material = Material.CHEST;
|
||||
protected boolean disabled = false;
|
||||
protected List<Element> elements = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Element {
|
||||
|
||||
/**
|
||||
* One of "TNT", "Redstone" or "Observer"
|
||||
*/
|
||||
protected String type;
|
||||
protected Material material;
|
||||
protected boolean disabled = false;
|
||||
protected double x;
|
||||
protected double y;
|
||||
protected double z;
|
||||
|
||||
/**
|
||||
* Only used by TNT
|
||||
*/
|
||||
protected Double alignmentX;
|
||||
protected Double alignmentZ;
|
||||
|
||||
protected List<Phase> phases = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Phase {
|
||||
|
||||
protected int tickOffset;
|
||||
protected int lifetime;
|
||||
protected int order;
|
||||
|
||||
/**
|
||||
* Only used by TNT
|
||||
*/
|
||||
protected Integer count;
|
||||
protected Boolean xJump;
|
||||
protected Boolean yJump;
|
||||
protected Boolean zJump;
|
||||
|
||||
/**
|
||||
* Only used by Observer
|
||||
*/
|
||||
protected BlockFace orientation;
|
||||
}
|
||||
}
|
||||
+43
-35
@@ -19,24 +19,30 @@
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.storage;
|
||||
|
||||
import de.steamwar.bausystem.config.legacy.YapionReader;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.exceptions.YAPIONException;
|
||||
import yapion.hierarchy.types.YAPIONArray;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.YAPIONParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.bausystem.config.legacy.YapionReader.*;
|
||||
|
||||
/**
|
||||
* Loads the legacy .simulator files stored as YAPION, they are deleted after loading
|
||||
* and saved in the current format by the {@link SimulatorSaver}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
|
||||
|
||||
@Override
|
||||
@@ -45,20 +51,19 @@ public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
YAPIONObject yapionObject;
|
||||
Map<String, Object> yapionObject;
|
||||
try {
|
||||
yapionObject = YAPIONParser.parse(file);
|
||||
} catch (YAPIONException | IOException e) {
|
||||
yapionObject = YapionReader.parse(Files.readString(file.toPath(), StandardCharsets.UTF_8));
|
||||
} catch (IllegalArgumentException | IOException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String name = file.getName().substring(0, file.getName().length() - ".simulator".length());
|
||||
|
||||
Simulator simulator = new Simulator(name);
|
||||
simulator.setMaterial(Material.valueOf(yapionObject.getStringOrDefault("material", "BARREL")));
|
||||
simulator.setMaterial(Material.valueOf(getString(yapionObject, "material", "BARREL")));
|
||||
|
||||
YAPIONArray tntElements = yapionObject.getArrayOrDefault("tntElements", new YAPIONArray());
|
||||
for (YAPIONObject element : tntElements.streamObject().collect(Collectors.toList())) {
|
||||
for (Map<?, ?> element : getObjects(yapionObject, "tntElements")) {
|
||||
if (element.containsKey("elements")) {
|
||||
simulator.add(loadGroup(element));
|
||||
} else {
|
||||
@@ -70,27 +75,26 @@ public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
|
||||
return Optional.of(Collections.singletonList(simulator));
|
||||
}
|
||||
|
||||
private SimulatorGroup loadGroup(YAPIONObject element) {
|
||||
double x = element.getDoubleOrDefault("x", 0);
|
||||
double y = element.getDoubleOrDefault("y", 0);
|
||||
double z = element.getDoubleOrDefault("z", 0);
|
||||
int tickOffset = element.getIntOrDefault("tickOffset", 0);
|
||||
private SimulatorGroup loadGroup(Map<?, ?> element) {
|
||||
double x = getDouble(element, "x", 0);
|
||||
double y = getDouble(element, "y", 0);
|
||||
double z = getDouble(element, "z", 0);
|
||||
int tickOffset = getInt(element, "tickOffset", 0);
|
||||
|
||||
SimulatorGroup simulatorGroup = new SimulatorGroup();
|
||||
simulatorGroup.setDisabled(element.getBooleanOrDefault("disabled", false));
|
||||
simulatorGroup.setDisabled(getBoolean(element, "disabled", false));
|
||||
|
||||
YAPIONArray elements = element.getArrayOrDefault("elements", new YAPIONArray());
|
||||
for (YAPIONObject e : elements.streamObject().collect(Collectors.toList())) {
|
||||
for (Map<?, ?> e : getObjects(element, "elements")) {
|
||||
simulatorGroup.add(loadElement(e, x, y, z, tickOffset));
|
||||
}
|
||||
|
||||
return simulatorGroup;
|
||||
}
|
||||
|
||||
private TNTElement loadElement(YAPIONObject element, double dx, double dy, double dz, int dTickOffset) {
|
||||
TNTElement tntElement = new TNTElement(new Vector(element.getDouble("x") + dx, element.getDouble("y") + dy, element.getDouble("z") + dz));
|
||||
tntElement.setDisabled(element.getBooleanOrDefault("disabled", false));
|
||||
tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT")));
|
||||
private TNTElement loadElement(Map<?, ?> element, double dx, double dy, double dz, int dTickOffset) {
|
||||
TNTElement tntElement = new TNTElement(new Vector(requireDouble(element, "x") + dx, requireDouble(element, "y") + dy, requireDouble(element, "z") + dz));
|
||||
tntElement.setDisabled(getBoolean(element, "disabled", false));
|
||||
tntElement.setMaterial(Material.valueOf(getString(element, "material", "TNT")));
|
||||
|
||||
TNTPhase tntPhase = loadPhase(element);
|
||||
tntPhase.setTickOffset(tntPhase.getTickOffset() + dTickOffset);
|
||||
@@ -99,12 +103,12 @@ public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
|
||||
return tntElement;
|
||||
}
|
||||
|
||||
private SimulatorGroup loadElement(YAPIONObject element) {
|
||||
private SimulatorGroup loadElement(Map<?, ?> element) {
|
||||
SimulatorGroup simulatorGroup = new SimulatorGroup();
|
||||
|
||||
TNTElement tntElement = new TNTElement(new Vector(element.getDouble("x"), element.getDouble("y"), element.getDouble("z")));
|
||||
tntElement.setDisabled(element.getBooleanOrDefault("disabled", false));
|
||||
tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT")));
|
||||
TNTElement tntElement = new TNTElement(new Vector(requireDouble(element, "x"), requireDouble(element, "y"), requireDouble(element, "z")));
|
||||
tntElement.setDisabled(getBoolean(element, "disabled", false));
|
||||
tntElement.setMaterial(Material.valueOf(getString(element, "material", "TNT")));
|
||||
simulatorGroup.add(tntElement);
|
||||
|
||||
tntElement.add(loadPhase(element));
|
||||
@@ -112,15 +116,15 @@ public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
|
||||
return simulatorGroup;
|
||||
}
|
||||
|
||||
private TNTPhase loadPhase(YAPIONObject element) {
|
||||
private TNTPhase loadPhase(Map<?, ?> element) {
|
||||
TNTPhase tntPhase = new TNTPhase();
|
||||
tntPhase.setLifetime(element.getIntOrDefault("fuseTicks", 80));
|
||||
tntPhase.setCount(element.getIntOrDefault("count", 1));
|
||||
tntPhase.setTickOffset(element.getIntOrDefault("tickOffset", 0));
|
||||
tntPhase.setXJump(element.getBooleanOrDefault("xVelocity", false));
|
||||
tntPhase.setYJump(element.getBooleanOrDefault("yVelocity", false));
|
||||
tntPhase.setZJump(element.getBooleanOrDefault("zVelocity", false));
|
||||
switch (element.getStringOrDefault("order", "REPEATER")) {
|
||||
tntPhase.setLifetime(getInt(element, "fuseTicks", 80));
|
||||
tntPhase.setCount(getInt(element, "count", 1));
|
||||
tntPhase.setTickOffset(getInt(element, "tickOffset", 0));
|
||||
tntPhase.setXJump(getBoolean(element, "xVelocity", false));
|
||||
tntPhase.setYJump(getBoolean(element, "yVelocity", false));
|
||||
tntPhase.setZJump(getBoolean(element, "zVelocity", false));
|
||||
switch (getString(element, "order", "REPEATER")) {
|
||||
case "REPEATER":
|
||||
tntPhase.setOrder(0);
|
||||
break;
|
||||
@@ -133,4 +137,8 @@ public class SimulatorFormatSimulatorLoader implements SimulatorLoader {
|
||||
}
|
||||
return tntPhase;
|
||||
}
|
||||
|
||||
private double requireDouble(Map<?, ?> element, String key) {
|
||||
return ((Number) element.get(key)).doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
+24
-33
@@ -21,9 +21,6 @@ package de.steamwar.bausystem.features.simulator.storage;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import yapion.hierarchy.output.FileOutput;
|
||||
import yapion.hierarchy.types.YAPIONArray;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -36,48 +33,42 @@ public class SimulatorSaver {
|
||||
directory.mkdirs();
|
||||
}
|
||||
|
||||
YAPIONObject simulatorObject = new YAPIONObject();
|
||||
simulatorObject.add("material", simulator.getMaterial().name());
|
||||
simulatorObject.add("autoTrace", simulator.isAutoTrace());
|
||||
simulatorObject.add("autoTestblock", simulator.isAutoTestblock());
|
||||
SimulatorConfig config = new SimulatorConfig();
|
||||
config.setMaterial(simulator.getMaterial());
|
||||
config.setAutoTrace(simulator.isAutoTrace());
|
||||
config.setAutoTestblock(simulator.isAutoTestblock());
|
||||
|
||||
YAPIONArray groups = new YAPIONArray();
|
||||
simulator.getGroups().forEach(group -> {
|
||||
YAPIONObject groupObject = new YAPIONObject();
|
||||
groupObject.add("material", group.getMaterial().name());
|
||||
groupObject.add("disabled", group.isDisabled());
|
||||
SimulatorConfig.Group groupConfig = new SimulatorConfig.Group();
|
||||
groupConfig.setMaterial(group.getMaterial());
|
||||
groupConfig.setDisabled(group.isDisabled());
|
||||
|
||||
YAPIONArray elements = new YAPIONArray();
|
||||
group.getElements().forEach(element -> {
|
||||
YAPIONObject elementObject = new YAPIONObject();
|
||||
elementObject.add("type", element.getType());
|
||||
elementObject.add("material", element.getMaterial().name());
|
||||
elementObject.add("disabled", element.isDisabled());
|
||||
elementObject.add("x", element.getPosition().getX());
|
||||
elementObject.add("y", element.getPosition().getY());
|
||||
elementObject.add("z", element.getPosition().getZ());
|
||||
element.saveExtra(elementObject);
|
||||
SimulatorConfig.Element elementConfig = new SimulatorConfig.Element();
|
||||
elementConfig.setType(element.getType());
|
||||
elementConfig.setMaterial(element.getMaterial());
|
||||
elementConfig.setDisabled(element.isDisabled());
|
||||
elementConfig.setX(element.getPosition().getX());
|
||||
elementConfig.setY(element.getPosition().getY());
|
||||
elementConfig.setZ(element.getPosition().getZ());
|
||||
element.saveExtra(elementConfig);
|
||||
|
||||
YAPIONArray phases = new YAPIONArray();
|
||||
element.getPhases().forEach(phase -> {
|
||||
YAPIONObject phaseObject = new YAPIONObject();
|
||||
phaseObject.add("tickOffset", phase.getTickOffset());
|
||||
phaseObject.add("lifetime", phase.getLifetime());
|
||||
phaseObject.add("order", phase.getOrder());
|
||||
phase.saveExtra(phaseObject);
|
||||
phases.add(phaseObject);
|
||||
SimulatorConfig.Phase phaseConfig = new SimulatorConfig.Phase();
|
||||
phaseConfig.setTickOffset(phase.getTickOffset());
|
||||
phaseConfig.setLifetime(phase.getLifetime());
|
||||
phaseConfig.setOrder(phase.getOrder());
|
||||
phase.saveExtra(phaseConfig);
|
||||
elementConfig.getPhases().add(phaseConfig);
|
||||
});
|
||||
elementObject.add("phases", phases);
|
||||
elements.add(elementObject);
|
||||
groupConfig.getElements().add(elementConfig);
|
||||
});
|
||||
groupObject.add("elements", elements);
|
||||
groups.add(groupObject);
|
||||
config.getGroups().add(groupConfig);
|
||||
});
|
||||
simulatorObject.add("groups", groups);
|
||||
|
||||
File file = new File(directory, simulator.getName() + ".sim");
|
||||
try {
|
||||
simulatorObject.toJSONLossy(new FileOutput(file)).close();
|
||||
SimulatorConfig.STORE.save(file, config);
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
+31
-21
@@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.storage;
|
||||
|
||||
import de.steamwar.bausystem.config.legacy.YapionReader;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
@@ -26,18 +27,23 @@ import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.exceptions.YAPIONException;
|
||||
import yapion.hierarchy.types.YAPIONArray;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.YAPIONParser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.bausystem.config.legacy.YapionReader.*;
|
||||
|
||||
/**
|
||||
* Loads the legacy per player .yapion files containing multiple simulators, they are
|
||||
* deleted after loading and saved in the current format by the {@link SimulatorSaver}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class YAPIONFormatSimulatorLoader implements SimulatorLoader {
|
||||
|
||||
@Override
|
||||
@@ -46,10 +52,10 @@ public class YAPIONFormatSimulatorLoader implements SimulatorLoader {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
YAPIONObject yapionObject;
|
||||
Map<String, Object> yapionObject;
|
||||
try {
|
||||
yapionObject = YAPIONParser.parse(file);
|
||||
} catch (YAPIONException | IOException e) {
|
||||
yapionObject = YapionReader.parse(Files.readString(file.toPath(), StandardCharsets.UTF_8));
|
||||
} catch (IllegalArgumentException | IOException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -57,28 +63,28 @@ public class YAPIONFormatSimulatorLoader implements SimulatorLoader {
|
||||
SteamwarUser steamwarUser = SteamwarUser.byId(Integer.parseInt(name));
|
||||
|
||||
List<Simulator> simulators = new ArrayList<>();
|
||||
for (String s : yapionObject.getKeys()) {
|
||||
for (String s : yapionObject.keySet()) {
|
||||
String newName = steamwarUser.getUserName() + (s.isEmpty() ? "" : "_" + s);
|
||||
YAPIONArray content = yapionObject.getArray(s);
|
||||
List<Map<?, ?>> content = getObjects(yapionObject, s);
|
||||
if (content.isEmpty()) continue;
|
||||
Simulator simulator = new Simulator(newName);
|
||||
for (YAPIONObject element : content.streamObject().collect(Collectors.toList())) {
|
||||
for (Map<?, ?> element : content) {
|
||||
SimulatorGroup simulatorGroup = new SimulatorGroup();
|
||||
simulator.add(simulatorGroup);
|
||||
|
||||
TNTElement tntElement = new TNTElement(new Vector(element.getDouble("positionX"), element.getDouble("positionY"), element.getDouble("positionZ")));
|
||||
tntElement.setDisabled(element.getBooleanOrDefault("disabled", false)); // IDK if this existed back then?
|
||||
tntElement.setMaterial(Material.valueOf(element.getStringOrDefault("material", "TNT")));
|
||||
TNTElement tntElement = new TNTElement(new Vector(requireDouble(element, "positionX"), requireDouble(element, "positionY"), requireDouble(element, "positionZ")));
|
||||
tntElement.setDisabled(getBoolean(element, "disabled", false)); // IDK if this existed back then?
|
||||
tntElement.setMaterial(Material.valueOf(getString(element, "material", "TNT")));
|
||||
simulatorGroup.add(tntElement);
|
||||
|
||||
TNTPhase tntPhase = new TNTPhase();
|
||||
tntPhase.setLifetime(element.getIntOrDefault("fuseTicks", 80));
|
||||
tntPhase.setCount(element.getIntOrDefault("count", 1));
|
||||
tntPhase.setTickOffset(element.getIntOrDefault("tickOffset", 0));
|
||||
tntPhase.setXJump(element.getBooleanOrDefault("xVelocity", false));
|
||||
tntPhase.setYJump(element.getBooleanOrDefault("yVelocity", false));
|
||||
tntPhase.setZJump(element.getBooleanOrDefault("zVelocity", false));
|
||||
tntPhase.setOrder(element.getBooleanOrDefault("comparator", false) ? 2 : 0);
|
||||
tntPhase.setLifetime(getInt(element, "fuseTicks", 80));
|
||||
tntPhase.setCount(getInt(element, "count", 1));
|
||||
tntPhase.setTickOffset(getInt(element, "tickOffset", 0));
|
||||
tntPhase.setXJump(getBoolean(element, "xVelocity", false));
|
||||
tntPhase.setYJump(getBoolean(element, "yVelocity", false));
|
||||
tntPhase.setZJump(getBoolean(element, "zVelocity", false));
|
||||
tntPhase.setOrder(getBoolean(element, "comparator", false) ? 2 : 0);
|
||||
tntElement.add(tntPhase);
|
||||
}
|
||||
simulators.add(simulator);
|
||||
@@ -87,4 +93,8 @@ public class YAPIONFormatSimulatorLoader implements SimulatorLoader {
|
||||
file.delete();
|
||||
return Optional.of(simulators);
|
||||
}
|
||||
|
||||
private double requireDouble(Map<?, ?> element, String key) {
|
||||
return ((Number) element.get(key)).doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
+204
@@ -19,17 +19,28 @@
|
||||
|
||||
package de.steamwar.bausystem.features.slaves.laufbau;
|
||||
|
||||
import com.sk89q.worldedit.blocks.SkullBlock;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.Bisected;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
import org.bukkit.block.data.type.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@ToString
|
||||
@Getter
|
||||
public class BlockBoundingBox {
|
||||
@@ -81,4 +92,197 @@ public class BlockBoundingBox {
|
||||
public double volume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
static {
|
||||
addPixel(Material.AIR.createBlockData(), 0, 0, 0, 0, 0, 0, null);
|
||||
// addPixel(Material.COBWEB.createBlockData(), 0, 0, 0, 0, 0, 0, createItem("LAUFBAU_BLOCK_COBWEB", Material.COBWEB));
|
||||
addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null);
|
||||
|
||||
addPixel(Material.DIRT_PATH.createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", Material.DIRT_PATH));
|
||||
addPixel(Material.MUD.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
|
||||
|
||||
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaNorth.setAge(2);
|
||||
cocoaNorth.setFacing(BlockFace.NORTH);
|
||||
addPixel(cocoaNorth, 4, 3, 1, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_NORTH"));
|
||||
|
||||
Cocoa cocoaSouth = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaSouth.setAge(2);
|
||||
cocoaSouth.setFacing(BlockFace.SOUTH);
|
||||
addPixel(cocoaSouth, 4, 3, 7, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_SOUTH"));
|
||||
|
||||
Cocoa cocoaWest = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaWest.setAge(2);
|
||||
cocoaWest.setFacing(BlockFace.WEST);
|
||||
addPixel(cocoaWest, 1, 3, 4, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_WEST"));
|
||||
|
||||
Cocoa cocoaEast = (Cocoa) Material.COCOA.createBlockData();
|
||||
cocoaEast.setAge(2);
|
||||
cocoaEast.setFacing(BlockFace.EAST);
|
||||
addPixel(cocoaEast, 7, 3, 4, 8, 9, 8, createItem("LAUFBAU_BLOCK_COCOA", Material.COCOA_BEANS, "LAUFBAU_FACING_EAST"));
|
||||
|
||||
TurtleEgg singleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData();
|
||||
singleTurtleEgg.setEggs(1);
|
||||
singleTurtleEgg.setHatch(0);
|
||||
addPixel(singleTurtleEgg, 4, 0, 3, 9, 7, 9, createItem("LAUFBAU_BLOCK_TURTLE_EGG", Material.TURTLE_EGG, "LAUFBAU_COUNT_1"));
|
||||
|
||||
TurtleEgg doubleTurtleEgg = (TurtleEgg) Material.TURTLE_EGG.createBlockData();
|
||||
doubleTurtleEgg.setEggs(2);
|
||||
doubleTurtleEgg.setHatch(0);
|
||||
addPixel(doubleTurtleEgg, 1, 0, 1, 14, 7, 14, createItem("LAUFBAU_BLOCK_TURTLE_EGG", Material.TURTLE_EGG, "LAUFBAU_COUNT_2"));
|
||||
|
||||
addPixel(Material.CHEST.createBlockData(), 1, 0, 1, 14, 14, 14, createItem("LAUFBAU_BLOCK_CHEST", Material.CHEST));
|
||||
|
||||
Snow snowLayers8 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers8.setLayers(8);
|
||||
addPixel(snowLayers8, 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_8"));
|
||||
|
||||
Directional headNorth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headNorth.setFacing(BlockFace.NORTH);
|
||||
addPixel(headNorth, 4, 4, 8, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_NORTH"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Directional headSouth = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headSouth.setFacing(BlockFace.SOUTH);
|
||||
addPixel(headSouth, 4, 4, 0, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_SOUTH"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Directional headWest = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headWest.setFacing(BlockFace.WEST);
|
||||
addPixel(headWest, 8, 4, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_WEST"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Directional headEast = (Directional) Material.PLAYER_WALL_HEAD.createBlockData();
|
||||
headEast.setFacing(BlockFace.EAST);
|
||||
addPixel(headEast, 0, 4, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_WALL_HEAD", Material.PLAYER_HEAD, "LAUFBAU_FACING_EAST"), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
Snow snowLayers7 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers7.setLayers(7);
|
||||
addPixel(snowLayers7, 0, 0, 0, 16, 12, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_7"));
|
||||
|
||||
Snow snowLayers6 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers6.setLayers(6);
|
||||
addPixel(snowLayers6, 0, 0, 0, 16, 10, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_6"));
|
||||
|
||||
addPixel(Material.STONECUTTER.createBlockData(), 0, 0, 0, 16, 9, 16, createItem("LAUFBAU_BLOCK_STONECUTTER", Material.STONECUTTER));
|
||||
|
||||
addPixel(Material.PLAYER_HEAD.createBlockData(), 4, 0, 4, 8, 8, 8, createItem("LAUFBAU_BLOCK_PLAYER_HEAD", Material.PLAYER_HEAD), BlockBoundingBox::randomPlayerHead);
|
||||
|
||||
addPixel(Material.CAKE.createBlockData(), 1, 0, 1, 14, 8, 14, createItem("LAUFBAU_BLOCK_CAKE", Material.CAKE));
|
||||
|
||||
Slab bottomSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData();
|
||||
bottomSlab.setType(Slab.Type.BOTTOM);
|
||||
addPixel(bottomSlab, 0, 0, 0, 16, 8, 16, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_SLAB", Material.END_STONE_BRICK_SLAB, "LAUFBAU_TYPE_BOTTOM"));
|
||||
|
||||
Slab topSlab = (Slab) Material.END_STONE_BRICK_SLAB.createBlockData();
|
||||
topSlab.setType(Slab.Type.TOP);
|
||||
addPixel(topSlab, 0, 8, 0, 16, 8, 16, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_SLAB", Material.END_STONE_BRICK_SLAB, "LAUFBAU_TYPE_TOP"));
|
||||
|
||||
SeaPickle quadSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
quadSeaPickle.setWaterlogged(false);
|
||||
quadSeaPickle.setPickles(4);
|
||||
addPixel(quadSeaPickle, 2, 0, 2, 12, 7, 12, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_4"));
|
||||
|
||||
Campfire campfire = (Campfire) Material.CAMPFIRE.createBlockData();
|
||||
campfire.setSignalFire(false);
|
||||
campfire.setLit(false);
|
||||
addPixel(campfire, 0, 0, 0, 16, 7, 16, createItem("LAUFBAU_BLOCK_CAMPFIRE", Material.CAMPFIRE));
|
||||
|
||||
SeaPickle trippleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
trippleSeaPickle.setWaterlogged(false);
|
||||
trippleSeaPickle.setPickles(3);
|
||||
addPixel(trippleSeaPickle, 2, 0, 2, 12, 6, 12, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_3"));
|
||||
|
||||
SeaPickle doubleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
doubleSeaPickle.setWaterlogged(false);
|
||||
doubleSeaPickle.setPickles(2);
|
||||
addPixel(doubleSeaPickle, 3, 0, 3, 10, 6, 10, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_2"));
|
||||
|
||||
SeaPickle singleSeaPickle = (SeaPickle) Material.SEA_PICKLE.createBlockData();
|
||||
singleSeaPickle.setWaterlogged(false);
|
||||
singleSeaPickle.setPickles(1);
|
||||
addPixel(singleSeaPickle, 6, 0, 6, 4, 6, 4, createItem("LAUFBAU_BLOCK_SEA_PICKLE", Material.SEA_PICKLE, "LAUFBAU_COUNT_1"));
|
||||
|
||||
addPixel(Material.FLOWER_POT.createBlockData(), 5, 0, 5, 6, 6, 6, createItem("LAUFBAU_BLOCK_FLOWER_POT", Material.FLOWER_POT));
|
||||
|
||||
Snow snowLayers3 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers3.setLayers(3);
|
||||
addPixel(snowLayers3, 0, 0, 0, 16, 4, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_3"));
|
||||
|
||||
TrapDoor bottomTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
bottomTrapDoor.setHalf(Bisected.Half.BOTTOM);
|
||||
addPixel(bottomTrapDoor, 0, 0, 0, 16, 3, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_HALF_BOTTOM"));
|
||||
|
||||
TrapDoor topTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
topTrapDoor.setHalf(Bisected.Half.TOP);
|
||||
addPixel(topTrapDoor, 0, 13, 0, 16, 3, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_HALF_TOP"));
|
||||
|
||||
Snow snowLayers2 = (Snow) Material.SNOW.createBlockData();
|
||||
snowLayers2.setLayers(2);
|
||||
addPixel(snowLayers2, 0, 0, 0, 16, 2, 16, createItem("LAUFBAU_BLOCK_SNOW", Material.SNOW, "LAUFBAU_LAYERS_2"));
|
||||
|
||||
addPixel(Material.LILY_PAD.createBlockData(), 1, 0, 1, 14, 1.5, 14, createItem("LAUFBAU_BLOCK_LILY_PAD", Material.LILY_PAD));
|
||||
addPixel(Material.WHITE_CARPET.createBlockData(), 0, 0, 0, 16, 1, 16, createItem("LAUFBAU_BLOCK_WHITE_CARPET", Material.WHITE_CARPET));
|
||||
|
||||
Directional endRodBottomTop = (Directional) Material.END_ROD.createBlockData();
|
||||
endRodBottomTop.setFacing(BlockFace.UP);
|
||||
addPixel(endRodBottomTop, 6, 0, 6, 4, 16, 4, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
|
||||
|
||||
Directional endRodNorthSouth = (Directional) Material.END_ROD.createBlockData();
|
||||
endRodNorthSouth.setFacing(BlockFace.NORTH);
|
||||
addPixel(endRodNorthSouth, 6, 6, 0, 4, 4, 16, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
|
||||
Directional endRodEastWest = (Directional) Material.END_ROD.createBlockData();
|
||||
endRodEastWest.setFacing(BlockFace.EAST);
|
||||
addPixel(endRodEastWest, 0, 6, 6, 16, 4, 4, createItem("LAUFBAU_BLOCK_END_ROD", Material.END_ROD, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
|
||||
Directional lightningRodBottomTop = (Directional) Material.LIGHTNING_ROD.createBlockData();
|
||||
lightningRodBottomTop.setFacing(BlockFace.UP);
|
||||
addPixel(lightningRodBottomTop, 6, 0, 6, 4, 16, 4, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
|
||||
|
||||
Directional lightningRodNorthSouth = (Directional) Material.LIGHTNING_ROD.createBlockData();
|
||||
lightningRodNorthSouth.setFacing(BlockFace.NORTH);
|
||||
addPixel(lightningRodNorthSouth, 6, 6, 0, 4, 4, 16, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
|
||||
Directional lightningRodEastWest = (Directional) Material.LIGHTNING_ROD.createBlockData();
|
||||
lightningRodEastWest.setFacing(BlockFace.EAST);
|
||||
addPixel(lightningRodEastWest, 0, 6, 6, 16, 4, 4, createItem("LAUFBAU_BLOCK_LIGHTNING_ROD", Material.LIGHTNING_ROD, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
|
||||
Waterlogged conduit = (Waterlogged) Material.CONDUIT.createBlockData();
|
||||
conduit.setWaterlogged(false);
|
||||
addPixel(conduit, 5, 5, 5, 6, 6, 6, createItem("LAUFBAU_BLOCK_CONDUIT", Material.CONDUIT));
|
||||
|
||||
TrapDoor northTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
northTrapDoor.setFacing(BlockFace.NORTH);
|
||||
northTrapDoor.setOpen(true);
|
||||
addPixel(northTrapDoor, 0, 0, 13, 16, 16, 3, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_NORTH", "LAUFBAU_OPEN"));
|
||||
|
||||
TrapDoor southTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
southTrapDoor.setFacing(BlockFace.SOUTH);
|
||||
southTrapDoor.setOpen(true);
|
||||
addPixel(southTrapDoor, 0, 0, 0, 16, 16, 3, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_SOUTH", "LAUFBAU_OPEN"));
|
||||
|
||||
TrapDoor westTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
westTrapDoor.setFacing(BlockFace.WEST);
|
||||
westTrapDoor.setOpen(true);
|
||||
addPixel(westTrapDoor, 13, 0, 0, 3, 16, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_WEST", "LAUFBAU_OPEN"));
|
||||
|
||||
TrapDoor eastTrapDoor = (TrapDoor) Material.IRON_TRAPDOOR.createBlockData();
|
||||
eastTrapDoor.setFacing(BlockFace.EAST);
|
||||
eastTrapDoor.setOpen(true);
|
||||
addPixel(eastTrapDoor, 0, 0, 0, 3, 16, 16, createItem("LAUFBAU_BLOCK_IRON_TRAPDOOR", Material.IRON_TRAPDOOR, "LAUFBAU_FACING_EAST", "LAUFBAU_OPEN"));
|
||||
}
|
||||
|
||||
private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel, SWItem swItem) {
|
||||
new BlockBoundingBox(blockData, Arrays.asList(pixelCuboid(xPixel, yPixel, zPixel, dxPixel, dyPixel, dzPixel)), swItem);
|
||||
}
|
||||
|
||||
private static void addPixel(BlockData blockData, double xPixel, double yPixel, double zPixel, double dxPixel, double dyPixel, double dzPixel, SWItem swItem, Consumer<BaseBlock> blockConsumer) {
|
||||
new BlockBoundingBox(blockData, Arrays.asList(pixelCuboid(xPixel, yPixel, zPixel, dxPixel, dyPixel, dzPixel)), swItem, blockConsumer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void randomPlayerHead(BaseBlock block) {
|
||||
if (block instanceof SkullBlock) {
|
||||
SkullBlock skullBlock = (SkullBlock) block;
|
||||
skullBlock.setOwner(randomPlayerHead.get(random.nextInt(randomPlayerHead.size())).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau;
|
||||
|
||||
public interface BoundingBoxLoader {
|
||||
|
||||
void load();
|
||||
}
|
||||
-10
@@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.slaves.laufbau;
|
||||
import de.steamwar.bausystem.region.Point;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@@ -34,15 +33,6 @@ public class Cuboid {
|
||||
private double dy;
|
||||
private double dz;
|
||||
|
||||
public Cuboid(BoundingBox boundingBox) {
|
||||
this.x = boundingBox.getMinX();
|
||||
this.y = boundingBox.getMinY();
|
||||
this.z = boundingBox.getMinZ();
|
||||
this.dx = boundingBox.getWidthX();
|
||||
this.dy = boundingBox.getHeight();
|
||||
this.dz = boundingBox.getWidthZ();
|
||||
}
|
||||
|
||||
public boolean intersects(Cuboid cuboid) {
|
||||
double minx = x - cuboid.dx;
|
||||
double miny = y - cuboid.dy;
|
||||
|
||||
-37
@@ -24,52 +24,15 @@ import de.steamwar.bausystem.SWUtils;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockType;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.util.CraftVoxelShape;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.VoxelShape;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Linked
|
||||
public class LaufbauCommand extends SWCommand {
|
||||
|
||||
static {
|
||||
AtomicLong counter = new AtomicLong();
|
||||
AtomicReference<VoxelShape> shape = new AtomicReference<>();
|
||||
long time = System.currentTimeMillis();
|
||||
Registry.BLOCK.forEach(blockType -> {
|
||||
Block block = CraftBlockType.bukkitToMinecraftNew(blockType);
|
||||
block.getStateDefinition().getPossibleStates().forEach(blockState -> {
|
||||
VoxelShape voxelShape = new CraftVoxelShape(blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO, CollisionContext.empty()));
|
||||
shape.set(voxelShape);
|
||||
Material material = blockType.asMaterial();
|
||||
if (!material.isItem()) return;
|
||||
new BlockBoundingBox(
|
||||
CraftBlockData.createData(blockState),
|
||||
voxelShape.getBoundingBoxes().stream().map(Cuboid::new).collect(Collectors.toList()),
|
||||
new SWItem(material, "Item")
|
||||
);
|
||||
counter.incrementAndGet();
|
||||
});
|
||||
});
|
||||
System.out.println(System.currentTimeMillis() - time + "ms " + shape.get() + " " + counter.get());
|
||||
}
|
||||
|
||||
public LaufbauCommand() {
|
||||
super("laufbau", "laufsklave");
|
||||
}
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.bausystem.features.slaves.laufbau;
|
||||
|
||||
import de.steamwar.bausystem.config.ConfigStore;
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.converter.LaufbauConfigV1ToV2Converter;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The current laufbau config of a player. It is stored as JSON, fields missing
|
||||
* in the stored JSON keep the default value of their initializer, so adding a
|
||||
* new field does not need a new version.
|
||||
* <p>
|
||||
* When a field gets removed, renamed or its meaning changes, copy this class
|
||||
* to LaufbauConfigV{@link #VERSION} (without the {@link #STORE}), increase {@link #VERSION}, write a
|
||||
* {@link de.steamwar.bausystem.config.ConfigConverter} from the copy to
|
||||
* this class and register it in the {@link #STORE}.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class LaufbauConfig implements VersionedConfig {
|
||||
|
||||
public static final int VERSION = 2;
|
||||
|
||||
/**
|
||||
* LaufbauConfigV1 is stored as Base64 of gzipped YAPION, the current version as JSON
|
||||
*/
|
||||
public static final ConfigStore<LaufbauConfig> STORE = new ConfigStore<>(LaufbauConfig.class, VERSION, LaufbauConfig::new)
|
||||
.legacy(s -> !s.startsWith("{"), LaufbauConfigV1::parse)
|
||||
.converter(new LaufbauConfigV1ToV2Converter())
|
||||
.userConfig("bausystem-laufbau")
|
||||
.removeIf(config -> config.getDeactivated().isEmpty());
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
/**
|
||||
* Identifiers of the deactivated {@link BlockBoundingBox}es, see {@link LaufbauUtils#identifier(BlockBoundingBox)}
|
||||
*/
|
||||
protected Set<String> deactivated = new HashSet<>();
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.bausystem.features.slaves.laufbau;
|
||||
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import de.steamwar.bausystem.config.legacy.YapionReader;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* The legacy laufbau config that was stored as Base64 of the gzipped YAPION,
|
||||
* an object with the deactivated identifiers as keys.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Deprecated
|
||||
public class LaufbauConfigV1 implements VersionedConfig {
|
||||
|
||||
public static final int VERSION = 1;
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
protected Set<String> deactivated = new HashSet<>();
|
||||
|
||||
public static LaufbauConfigV1 parse(String base64) {
|
||||
String yapion;
|
||||
try (InputStream inputStream = new GZIPInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(base64)))) {
|
||||
yapion = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
LaufbauConfigV1 config = new LaufbauConfigV1();
|
||||
config.deactivated.addAll(YapionReader.parse(yapion).keySet());
|
||||
return config;
|
||||
}
|
||||
}
|
||||
+5
-48
@@ -20,63 +20,22 @@
|
||||
package de.steamwar.bausystem.features.slaves.laufbau;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.core.SWPlayer;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.sql.UserConfig;
|
||||
import lombok.Cleanup;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import yapion.hierarchy.output.StreamOutput;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.YAPIONParser;
|
||||
import yapion.parser.options.StreamOptions;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
@UtilityClass
|
||||
public class LaufbauUtils {
|
||||
|
||||
public static class LaufbauComponent implements SWPlayer.Component {
|
||||
|
||||
private YAPIONObject yapionObject = new YAPIONObject();
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onMount(SWPlayer player) {
|
||||
String config = UserConfig.getConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau");
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
byte[] bytes = Base64.getDecoder().decode(config);
|
||||
@Cleanup GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(bytes));
|
||||
yapionObject = new YAPIONParser(gzipInputStream, new StreamOptions().stopOnStreamEnd(true)).parse().result();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void onUnmount(SWPlayer player) {
|
||||
if (yapionObject.isEmpty()) {
|
||||
UserConfig.removePlayerConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau");
|
||||
return;
|
||||
}
|
||||
@Cleanup ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
@Cleanup GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
|
||||
yapionObject.toYAPION(new StreamOutput(gzipOutputStream)).close();
|
||||
UserConfig.updatePlayerConfig(player.getPlayer().getUniqueId(), "bausystem-laufbau", Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
public static Cuboid pixelCuboid(double pixelX, double pixelY, double pixelZ, double pixelDX, double pixelDY, double pixelDZ) {
|
||||
return new Cuboid(pixelToBlock(pixelX), pixelToBlock(pixelY), pixelToBlock(pixelZ), pixelToBlock(pixelDX), pixelToBlock(pixelDY), pixelToBlock(pixelDZ));
|
||||
}
|
||||
@@ -123,7 +82,7 @@ public class LaufbauUtils {
|
||||
return false;
|
||||
}
|
||||
String identifier = identifier(bb);
|
||||
return SWPlayer.of(p).getComponentOrDefault(LaufbauComponent.class, LaufbauComponent::new).yapionObject.containsKey(identifier);
|
||||
return LaufbauConfig.STORE.get(p).getDeactivated().contains(identifier);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@@ -132,11 +91,9 @@ public class LaufbauUtils {
|
||||
return;
|
||||
}
|
||||
String identifier = identifier(bb);
|
||||
YAPIONObject yapionObject = SWPlayer.of(p).getComponentOrDefault(LaufbauComponent.class, LaufbauComponent::new).yapionObject;
|
||||
if (yapionObject.containsKey(identifier)) {
|
||||
yapionObject.remove(identifier);
|
||||
} else {
|
||||
yapionObject.put(identifier, new YAPIONObject());
|
||||
Set<String> deactivated = LaufbauConfig.STORE.get(p).getDeactivated();
|
||||
if (!deactivated.remove(identifier)) {
|
||||
deactivated.add(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.AmethystCluster;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class AmethystBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
floorSmallAmethystBud();
|
||||
ceilingSmallAmethystBud();
|
||||
northSmallAmethystBud();
|
||||
southSmallAmethystBud();
|
||||
eastSmallAmethystBud();
|
||||
westSmallAmethystBud();
|
||||
|
||||
floorMediumAmethystBud();
|
||||
ceilingMediumAmethystBud();
|
||||
northMediumAmethystBud();
|
||||
southMediumAmethystBud();
|
||||
eastMediumAmethystBud();
|
||||
westMediumAmethystBud();
|
||||
|
||||
floorLargeAmethystBud();
|
||||
ceilingLargeAmethystBud();
|
||||
northLargeAmethystBud();
|
||||
southLargeAmethystBud();
|
||||
eastLargeAmethystBud();
|
||||
westLargeAmethystBud();
|
||||
|
||||
floorAmethystCluster();
|
||||
ceilingAmethystCluster();
|
||||
northAmethystCluster();
|
||||
southAmethystCluster();
|
||||
eastAmethystCluster();
|
||||
westAmethystCluster();
|
||||
}
|
||||
|
||||
private void floorSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 4, 8, 3, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 13, 4, 8, 3, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 13, 8, 8, 3));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 0, 8, 8, 3));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 4, 4, 3, 8, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westSmallAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.SMALL_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(13, 4, 4, 3, 8, 8));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_SMALL_AMETHYST_BUD", Material.SMALL_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
private void floorMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 4, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 12, 3, 10, 4, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 12, 10, 10, 4));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 4));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 4, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westMediumAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.MEDIUM_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(12, 3, 3, 4, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_MEDIUM_AMETHYST_BUD", Material.MEDIUM_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
private void floorLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 5, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 11, 3, 10, 5, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 11, 10, 10, 5));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 5));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 5, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westLargeAmethystBud() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.LARGE_AMETHYST_BUD.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(11, 3, 3, 5, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_LARGE_AMETHYST_BUD", Material.LARGE_AMETHYST_BUD, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
private void floorAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.UP);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 7, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_UP"));
|
||||
}
|
||||
|
||||
private void ceilingAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 9, 3, 10, 7, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 9, 10, 10, 7));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
private void southAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 7));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 7, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
private void westAmethystCluster() {
|
||||
AmethystCluster cluster = (AmethystCluster) Material.AMETHYST_CLUSTER.createBlockData();
|
||||
cluster.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(9, 3, 3, 7, 10, 10));
|
||||
new BlockBoundingBox(cluster, cuboidList, createItem("LAUFBAU_BLOCK_AMETHYST_CLUSTER", Material.AMETHYST_CLUSTER, "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class AzaleaBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BlockData blockData = Material.FLOWERING_AZALEA.createBlockData();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(6, 0, 6, 4, 8, 4));
|
||||
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_AZALEA", Material.FLOWERING_AZALEA));
|
||||
}
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Bell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class BellBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
ceilingBell();
|
||||
|
||||
floorNorthBell();
|
||||
floorEastBell();
|
||||
|
||||
doubleWallNorthBell();
|
||||
doubleWallEastBell();
|
||||
|
||||
singleWallNorthBell();
|
||||
singleWallSouthBell();
|
||||
singleWallEastBell();
|
||||
singleWallWestBell();
|
||||
}
|
||||
|
||||
public void ceilingBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.CEILING);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 7, 2, 3, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_CEILING"));
|
||||
}
|
||||
|
||||
public void floorNorthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.FLOOR);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 4, 16, 16, 8));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void floorEastBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.FLOOR);
|
||||
bell.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 0, 8, 16, 16));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void doubleWallNorthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.DOUBLE_WALL);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 0, 2, 2, 16));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_DOUBLE_WALL", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void doubleWallEastBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.DOUBLE_WALL);
|
||||
bell.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(0, 13, 7, 16, 2, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_DOUBLE_WALL", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void singleWallNorthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 0, 2, 2, 13));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void singleWallSouthBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(7, 13, 3, 2, 2, 13));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void singleWallEastBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(3, 13, 7, 13, 2, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void singleWallWestBell() {
|
||||
Bell bell = (Bell) Material.BELL.createBlockData();
|
||||
bell.setAttachment(Bell.Attachment.SINGLE_WALL);
|
||||
bell.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 2, 8));
|
||||
cuboidList.add(pixelCuboid(5, 6, 5, 6, 8, 6));
|
||||
cuboidList.add(pixelCuboid(0, 13, 7, 13, 2, 2));
|
||||
new BlockBoundingBox(bell, cuboidList, createItem("LAUFBAU_BLOCK_BELL", Material.BELL, "LAUFBAU_ATTACHMENT_SINGLE_WALL", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.BrewingStand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class BrewingStandBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BrewingStand brewingStand = (BrewingStand) Material.BREWING_STAND.createBlockData();
|
||||
List<Cuboid> cuboids = new ArrayList<>();
|
||||
cuboids.add(pixelCuboid(1, 0, 1, 14, 2, 14));
|
||||
cuboids.add(pixelCuboid(7, 2, 7, 2, 12, 2));
|
||||
new BlockBoundingBox(brewingStand, cuboids, createItem("LAUFBAU_BLOCK_BREWING_STAND", Material.BREWING_STAND));
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.Lightable;
|
||||
import org.bukkit.block.data.type.Candle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class CandleBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
caked();
|
||||
|
||||
single();
|
||||
}
|
||||
|
||||
private void caked() {
|
||||
Lightable candleCake = (Lightable) Material.CYAN_CANDLE_CAKE.createBlockData();
|
||||
candleCake.setLit(true);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(7, 8, 7, 2, 6, 2));
|
||||
new BlockBoundingBox(candleCake, cuboidList, createItem("LAUFBAU_BLOCK_CANDLE_CAKE", Material.CAKE));
|
||||
}
|
||||
|
||||
private void single() {
|
||||
Candle candle = (Candle) Material.CYAN_CANDLE.createBlockData();
|
||||
candle.setCandles(1);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(7, 0, 7, 2, 6, 2));
|
||||
new BlockBoundingBox(candle, cuboidList, createItem("LAUFBAU_BLOCK_CANDLE", Material.CYAN_CANDLE, "LAUFBAU_COUNT_1"));
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.Orientable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class ChainBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
bottomTopChain();
|
||||
northSouthChain();
|
||||
eastWestChain();
|
||||
}
|
||||
|
||||
private void bottomTopChain() {
|
||||
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
|
||||
chainBottomTop.setAxis(Axis.Y);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(6.5, 0, 6.5, 3, 16, 3));
|
||||
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_UP", "LAUFBAU_FACING_DOWN"));
|
||||
}
|
||||
|
||||
private void northSouthChain() {
|
||||
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
|
||||
chainBottomTop.setAxis(Axis.Z);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(6.5, 6.5, 0, 3, 3, 16));
|
||||
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
private void eastWestChain() {
|
||||
Orientable chainBottomTop = (Orientable) Material.CHAIN.createBlockData();
|
||||
chainBottomTop.setAxis(Axis.X);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 6.5, 6.5, 16, 3, 3));
|
||||
new BlockBoundingBox(chainBottomTop, cuboidList, createItem("LAUFBAU_BLOCK_CHAIN", Material.CHAIN, "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.MultipleFacing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class ChorusPlantBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int ny = 0; ny < 2; ny++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int py = 0; py < 2; py++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
MultipleFacing chorusPlant = (MultipleFacing) Material.CHORUS_PLANT.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(3, 3, 3, 10, 10, 10));
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
chorusPlant.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 3, 3, 3, 10, 10));
|
||||
}
|
||||
if (ny == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_DOWN");
|
||||
chorusPlant.setFace(BlockFace.DOWN, true);
|
||||
cuboidList.add(pixelCuboid(3, 0, 3, 10, 3, 10));
|
||||
}
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
chorusPlant.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(3, 3, 0, 10, 10, 3));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
chorusPlant.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(13, 3, 3, 3, 10, 10));
|
||||
}
|
||||
if (py == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_UP");
|
||||
chorusPlant.setFace(BlockFace.UP, true);
|
||||
cuboidList.add(pixelCuboid(3, 13, 3, 10, 3, 10));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
chorusPlant.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(3, 3, 13, 10, 10, 3));
|
||||
}
|
||||
new BlockBoundingBox(chorusPlant, cuboidList, createItem("LAUFBAU_BLOCK_CHORUS_PLANT", Material.CHORUS_PLANT, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class DragonEggBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BlockData blockData = Material.DRAGON_EGG.createBlockData();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(1, 0, 1, 14, 16, 14));
|
||||
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_DRAGON_EGG", Material.DRAGON_EGG));
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.BigDripleaf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class DripLeafBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
tiltNone();
|
||||
tiltPartial();
|
||||
}
|
||||
|
||||
private void tiltNone() {
|
||||
BigDripleaf bigDripleaf = (BigDripleaf) Material.BIG_DRIPLEAF.createBlockData();
|
||||
bigDripleaf.setTilt(BigDripleaf.Tilt.NONE);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 11, 0, 16, 4, 16));
|
||||
new BlockBoundingBox(bigDripleaf, cuboidList, createItem("LAUFBAU_BLOCK_BIG_DRIP_LEAF", Material.BIG_DRIPLEAF, "LAUFBAU_TILT_NONE"));
|
||||
}
|
||||
|
||||
private void tiltPartial() {
|
||||
BigDripleaf bigDripleaf = (BigDripleaf) Material.BIG_DRIPLEAF.createBlockData();
|
||||
bigDripleaf.setTilt(BigDripleaf.Tilt.PARTIAL);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 11, 0, 16, 2, 16));
|
||||
new BlockBoundingBox(bigDripleaf, cuboidList, createItem("LAUFBAU_BLOCK_BIG_DRIP_LEAF", Material.BIG_DRIPLEAF, "LAUFBAU_TILT_PARTIAL"));
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Fence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class FencesBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Fence fence = (Fence) Material.NETHER_BRICK_FENCE.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(6, 0, 6, 4, 24, 4));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(6, 0, 0, 4, 24, 6));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(6, 0, 10, 4, 24, 6));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 0, 6, 6, 24, 4));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(10, 0, 6, 6, 24, 4));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_NETHER_BRICK_FENCE", Material.NETHER_BRICK_FENCE, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.FaceAttachable;
|
||||
import org.bukkit.block.data.type.Grindstone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class GrindstoneBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
floorNorthGrindstone();
|
||||
floorEastGrindstone();
|
||||
|
||||
ceilingNorthGrindstone();
|
||||
ceilingEastGrindstone();
|
||||
|
||||
wallNorthGrindstone();
|
||||
wallSouthGrindstone();
|
||||
wallEastGrindstone();
|
||||
wallWestGrindstone();
|
||||
}
|
||||
|
||||
public void floorNorthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
|
||||
grindstone.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 4, 2, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 0, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(12, 0, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(2, 7, 5, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 7, 5, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void floorEastGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.FLOOR);
|
||||
grindstone.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(2, 4, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(6, 0, 2, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(6, 0, 12, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(5, 7, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(5, 7, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_FLOOR", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void ceilingNorthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
|
||||
grindstone.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 2, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 9, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(12, 9, 6, 2, 7, 4));
|
||||
cuboidList.add(pixelCuboid(2, 3, 5, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 3, 5, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_CEILING", "LAUFBAU_FACING_NORTH", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void ceilingEastGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.CEILING);
|
||||
grindstone.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(2, 0, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(6, 9, 2, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(6, 9, 12, 4, 7, 2));
|
||||
cuboidList.add(pixelCuboid(5, 3, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(5, 3, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_CEILING", "LAUFBAU_FACING_EAST", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void wallNorthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 2, 0, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 6, 9, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(12, 6, 9, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(2, 5, 3, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 5, 3, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void wallSouthGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 2, 4, 8, 12, 12));
|
||||
cuboidList.add(pixelCuboid(2, 6, 0, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(12, 6, 0, 2, 4, 7));
|
||||
cuboidList.add(pixelCuboid(2, 5, 7, 2, 6, 6));
|
||||
cuboidList.add(pixelCuboid(12, 5, 7, 2, 6, 6));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void wallEastGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 2, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(0, 6, 2, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(0, 6, 12, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(7, 5, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(7, 5, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void wallWestGrindstone() {
|
||||
Grindstone grindstone = (Grindstone) Material.GRINDSTONE.createBlockData();
|
||||
grindstone.setAttachedFace(FaceAttachable.AttachedFace.WALL);
|
||||
grindstone.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 2, 4, 12, 12, 8));
|
||||
cuboidList.add(pixelCuboid(9, 6, 2, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(9, 6, 12, 7, 4, 2));
|
||||
cuboidList.add(pixelCuboid(3, 5, 2, 6, 6, 2));
|
||||
cuboidList.add(pixelCuboid(3, 5, 12, 6, 6, 2));
|
||||
new BlockBoundingBox(grindstone, cuboidList, createItem("LAUFBAU_BLOCK_GRINDSTONE", Material.GRINDSTONE, "LAUFBAU_ATTACHMENT_WALL", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Hopper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class HopperBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
downHopper();
|
||||
northHopper();
|
||||
southHopper();
|
||||
eastHopper();
|
||||
westHopper();
|
||||
}
|
||||
|
||||
public void downHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.DOWN);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(6, 0, 6, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_FLOOR"));
|
||||
}
|
||||
|
||||
public void northHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(6, 4, 0, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_NORTH"));
|
||||
}
|
||||
|
||||
public void southHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(6, 4, 12, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_SOUTH"));
|
||||
}
|
||||
|
||||
public void eastHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(12, 4, 6, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_EAST"));
|
||||
}
|
||||
|
||||
public void westHopper() {
|
||||
Hopper hopper = (Hopper) Material.HOPPER.createBlockData();
|
||||
hopper.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 10, 0, 16, 6, 16));
|
||||
cuboidList.add(pixelCuboid(4, 4, 4, 8, 6, 8));
|
||||
cuboidList.add(pixelCuboid(0, 4, 6, 4, 4, 4));
|
||||
new BlockBoundingBox(hopper, cuboidList, createItem("LAUFBAU_BLOCK_HOPPER", Material.HOPPER, "LAUFBAU_CONNECTION_WEST"));
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Fence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class IronBarBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Fence fence = (Fence) Material.IRON_BARS.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(7, 0, 7, 2, 16, 2));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setFace(BlockFace.NORTH, true);
|
||||
cuboidList.add(pixelCuboid(7, 0, 0, 2, 16, 7));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setFace(BlockFace.SOUTH, true);
|
||||
cuboidList.add(pixelCuboid(7, 0, 9, 2, 16, 7));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setFace(BlockFace.WEST, true);
|
||||
cuboidList.add(pixelCuboid(0, 0, 7, 7, 16, 2));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setFace(BlockFace.EAST, true);
|
||||
cuboidList.add(pixelCuboid(9, 0, 7, 7, 16, 2));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_IRON_BARS", Material.IRON_BARS, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.type.Lantern;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class LanternBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
lantern();
|
||||
hangingLantern();
|
||||
}
|
||||
|
||||
public void lantern() {
|
||||
Lantern lantern = (Lantern) Material.LANTERN.createBlockData();
|
||||
lantern.setHanging(false);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(5, 0, 5, 6, 7, 6));
|
||||
cuboidList.add(pixelCuboid(6, 7, 6, 4, 2, 4));
|
||||
new BlockBoundingBox(lantern, cuboidList, createItem("LAUFBAU_BLOCK_LANTERN", Material.LANTERN));
|
||||
}
|
||||
|
||||
public void hangingLantern() {
|
||||
Lantern lantern = (Lantern) Material.LANTERN.createBlockData();
|
||||
lantern.setHanging(true);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(5, 1, 5, 6, 7, 6));
|
||||
cuboidList.add(pixelCuboid(6, 8, 6, 4, 2, 4));
|
||||
new BlockBoundingBox(lantern, cuboidList, createItem("LAUFBAU_BLOCK_LANTERN", Material.LANTERN, "LAUFBAU_HANGING"));
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class LecternBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
BlockData blockData = Material.LECTERN.createBlockData();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 2, 16));
|
||||
cuboidList.add(pixelCuboid(4, 2, 4, 8, 12, 8));
|
||||
new BlockBoundingBox(blockData, cuboidList, createItem("LAUFBAU_BLOCK_LECTERN", Material.LECTERN));
|
||||
}
|
||||
}
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Stairs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class StairBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
straightBottomNorthStair();
|
||||
straightBottomSouthStair();
|
||||
straightBottomEastStair();
|
||||
straightBottomWestStair();
|
||||
|
||||
straightTopNorthStair();
|
||||
straightTopSouthStair();
|
||||
straightTopEastStair();
|
||||
straightTopWestStair();
|
||||
|
||||
outerLeftBottomNorthStair();
|
||||
outerLeftBottomSouthStair();
|
||||
outerLeftBottomEastStair();
|
||||
outerLeftBottomWestStair();
|
||||
|
||||
outerLeftTopNorthStair();
|
||||
outerLeftTopSouthStair();
|
||||
outerLeftTopEastStair();
|
||||
outerLeftTopWestStair();
|
||||
|
||||
innerLeftBottomNorthStair();
|
||||
innerLeftBottomSouthStair();
|
||||
innerLeftBottomEastStair();
|
||||
innerLeftBottomWestStair();
|
||||
|
||||
innerLeftTopNorthStair();
|
||||
innerLeftTopSouthStair();
|
||||
innerLeftTopEastStair();
|
||||
innerLeftTopWestStair();
|
||||
}
|
||||
|
||||
public void straightBottomNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void straightBottomSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void straightBottomEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void straightBottomWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void straightTopNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void straightTopSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void straightTopEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void straightTopWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.STRAIGHT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 16));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_STRAIGHT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void outerLeftBottomWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void outerLeftTopNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void outerLeftTopSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void outerLeftTopEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void outerLeftTopWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.OUTER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_OUTER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 8, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void innerLeftBottomWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.BOTTOM);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 8, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_BOTTOM", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
|
||||
public void innerLeftTopNorthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.NORTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_NORTH"));
|
||||
}
|
||||
|
||||
public void innerLeftTopSouthStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.SOUTH);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_SOUTH"));
|
||||
}
|
||||
|
||||
public void innerLeftTopEastStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.EAST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(8, 0, 8, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_EAST"));
|
||||
}
|
||||
|
||||
public void innerLeftTopWestStair() {
|
||||
Stairs stairs = (Stairs) Material.END_STONE_BRICK_STAIRS.createBlockData();
|
||||
stairs.setShape(Stairs.Shape.INNER_LEFT);
|
||||
stairs.setHalf(Stairs.Half.TOP);
|
||||
stairs.setFacing(BlockFace.WEST);
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(0, 8, 0, 16, 8, 16));
|
||||
cuboidList.add(pixelCuboid(0, 0, 8, 16, 8, 8));
|
||||
cuboidList.add(pixelCuboid(0, 0, 0, 8, 8, 8));
|
||||
new BlockBoundingBox(stairs, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_STAIRS", Material.END_STONE_BRICK_STAIRS, "LAUFBAU_SHAPE_INNER_LEFT", "LAUFBAU_HALF_TOP", "LAUFBAU_FACING_WEST"));
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.features.slaves.laufbau.boundingboxes;
|
||||
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.BoundingBoxLoader;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.type.Wall;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.createItem;
|
||||
import static de.steamwar.bausystem.features.slaves.laufbau.LaufbauUtils.pixelCuboid;
|
||||
|
||||
@Linked
|
||||
public class WallBoundingBox implements BoundingBoxLoader {
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
v18();
|
||||
}
|
||||
|
||||
private void v18() {
|
||||
for (int nx = 0; nx < 2; nx++) {
|
||||
for (int nz = 0; nz < 2; nz++) {
|
||||
for (int px = 0; px < 2; px++) {
|
||||
for (int pz = 0; pz < 2; pz++) {
|
||||
Wall fence = (Wall) Material.END_STONE_BRICK_WALL.createBlockData();
|
||||
List<String> lore = new ArrayList<>();
|
||||
List<Cuboid> cuboidList = new ArrayList<>();
|
||||
cuboidList.add(pixelCuboid(4, 0, 4, 8, 24, 8));
|
||||
if (nz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_NORTH");
|
||||
fence.setHeight(BlockFace.NORTH, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(5, 0, 0, 6, 24, 4));
|
||||
}
|
||||
if (pz == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_SOUTH");
|
||||
fence.setHeight(BlockFace.SOUTH, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(5, 0, 12, 6, 24, 4));
|
||||
}
|
||||
if (nx == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_WEST");
|
||||
fence.setHeight(BlockFace.WEST, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(0, 0, 5, 4, 24, 6));
|
||||
}
|
||||
if (px == 1) {
|
||||
lore.add("LAUFBAU_CONNECTION_EAST");
|
||||
fence.setHeight(BlockFace.EAST, Wall.Height.LOW);
|
||||
cuboidList.add(pixelCuboid(12, 0, 5, 4, 24, 6));
|
||||
}
|
||||
new BlockBoundingBox(fence, cuboidList, createItem("LAUFBAU_BLOCK_END_STONE_BRICK_WALL", Material.END_STONE_BRICK_WALL, lore.toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.bausystem.features.slaves.laufbau.converter;
|
||||
|
||||
import de.steamwar.bausystem.config.ConfigConverter;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.LaufbauConfig;
|
||||
import de.steamwar.bausystem.features.slaves.laufbau.LaufbauConfigV1;
|
||||
|
||||
@Deprecated
|
||||
public class LaufbauConfigV1ToV2Converter implements ConfigConverter<LaufbauConfigV1, LaufbauConfig> {
|
||||
|
||||
@Override
|
||||
public int version() {
|
||||
return LaufbauConfigV1.VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LaufbauConfig convert(LaufbauConfigV1 old) {
|
||||
LaufbauConfig config = new LaufbauConfig();
|
||||
config.getDeactivated().addAll(old.getDeactivated());
|
||||
return config;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -35,8 +35,8 @@ public class SmartPlaceCommand extends SWCommand {
|
||||
|
||||
@Register(description = {"SMART_PLACE_HELP", "SMART_PLACE_INFO"})
|
||||
public void genericToggle(Player p) {
|
||||
boolean smartPlace = Config.getInstance().get(p).getPlainValueOrDefault("smartPlace", false);
|
||||
Config.getInstance().get(p).put("smartPlace", !smartPlace);
|
||||
boolean smartPlace = Config.STORE.get(p).isSmartPlace();
|
||||
Config.STORE.get(p).setSmartPlace(!smartPlace);
|
||||
if (!smartPlace) {
|
||||
SWUtils.sendToActionbar(p, BauSystem.MESSAGE.parse("SMART_PLACE_ENABLE", p));
|
||||
BauSystem.MESSAGE.send("SMART_PLACE_INFO", p);
|
||||
|
||||
+3
-3
@@ -87,7 +87,7 @@ public class SmartPlaceListener implements Listener {
|
||||
public SmartPlaceListener() {
|
||||
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, (player, packet) -> {
|
||||
if (!Permission.BUILD.hasPermission(player)) return packet;
|
||||
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet;
|
||||
if (!Config.STORE.get(player).isSmartPlace()) return packet;
|
||||
RayTraceResult rayTraceResult = player.rayTraceBlocks(6);
|
||||
Block block = rayTraceResult != null ? rayTraceResult.getHitBlock() : null;
|
||||
BlockFace blockFace = rayTraceResult != null ? rayTraceResult.getHitBlockFace() : null;
|
||||
@@ -127,7 +127,7 @@ public class SmartPlaceListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
|
||||
if (!Config.STORE.get(event.getPlayer()).isSmartPlace()) return;
|
||||
WAS_EXECUTED.add(event.getPlayer());
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return;
|
||||
@@ -146,7 +146,7 @@ public class SmartPlaceListener implements Listener {
|
||||
@EventHandler
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return;
|
||||
if (!Config.STORE.get(event.getPlayer()).isSmartPlace()) return;
|
||||
if (!SMART_PLACING.contains(event.getPlayer())) {
|
||||
if (CONTAINERS.contains(event.getBlockAgainst().getType())) {
|
||||
SoundGroup soundGroup = event.getBlockPlaced().getBlockData().getSoundGroup();
|
||||
|
||||
+3
-6
@@ -35,18 +35,15 @@ public class BlockCounter {
|
||||
public final Map<Region, BlockCount> blockCountMap = new HashMap<>();
|
||||
|
||||
public boolean isActive(final Player p) {
|
||||
if (!Config.getInstance().get(p).containsKey("blockCounter")) {
|
||||
return false;
|
||||
}
|
||||
return Config.getInstance().get(p).getPlainValue("blockCounter");
|
||||
return Config.STORE.get(p).isBlockCounter();
|
||||
}
|
||||
|
||||
public void enable(final Player p) {
|
||||
Config.getInstance().get(p).put("blockCounter", true);
|
||||
Config.STORE.get(p).setBlockCounter(true);
|
||||
}
|
||||
|
||||
public void disable(final Player p) {
|
||||
Config.getInstance().get(p).put("blockCounter", false);
|
||||
Config.STORE.get(p).setBlockCounter(false);
|
||||
}
|
||||
|
||||
public String getMessage(Player player, int count, int tntCount, long tick, long lastTick) {
|
||||
|
||||
@@ -165,6 +165,7 @@ public class TPSSystem implements Listener {
|
||||
}
|
||||
|
||||
@Register(value = "default", description = "TPSLIMIT_DEFAULT_HELP")
|
||||
@Register(value = "rate")
|
||||
public void reset(@Validator Player player) {
|
||||
TickManager.impl.setTickRate(20.0F);
|
||||
sendTickRateChange();
|
||||
@@ -187,15 +188,18 @@ public class TPSSystem implements Listener {
|
||||
}
|
||||
|
||||
@Register(value = {"rate", "0"}, description = "TICK_FREEZE_HELP")
|
||||
@Register(value = "freeze", description = "TICK_FREEZE_HELP_2")
|
||||
public void freeze(@Validator Player player) {
|
||||
public void rate(@Validator Player player) {
|
||||
TickManager.impl.setFreeze(true);
|
||||
sendTickRateChange();
|
||||
}
|
||||
|
||||
@Register(value = "unfreeze", description = "TICK_UNFREEZE_HELP")
|
||||
public void unfreeze(@Validator Player player) {
|
||||
TickManager.impl.setTickRate(20.0F);
|
||||
@Register(value = "freeze", description = "TICK_FREEZE_HELP_2")
|
||||
public void freezeToggle(@Validator Player player) {
|
||||
if (TickManager.impl.isFrozen()) {
|
||||
TickManager.impl.setTickRate(20.0F);
|
||||
} else {
|
||||
TickManager.impl.setFreeze(true);
|
||||
}
|
||||
sendTickRateChange();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -153,7 +153,11 @@ public class TraceCommand extends SWCommand {
|
||||
|
||||
@Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE")
|
||||
public void isolate(@Validator Player player, Trace trace, @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) {
|
||||
TraceManager.instance.isolate(player, records);
|
||||
if (records.length == 0) {
|
||||
TraceManager.instance.isolate(player, trace, trace.getRecords().toArray(TNTPoint[]::new));
|
||||
} else {
|
||||
TraceManager.instance.isolate(player, trace, records);
|
||||
}
|
||||
BauSystem.MESSAGE.send("TRACE_MESSAGE_ISOLATE", player);
|
||||
}
|
||||
|
||||
|
||||
+15
-6
@@ -347,9 +347,10 @@ public class TraceManager implements Listener {
|
||||
* Toggles the isolated render for the given records and player
|
||||
*
|
||||
* @param player the player the trace is shown to
|
||||
* @param records the record for which isolation is toggled
|
||||
* @param ptrace the trace for whitch isolation is toggled
|
||||
* @param records the records of the trace for which isolation is toggled
|
||||
*/
|
||||
public void isolate(Player player, TNTPoint... records) {
|
||||
public void isolate(Player player, Trace ptrace, TNTPoint... records) {
|
||||
unfollow(player);
|
||||
|
||||
Region region = Region.getRegion(player.getLocation());
|
||||
@@ -374,12 +375,20 @@ public class TraceManager implements Listener {
|
||||
isolateFlag.toggleId(record.getTntId());
|
||||
}
|
||||
|
||||
if (isolateFlag.isEmpty() && playerTraceShowData.hasViewFlagOnly(IsolateFlag.class) && records.length != 0) {
|
||||
playerTraceShowData.removeViewFlag(IsolateFlag.class);
|
||||
}
|
||||
|
||||
PlayerTraceShowData finalPlayerTraceShowData = playerTraceShowData;
|
||||
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
|
||||
trace.render(player, finalPlayerTraceShowData);
|
||||
followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> {
|
||||
trace.render(follower, finalPlayerTraceShowData);
|
||||
});
|
||||
if (trace.getUuid() == ptrace.getUuid() || finalPlayerTraceShowData.hasNoViewFlags()) {
|
||||
trace.render(player, finalPlayerTraceShowData);
|
||||
followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> {
|
||||
trace.render(follower, finalPlayerTraceShowData);
|
||||
});
|
||||
} else {
|
||||
trace.hide(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,13 @@ public class TraceRecorder implements Listener {
|
||||
Iterator<TNTPrimed> iter = trackedTNT.getOrDefault(region, Collections.emptyList()).iterator();
|
||||
while (iter.hasNext()) {
|
||||
TNTPrimed tnt = iter.next();
|
||||
if (tnt.isDead()) {
|
||||
iter.remove();
|
||||
tntSpawnRegion.remove(tnt);
|
||||
historyMap.remove(tnt);
|
||||
tntSpawnRegion.remove(tnt);
|
||||
continue;
|
||||
}
|
||||
if (tnt.getFuseTicks() == 80) continue;
|
||||
TNTPoint record = record(tnt, wrappedTrace, Collections.emptyList());
|
||||
if (record == null) {
|
||||
|
||||
+4
@@ -95,4 +95,8 @@ public class PlayerTraceShowData {
|
||||
public void addViewFlag(ViewFlag viewFlag) {
|
||||
viewFlags.put(viewFlag.getClass(), viewFlag);
|
||||
}
|
||||
|
||||
public <T extends ViewFlag> void removeViewFlag(Class<T> clazz) {
|
||||
viewFlags.remove(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -36,21 +36,18 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Transformation;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import yapion.hierarchy.types.YAPIONValue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DETAILS;
|
||||
|
||||
/**
|
||||
* Wrapper for the rendering of a record bundle
|
||||
*/
|
||||
public class TraceEntity extends RBlockDisplay {
|
||||
|
||||
private static final float TNT_VISUAL_SCALE = 0.98F;
|
||||
private static final float TNT_VISUAL_OFFSET = -TNT_VISUAL_SCALE / 2.0F;
|
||||
private static final Transformation TNT_VISUAL_TRANSFORM = new Transformation(
|
||||
public static final float TNT_VISUAL_SCALE = 0.98F;
|
||||
public static final float TNT_VISUAL_OFFSET = -TNT_VISUAL_SCALE / 2.0F;
|
||||
public static final Transformation TNT_VISUAL_TRANSFORM = new Transformation(
|
||||
new Vector3f(TNT_VISUAL_OFFSET, 0.0F, TNT_VISUAL_OFFSET),
|
||||
new Quaternionf(0, 0, 0, 1),
|
||||
new Vector3f(TNT_VISUAL_SCALE, TNT_VISUAL_SCALE, TNT_VISUAL_SCALE),
|
||||
@@ -102,7 +99,7 @@ public class TraceEntity extends RBlockDisplay {
|
||||
* @param player the player the message should be printed for
|
||||
*/
|
||||
public void printIntoChat(Player player) {
|
||||
if (!Config.getInstance().get(player).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) {
|
||||
if (!Config.STORE.get(player).isTntClickDetails()) {
|
||||
return;
|
||||
}
|
||||
TNTPoint representative = records.get(0);
|
||||
|
||||
+2
@@ -131,6 +131,7 @@ public abstract class ViewFlag {
|
||||
if (yLocation.distanceSquared(representative.getLocation()) >= 1.0 / 256.0 && yLocation.distanceSquared(previous.getLocation()) >= 1.0 / 256.0) {
|
||||
RBlockDisplay y = new RBlockDisplay(server, yLocation);
|
||||
y.setBlock(Material.WHITE_STAINED_GLASS.createBlockData());
|
||||
y.setTransform(TraceEntity.TNT_VISUAL_TRANSFORM);
|
||||
}
|
||||
|
||||
Location secoundLocation;
|
||||
@@ -143,6 +144,7 @@ public abstract class ViewFlag {
|
||||
if (secoundLocation.distanceSquared(representative.getLocation()) >= 1.0 / 256.0 && secoundLocation.distanceSquared(previous.getLocation()) >= 1.0 / 256.0) {
|
||||
RBlockDisplay second = new RBlockDisplay(server, secoundLocation);
|
||||
second.setBlock(Material.WHITE_STAINED_GLASS.createBlockData());
|
||||
second.setTransform(TraceEntity.TNT_VISUAL_TRANSFORM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -51,6 +51,10 @@ public class IsolateFlag extends ViewFlag {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return tntToIsolate.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<TNTPoint> filter(Stream<TNTPoint> records) {
|
||||
if (tntToIsolate.isEmpty()) return records;
|
||||
|
||||
+4
-5
@@ -30,7 +30,6 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
@Linked
|
||||
public class NightVisionCommand extends SWCommand implements Listener {
|
||||
@@ -41,15 +40,15 @@ public class NightVisionCommand extends SWCommand implements Listener {
|
||||
|
||||
@Register(description = "NIGHT_VISION_HELP")
|
||||
public void genericCommand(Player p) {
|
||||
YAPIONObject yapionObject = Config.getInstance().get(p);
|
||||
boolean value = !yapionObject.getBooleanOrDefault("nightvision", false);
|
||||
yapionObject.put("nightvision", value);
|
||||
Config config = Config.STORE.get(p);
|
||||
boolean value = !config.isNightVision();
|
||||
config.setNightVision(value);
|
||||
setNightVision(p, value);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
setNightVision(event.getPlayer(), Config.getInstance().get(event.getPlayer()).getBooleanOrDefault("nightvision", false));
|
||||
setNightVision(event.getPlayer(), Config.STORE.get(event.getPlayer()).isNightVision());
|
||||
}
|
||||
|
||||
private void setNightVision(Player p, boolean value) {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
|
||||
@Override
|
||||
public void onUnmount(SWPlayer player) {
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
player.getPlayer().setGameMode(GameMode.CREATIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
|
||||
abilities.mayBuild = true;
|
||||
abilities.mayfly = true;
|
||||
abilities.instabuild = true;
|
||||
|
||||
swPlayer.setComponent(new NoClipData());
|
||||
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
|
||||
@@ -139,6 +140,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlock(BlockCanBuildEvent event) {
|
||||
if (event.getPlayer() == null) return;
|
||||
if (SWPlayer.of(event.getPlayer()).hasComponent(NoClipData.class)) {
|
||||
event.setBuildable(true);
|
||||
}
|
||||
|
||||
+5
-9
@@ -32,26 +32,22 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.hierarchy.types.YAPIONValue;
|
||||
|
||||
@Linked
|
||||
public class TNTClickListener extends SWCommand implements Listener {
|
||||
|
||||
public static final String TNT_CLICK_DETAILS = "tnt_click_details";
|
||||
|
||||
public TNTClickListener() {
|
||||
super("tntdetails");
|
||||
}
|
||||
|
||||
@Register(description = "TNT_DETAILS_COMMAND")
|
||||
public void toggle(Player player) {
|
||||
YAPIONObject yapionObject = Config.getInstance().get(player);
|
||||
if (yapionObject.getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) {
|
||||
yapionObject.put(TNT_CLICK_DETAILS, false);
|
||||
Config config = Config.STORE.get(player);
|
||||
if (config.isTntClickDetails()) {
|
||||
config.setTntClickDetails(false);
|
||||
BauSystem.MESSAGE.send("TNT_DETAILS_OFF", player);
|
||||
} else {
|
||||
yapionObject.put(TNT_CLICK_DETAILS, true);
|
||||
config.setTntClickDetails(true);
|
||||
BauSystem.MESSAGE.send("TNT_DETAILS_ON", player);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +56,7 @@ public class TNTClickListener extends SWCommand implements Listener {
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (event.getHand() != EquipmentSlot.HAND) return;
|
||||
if (!Config.getInstance().get(event.getPlayer()).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) {
|
||||
if (!Config.STORE.get(event.getPlayer()).isTntClickDetails()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import lombok.Getter;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -56,27 +55,22 @@ public class Warp {
|
||||
warpMap.put(name, this);
|
||||
}
|
||||
|
||||
public Warp(String name, YAPIONObject object) {
|
||||
public Warp(String name, WorldData.WarpEntry warp) {
|
||||
this.name = name;
|
||||
double x = object.getPlainValue("x");
|
||||
double y = object.getPlainValue("y");
|
||||
double z = object.getPlainValue("z");
|
||||
float yaw = object.getPlainValue("yaw");
|
||||
float pitch = object.getPlainValue("pitch");
|
||||
location = new Location(Bukkit.getWorlds().get(0), x, y, z, yaw, pitch);
|
||||
mat = Material.getMaterial(object.getPlainValue("material"));
|
||||
location = new Location(Bukkit.getWorlds().get(0), warp.getX(), warp.getY(), warp.getZ(), warp.getYaw(), warp.getPitch());
|
||||
mat = Material.getMaterial(warp.getMaterial());
|
||||
warpMap.put(name, this);
|
||||
}
|
||||
|
||||
public YAPIONObject output() {
|
||||
YAPIONObject yapionObject = new YAPIONObject();
|
||||
yapionObject.add("x", location.getX());
|
||||
yapionObject.add("y", location.getY());
|
||||
yapionObject.add("z", location.getZ());
|
||||
yapionObject.add("yaw", location.getYaw());
|
||||
yapionObject.add("pitch", location.getPitch());
|
||||
yapionObject.add("material", mat.toString());
|
||||
return yapionObject;
|
||||
public WorldData.WarpEntry output() {
|
||||
WorldData.WarpEntry warp = new WorldData.WarpEntry();
|
||||
warp.setX(location.getX());
|
||||
warp.setY(location.getY());
|
||||
warp.setZ(location.getZ());
|
||||
warp.setYaw(location.getYaw());
|
||||
warp.setPitch(location.getPitch());
|
||||
warp.setMaterial(mat.toString());
|
||||
return warp;
|
||||
}
|
||||
|
||||
public static Set<String> getWarpNames() {
|
||||
@@ -101,7 +95,7 @@ public class Warp {
|
||||
|
||||
public void delete() {
|
||||
warpMap.remove(name);
|
||||
WorldData.getWarpData().remove(name);
|
||||
WorldData.STORE.get().getWarps().remove(name);
|
||||
}
|
||||
|
||||
public void teleport(Player player) {
|
||||
|
||||
@@ -34,9 +34,9 @@ import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
@Linked
|
||||
public class WarpCommand extends SWCommand implements Disable, Enable {
|
||||
@@ -135,17 +135,15 @@ public class WarpCommand extends SWCommand implements Disable, Enable {
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
WorldData.getWarpData().forEach((name, yapionAnyType) -> {
|
||||
new Warp(name, (YAPIONObject) yapionAnyType);
|
||||
});
|
||||
WorldData.STORE.get().getWarps().forEach(Warp::new);
|
||||
Warp.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
YAPIONObject yapionObject = WorldData.getWarpData();
|
||||
Map<String, WorldData.WarpEntry> warps = WorldData.STORE.get().getWarps();
|
||||
for (Warp warp : Warp.getWarps()) {
|
||||
yapionObject.add(warp.getName(), warp.output());
|
||||
warps.put(warp.getName(), warp.output());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.bausystem.features.world;
|
||||
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
@Linked
|
||||
public class AntiPlayerCollision implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Scoreboard board = event.getPlayer().getScoreboard();
|
||||
Team team = board.getTeam("players");
|
||||
if (team == null) team = board.registerNewTeam("players");
|
||||
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
|
||||
team.addPlayer(event.getPlayer());
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,7 @@ public class BauScoreboard implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
SWScoreboard.impl.removeScoreboard(event.getPlayer());
|
||||
ADDITIONAL_SCOREBOARD_LINES.remove(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class WorldEditListener implements Listener {
|
||||
|
||||
private static final Set<String> commands = new HashSet<>();
|
||||
private static final Set<String> commandExclusions = new HashSet<>();
|
||||
private static final String[] shortcutCommands = {"//1", "//2", "//90", "//-90", "//180", "//p", "//c", "//flopy", "//floppy", "//flopyp", "//floppyp", "//u", "//r"};
|
||||
private static final String[] shortcutCommands = {"//1", "//2", "//90", "//-90", "//180", "//p", "//c", "//flopy", "//floppy", "//flopyp", "//floppyp", "//u", "//r", "//download", "/download"};
|
||||
|
||||
public static boolean isWorldEditCommand(String command) {
|
||||
for (String shortcut : shortcutCommands) {
|
||||
|
||||
@@ -20,78 +20,39 @@
|
||||
package de.steamwar.bausystem.region;
|
||||
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import lombok.NonNull;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class RegionData {
|
||||
|
||||
private final List<Property<?, ?>> properties = new ArrayList<>();
|
||||
|
||||
protected final YAPIONObject data;
|
||||
protected final YAPIONObject flagData;
|
||||
protected final WorldData.RegionEntry data;
|
||||
protected final Map<String, String> flagData;
|
||||
protected final Runnable onChange;
|
||||
protected final Map<Flag<?>, Flag.Value<?>> flagMap = new HashMap<>();
|
||||
|
||||
private final class Property<T, K> {
|
||||
private final String field;
|
||||
private final Function<K, T> loader;
|
||||
private final Function<T, K> writer;
|
||||
private SchematicNode testblockSchematic;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Property<SchematicNode, Integer> testblockSchematic = new Property<>("testblockSchematic", SchematicNode::byId, SchematicNode::getId);
|
||||
|
||||
protected RegionData(YAPIONObject data, Runnable onChange) {
|
||||
protected RegionData(WorldData.RegionEntry data, Runnable onChange) {
|
||||
this.data = data;
|
||||
this.flagData = data.getObjectOrSetDefault("flagStorage", new YAPIONObject());
|
||||
this.flagData = data.getFlags();
|
||||
this.onChange = onChange;
|
||||
initialize();
|
||||
for (final Flag flag : Flag.getFlags()) {
|
||||
if (!has(flag).isWritable()) continue;
|
||||
try {
|
||||
String s = flagData.getPlainValue(flag.name());
|
||||
String s = flagData.get(flag.name());
|
||||
flagMap.put(flag, flag.valueOfValue(s));
|
||||
} catch (Exception e) {
|
||||
flagMap.put(flag, (Flag.Value<?>) flag.getDefaultValue());
|
||||
}
|
||||
}
|
||||
properties.forEach(Property::load);
|
||||
if (data.getTestblockSchematic() != null) {
|
||||
testblockSchematic = SchematicNode.byId(data.getTestblockSchematic());
|
||||
}
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
@@ -126,7 +87,8 @@ public abstract class RegionData {
|
||||
flagData.remove(flag.name());
|
||||
}
|
||||
}
|
||||
properties.forEach(property -> property.set(null));
|
||||
testblockSchematic = null;
|
||||
data.setTestblockSchematic(null);
|
||||
onChange.run();
|
||||
}
|
||||
|
||||
@@ -135,11 +97,12 @@ public abstract class RegionData {
|
||||
}
|
||||
|
||||
public SchematicNode getTestblockSchematic() {
|
||||
return testblockSchematic.get();
|
||||
return testblockSchematic;
|
||||
}
|
||||
|
||||
public void setTestblockSchematic(SchematicNode schematic) {
|
||||
testblockSchematic.set(schematic);
|
||||
testblockSchematic = schematic;
|
||||
data.setTestblockSchematic(schematic == null ? null : schematic.getId());
|
||||
onChange.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,101 +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.worlddata;
|
||||
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import yapion.hierarchy.output.FileOutput;
|
||||
import yapion.hierarchy.types.YAPIONArray;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.InputStreamCharsets;
|
||||
import yapion.parser.YAPIONParser;
|
||||
import yapion.parser.options.FileOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class SimulatorData {
|
||||
|
||||
private final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators");
|
||||
|
||||
static {
|
||||
simulatorsDir.mkdirs();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public YAPIONObject getSimulator(Player player) {
|
||||
File file = getFile(player);
|
||||
if (!file.exists()) {
|
||||
return new YAPIONObject();
|
||||
}
|
||||
return YAPIONParser.parse(file, new FileOptions().charset(InputStreamCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void internalSaveSimulator(Player player, YAPIONObject yapionObject) {
|
||||
File file = getFile(player);
|
||||
yapionObject.toYAPION(new FileOutput(file)).close();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
void saveSimulator(SteamwarUser steamwarUser, YAPIONObject yapionObject) {
|
||||
File file = new File(simulatorsDir, steamwarUser.getId() + ".yapion");
|
||||
yapionObject.toYAPION(new FileOutput(file)).close();
|
||||
}
|
||||
|
||||
public List<String> listSimulator(Player player) {
|
||||
List<String> strings = getSimulator(player).getKeys();
|
||||
strings.remove("");
|
||||
return strings;
|
||||
}
|
||||
|
||||
public void saveSimulator(Player player, String name) {
|
||||
YAPIONObject yapionObject = getSimulator(player);
|
||||
yapionObject.put(name, yapionObject.getArray("").copy());
|
||||
internalSaveSimulator(player, yapionObject);
|
||||
}
|
||||
|
||||
public void saveSimulator(Player player, YAPIONArray simulator) {
|
||||
YAPIONObject yapionObject = getSimulator(player);
|
||||
yapionObject.put("", simulator);
|
||||
internalSaveSimulator(player, yapionObject);
|
||||
}
|
||||
|
||||
public void loadSimulator(Player player, String name) {
|
||||
YAPIONObject yapionObject = getSimulator(player);
|
||||
yapionObject.put("", yapionObject.getArray(name).copy());
|
||||
internalSaveSimulator(player, yapionObject);
|
||||
}
|
||||
|
||||
public void removeSimulator(Player player, String name) {
|
||||
YAPIONObject yapionObject = getSimulator(player);
|
||||
yapionObject.remove(name);
|
||||
internalSaveSimulator(player, yapionObject);
|
||||
}
|
||||
|
||||
private File getFile(Player player) {
|
||||
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
|
||||
return new File(simulatorsDir, steamwarUser.getId() + ".yapion");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -19,58 +19,83 @@
|
||||
|
||||
package de.steamwar.bausystem.worlddata;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import de.steamwar.bausystem.config.ConfigStore;
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import de.steamwar.bausystem.worlddata.converter.WorldDataV1ToV2Converter;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import yapion.hierarchy.output.FileOutput;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.parser.InputStreamCharsets;
|
||||
import yapion.parser.YAPIONParser;
|
||||
import yapion.parser.options.StreamOptions;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@UtilityClass
|
||||
public class WorldData {
|
||||
/**
|
||||
* The current world data. It is stored as JSON, fields missing in the
|
||||
* stored JSON keep the default value of their initializer, so adding a new
|
||||
* field does not need a new version.
|
||||
* <p>
|
||||
* When a field gets removed, renamed or its meaning changes, copy this class
|
||||
* to WorldDataV{@link #VERSION} (without the {@link #STORE}), increase {@link #VERSION}, write a
|
||||
* {@link de.steamwar.bausystem.config.ConfigConverter} from the copy to this class and register it in the {@link #STORE}.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class WorldData implements VersionedConfig {
|
||||
|
||||
private final File optionsFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "options.yapion");
|
||||
private YAPIONObject worldData;
|
||||
public static final int VERSION = 2;
|
||||
|
||||
public YAPIONObject getWorldData() {
|
||||
if (worldData == null) {
|
||||
read();
|
||||
}
|
||||
return worldData;
|
||||
public static final ConfigStore<WorldData> STORE = new ConfigStore<>(WorldData.class, VERSION, WorldData::new)
|
||||
.gson(new GsonBuilder().setPrettyPrinting().create())
|
||||
.converter(new WorldDataV1ToV2Converter())
|
||||
.file(new File(Bukkit.getWorlds().get(0).getWorldFolder(), "options.json"))
|
||||
.legacyFile(new File(Bukkit.getWorlds().get(0).getWorldFolder(), "options.yapion"), WorldDataV1::parse);
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
/**
|
||||
* Region name to the data of the region
|
||||
*/
|
||||
protected Map<String, RegionEntry> regions = new HashMap<>();
|
||||
protected RegionEntry globalRegion = new RegionEntry();
|
||||
|
||||
/**
|
||||
* Warp name to warp
|
||||
*/
|
||||
protected Map<String, WarpEntry> warps = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class RegionEntry {
|
||||
|
||||
/**
|
||||
* Overrides the prototype of the region config, null if not overridden
|
||||
*/
|
||||
protected String prototype = null;
|
||||
|
||||
/**
|
||||
* Flag name to flag value name
|
||||
*/
|
||||
protected Map<String, String> flags = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Id of the testblock SchematicNode, null if the default testblock is used
|
||||
*/
|
||||
protected Integer testblockSchematic = null;
|
||||
}
|
||||
|
||||
public YAPIONObject getRegionsData() {
|
||||
return getWorldData().getYAPIONObjectOrSetDefault("regions", new YAPIONObject());
|
||||
}
|
||||
@Getter
|
||||
@Setter
|
||||
public static class WarpEntry {
|
||||
|
||||
public YAPIONObject getWarpData() {
|
||||
return getWorldData().getYAPIONObjectOrSetDefault("warps", new YAPIONObject());
|
||||
}
|
||||
|
||||
private void read() {
|
||||
worldData = new YAPIONObject();
|
||||
if (optionsFile.length() != 0) {
|
||||
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(optionsFile))) {
|
||||
worldData = YAPIONParser.parse(bufferedInputStream, new StreamOptions().charset(InputStreamCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
// Ignored
|
||||
}
|
||||
} else {
|
||||
write();
|
||||
}
|
||||
}
|
||||
|
||||
public void write() {
|
||||
try {
|
||||
worldData.toYAPION(new FileOutput(optionsFile)).close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
protected double x;
|
||||
protected double y;
|
||||
protected double z;
|
||||
protected float yaw;
|
||||
protected float pitch;
|
||||
protected String material;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.bausystem.worlddata;
|
||||
|
||||
import de.steamwar.bausystem.config.VersionedConfig;
|
||||
import de.steamwar.bausystem.config.legacy.YapionReader;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The legacy world data that was stored in the YAPION format in options.yapion.
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Deprecated
|
||||
public class WorldDataV1 implements VersionedConfig {
|
||||
|
||||
public static final int VERSION = 1;
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
protected int version = VERSION;
|
||||
|
||||
/**
|
||||
* Region name to the data of the region, the global region is stored with the name "global"
|
||||
*/
|
||||
protected Map<String, RegionEntry> regions = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Warp name to warp
|
||||
*/
|
||||
protected Map<String, WarpEntry> warps = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class RegionEntry {
|
||||
|
||||
protected String prototype = null;
|
||||
|
||||
/**
|
||||
* Flag name to flag value name and "testblockSchematic" to the SchematicNode id
|
||||
*/
|
||||
protected Map<String, Object> flagStorage = new HashMap<>();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class WarpEntry {
|
||||
|
||||
protected double x;
|
||||
protected double y;
|
||||
protected double z;
|
||||
protected float yaw;
|
||||
protected float pitch;
|
||||
protected String material;
|
||||
}
|
||||
|
||||
public static WorldDataV1 parse(String yapion) {
|
||||
Map<String, Object> object = YapionReader.parse(yapion);
|
||||
WorldDataV1 worldData = new WorldDataV1();
|
||||
|
||||
if (object.get("regions") instanceof Map<?, ?> regions) {
|
||||
regions.forEach((name, value) -> {
|
||||
if (!(value instanceof Map<?, ?> region)) return;
|
||||
RegionEntry entry = new RegionEntry();
|
||||
if (region.get("prototype") instanceof String prototype) {
|
||||
entry.prototype = prototype;
|
||||
}
|
||||
if (region.get("flagStorage") instanceof Map<?, ?> flagStorage) {
|
||||
flagStorage.forEach((key, flag) -> entry.flagStorage.put((String) key, flag));
|
||||
}
|
||||
worldData.regions.put((String) name, entry);
|
||||
});
|
||||
}
|
||||
|
||||
if (object.get("warps") instanceof Map<?, ?> warps) {
|
||||
warps.forEach((name, value) -> {
|
||||
if (!(value instanceof Map<?, ?> warp)) return;
|
||||
WarpEntry entry = new WarpEntry();
|
||||
entry.x = ((Number) warp.get("x")).doubleValue();
|
||||
entry.y = ((Number) warp.get("y")).doubleValue();
|
||||
entry.z = ((Number) warp.get("z")).doubleValue();
|
||||
entry.yaw = ((Number) warp.get("yaw")).floatValue();
|
||||
entry.pitch = ((Number) warp.get("pitch")).floatValue();
|
||||
entry.material = (String) warp.get("material");
|
||||
worldData.warps.put((String) name, entry);
|
||||
});
|
||||
}
|
||||
return worldData;
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.bausystem.worlddata.converter;
|
||||
|
||||
import de.steamwar.bausystem.config.ConfigConverter;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import de.steamwar.bausystem.worlddata.WorldDataV1;
|
||||
|
||||
@Deprecated
|
||||
public class WorldDataV1ToV2Converter implements ConfigConverter<WorldDataV1, WorldData> {
|
||||
|
||||
private static final String GLOBAL_REGION = "global";
|
||||
private static final String TESTBLOCK_SCHEMATIC = "testblockSchematic";
|
||||
|
||||
@Override
|
||||
public int version() {
|
||||
return WorldDataV1.VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldData convert(WorldDataV1 old) {
|
||||
WorldData worldData = new WorldData();
|
||||
old.getRegions().forEach((name, region) -> {
|
||||
if (name.equals(GLOBAL_REGION)) {
|
||||
worldData.setGlobalRegion(convert(region));
|
||||
} else {
|
||||
worldData.getRegions().put(name, convert(region));
|
||||
}
|
||||
});
|
||||
old.getWarps().forEach((name, warp) -> worldData.getWarps().put(name, convert(warp)));
|
||||
return worldData;
|
||||
}
|
||||
|
||||
private WorldData.RegionEntry convert(WorldDataV1.RegionEntry old) {
|
||||
WorldData.RegionEntry region = new WorldData.RegionEntry();
|
||||
region.setPrototype(old.getPrototype());
|
||||
old.getFlagStorage().forEach((key, value) -> {
|
||||
if (value == null) return;
|
||||
if (key.equals(TESTBLOCK_SCHEMATIC)) {
|
||||
region.setTestblockSchematic(((Number) value).intValue());
|
||||
} else {
|
||||
region.getFlags().put(key, value.toString());
|
||||
}
|
||||
});
|
||||
return region;
|
||||
}
|
||||
|
||||
private WorldData.WarpEntry convert(WorldDataV1.WarpEntry old) {
|
||||
WorldData.WarpEntry warp = new WorldData.WarpEntry();
|
||||
warp.setX(old.getX());
|
||||
warp.setY(old.getY());
|
||||
warp.setZ(old.getZ());
|
||||
warp.setYaw(old.getYaw());
|
||||
warp.setPitch(old.getPitch());
|
||||
warp.setMaterial(old.getMaterial());
|
||||
return warp;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -25,12 +25,12 @@ import de.steamwar.bausystem.region.flags.ColorMode;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.ProtectMode;
|
||||
import de.steamwar.bausystem.region.flags.TNTMode;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import lombok.NonNull;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
public class FixedGlobalRegionData extends RegionData {
|
||||
|
||||
public FixedGlobalRegionData(YAPIONObject data, Runnable onChange) {
|
||||
public FixedGlobalRegionData(WorldData.RegionEntry data, Runnable onChange) {
|
||||
super(data, onChange);
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -26,6 +26,7 @@ import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.TestblockMode;
|
||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.sql.GameModeConfig;
|
||||
import de.steamwar.sql.SchematicType;
|
||||
@@ -139,7 +140,7 @@ public class FixedRegion implements Region {
|
||||
}
|
||||
}
|
||||
|
||||
public FixedRegion(String name, FixedRegionData flagStorage, Prototype prototype, YAPIONObject regionConfig, YAPIONObject regionData) {
|
||||
public FixedRegion(String name, FixedRegionData flagStorage, Prototype prototype, YAPIONObject regionConfig, WorldData.RegionEntry regionData) {
|
||||
this.name = name;
|
||||
uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
|
||||
this.flagStorage = flagStorage;
|
||||
@@ -325,7 +326,7 @@ public class FixedRegion implements Region {
|
||||
}
|
||||
|
||||
floorLevel = prototype.getFloorOffset() != 0 ? minPoint.getY() + prototype.getFloorOffset() : 0;
|
||||
waterLevel = prototype.getWaterOffset() != 0 ? minPoint.getX() + prototype.getWaterOffset() : 0;
|
||||
waterLevel = prototype.getWaterOffset() != 0 ? minPoint.getY() + prototype.getWaterOffset() : 0;
|
||||
|
||||
File found = null;
|
||||
File baseFile = new File(BauSystem.getInstance().getDataFolder().getParentFile(), "FightSystem");
|
||||
|
||||
+2
-2
@@ -22,12 +22,12 @@ package de.steamwar.bausystem.region.fixed;
|
||||
import de.steamwar.bausystem.region.RegionData;
|
||||
import de.steamwar.bausystem.region.RegionFlagPolicy;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.worlddata.WorldData;
|
||||
import lombok.NonNull;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
|
||||
public class FixedRegionData extends RegionData {
|
||||
|
||||
public FixedRegionData(YAPIONObject data, Runnable onChange) {
|
||||
public FixedRegionData(WorldData.RegionEntry data, Runnable onChange) {
|
||||
super(data, onChange);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -210,14 +210,14 @@ public class Prototype {
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateRegion(String name, YAPIONObject regionConfig, YAPIONObject regionData) {
|
||||
public static void generateRegion(String name, YAPIONObject regionConfig, WorldData.RegionEntry regionData) {
|
||||
Prototype prototype;
|
||||
if (regionData.containsKey("prototype", String.class)) {
|
||||
prototype = PROTOTYPE_MAP.get(regionData.getPlainValue("prototype"));
|
||||
if (regionData.getPrototype() != null) {
|
||||
prototype = PROTOTYPE_MAP.get(regionData.getPrototype());
|
||||
} else {
|
||||
prototype = PROTOTYPE_MAP.get(regionConfig.getPlainValue("prototype"));
|
||||
}
|
||||
FixedRegionData flagStorage = new FixedRegionData(regionData, WorldData::write);
|
||||
FixedRegionData flagStorage = new FixedRegionData(regionData, WorldData.STORE::save);
|
||||
FixedRegionSystem.addRegion(new FixedRegion(name, flagStorage, prototype, regionConfig, regionData));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-15
@@ -28,7 +28,6 @@ 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;
|
||||
@@ -55,7 +54,7 @@ public class RegionLoader {
|
||||
}
|
||||
loaded = yapionObject;
|
||||
|
||||
YAPIONObject optionsYapionObject = WorldData.getRegionsData();
|
||||
WorldData worldData = WorldData.STORE.get();
|
||||
yapionObject.forEach((key, yapionAnyType) -> {
|
||||
if (key.equals("global")) {
|
||||
return;
|
||||
@@ -65,21 +64,10 @@ public class RegionLoader {
|
||||
}
|
||||
|
||||
YAPIONObject regionConfig = (YAPIONObject) yapionAnyType;
|
||||
YAPIONObject regionData = new YAPIONObject();
|
||||
if (optionsYapionObject.containsKey(key, YAPIONType.OBJECT)) {
|
||||
regionData = optionsYapionObject.getObject(key);
|
||||
} else {
|
||||
optionsYapionObject.add(key, regionData);
|
||||
}
|
||||
|
||||
WorldData.RegionEntry regionData = worldData.getRegions().computeIfAbsent(key, k -> new WorldData.RegionEntry());
|
||||
Prototype.generateRegion(key, regionConfig, regionData);
|
||||
});
|
||||
|
||||
YAPIONObject globalOptions = optionsYapionObject.getObject("global");
|
||||
if (globalOptions == null) {
|
||||
globalOptions = new YAPIONObject();
|
||||
optionsYapionObject.add("global", globalOptions);
|
||||
}
|
||||
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(globalOptions, WorldData::write));
|
||||
FixedGlobalRegion.setFLAG_STORAGE(new FixedGlobalRegionData(worldData.getGlobalRegion(), WorldData.STORE::save));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ dependencies {
|
||||
implementation("com.github.ajalt.clikt:clikt:5.0.3")
|
||||
implementation("com.github.ajalt.mordant:mordant:3.0.2")
|
||||
implementation(libs.logback)
|
||||
implementation("org.yaml:snakeyaml:2.2")
|
||||
implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1")
|
||||
|
||||
implementation(libs.exposedCore)
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.github.ajalt.mordant.rendering.TextColors
|
||||
import com.github.ajalt.mordant.rendering.TextStyles
|
||||
import de.steamwar.db.Database
|
||||
import de.steamwar.db.execute
|
||||
import de.steamwar.db.executeScript
|
||||
import de.steamwar.db.useDb
|
||||
import java.io.File
|
||||
|
||||
@@ -22,13 +23,25 @@ class ResetCommand : CliktCommand() {
|
||||
|
||||
val schema = schemaFile.readText()
|
||||
|
||||
val tables = execute("SHOW TABLES;") { it.getString(1) }
|
||||
for (table in tables) {
|
||||
execute("DROP TABLE IF EXISTS $table;") { }
|
||||
execute("SET FOREIGN_KEY_CHECKS=0;") { }
|
||||
|
||||
val databaseObjects = execute("SHOW FULL TABLES;") { it.getString(1) to it.getString(2) }
|
||||
for (view in databaseObjects.filter { it.second == "VIEW" }.map { it.first }) {
|
||||
execute("DROP VIEW IF EXISTS `${view.replace("`", "``")}`;") { }
|
||||
}
|
||||
for (table in databaseObjects.filter { it.second == "BASE TABLE" }.map { it.first }) {
|
||||
execute("DROP TABLE IF EXISTS `${table.replace("`", "``")}`;") { }
|
||||
}
|
||||
|
||||
execute(schema) { }
|
||||
executeScript(schema)
|
||||
|
||||
val seed = javaClass.getResource("/db/reset-seed.sql")
|
||||
?: throw CliktError("Reset seed file not found!")
|
||||
|
||||
executeScript(seed.readText())
|
||||
|
||||
execute("SET FOREIGN_KEY_CHECKS=1;") { }
|
||||
|
||||
echo(TextColors.brightGreen(TextStyles.bold("Database reset!")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ import com.github.ajalt.clikt.parameters.types.file
|
||||
import com.github.ajalt.clikt.parameters.types.long
|
||||
import com.github.ajalt.clikt.parameters.types.path
|
||||
import com.sun.security.auth.module.UnixSystem
|
||||
import org.yaml.snakeyaml.Yaml
|
||||
import java.io.File
|
||||
import kotlin.io.path.absolute
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.random.Random
|
||||
|
||||
const val LOG4J_CONFIG = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN" packages="com.mojang.util">
|
||||
@@ -69,35 +71,47 @@ class DevCommand : CliktCommand("dev") {
|
||||
override fun run() {
|
||||
val args = mutableListOf<String>()
|
||||
|
||||
val serverDirectory = File(workingDir, server)
|
||||
val serverDir =
|
||||
if (serverDirectory.exists() && serverDirectory.isDirectory) serverDirectory else File(workingDir, server)
|
||||
var serverDir = resolveServerDirectory(server)
|
||||
|
||||
if (isVelocity(server)) {
|
||||
runServer(
|
||||
args, jvmArgs, listOf(
|
||||
jar?.absolutePath
|
||||
?: File("/jar/Velocity.jar").absolutePath
|
||||
?: File("/jars/Velocity.jar").absolutePath
|
||||
), serverDir
|
||||
)
|
||||
} else {
|
||||
setLogConfig(args)
|
||||
val version = findVersion(server)
|
||||
?: throw CliktError("Unknown Server Version")
|
||||
val gameModeTemplate = if (serverDir.isDirectory) null else loadGameModeTemplate(server)
|
||||
if (gameModeTemplate != null) {
|
||||
serverDir = gameModeTemplate.serverDir
|
||||
args += "-Dconfig=$server.yml"
|
||||
}
|
||||
val worldFile = world?.absolute()?.toFile()
|
||||
?: File(serverDir, "devtempworld")
|
||||
val jarFile = jar?.absolutePath
|
||||
?: File(workingDir, "devtempworld")
|
||||
var jarFile = jar?.absolutePath
|
||||
?: additionalVersions[server]?.let { supportedVersionJars[it] }
|
||||
?: supportedVersionJars[version]
|
||||
?: throw CliktError("Unknown Server Version")
|
||||
if (gameModeTemplate != null) {
|
||||
jarFile = if (gameModeTemplate.spigot) {
|
||||
jarFile.replace("paper", "spigot")
|
||||
} else {
|
||||
jarFile.replace("spigot", "paper")
|
||||
}
|
||||
}
|
||||
|
||||
if (!worldFile.exists()) {
|
||||
val templateFile = File(serverDir, "Bauwelt")
|
||||
val templateFile = gameModeTemplate?.worldTemplate ?: File(serverDir, "Bauwelt")
|
||||
if (!templateFile.exists()) {
|
||||
throw CliktError("World Template not found!")
|
||||
throw CliktError("Could not find world template: ${templateFile.absolutePath}")
|
||||
}
|
||||
worldFile.parentFile?.mkdirs()
|
||||
templateFile.copyRecursively(worldFile)
|
||||
}
|
||||
val worldDir = worldFile.parentFile ?: workingDir
|
||||
|
||||
val devFile = File("/configs/DevServer/${System.getProperty("user.name")}.$port.$version")
|
||||
if (System.getProperty("user.name") != "minecraft") {
|
||||
@@ -108,10 +122,11 @@ class DevCommand : CliktCommand("dev") {
|
||||
args, jvmArgs, listOf(
|
||||
jarFile,
|
||||
*(if (forceUpgrade) arrayOf("-forceUpgrade") else arrayOf()),
|
||||
"--log-strip-color",
|
||||
"--port", port.toString(),
|
||||
"--level-name", worldFile.name,
|
||||
"--world-dir", workingDir.absolutePath,
|
||||
"--nogui",
|
||||
"--world-dir", worldDir.absolutePath,
|
||||
"nogui",
|
||||
*(if (plugins != null) arrayOf("--plugins", plugins!!.absolutePathString()) else arrayOf())
|
||||
), serverDir
|
||||
)
|
||||
@@ -123,6 +138,12 @@ class DevCommand : CliktCommand("dev") {
|
||||
}
|
||||
}
|
||||
|
||||
data class GameModeTemplate(
|
||||
val serverDir: File,
|
||||
val worldTemplate: File,
|
||||
val spigot: Boolean
|
||||
)
|
||||
|
||||
val jvmDefaultParams = arrayOf(
|
||||
"-Xmx1G",
|
||||
"-Xgc:excessiveGCratio=80",
|
||||
@@ -138,6 +159,16 @@ class DevCommand : CliktCommand("dev") {
|
||||
|
||||
val jvmArgOverrides = arrayOf("--add-opens", "java.base/jdk.internal.misc=ALL-UNNAMED")
|
||||
|
||||
val jvmNonJava8Params = arrayOf(
|
||||
*jvmArgOverrides,
|
||||
"-XX:-CRIUSecProvider"
|
||||
)
|
||||
|
||||
val extendedStartupParams = arrayOf(
|
||||
"-Dpaper.disablePluginRemapping=true",
|
||||
"-javaagent:/jars/AccessWidener.jar=start"
|
||||
)
|
||||
|
||||
val supportedVersionJars = mapOf(
|
||||
8 to "/jars/paper-1.8.8.jar",
|
||||
9 to "/jars/spigot-1.9.4.jar",
|
||||
@@ -165,6 +196,41 @@ class DevCommand : CliktCommand("dev") {
|
||||
fun isVelocity(server: String): Boolean =
|
||||
server.endsWith("Velocity")
|
||||
|
||||
fun resolveServerDirectory(server: String): File {
|
||||
val localServer = File(workingDir, server)
|
||||
if (localServer.isDirectory) {
|
||||
return localServer
|
||||
}
|
||||
return File("/servers", server)
|
||||
}
|
||||
|
||||
fun loadGameModeTemplate(server: String): GameModeTemplate? {
|
||||
val configFile = File("/configs/GameModes/$server.yml")
|
||||
if (!configFile.exists()) {
|
||||
throw CliktError("Server/GameMode not found")
|
||||
}
|
||||
|
||||
val document = configFile.reader().use { reader ->
|
||||
Yaml().load<Map<String, Any?>>(reader)
|
||||
} ?: throw CliktError("GameMode config is empty: ${configFile.absolutePath}")
|
||||
val serverConfig = document["Server"] as? Map<*, *>
|
||||
?: throw CliktError("GameMode config is missing Server section: ${configFile.absolutePath}")
|
||||
val folder = serverConfig["Folder"] as? String
|
||||
?: throw CliktError("GameMode config is missing Server.Folder: ${configFile.absolutePath}")
|
||||
val maps = (serverConfig["Maps"] as? List<*>)
|
||||
?.filterIsInstance<String>()
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?: throw CliktError("GameMode config is missing Server.Maps: ${configFile.absolutePath}")
|
||||
|
||||
val serverDir = File("/servers", folder)
|
||||
val worldTemplate = File(File(serverDir, "arenas"), maps[Random.nextInt(maps.size)])
|
||||
return GameModeTemplate(
|
||||
serverDir = serverDir,
|
||||
worldTemplate = worldTemplate,
|
||||
spigot = serverConfig["Spigot"] == true
|
||||
)
|
||||
}
|
||||
|
||||
fun setLogConfig(args: MutableList<String>) {
|
||||
args += "-DlogPath=${workingDir.absolutePath}/logs"
|
||||
args += "-Dlog4j.configurationFile=${log4jConfig.absolutePath}"
|
||||
@@ -175,13 +241,23 @@ class DevCommand : CliktCommand("dev") {
|
||||
}
|
||||
|
||||
fun runServer(args: List<String>, jvmArgs: List<String>, cmd: List<String>, serverDir: File) {
|
||||
val effectiveJvmArgs = mutableListOf<String>()
|
||||
effectiveJvmArgs += jvmArgs
|
||||
if (!isVelocity(server)) {
|
||||
extendedStartupParams.forEach { arg ->
|
||||
if (effectiveJvmArgs.none { it == arg }) {
|
||||
effectiveJvmArgs += arg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val process = ProcessBuilder(
|
||||
jvm?.absolutePath
|
||||
?: if (isJava8(server)) "/usr/lib/jvm/openj9-8/bin/java" else "java",
|
||||
*jvmArgs.toTypedArray(),
|
||||
?: if (isJava8(server)) "/usr/lib/jvm/openj9-8/bin/java" else "/usr/lib/jvm/openj9-21/bin/java",
|
||||
*effectiveJvmArgs.toTypedArray(),
|
||||
*args.toTypedArray(),
|
||||
*jvmDefaultParams,
|
||||
*(if (isJava8(server)) arrayOf() else jvmArgOverrides),
|
||||
*(if (isJava8(server)) arrayOf() else jvmNonJava8Params),
|
||||
*(if (profile) arrayOf("-javaagent:/jars/LixfelsProfiler.jar=start") else arrayOf()),
|
||||
"-Xshareclasses:nonfatal,name=$server",
|
||||
"-jar",
|
||||
@@ -190,4 +266,4 @@ class DevCommand : CliktCommand("dev") {
|
||||
Runtime.getRuntime().addShutdownHook(Thread { if (process.isAlive) process.destroyForcibly() })
|
||||
process.waitFor()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+120
-9
@@ -16,15 +16,14 @@ import java.sql.ResultSet
|
||||
import java.util.*
|
||||
|
||||
object Database {
|
||||
lateinit var host: String
|
||||
lateinit var port: String
|
||||
lateinit var database: String
|
||||
val host: String
|
||||
val port: String
|
||||
val database: String
|
||||
val username: String
|
||||
val password: String
|
||||
lateinit var db: Database
|
||||
|
||||
fun ensureConnected() {
|
||||
if (::db.isInitialized) {
|
||||
return
|
||||
}
|
||||
init {
|
||||
val config = File(System.getProperty("user.home"), "mysql.properties")
|
||||
|
||||
if (!config.exists()) {
|
||||
@@ -38,9 +37,14 @@ object Database {
|
||||
host = props.getProperty("host")
|
||||
port = props.getProperty("port")
|
||||
database = props.getProperty("database")
|
||||
username = props.getProperty("user")
|
||||
password = props.getProperty("password")
|
||||
}
|
||||
|
||||
val username = props.getProperty("user")
|
||||
val password = props.getProperty("password")
|
||||
fun ensureConnected() {
|
||||
if (::db.isInitialized) {
|
||||
return
|
||||
}
|
||||
|
||||
val url = "jdbc:mariadb://$host:$port/$database"
|
||||
|
||||
@@ -79,6 +83,113 @@ fun <T> JdbcTransaction.executeSingle(sql: String, transform: (ResultSet) -> T):
|
||||
}.single()
|
||||
}
|
||||
|
||||
fun JdbcTransaction.executeScript(sql: String) {
|
||||
for (statement in splitSqlScript(sql)) {
|
||||
exec(statement) { }
|
||||
}
|
||||
}
|
||||
|
||||
private fun splitSqlScript(sql: String): List<String> {
|
||||
val statements = mutableListOf<String>()
|
||||
val current = StringBuilder()
|
||||
var quote: Char? = null
|
||||
var inLineComment = false
|
||||
var inBlockComment = false
|
||||
var index = 0
|
||||
|
||||
fun addStatement() {
|
||||
val statement = current.toString().trim()
|
||||
if (statement.isNotEmpty()) {
|
||||
statements += statement
|
||||
}
|
||||
current.clear()
|
||||
}
|
||||
|
||||
while (index < sql.length) {
|
||||
val char = sql[index]
|
||||
val next = sql.getOrNull(index + 1)
|
||||
|
||||
if (inLineComment) {
|
||||
current.append(char)
|
||||
if (char == '\n') {
|
||||
inLineComment = false
|
||||
}
|
||||
index++
|
||||
continue
|
||||
}
|
||||
|
||||
if (inBlockComment) {
|
||||
current.append(char)
|
||||
if (char == '*' && next == '/') {
|
||||
current.append(next)
|
||||
inBlockComment = false
|
||||
index += 2
|
||||
} else {
|
||||
index++
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (quote != null) {
|
||||
current.append(char)
|
||||
if (char == '\\' && quote != '`' && next != null) {
|
||||
current.append(next)
|
||||
index += 2
|
||||
continue
|
||||
}
|
||||
if (char == quote) {
|
||||
if (next == quote) {
|
||||
current.append(next)
|
||||
index += 2
|
||||
continue
|
||||
}
|
||||
quote = null
|
||||
}
|
||||
index++
|
||||
continue
|
||||
}
|
||||
|
||||
when {
|
||||
char == '-' && next == '-' -> {
|
||||
current.append(char).append(next)
|
||||
inLineComment = true
|
||||
index += 2
|
||||
}
|
||||
|
||||
char == '#' -> {
|
||||
current.append(char)
|
||||
inLineComment = true
|
||||
index++
|
||||
}
|
||||
|
||||
char == '/' && next == '*' -> {
|
||||
current.append(char).append(next)
|
||||
inBlockComment = true
|
||||
index += 2
|
||||
}
|
||||
|
||||
char == '\'' || char == '"' || char == '`' -> {
|
||||
current.append(char)
|
||||
quote = char
|
||||
index++
|
||||
}
|
||||
|
||||
char == ';' -> {
|
||||
addStatement()
|
||||
index++
|
||||
}
|
||||
|
||||
else -> {
|
||||
current.append(char)
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addStatement()
|
||||
return statements
|
||||
}
|
||||
|
||||
fun useDb(statement: JdbcTransaction.() -> Unit) {
|
||||
de.steamwar.db.Database.ensureConnected()
|
||||
transaction(de.steamwar.db.Database.db, statement = statement)
|
||||
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user