diff --git a/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt b/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt index 77709c9..cee4dc5 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt @@ -18,6 +18,7 @@ import club.mcscrims.speedhg.listener.SoupListener import club.mcscrims.speedhg.listener.StatsListener import club.mcscrims.speedhg.scoreboard.ScoreboardManager import club.mcscrims.speedhg.webhook.DiscordWebhookManager +import club.mcscrims.speedhg.world.WorldManager import org.bukkit.Bukkit import org.bukkit.Material import org.bukkit.NamespacedKey @@ -58,11 +59,19 @@ class SpeedHG : JavaPlugin() { lateinit var discordWebhookManager: DiscordWebhookManager private set - override fun onEnable() + override fun onLoad() { instance = this - saveDefaultConfig() + saveDefaultConfig() + reloadConfig() + + val worldManager = WorldManager( this ) + worldManager.prepareRandomWorld() + } + + override fun onEnable() + { databaseManager = DatabaseManager( this ) try { databaseManager.connect() diff --git a/src/main/kotlin/club/mcscrims/speedhg/world/WorldManager.kt b/src/main/kotlin/club/mcscrims/speedhg/world/WorldManager.kt new file mode 100644 index 0000000..39a334c --- /dev/null +++ b/src/main/kotlin/club/mcscrims/speedhg/world/WorldManager.kt @@ -0,0 +1,89 @@ +package club.mcscrims.speedhg.world + +import club.mcscrims.speedhg.SpeedHG +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.util.zip.ZipInputStream + +class WorldManager( + private val plugin: SpeedHG +) { + + /** + * Wird in onLoad() aufgerufen, um die Welt VOR dem Server-Start auszutauschen + */ + fun prepareRandomWorld() + { + if (!plugin.config.getBoolean( "map-system.enabled", false )) + return + + val maps = plugin.config.getStringList( "map-system.maps" ) + if ( maps.isEmpty() ) + { + plugin.logger.warning( "[WorldManager] Keine Maps in der Config definiert" ) + return + } + + val randomMapName = maps.random() + val mapsFolder = File( plugin.dataFolder, plugin.config.getString( "map-system.zip-folder", "maps" )!!) + val zipFile = File( mapsFolder, randomMapName ) + + if ( !zipFile.exists() ) + { + plugin.logger.severe( "[WorldManager] Map-ZIP nicht gefunden: $randomMapName" ) + return + } + + plugin.logger.info( "[WorldManager] Ausgewählte Map: $randomMapName. Entpacke..." ) + + val targetWorldName = plugin.config.getString( "map-system.target-world-name", "world" )!! + val serverRoot = plugin.dataFolder.parentFile.parentFile // Geht von plugins/SpeedHG -> plugins -> Server Root + val targetWorldFolder = File( serverRoot, targetWorldName ) + + if ( targetWorldFolder.exists() ) + { + plugin.logger.info( "[WorldManager] Lösche alte Welt..." ) + targetWorldFolder.deleteRecursively() + } + + File( serverRoot, "${targetWorldName}_nether" ).deleteRecursively() + File( serverRoot, "${targetWorldName}_the_end" ).deleteRecursively() + + targetWorldFolder.mkdirs() + unzip( zipFile, targetWorldFolder ) + + plugin.logger.info( "[WorldManager] Map erfolgreich entpackt!" ) + } + + private fun unzip( + zipFile: File, + targetDir: File + ) { + ZipInputStream(FileInputStream( zipFile )).use { zis -> + var entry = zis.nextEntry + while ( entry != null ) + { + val newFile = File( targetDir, entry.name ) + + if (!newFile.canonicalPath.startsWith( targetDir.canonicalPath + File.separator )) + throw SecurityException("Ungültiger ZIP-Eintrag (Zip Slip): ${entry.name}") + + if ( entry.isDirectory ) + { + newFile.mkdirs() + } + else + { + File( newFile.parent ).mkdirs() + FileOutputStream( newFile ).use { fos -> + zis.copyTo( fos ) + } + } + zis.closeEntry() + entry = zis.nextEntry + } + } + } + +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4020c9a..da27af5 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -25,6 +25,18 @@ recraftNerf: beforeFeast: true maxAmount: 64 +map-system: + enabled: false + # Der Ordner im Plugin-Verzeichnis, in welchem die ZIPs liegen + zip-folder: "maps" + # Name der Zielwelt + target-world-name: "world" + # Liste der verfügbaren Maps + maps: + - "hg_map_1.zip" + - "hg_map_2.zip" + - "hg_map_3.zip" + discord: enabled: false webhook-url: "DEINE_WEBHOOK_URL_HIER"