diff --git a/CommonCore/SQL/src/de/steamwar/sql/World.kt b/CommonCore/SQL/src/de/steamwar/sql/World.kt
new file mode 100644
index 00000000..174feda2
--- /dev/null
+++ b/CommonCore/SQL/src/de/steamwar/sql/World.kt
@@ -0,0 +1,181 @@
+/*
+ * 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 .
+ */
+
+package de.steamwar.sql
+
+import de.steamwar.sql.internal.useDb
+import org.jetbrains.exposed.v1.core.and
+import org.jetbrains.exposed.v1.core.dao.id.EntityID
+import org.jetbrains.exposed.v1.core.dao.id.UUIDTable
+import org.jetbrains.exposed.v1.core.eq
+import org.jetbrains.exposed.v1.core.not
+import org.jetbrains.exposed.v1.dao.Entity
+import org.jetbrains.exposed.v1.dao.EntityClass
+import org.jetbrains.exposed.v1.javatime.CurrentTimestamp
+import org.jetbrains.exposed.v1.javatime.timestamp
+import java.io.File
+import java.time.Instant
+import java.time.temporal.ChronoUnit
+import java.util.UUID
+
+object WorldTable : UUIDTable("world") {
+ val name = varchar("Name", 512)
+ val version = integer("Version")
+ val type = enumeration("Type")
+ val owner = reference("Owner", SteamwarUserTable).nullable()
+ val deleted = bool("Deleted").default(false)
+ val created = timestamp("Created").defaultExpression(CurrentTimestamp)
+ val lastUsed = timestamp("LastUsed").defaultExpression(CurrentTimestamp)
+}
+
+enum class WorldType {
+ BAU,
+ BUILDER,
+}
+
+class SteamwarWorld(id: EntityID) : Entity(id) {
+ var name by WorldTable.name
+ private set
+ var version by WorldTable.version
+ private set
+ var type by WorldTable.type
+ private set
+ var owner by WorldTable.owner
+ private set
+ var deleted by WorldTable.deleted
+ private set
+ val created by WorldTable.created
+ var lastUsed by WorldTable.lastUsed
+ private set
+
+ val archived: Boolean
+ get() = !storageDirectory.exists() && archiveFile.exists()
+
+ val shouldArchive: Boolean
+ get() = !archived && (deleted || lastUsed.plus(7, ChronoUnit.DAYS).isBefore(Instant.now()))
+
+ val uuid: UUID
+ get() = id.value
+
+ val storageDirectory: File
+ get() = File(WORLD_STORAGE, id.value.toString())
+
+ private val archiveFile: File
+ get() = File(ARCHIVE_WORLD_STORAGE, "${id.value}.zip")
+
+ @JvmOverloads
+ fun setupAndGetStoragePath(prototype: File? = null): String {
+ if (archived) {
+ loadFromArchive()
+ }
+
+ val needsInitialization = !storageDirectory.exists() || storageDirectory.list()?.isEmpty() == true
+ if (needsInitialization) {
+ if (prototype != null && prototype.exists()) {
+ prototype.copyRecursively(storageDirectory, overwrite = true)
+ } else {
+ storageDirectory.mkdirs()
+ }
+ }
+
+ useDb {
+ lastUsed = Instant.now()
+ }
+
+ return storageDirectory.path
+ }
+
+ fun markDeleted() = useDb {
+ deleted = true
+ }
+
+ fun rename(newName: String) = useDb {
+ name = newName
+ }
+
+ private fun archiveWorld() = ProcessBuilder("zip", "-u9oymrqq", "$ARCHIVE_WORLD_STORAGE/${id.value}.zip", id.value.toString())
+ .directory(File(WORLD_STORAGE))
+ .inheritIO()
+ .start()
+ .waitFor()
+
+
+ private fun loadFromArchive() = ProcessBuilder("unzip", "-qq", "-o", "$ARCHIVE_WORLD_STORAGE/${id.value}.zip", "-d", WORLD_STORAGE)
+ .inheritIO()
+ .start()
+ .waitFor()
+
+ companion object : EntityClass(WorldTable) {
+ const val WORLD_STORAGE = "/worlds/storage"
+ const val ARCHIVE_WORLD_STORAGE = "/mnt/storage/worlds/storage"
+
+ @JvmStatic
+ fun getBauWorld(user: SteamwarUser, version: Int) = useDb {
+ find {
+ (WorldTable.owner eq user.id) and
+ (WorldTable.version eq version) and
+ (WorldTable.type eq WorldType.BAU) and
+ not(WorldTable.deleted)
+ }.firstOrNull()
+ }
+
+ @JvmStatic
+ @JvmOverloads
+ fun getOrCreateBauWorld(user: SteamwarUser, version: Int, prototype: File? = null): SteamwarWorld =
+ getBauWorld(user, version) ?: createWorld(user, user.userName, version, WorldType.BAU, prototype)
+
+ @JvmStatic
+ fun getBuilderWorld(name: String, version: Int) = useDb {
+ find {
+ (WorldTable.name eq name) and
+ (WorldTable.version eq version) and
+ (WorldTable.type eq WorldType.BUILDER) and
+ not(WorldTable.deleted)
+ }.firstOrNull()
+ }
+
+ @JvmStatic
+ fun getBuilderWorlds(version: Int) = useDb {
+ find {
+ (WorldTable.version eq version) and
+ (WorldTable.type eq WorldType.BUILDER) and
+ not(WorldTable.deleted)
+ }.toList()
+ }
+
+ @JvmStatic
+ @JvmOverloads
+ fun getOrCreateBuilderWorld(name: String, version: Int, prototype: File? = null): SteamwarWorld =
+ getBuilderWorld(name, version) ?: createWorld(null, name, version, WorldType.BUILDER, prototype)
+
+ @JvmStatic
+ @JvmOverloads
+ fun createWorld(user: SteamwarUser?, name: String, version: Int, type: WorldType, prototype: File? = null): SteamwarWorld {
+ val world = useDb { new {
+ this.name = name
+ this.version = version
+ this.type = type
+ this.owner = user?.id
+ } }
+
+ world.setupAndGetStoragePath(prototype)
+ return world
+ }
+ }
+}
diff --git a/VelocityCore/deployarena.py b/VelocityCore/deployarena.py
index 2195e264..6cd5d62f 100755
--- a/VelocityCore/deployarena.py
+++ b/VelocityCore/deployarena.py
@@ -37,7 +37,7 @@ if __name__ == "__main__":
with open(configfile, 'r') as file:
gamemode = yaml.load(file)
- builderworld = path.expanduser(f'/worlds/builder{version}/{worldname}')
+ builderworld = sys.argv[4] if len(sys.argv) > 4 else path.expanduser(f'/worlds/builder{version}/{worldname}')
arenaworld = f'/servers/{gamemode["Server"]["Folder"]}/arenas/{worldname}'
if path.exists(arenaworld):
diff --git a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java
index 3ea195cd..dd7a952b 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/ServerStarter.java
@@ -52,11 +52,9 @@ public class ServerStarter {
private static final String EVENT_PATH = TMP_DATA + "event/";
public static final String TEMP_WORLD_PATH = TMP_DATA + "arenaserver/";
- private static final String WORLDS_FOLDER = "/worlds";
- public static final String WORLDS_BASE_PATH = WORLDS_FOLDER + "/userworlds";
- public static final String BUILDER_BASE_PATH = WORLDS_FOLDER + "/builder";
-
- private static final String WORLDS_STORAGE_BASE_PATH = "/mnt/storage/worlds/userworlds";
+ public static final String WORLDS_BASE_PATH = SteamwarWorld.WORLD_STORAGE + "/";
+ public static final String LEGACY_WORLDS_BASE_PATH = "/worlds/userworlds";
+ public static final String LEGACY_BUILDER_BASE_PATH = "/worlds/builder";
private File directory = null;
private String worldDir = null;
@@ -152,23 +150,15 @@ public class ServerStarter {
public ServerStarter build(ServerVersion version, UUID owner) {
this.version = version;
directory = version.getServerDirectory("Bau");
- worldDir = version.getWorldFolder(WORLDS_BASE_PATH);
- worldName = String.valueOf(SteamwarUser.get(owner).getId());
+ SteamwarUser user = SteamwarUser.get(owner);
+ SteamwarWorld world = SteamwarWorld.getOrCreateBauWorld(user, version.getVersionSuffix());
+ worldDir = WORLDS_BASE_PATH;
+ worldName = world.getUuid().toString();
checkpoint = true;
build(owner);
- worldSetup = () -> {
- File world = new File(worldDir, worldName);
- if (!world.exists()) {
- File storage = new File(version.getWorldFolder(WORLDS_STORAGE_BASE_PATH), worldName);
-
- if(storage.exists())
- node.execute("mv", storage.getPath(), world.getPath());
- else
- copyWorld(node, new File(directory, "Bauwelt").getPath(), world.getPath());
- }
- };
+ worldSetup = () -> world.setupAndGetStoragePath(new File(directory, "Bauwelt"));
// Send players to existing server
startCondition = () -> {
@@ -224,8 +214,9 @@ public class ServerStarter {
public ServerStarter builder(ServerVersion version, String map, File generator) {
this.version = version;
directory = version.getServerDirectory("Builder");
- worldDir = version.getWorldFolder(BUILDER_BASE_PATH);
- worldName = map;
+ SteamwarWorld world = SteamwarWorld.getOrCreateBuilderWorld(map, version.getVersionSuffix());
+ worldDir = WORLDS_BASE_PATH;
+ worldName = world.getUuid().toString();
serverNameProvider = port -> "*" + map;
checkpoint = true;
constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback, failureCallback);
@@ -243,13 +234,15 @@ public class ServerStarter {
if(generator != null) {
worldSetup = () -> {
- File leveldat = new File(new File(worldDir, worldName), "level.dat");
+ File leveldat = new File(world.setupAndGetStoragePath(), "level.dat");
try {
Files.copy(generator.toPath(), leveldat.toPath());
} catch (IOException e) {
throw new SecurityException(e);
}
};
+ } else {
+ worldSetup = () -> world.setupAndGetStoragePath(legacyBuilderWorld(version, map));
}
return this;
@@ -350,6 +343,22 @@ public class ServerStarter {
node.execute("cp", "-r", template, target);
}
+ private static File legacyBauWorld(ServerVersion version, SteamwarUser user) {
+ File legacyIdWorld = new File(version.getWorldFolder(LEGACY_WORLDS_BASE_PATH), String.valueOf(user.getId()));
+ if(legacyIdWorld.exists())
+ return legacyIdWorld;
+
+ File legacyUuidWorld = new File(version.getWorldFolder(LEGACY_WORLDS_BASE_PATH), user.getUUID().toString());
+ if(legacyUuidWorld.exists())
+ return legacyUuidWorld;
+
+ return new File(version.getServerDirectory("Bau"), "Bauwelt");
+ }
+
+ public static File legacyBuilderWorld(ServerVersion version, String map) {
+ return new File(version.getWorldFolder(LEGACY_BUILDER_BASE_PATH), map);
+ }
+
private interface ServerConstructor {
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback, Consumer failureCallback);
}
@@ -390,4 +399,4 @@ public class ServerStarter {
}
}
-}
\ No newline at end of file
+}
diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java
index 77e5fae6..518376ea 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/commands/BauCommand.java
@@ -34,6 +34,7 @@ import de.steamwar.network.packets.server.BaumemberUpdatePacket;
import de.steamwar.persistent.Bauserver;
import de.steamwar.sql.BauweltMember;
import de.steamwar.sql.SteamwarUser;
+import de.steamwar.sql.SteamwarWorld;
import de.steamwar.velocitycore.*;
import de.steamwar.velocitycore.inventory.SWInventory;
import de.steamwar.velocitycore.inventory.SWItem;
@@ -41,6 +42,7 @@ import de.steamwar.velocitycore.network.NetworkSender;
import de.steamwar.velocitycore.util.BauLock;
import de.steamwar.data.BauLockState;
+import java.io.File;
import java.util.Collection;
import java.util.function.Consumer;
@@ -220,14 +222,20 @@ public class BauCommand extends SWCommand {
public void delete(PlayerChatter sender, ServerVersion version) {
SWInventory inventory = new SWInventory(sender, 9, new Message("BAU_DELETE_GUI_NAME"));
inventory.addItem(0, new SWItem(new Message("BAU_DELETE_GUI_DELETE"), 10), click -> {
- String world = version.getWorldFolder(ServerStarter.WORLDS_BASE_PATH) + sender.user().getId();
+ SteamwarWorld world = SteamwarWorld.getBauWorld(sender.user(), version.getVersionSuffix());
VelocityCore.schedule(() -> {
Bauserver subserver = Bauserver.get(sender.user().getUUID());
if(subserver != null)
subserver.stop();
- SubserverSystem.deleteFolder(VelocityCore.local, world);
+ if(world != null) {
+ world.markDeleted();
+ SubserverSystem.deleteFolder(VelocityCore.local, world.getStorageDirectory().getPath());
+ } else {
+ File legacyWorld = new File(version.getWorldFolder(ServerStarter.LEGACY_WORLDS_BASE_PATH), String.valueOf(sender.user().getId()));
+ SubserverSystem.deleteFolder(VelocityCore.local, legacyWorld.getPath());
+ }
sender.system("BAU_DELETE_DELETED");
}).schedule();
diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/BuilderCloudCommand.java b/VelocityCore/src/de/steamwar/velocitycore/commands/BuilderCloudCommand.java
index 5ae01fe7..7ba21d41 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/commands/BuilderCloudCommand.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/commands/BuilderCloudCommand.java
@@ -21,7 +21,7 @@ package de.steamwar.velocitycore.commands;
import de.steamwar.sql.GameModeConfig;
import de.steamwar.linkage.Linked;
-import de.steamwar.sql.SchematicType;
+import de.steamwar.sql.SteamwarWorld;
import de.steamwar.velocitycore.ArenaMode;
import de.steamwar.velocitycore.ServerStarter;
import de.steamwar.velocitycore.ServerVersion;
@@ -34,11 +34,11 @@ import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.UserPerm;
import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
@Linked
public class BuilderCloudCommand extends SWCommand {
@@ -49,13 +49,18 @@ public class BuilderCloudCommand extends SWCommand {
@Register(value = "create", description = "BUILDERCLOUD_CREATE_USAGE")
public void create(Chatter sender, @ErrorMessage("BUILDERCLOUD_VERSION") ServerVersion version, @Mapper("map") String map, @OptionalValue("") @Mapper("generator") @AllowNull File generator) {
- mapFile(version, map).mkdir();
+ if(mapExists(version, map)) {
+ sender.system("BUILDERCLOUD_EXISTING_MAP");
+ return;
+ }
+
+ SteamwarWorld.getOrCreateBuilderWorld(map, version.getVersionSuffix()).setupAndGetStoragePath();
sender.withPlayer(p -> new ServerStarter().builder(version, map, generator).send(p).start());
}
@Register(description = "BUILDERCLOUD_USAGE")
public void start(PlayerChatter sender, @ErrorMessage("BUILDERCLOUD_VERSION") ServerVersion version, @Mapper("map") String map) {
- if(!mapFile(version, map).exists()) {
+ if(!mapExists(version, map)) {
sender.system("BUILDERCLOUD_UNKNOWN_MAP");
return;
}
@@ -65,36 +70,32 @@ public class BuilderCloudCommand extends SWCommand {
@Register(value = "rename", description = "BUILDERCLOUD_RENAME_USAGE")
public void rename(Chatter sender, @ErrorMessage("BUILDERCLOUD_VERSION") ServerVersion version, @Mapper("map") String oldName, String newName) {
- File oldMap = mapFile(version, oldName);
- if(!oldMap.exists()) {
+ SteamwarWorld oldMap = builderWorld(version, oldName);
+ if(oldMap == null) {
sender.system("BUILDERCLOUD_UNKNOWN_MAP");
return;
}
- File newMap = mapFile(version, newName);
- if(newMap.exists()) {
+ if(mapExists(version, newName)) {
sender.system("BUILDERCLOUD_EXISTING_MAP");
return;
}
- try {
- Files.move(oldMap.toPath(), newMap.toPath());
- } catch (IOException e) {
- throw new SecurityException(e);
- }
+ oldMap.rename(newName);
sender.system("BUILDERCLOUD_RENAMED");
}
@Register(value = "deploy", description = "BUILDERCLOUD_DEPLOY_USAGE")
public void deploy(Chatter sender, @Mapper("nonHistoricArenaMode") GameModeConfig arenaMode, @ErrorMessage("BUILDERCLOUD_VERSION") ServerVersion version, @Mapper("map") String map) {
- if(!mapFile(version, map).exists()) {
+ SteamwarWorld builderWorld = builderWorld(version, map);
+ if(builderWorld == null) {
sender.system("BUILDERCLOUD_UNKNOWN_MAP");
return;
}
VelocityCore.schedule(() -> {
- VelocityCore.local.execute("deployarena.py", arenaMode.configFile.getName(), Integer.toString(version.getVersionSuffix()), map);
+ VelocityCore.local.execute("deployarena.py", arenaMode.configFile.getName(), Integer.toString(version.getVersionSuffix()), map, builderWorld.setupAndGetStoragePath());
ArenaMode.init();
sender.system("BUILDERCLOUD_DEPLOY_FINISHED");
}).schedule();
@@ -112,13 +113,23 @@ public class BuilderCloudCommand extends SWCommand {
@Override
public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
- File folder = getWorldFolder(previousArguments, 1);
-
- String[] files;
- if(folder == null || (files = folder.list()) == null)
+ ServerVersion version = getVersion(previousArguments, 1);
+ if(version == null)
return Collections.emptyList();
- return Arrays.stream(files).filter(file -> new File(folder, file).isDirectory()).filter(file -> s.startsWith(".") || !file.startsWith(".")).toList();
+ Set maps = new LinkedHashSet<>();
+ SteamwarWorld.getBuilderWorlds(version.getVersionSuffix()).stream()
+ .map(SteamwarWorld::getName)
+ .forEach(maps::add);
+
+ File legacyFolder = new File(version.getWorldFolder(ServerStarter.LEGACY_BUILDER_BASE_PATH));
+ String[] files = legacyFolder.list();
+ if(files != null)
+ Arrays.stream(files).filter(file -> new File(legacyFolder, file).isDirectory()).forEach(maps::add);
+
+ return maps.stream()
+ .filter(file -> s.startsWith(".") || !file.startsWith("."))
+ .toList();
}
};
}
@@ -133,7 +144,7 @@ public class BuilderCloudCommand extends SWCommand {
if(s.isEmpty())
return null;
- File folder = getWorldFolder(previousArguments, 2);
+ File folder = getLegacyWorldFolder(previousArguments, 2);
if(folder == null)
throw new SecurityException();
@@ -147,7 +158,7 @@ public class BuilderCloudCommand extends SWCommand {
@Override
public Collection tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
- File folder = getWorldFolder(previousArguments, 2);
+ File folder = getLegacyWorldFolder(previousArguments, 2);
String[] files;
if(folder == null || (files = folder.list()) == null)
@@ -158,14 +169,36 @@ public class BuilderCloudCommand extends SWCommand {
};
}
- private File mapFile(ServerVersion version, String map) {
- return new File(version.getWorldFolder(ServerStarter.BUILDER_BASE_PATH), map);
+ private SteamwarWorld builderWorld(ServerVersion version, String map) {
+ SteamwarWorld world = SteamwarWorld.getBuilderWorld(map, version.getVersionSuffix());
+ if(world != null)
+ return world;
+
+ File legacyWorld = mapFile(version, map);
+ if(!legacyWorld.exists())
+ return null;
+
+ return SteamwarWorld.getOrCreateBuilderWorld(map, version.getVersionSuffix(), legacyWorld);
}
- private File getWorldFolder(PreviousArguments previousArguments, int offset) {
- ServerVersion v = ServerVersion.get(previousArguments.userArgs[previousArguments.userArgs.length - offset]);
+ private boolean mapExists(ServerVersion version, String map) {
+ return SteamwarWorld.getBuilderWorld(map, version.getVersionSuffix()) != null || mapFile(version, map).exists();
+ }
+
+ private File mapFile(ServerVersion version, String map) {
+ return new File(version.getWorldFolder(ServerStarter.LEGACY_BUILDER_BASE_PATH), map);
+ }
+
+ private File getLegacyWorldFolder(PreviousArguments previousArguments, int offset) {
+ ServerVersion v = getVersion(previousArguments, offset);
if(v == null)
return null;
- return new File(v.getWorldFolder(ServerStarter.BUILDER_BASE_PATH));
+ return new File(v.getWorldFolder(ServerStarter.LEGACY_BUILDER_BASE_PATH));
+ }
+
+ private ServerVersion getVersion(PreviousArguments previousArguments, int offset) {
+ if(previousArguments.userArgs.length < offset)
+ return null;
+ return ServerVersion.get(previousArguments.userArgs[previousArguments.userArgs.length - offset]);
}
}
diff --git a/VelocityCore/src/de/steamwar/velocitycore/commands/GDPRQuery.java b/VelocityCore/src/de/steamwar/velocitycore/commands/GDPRQuery.java
index 4cdbfc69..e75e6e4b 100644
--- a/VelocityCore/src/de/steamwar/velocitycore/commands/GDPRQuery.java
+++ b/VelocityCore/src/de/steamwar/velocitycore/commands/GDPRQuery.java
@@ -24,11 +24,16 @@ import de.steamwar.linkage.Linked;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.SteamwarUser;
+import de.steamwar.sql.SteamwarWorld;
import de.steamwar.sql.UserPerm;
import de.steamwar.sql.internal.Statement;
+import de.steamwar.velocitycore.ServerStarter;
+import de.steamwar.velocitycore.ServerVersion;
import de.steamwar.velocitycore.VelocityCore;
import java.io.*;
+import java.util.LinkedHashSet;
+import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -64,12 +69,21 @@ public class GDPRQuery extends SWCommand {
copy(getClass().getClassLoader().getResourceAsStream("GDPRQueryREADME.md"), out, "README.txt");
sender.system("GDPR_STATUS_WORLD");
- copyBauwelt(user, out, "/home/minecraft/userworlds/" + user.getUUID().toString(), "BuildWorld12");
- copyBauwelt(user, out, "/home/minecraft/userworlds15/" + user.getId(), "BuildWorld15");
+ Set exportedVersions = new LinkedHashSet<>();
+ for(ServerVersion version : ServerVersion.values()) {
+ int versionSuffix = version.getVersionSuffix();
+ if(!exportedVersions.add(versionSuffix))
+ continue;
+
+ SteamwarWorld world = SteamwarWorld.getBauWorld(user, versionSuffix);
+ if(world != null)
+ copyBauwelt(user, out, world.setupAndGetStoragePath(), "BuildWorld" + versionSuffix);
+ else
+ copyLegacyBauwelt(user, out, version);
+ }
sender.system("GDPR_STATUS_INVENTORIES");
- copyPlayerdata(user, out, "/home/minecraft/userworlds", "BuildInventories12");
- copyPlayerdata(user, out, "/home/minecraft/userworlds15", "BuildInventories15");
+ copyPlayerdata(user, out, SteamwarWorld.WORLD_STORAGE, "BuildInventories");
sender.system("GDPR_STATUS_DATABASE");
sqlCSV(user, out, bannedIPs, "BannedIPs.csv");
@@ -230,6 +244,18 @@ public class GDPRQuery extends SWCommand {
copy(playerdata, out, outDir + "/playerdata/" + user.getUUID().toString() + ".dat");
}
+ private void copyLegacyBauwelt(SteamwarUser user, ZipOutputStream out, ServerVersion version) throws IOException {
+ File legacyIdWorld = new File(version.getWorldFolder(ServerStarter.LEGACY_WORLDS_BASE_PATH), String.valueOf(user.getId()));
+ if(legacyIdWorld.exists()) {
+ copyBauwelt(user, out, legacyIdWorld.getPath(), "BuildWorld" + version.getVersionSuffix());
+ return;
+ }
+
+ File legacyUuidWorld = new File(version.getWorldFolder(ServerStarter.LEGACY_WORLDS_BASE_PATH), user.getUUID().toString());
+ if(legacyUuidWorld.exists())
+ copyBauwelt(user, out, legacyUuidWorld.getPath(), "BuildWorld" + version.getVersionSuffix());
+ }
+
private void copyPlayerdata(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException {
File worlds = new File(inDir);
String path = "playerdata/" + user.getUUID().toString() + ".dat";