Ver código fonte

gamerules and time management per world, block state commands

Kajetan Johannes Hammerle 4 anos atrás
pai
commit
8cb275c8db

+ 3 - 0
src/main/java/me/km/Server.java

@@ -34,6 +34,7 @@ import me.km.snuviscript.MinecraftFunctions;
 import me.km.snuviscript.ScriptBank;
 import me.km.snuviscript.ScriptEvents;
 import me.km.snuviscript.Scripts;
+import me.km.world.WorldEvents;
 
 @OnlyIn(Dist.DEDICATED_SERVER)
 public class Server
@@ -137,6 +138,8 @@ public class Server
         MinecraftFunctions.registerFunctions(
                 scripts.getScriptManager(), scripts, perms, scheduler, server, playerBank, 
                 customEventCaller, scriptBank, databank, blockProtection, protection);
+        
+        MinecraftForge.EVENT_BUS.register(new WorldEvents(logger));
         scripts.startScript("startscript");
     }
     

+ 24 - 3
src/main/java/me/km/snuviscript/MinecraftFunctions.java

@@ -108,6 +108,7 @@ import net.minecraft.potion.EffectInstance;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.management.PlayerList;
 import net.minecraft.server.management.ProfileBanEntry;
+import net.minecraft.state.IProperty;
 import net.minecraft.state.properties.ChestType;
 import net.minecraft.tags.BlockTags;
 import net.minecraft.tags.ItemTags;
@@ -587,16 +588,15 @@ public class MinecraftFunctions
         });  
         sm.registerFunction("world.setgamerule", (sc, in) -> 
         {                    
-            /*Object o = ((World) in[0].get(sc)).getGameRules().get(Mapper.getGameRule(in[1].getString(sc)));
+            Object o = ((World) in[0].get(sc)).getGameRules().get(Mapper.getGameRule(in[1].getString(sc)));
             if(o instanceof GameRules.BooleanValue)
             {
                 ((GameRules.BooleanValue) o).set(in[2].getBoolean(sc), server);
             }
             if(o instanceof GameRules.IntegerValue)
             {
-                ((GameRules.IntegerValue) o).set(in[2].getInt(sc), server);
+                ReflectionUtils.setIntegerValue((GameRules.IntegerValue) o, in[2].getInt(sc));
             }
-            ((World) in[0].get(sc)).getGameRules().setOrCreateGameRule(in[1].getString(sc), in[2].getString(sc), server);*/
             return Void.TYPE;
         });  
         sm.registerFunction("world.getgamerule", (sc, in) -> 
@@ -920,6 +920,27 @@ public class MinecraftFunctions
             Location l = (Location) in[0].get(sc);
             return l.getWorld().getBlockState(l.getBlockPos()).getBlock();
         });
+        sm.registerFunction("block.getproperty", (sc, in) -> Mapper.getProperty(in[0].getString(sc)));
+        sm.registerFunction("block.getstate", (sc, in) -> 
+        {
+            Location l = (Location) in[0].get(sc);
+            IProperty prop = (IProperty) in[1].get(sc);
+            BlockState state = l.getWorld().getBlockState(l.getBlockPos());
+            if(state.has(prop))
+            {
+                Object o =  l.getWorld().getBlockState(l.getBlockPos()).get(prop);
+                if(o instanceof Number)
+                {
+                    return ((Number) o).doubleValue();
+                }
+                else if(o instanceof Boolean)
+                {
+                    return o;
+                }
+                return o.toString();
+            }
+            return null;
+        });
         sm.registerFunction("block.clone", (sc, in) -> 
         { 
             Location l0 = (Location) in[0].get(sc);

+ 94 - 0
src/main/java/me/km/utils/Mapper.java

@@ -5,6 +5,8 @@ import net.minecraft.enchantment.Enchantment;
 import net.minecraft.item.Item;
 import net.minecraft.particles.IParticleData;
 import net.minecraft.potion.Effect;
+import net.minecraft.state.IProperty;
+import net.minecraft.state.properties.BlockStateProperties;
 import net.minecraft.util.ResourceLocation;
 import net.minecraft.util.SoundEvent;
 import net.minecraft.world.GameRules;
@@ -73,4 +75,96 @@ public class Mapper
         }
         return null;
     }
