diff --git a/src/main/java/org/ultramine/commands/basic/TechCommands.java b/src/main/java/org/ultramine/commands/basic/TechCommands.java index 387454d..f388298 100644 --- a/src/main/java/org/ultramine/commands/basic/TechCommands.java +++ b/src/main/java/org/ultramine/commands/basic/TechCommands.java @@ -1,5 +1,7 @@ package org.ultramine.commands.basic; +import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -22,6 +24,7 @@ import net.minecraft.world.chunk.Chunk; import net.minecraftforge.common.DimensionManager; +import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.ultramine.commands.Command; @@ -38,6 +41,7 @@ import org.ultramine.server.chunk.ChunkProfiler; import org.ultramine.server.chunk.IChunkLoadCallback; import org.ultramine.server.util.BasicTypeParser; +import org.ultramine.server.util.WarpLocation; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -155,7 +159,7 @@ permissions = {"command.technical.multiworld"}, syntax = { "[list]", - "[load unload goto] <%world>" //No world validation + "[load unload hold goto destroy delete] <%world>" //No world validation } ) public static void multiworld(CommandContext ctx) @@ -174,34 +178,77 @@ } int dim = ctx.get("world").asInt(); + WorldServer world = mw.getWorldByID(dim); if(!DimensionManager.isDimensionRegistered(dim)) ctx.failure("command.multiworld.notregistered"); if(ctx.getAction().equals("load")) { - if(mw.getWorldByID(dim) != null) + if(world != null) ctx.failure("command.multiworld.alreadyloaded"); + mw.unholdDimension(dim); //if was held DimensionManager.initDimension(dim); ctx.sendMessage("command.multiworld.load.success"); } - else if(ctx.getAction().equals("unload")) + else if(ctx.getAction().equals("unload") || ctx.getAction().equals("hold")) { - if(mw.getWorldByID(dim) == null) + if(world == null) ctx.failure("command.multiworld.notloaded"); + movePlayersOut(world); + if(ctx.getAction().equals("hold")) + mw.holdDimension(dim); DimensionManager.unloadWorld(dim); - ctx.sendMessage("command.multiworld.unload.success"); + ctx.sendMessage("command.multiworld."+ctx.getAction()+".success"); } else if(ctx.getAction().equals("goto")) { - WorldServer world = mw.getWorldByID(dim); if(world == null) ctx.failure("command.multiworld.notloaded"); Teleporter.tpNow(ctx.getSenderAsPlayer(), dim, world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnY(), world.getWorldInfo().getSpawnZ()); } + else if(ctx.getAction().equals("destroy") || ctx.getAction().equals("delete")) + { + if(world == null && !ctx.getAction().equals("delete")) + ctx.failure("command.multiworld.notloaded"); + + if(world != null) + { + movePlayersOut(world); + mw.destroyWorld(world); + } + + mw.holdDimension(dim); + + if(ctx.getAction().equals("delete")) + { + try + { + FileUtils.cleanDirectory(new File(ctx.getServer().getWorldsDir(), world != null ? mw.getSaveDirName(world) : mw.getNameByID(dim))); + } + catch(IOException e) + { + throw new RuntimeException(e); + } + } + ctx.sendMessage("command.multiworld."+ctx.getAction()+".success"); + + } + } + + private static void movePlayersOut(WorldServer world) + { + WarpLocation spawn = world.func_73046_m().getConfigurationManager().getDataLoader().getWarp("spawn"); + for(EntityPlayerMP player : GenericIterableFactory.newCastingIterable(world.playerEntities, EntityPlayerMP.class)) + { + if(player.dimension == spawn.dimension) + player.playerNetServerHandler.kickPlayerFromServer("The world has been unloaded"); + else + Teleporter.tpNow(player, spawn); + } } @Command( diff --git a/src/main/java/org/ultramine/server/MultiWorld.java b/src/main/java/org/ultramine/server/MultiWorld.java index d8cec88..3e135d3 100644 --- a/src/main/java/org/ultramine/server/MultiWorld.java +++ b/src/main/java/org/ultramine/server/MultiWorld.java @@ -60,6 +60,7 @@ private final Map nameToWorldMap = new HashMap(); private final TIntObjectMap dimToConfigMap = new TIntObjectHashMap(); private final Set backupDirs = new HashSet(); + private final TIntSet holdDims = new TIntHashSet(); private TIntSet isolatedDataDims; public MultiWorld(MinecraftServer server) @@ -229,6 +230,8 @@ @SideOnly(Side.SERVER) public void initDimension(int dim) { + if(holdDims.contains(dim)) + return; ISaveFormat format = server.getActiveAnvilConverter(); String name = resolveNameForDim(dim); @@ -443,6 +446,16 @@ return players; } + public void holdDimension(int dim) + { + holdDims.add(dim); + } + + public boolean unholdDimension(int dim) + { + return holdDims.remove(dim); + } + public WorldServer getWorldByID(int dim) { return dimToWorldMap.get(dim); diff --git a/src/main/resources/assets/ultramine/lang/en_US.lang b/src/main/resources/assets/ultramine/lang/en_US.lang index 6f9ecbd..c746b8c 100644 --- a/src/main/resources/assets/ultramine/lang/en_US.lang +++ b/src/main/resources/assets/ultramine/lang/en_US.lang @@ -227,13 +227,16 @@ command.memstat.usage=/memstat command.memstat.description=Displays max, current allocated and free memory -command.multiworld.usage=/multiworld or /multiworld list +command.multiworld.usage=/multiworld or /multiworld list command.multiworld.description=All multiworld commands command.multiworld.alreadyloaded=Dimension is already loaded command.multiworld.notregistered=Dimension is not registered (not exists) command.multiworld.notloaded=Dimension is not loaded command.multiworld.load.success=Dimension successfuly loaded command.multiworld.unload.success=Dimension successfuly unloaded +command.multiworld.hold.success=Dimension successfuly unloaded and held +command.multiworld.destroy.success=Dimension successfuly destroyed +command.multiworld.delete.success=Dimension successfuly deleted command.multiworld.list.head=Dimension list: command.countentity.usage=/countentity diff --git a/src/main/resources/assets/ultramine/lang/ru_RU.lang b/src/main/resources/assets/ultramine/lang/ru_RU.lang index ba1b334..9af2553 100644 --- a/src/main/resources/assets/ultramine/lang/ru_RU.lang +++ b/src/main/resources/assets/ultramine/lang/ru_RU.lang @@ -227,13 +227,16 @@ command.memstat.usage=/memstat command.memstat.description=Displays max, current allocated and free memory -command.multiworld.usage=/multiworld <мир> ИЛИ /multiworld list +command.multiworld.usage=/multiworld <мир> ИЛИ /multiworld list command.multiworld.description=Все команды MultiWorld command.multiworld.alreadyloaded=Измерение уже загружено command.multiworld.notregistered=Измерение на зарегистрировано (не существует) command.multiworld.notloaded=Измерение не загружено command.multiworld.load.success=Измерение загружено command.multiworld.unload.success=Измерение выгружено +command.multiworld.hold.success=Измерение выгружено и заморожено +command.multiworld.destroy.success=Измерение разрушено +command.multiworld.delete.success=Измерение удалено command.multiworld.list.head=Список измерений: command.countentity.usage=/countentity <радиус>