Add WorldManager and map-system support
Introduce WorldManager to select and unpack a random map ZIP into the server root before startup. The plugin now calls WorldManager.prepareRandomWorld() in onLoad (before onEnable) and reloads config there. Added map-system config options (enabled, zip-folder, target-world-name, maps) with example entries. WorldManager deletes existing world folders, extracts the chosen ZIP (with zip-slip protection) and logs progress.
This commit is contained in:
@@ -18,6 +18,7 @@ import club.mcscrims.speedhg.listener.SoupListener
|
|||||||
import club.mcscrims.speedhg.listener.StatsListener
|
import club.mcscrims.speedhg.listener.StatsListener
|
||||||
import club.mcscrims.speedhg.scoreboard.ScoreboardManager
|
import club.mcscrims.speedhg.scoreboard.ScoreboardManager
|
||||||
import club.mcscrims.speedhg.webhook.DiscordWebhookManager
|
import club.mcscrims.speedhg.webhook.DiscordWebhookManager
|
||||||
|
import club.mcscrims.speedhg.world.WorldManager
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
@@ -58,11 +59,19 @@ class SpeedHG : JavaPlugin() {
|
|||||||
lateinit var discordWebhookManager: DiscordWebhookManager
|
lateinit var discordWebhookManager: DiscordWebhookManager
|
||||||
private set
|
private set
|
||||||
|
|
||||||
override fun onEnable()
|
override fun onLoad()
|
||||||
{
|
{
|
||||||
instance = this
|
instance = this
|
||||||
saveDefaultConfig()
|
|
||||||
|
|
||||||
|
saveDefaultConfig()
|
||||||
|
reloadConfig()
|
||||||
|
|
||||||
|
val worldManager = WorldManager( this )
|
||||||
|
worldManager.prepareRandomWorld()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEnable()
|
||||||
|
{
|
||||||
databaseManager = DatabaseManager( this )
|
databaseManager = DatabaseManager( this )
|
||||||
try {
|
try {
|
||||||
databaseManager.connect()
|
databaseManager.connect()
|
||||||
|
|||||||
89
src/main/kotlin/club/mcscrims/speedhg/world/WorldManager.kt
Normal file
89
src/main/kotlin/club/mcscrims/speedhg/world/WorldManager.kt
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -25,6 +25,18 @@ recraftNerf:
|
|||||||
beforeFeast: true
|
beforeFeast: true
|
||||||
maxAmount: 64
|
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:
|
discord:
|
||||||
enabled: false
|
enabled: false
|
||||||
webhook-url: "DEINE_WEBHOOK_URL_HIER"
|
webhook-url: "DEINE_WEBHOOK_URL_HIER"
|
||||||
|
|||||||
Reference in New Issue
Block a user