+    
+    public static IProperty getProperty(String name)
+    {
+        switch(name)
+        {
+            case "attached": return BlockStateProperties.ATTACHED;
+            case "bottom": return BlockStateProperties.BOTTOM;
+            case "conditional": return BlockStateProperties.CONDITIONAL;
+            case "disarmed": return BlockStateProperties.DISARMED;
+            case "drag": return BlockStateProperties.DRAG;
+            case "enabled": return BlockStateProperties.ENABLED;
+            case "extended": return BlockStateProperties.EXTENDED;
+            case "eye": return BlockStateProperties.EYE;
+            case "falling": return BlockStateProperties.FALLING;
+            case "hanging": return BlockStateProperties.HANGING;
+            case "has_bottle_0": return BlockStateProperties.HAS_BOTTLE_0;
+            case "has_bottle_1": return BlockStateProperties.HAS_BOTTLE_1;
+            case "has_bottle_2": return BlockStateProperties.HAS_BOTTLE_2;
+            case "has_record": return BlockStateProperties.HAS_RECORD;
+            case "has_book": return BlockStateProperties.HAS_BOOK;
+            case "inverted": return BlockStateProperties.INVERTED;
+            case "in_wall": return BlockStateProperties.IN_WALL;
+            case "lit": return BlockStateProperties.LIT;
+            case "locked": return BlockStateProperties.LOCKED;
+            case "occupied": return BlockStateProperties.OCCUPIED;
+            case "open": return BlockStateProperties.OPEN;
+            case "persistent": return BlockStateProperties.PERSISTENT;
+            case "powered": return BlockStateProperties.POWERED;
+            case "short": return BlockStateProperties.SHORT;
+            case "signal_fire": return BlockStateProperties.SIGNAL_FIRE;
+            case "snowy": return BlockStateProperties.SNOWY;
+            case "triggered": return BlockStateProperties.TRIGGERED;
+            case "unstable": return BlockStateProperties.UNSTABLE;
+            case "waterlogged": return BlockStateProperties.WATERLOGGED;
+            case "horizontal_axis": return BlockStateProperties.HORIZONTAL_AXIS;
+            case "axis": return BlockStateProperties.AXIS;
+            case "up": return BlockStateProperties.UP;
+            case "down": return BlockStateProperties.DOWN;
+            case "north": return BlockStateProperties.NORTH;
+            case "east": return BlockStateProperties.EAST;
+            case "south": return BlockStateProperties.SOUTH;
+            case "west": return BlockStateProperties.WEST;
+            case "facing": return BlockStateProperties.FACING;
+            case "facing_except_up": return BlockStateProperties.FACING_EXCEPT_UP;
+            case "horizontal_facing": return BlockStateProperties.HORIZONTAL_FACING;
+            case "face": return BlockStateProperties.FACE;
+            case "attachment": return BlockStateProperties.BELL_ATTACHMENT;
+            case "redstone_east": return BlockStateProperties.REDSTONE_EAST;
+            case "redstone_north": return BlockStateProperties.REDSTONE_NORTH;
+            case "redstone_south": return BlockStateProperties.REDSTONE_SOUTH;
+            case "redstone_west": return BlockStateProperties.REDSTONE_WEST;
+            case "double_block_half": return BlockStateProperties.DOUBLE_BLOCK_HALF;
+            case "half": return BlockStateProperties.HALF;
+            case "rail_shape": return BlockStateProperties.RAIL_SHAPE;
+            case "rail_shape_straight": return BlockStateProperties.RAIL_SHAPE_STRAIGHT;
+            case "age_0_1": return BlockStateProperties.AGE_0_1;
+            case "age_0_2": return BlockStateProperties.AGE_0_2;
+            case "age_0_3": return BlockStateProperties.AGE_0_3;
+            case "age_0_5": return BlockStateProperties.AGE_0_5;
+            case "age_0_7": return BlockStateProperties.AGE_0_7;
+            case "age_0_15": return BlockStateProperties.AGE_0_15;
+            case "age_0_25": return BlockStateProperties.AGE_0_25;
+            case "bites": return BlockStateProperties.BITES_0_6;
+            case "delay": return BlockStateProperties.DELAY_1_4;
+            case "distance_1_7": return BlockStateProperties.DISTANCE_1_7;
+            case "eggs": return BlockStateProperties.EGGS_1_4;
+            case "hatch": return BlockStateProperties.HATCH_0_2;
+            case "layers": return BlockStateProperties.LAYERS_1_8;
+            case "level_0_3": return BlockStateProperties.LEVEL_0_3;
+            case "level_0_8": return BlockStateProperties.LEVEL_0_8;
+            case "level_1_8": return BlockStateProperties.LEVEL_1_8;
+            case "level_0_15": return BlockStateProperties.LEVEL_0_15;
+            case "moisture": return BlockStateProperties.MOISTURE_0_7;
+            case "note": return BlockStateProperties.NOTE_0_24;
+            case "pickles": return BlockStateProperties.PICKLES_1_4;
+            case "power": return BlockStateProperties.POWER_0_15;
+            case "stage": return BlockStateProperties.STAGE_0_1;
+            case "distance_0_7": return BlockStateProperties.DISTANCE_0_7;
+            case "rotation": return BlockStateProperties.ROTATION_0_15;
+            case "part": return BlockStateProperties.BED_PART;
+            case "chest_type": return BlockStateProperties.CHEST_TYPE;
+            case "mode": return BlockStateProperties.COMPARATOR_MODE;
+            case "hinge": return BlockStateProperties.DOOR_HINGE;
+            case "instrument": return BlockStateProperties.NOTE_BLOCK_INSTRUMENT;
+            case "piston_type": return BlockStateProperties.PISTON_TYPE;
+            case "slab_type": return BlockStateProperties.SLAB_TYPE;
+            case "stair_shape": return BlockStateProperties.STAIRS_SHAPE;
+            case "structure_block_mode": return BlockStateProperties.STRUCTURE_BLOCK_MODE;
+            case "leaves": return BlockStateProperties.BAMBOO_LEAVES;
+        }
+        return null;
+    }
 }

+ 28 - 1
src/main/java/me/km/utils/ReflectionUtils.java

@@ -4,6 +4,7 @@ import cpw.mods.modlauncher.api.INameMappingService;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.HashMap;
 import java.util.Map;
 import net.minecraft.command.Commands;
 import net.minecraft.entity.Entity;
@@ -11,14 +12,18 @@ import net.minecraft.entity.LivingEntity;
 import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.player.PlayerAbilities;
 import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.entity.projectile.AbstractArrowEntity;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.management.PlayerList;
+import net.minecraft.state.IProperty;
+import net.minecraft.state.properties.BlockStateProperties;
 import net.minecraft.util.DamageSource;
 import net.minecraft.util.FoodStats;
 import net.minecraft.util.ResourceLocation;
 import net.minecraft.world.Explosion;
+import net.minecraft.world.GameRules;
 import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraft.world.storage.WorldInfo;
 import net.minecraftforge.common.DimensionManager;
 import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
 import static net.minecraftforge.fml.common.ObfuscationReflectionHelper.remapName;
@@ -318,4 +323,26 @@ public class ReflectionUtils
     {
         return getFloat(ex, SIZE, 1);
     }
+    
+    // -----------------------------------------------------------------------------------
+    // world info
+    // -----------------------------------------------------------------------------------
+    
+    private final static Field WORLD_INFO = getField(World.class, "field_72986_A"); // worldInfo
+
+    public static void setWorldInfo(World w, WorldInfo info)
+    {
+        setFieldValue(w, WORLD_INFO, info);
+    }
+    
+    // -----------------------------------------------------------------------------------
+    // gamerule integer value
+    // -----------------------------------------------------------------------------------
+    
+    private final static Field INTEGER_VALUE = getField(GameRules.IntegerValue.class, "field_223566_a"); // value
+
+    public static void setIntegerValue(GameRules.IntegerValue rule, int value)
+    {
+        setInt(rule, INTEGER_VALUE, value);
+    }
 }

+ 24 - 0
src/main/java/me/km/world/ModOverworldDimension.java

@@ -0,0 +1,24 @@
+package me.km.world;
+
+import net.minecraft.world.World;
+import net.minecraft.world.dimension.DimensionType;
+import net.minecraft.world.dimension.OverworldDimension;
+
+public class ModOverworldDimension extends OverworldDimension
+{
+    public ModOverworldDimension(World worldIn, DimensionType typeIn)
+    {
+        super(worldIn, typeIn);
+    }
+
+    @Override
+    public void tick()
+    {
+        
+    }
+
+    @Override
+    public void onWorldSave() 
+    {
+    }
+}

+ 233 - 0
src/main/java/me/km/world/ModWorldInfo.java

@@ -0,0 +1,233 @@
+package me.km.world;
+
+import me.hammerle.snuviscript.code.ISnuviLogger;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.storage.DerivedWorldInfo;
+import net.minecraft.world.storage.WorldInfo;
+import me.hammerle.snuviscript.config.SnuviConfig;
+import me.km.utils.ReflectionUtils;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.GameRules;
+import static net.minecraft.world.GameRules.*;
+
+public class ModWorldInfo extends DerivedWorldInfo
+{
+    private final SnuviConfig config;
+    
+    private long gameTime;
+    private long dayTime;
+    private int clearWeatherTime;
+    private boolean raining;
+    private int rainTime;
+    private boolean thundering;
+    private int thunderTime;
+    private Difficulty difficulty;
+    private final GameRules gameRules = new GameRules();
+   
+    public ModWorldInfo(WorldInfo info, String name, ISnuviLogger logger, MinecraftServer server)
+    {
+        super(info);
+        
+        config = new SnuviConfig(logger, "worlddata", name);
+        if(config.exists())
+        {
+            config.load();
+        }
+        onLoad(info, server);
+    }
+    
+    private void onLoad(WorldInfo info, MinecraftServer server)
+    {
+        gameTime = config.getLong("gameTime", info.getGameTime());
+        dayTime = config.getLong("dayTime", info.getDayTime());
+        clearWeatherTime = config.getInt("clearWeatherTime", info.getClearWeatherTime());
+        raining = config.getBoolean("raining", info.isRaining());
+        rainTime = config.getInt("rainTime", info.getRainTime());
+        thundering = config.getBoolean("thundering", info.isThundering());
+        thunderTime = config.getInt("thunderTime", info.getThunderTime());
+        
+        String diffi = config.getString("difficulty");
+        if(diffi == null)
+        {
+            difficulty = info.getDifficulty();
+        }
+        else
+        {
+            try
+            {
+                difficulty = Difficulty.valueOf(diffi);
+            }
+            catch(Exception ex)
+            {
+                difficulty = info.getDifficulty();
+            }
+        }
+        
+        GameRules rules = info.getGameRulesInstance();
+        gameRules.get(DO_FIRE_TICK).set(config.getBoolean("doFireTick", rules.getBoolean(DO_FIRE_TICK)), server);
+        gameRules.get(MOB_GRIEFING).set(config.getBoolean("mobGriefing", rules.getBoolean(MOB_GRIEFING)), server);
+        gameRules.get(KEEP_INVENTORY).set(config.getBoolean("keepInventory", rules.getBoolean(KEEP_INVENTORY)), server);
+        gameRules.get(DO_MOB_SPAWNING).set(config.getBoolean("doMobSpawning", rules.getBoolean(DO_MOB_SPAWNING)), server);
+        gameRules.get(DO_MOB_LOOT).set(config.getBoolean("doMobLoot", rules.getBoolean(DO_MOB_LOOT)), server);
+        gameRules.get(DO_TILE_DROPS).set(config.getBoolean("doTileDrops", rules.getBoolean(DO_TILE_DROPS)), server);
+        gameRules.get(DO_ENTITY_DROPS).set(config.getBoolean("doEntityDrops", rules.getBoolean(DO_ENTITY_DROPS)), server);
+        gameRules.get(COMMAND_BLOCK_OUTPUT).set(config.getBoolean("commandBlockOutput", rules.getBoolean(COMMAND_BLOCK_OUTPUT)), server);
+        gameRules.get(NATURAL_REGENERATION).set(config.getBoolean("naturalRegeneration", rules.getBoolean(NATURAL_REGENERATION)), server);
+        gameRules.get(DO_DAYLIGHT_CYCLE).set(config.getBoolean("doDaylightCycle", rules.getBoolean(DO_DAYLIGHT_CYCLE)), server);
+        gameRules.get(LOG_ADMIN_COMMANDS).set(config.getBoolean("logAdminCommands", rules.getBoolean(LOG_ADMIN_COMMANDS)), server);
+        gameRules.get(SHOW_DEATH_MESSAGES).set(config.getBoolean("showDeathMessages", rules.getBoolean(SHOW_DEATH_MESSAGES)), server);
+        ReflectionUtils.setIntegerValue(gameRules.get(RANDOM_TICK_SPEED), config.getInt("randomTickSpeed", rules.getInt(RANDOM_TICK_SPEED)));
+        gameRules.get(SEND_COMMAND_FEEDBACK).set(config.getBoolean("sendCommandFeedback", rules.getBoolean(SEND_COMMAND_FEEDBACK)), server);
+        gameRules.get(REDUCED_DEBUG_INFO).set(config.getBoolean("reducedDebugInfo", rules.getBoolean(REDUCED_DEBUG_INFO)), server);
+        gameRules.get(SPECTATORS_GENERATE_CHUNKS).set(config.getBoolean("spectatorsGenerateChunks", rules.getBoolean(SPECTATORS_GENERATE_CHUNKS)), server);
+        ReflectionUtils.setIntegerValue(gameRules.get(SPAWN_RADIUS), config.getInt("spawnRadius", rules.getInt(SPAWN_RADIUS)));
+        gameRules.get(DISABLE_ELYTRA_MOVEMENT_CHECK).set(config.getBoolean("disableElytraMovementCheck", rules.getBoolean(DISABLE_ELYTRA_MOVEMENT_CHECK)), server);
+        ReflectionUtils.setIntegerValue(gameRules.get(MAX_ENTITY_CRAMMING), config.getInt("maxEntityCramming", rules.getInt(MAX_ENTITY_CRAMMING)));
+        gameRules.get(DO_WEATHER_CYCLE).set(config.getBoolean("doWeatherCycle", rules.getBoolean(DO_WEATHER_CYCLE)), server);
+        gameRules.get(DO_LIMITED_CRAFTING).set(config.getBoolean("doLimitedCrafting", rules.getBoolean(DO_LIMITED_CRAFTING)), server);
+        ReflectionUtils.setIntegerValue(gameRules.get(MAX_COMMAND_CHAIN_LENGTH), config.getInt("maxCommandChainLength", rules.getInt(MAX_COMMAND_CHAIN_LENGTH)));
+        gameRules.get(ANNOUNCE_ADVANCEMENTS).set(config.getBoolean("announceAdvancements", rules.getBoolean(ANNOUNCE_ADVANCEMENTS)), server);
+        gameRules.get(DISABLE_RAIDS).set(config.getBoolean("disableRaids", rules.getBoolean(DISABLE_RAIDS)), server);
+    }
+    
+    public void onSave()
+    {
+        config.set("gameTime", gameTime);
+        config.set("dayTime", dayTime);
+        config.set("clearWeatherTime", clearWeatherTime);
+        config.set("raining", raining);
+        config.set("rainTime", rainTime);
+        config.set("thundering", thundering);
+        config.set("thunderTime", thunderTime);
+        config.set("difficulty", difficulty);
+        
+        config.set("doFireTick", gameRules.getBoolean(DO_FIRE_TICK));
+        config.set("mobGriefing", gameRules.getBoolean(MOB_GRIEFING));
+        config.set("keepInventory", gameRules.getBoolean(KEEP_INVENTORY));
+        config.set("doMobSpawning", gameRules.getBoolean(DO_MOB_SPAWNING));
+        config.set("doMobLoot", gameRules.getBoolean(DO_MOB_LOOT));
+        config.set("doTileDrops", gameRules.getBoolean(DO_TILE_DROPS));
+        config.set("doEntityDrops", gameRules.getBoolean(DO_ENTITY_DROPS));
+        config.set("commandBlockOutput", gameRules.getBoolean(COMMAND_BLOCK_OUTPUT));
+        config.set("naturalRegeneration", gameRules.getBoolean(NATURAL_REGENERATION));
+        config.set("doDaylightCycle", gameRules.getBoolean(DO_DAYLIGHT_CYCLE));
+        config.set("logAdminCommands", gameRules.getBoolean(LOG_ADMIN_COMMANDS));
+        config.set("showDeathMessages", gameRules.getBoolean(SHOW_DEATH_MESSAGES));
+        config.set("randomTickSpeed", gameRules.getInt(RANDOM_TICK_SPEED));
+        config.set("sendCommandFeedback", gameRules.getBoolean(SEND_COMMAND_FEEDBACK));
+        config.set("reducedDebugInfo", gameRules.getBoolean(REDUCED_DEBUG_INFO));
+        config.set("spectatorsGenerateChunks", gameRules.getBoolean(SPECTATORS_GENERATE_CHUNKS));
+        config.set("spawnRadius", gameRules.getInt(SPAWN_RADIUS));
+        config.set("disableElytraMovementCheck", gameRules.getBoolean(DISABLE_ELYTRA_MOVEMENT_CHECK));
+        config.set("maxEntityCramming", gameRules.getInt(MAX_ENTITY_CRAMMING));
+        config.set("doWeatherCycle", gameRules.getBoolean(DO_WEATHER_CYCLE));
+        config.set("doLimitedCrafting", gameRules.getBoolean(DO_LIMITED_CRAFTING));
+        config.set("maxCommandChainLength", gameRules.getInt(MAX_COMMAND_CHAIN_LENGTH));
+        config.set("announceAdvancements", gameRules.getBoolean(ANNOUNCE_ADVANCEMENTS));
+        config.set("disableRaids", gameRules.getBoolean(DISABLE_RAIDS));
+        
+        config.save();
+    }
+
+    @Override
+    public long getGameTime()
+    {
+        return this.gameTime;
+    }
+
+    @Override
+    public long getDayTime()
+    {
+        return this.dayTime;
+    }
+
+    @Override
+    public void setGameTime(long time)
+    {
+        this.gameTime = time;
+    }
+
+    @Override
+    public void setDayTime(long time)
+    {
+        this.dayTime = time;
+    }
+
+    @Override
+    public int getClearWeatherTime()
+    {
+        return this.clearWeatherTime;
+    }
+
+    @Override
+    public void setClearWeatherTime(int cleanWeatherTimeIn)
+    {
+        this.clearWeatherTime = cleanWeatherTimeIn;
+    }
+
+    @Override
+    public boolean isThundering()
+    {
+        return this.thundering;
+    }
+
+    @Override
+    public void setThundering(boolean thunderingIn)
+    {
+        this.thundering = thunderingIn;
+    }
+
+    @Override
+    public int getThunderTime()
+    {
+        return this.thunderTime;
+    }
+
+    @Override
+    public void setThunderTime(int time)
+    {
+        this.thunderTime = time;
+    }
+
+    @Override
+    public boolean isRaining()
+    {
+        return this.raining;
+    }
+
+    @Override
+    public void setRaining(boolean isRaining)
+    {
+        this.raining = isRaining;
+    }
+
+    @Override
+    public int getRainTime()
+    {
+        return this.rainTime;
+    }
+
+    @Override
+    public void setRainTime(int time)
+    {
+        this.rainTime = time;
+    }
+
+    @Override
+    public Difficulty getDifficulty()
+    {
+        return this.difficulty;
+    }
+
+    @Override
+    public void setDifficulty(Difficulty newDifficulty)
+    {
+        this.difficulty = newDifficulty;
+    }
+
+    @Override
+    public GameRules getGameRulesInstance()
+    {
+        return gameRules;
+    }
+}

+ 56 - 0
src/main/java/me/km/world/WorldEvents.java

@@ -0,0 +1,56 @@
+package me.km.world;
+
+import me.hammerle.snuviscript.code.ISnuviLogger;
+import me.km.utils.ReflectionUtils;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.World;
+import net.minecraft.world.dimension.DimensionType;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraft.world.storage.WorldInfo;
+import net.minecraftforge.common.DimensionManager;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+
+public class WorldEvents
+{
+    private final ISnuviLogger logger;
+    
+    public WorldEvents(ISnuviLogger logger)
+    {
+        this.logger = logger;
+    }
+    
+    @SubscribeEvent
+    public void onWorldLoad(WorldEvent.Load e)
+    {      
+        World w = e.getWorld().getWorld();
+        
+        org.apache.logging.log4j.LogManager.getLogger().warn("Try swapping " + w + " " + w.getDimension().getType());
+        
+        if(w.getDimension().getType().isVanilla())
+        {
+            org.apache.logging.log4j.LogManager.getLogger().warn("no swap in vanilla world");
+            return;
+        }
+        
+        ServerWorld overworld = DimensionManager.getWorld(w.getServer(), DimensionType.OVERWORLD, false, false);
+        if(overworld == null)
+        {
+            org.apache.logging.log4j.LogManager.getLogger().warn("cannot get overworld");
+            return;
+        }
+        
+        DimensionManager.keepLoaded(w.getDimension().getType(), true);
+        ReflectionUtils.setWorldInfo(w, new ModWorldInfo(overworld.getWorldInfo(), WorldManager.getName(w), logger, w.getServer()));
+    }
+    
+    @SubscribeEvent
+    public void onWorldUnload(WorldEvent.Unload e)
+    {      
+        WorldInfo info = e.getWorld().getWorld().getWorldInfo();
+        if(info instanceof ModWorldInfo)
+        {
+            ((ModWorldInfo) info).onSave();
+        }
+    } 
+}

+ 1 - 1
src/main/java/me/km/world/WorldManager.java

@@ -136,7 +136,7 @@ public class WorldManager
             domain = KajetansMod.MODID;
         }
         ResourceLocation rl = new ResourceLocation(domain, name);
-        DimensionType type = getType(new ResourceLocation(domain, name));
+        DimensionType type = getType(rl);
         if(type == null)
         {
             return null;