Add in a savehandler strategy for reading and writing data to the

world save. This service is only available to coremods via the
WorldAccessContainer interface on the mod wrapper. This is deliberate
and will not change.
This commit is contained in:
Christian 2012-10-02 21:54:47 -04:00
parent a554846e57
commit 550e622bc7
6 changed files with 236 additions and 1 deletions

View file

@ -15,7 +15,9 @@ package cpw.mods.fml.common;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -25,11 +27,15 @@ import net.minecraft.src.DedicatedServer;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.EntityPlayerMP;
import net.minecraft.src.NBTBase;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NetHandler;
import net.minecraft.src.Packet131MapData;
import net.minecraft.src.SaveHandler;
import net.minecraft.src.ServerListenThread;
import net.minecraft.src.ThreadServerApplication;
import net.minecraft.src.World;
import net.minecraft.src.WorldInfo;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
@ -37,6 +43,9 @@ import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
@ -75,6 +84,8 @@ public class FMLCommonHandler
private boolean noForge;
private List<String> brandings;
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
public void beginLoading(IFMLSidedHandler handler)
@ -385,4 +396,46 @@ public class FMLCommonHandler
{
sidedDelegate.handleTinyPacket(handler, mapData);
}
public void handleWorldDataSave(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
{
for (ModContainer mc : Loader.instance().getModList())
{
if (mc instanceof InjectedModContainer)
{
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
if (wac != null)
{
NBTTagCompound dataForWriting = wac.getDataForWriting(handler, worldInfo);
tagCompound.func_74766_a(mc.getModId(), dataForWriting);
}
}
}
}
public void handleWorldDataLoad(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
{
if (getEffectiveSide()!=Side.SERVER)
{
return;
}
if (handlerSet.contains(handler))
{
return;
}
handlerSet.add(handler);
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
worldInfo.setAdditionalProperties(additionalProperties);
for (ModContainer mc : Loader.instance().getModList())
{
if (mc instanceof InjectedModContainer)
{
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
if (wac != null)
{
wac.readData(handler, worldInfo, additionalProperties, tagCompound.func_74775_l(mc.getModId()));
}
}
}
}
}

View file

@ -15,14 +15,26 @@
package cpw.mods.fml.common;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import net.minecraft.src.NBTBase;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import net.minecraft.src.NBTTagString;
import net.minecraft.src.SaveHandler;
import net.minecraft.src.WorldInfo;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
/**
* @author cpw
*
*/
public class FMLDummyContainer extends DummyModContainer
public class FMLDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public FMLDummyContainer()
{
@ -49,4 +61,45 @@ public class FMLDummyContainer extends DummyModContainer
{
return true;
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
NBTTagCompound fmlData = new NBTTagCompound();
NBTTagList list = new NBTTagList();
for (ModContainer mc : Loader.instance().getActiveModList())
{
NBTTagCompound mod = new NBTTagCompound();
mod.func_74778_a("ModId", mc.getModId());
mod.func_74778_a("ModVersion", mc.getVersion());
list.func_74742_a(mod);
}
fmlData.func_74782_a("ModList", list);
return fmlData;
}
@Override
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
{
if (tag.func_74764_b("ModList"))
{
NBTTagList modList = tag.func_74761_m("ModList");
for (int i = 0; i < modList.func_74745_c(); i++)
{
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
String modId = mod.func_74779_i("ModId");
String modVersion = mod.func_74779_i("ModVersion");
ModContainer container = Loader.instance().getIndexedModList().get(modId);
if (container == null)
{
FMLLog.severe("This world was saved with mod %s which appears to be missing, things may not work well", modId);
continue;
}
if (!modVersion.equals(container.getVersion()))
{
FMLLog.info("This world was saved with mod %s version %s and it is now at version %s, things may not work well", modId, modVersion, container.getVersion());
}
}
}
}
}

View file

@ -117,4 +117,16 @@ public class InjectedModContainer implements ModContainer
{
return wrappedContainer.acceptableMinecraftVersionRange();
}
public WorldAccessContainer getWrappedWorldAccessContainer()
{
if (wrappedContainer instanceof WorldAccessContainer)
{
return (WorldAccessContainer) wrappedContainer;
}
else
{
return null;
}
}
}

View file

@ -0,0 +1,14 @@
package cpw.mods.fml.common;
import java.util.Map;
import net.minecraft.src.NBTBase;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.SaveHandler;
import net.minecraft.src.WorldInfo;
public interface WorldAccessContainer
{
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info);
public void readData(SaveHandler handler, WorldInfo info, Map<String,NBTBase> propertyMap, NBTTagCompound tag);
}

View file

@ -0,0 +1,59 @@
--- ../src-base/common/net/minecraft/src/SaveHandler.java
+++ ../src-work/common/net/minecraft/src/SaveHandler.java
@@ -7,6 +7,8 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Logger;
+
+import cpw.mods.fml.common.FMLCommonHandler;
public class SaveHandler implements ISaveHandler, IPlayerFileData
{
@@ -97,14 +99,16 @@
File var1 = new File(this.field_75770_b, "level.dat");
NBTTagCompound var2;
NBTTagCompound var3;
-
+ WorldInfo worldInfo = null;
if (var1.exists())
{
try
{
var2 = CompressedStreamTools.func_74796_a(new FileInputStream(var1));
var3 = var2.func_74775_l("Data");
- return new WorldInfo(var3);
+ worldInfo = new WorldInfo(var3);
+ FMLCommonHandler.instance().handleWorldDataLoad(worldInfo, var2);
+ return worldInfo;
}
catch (Exception var5)
{
@@ -120,7 +124,9 @@
{
var2 = CompressedStreamTools.func_74796_a(new FileInputStream(var1));
var3 = var2.func_74775_l("Data");
- return new WorldInfo(var3);
+ worldInfo = new WorldInfo(var3);
+ FMLCommonHandler.instance().handleWorldDataLoad(worldInfo, var2);
+ return worldInfo;
}
catch (Exception var4)
{
@@ -136,7 +142,7 @@
NBTTagCompound var3 = p_75755_1_.func_76082_a(p_75755_2_);
NBTTagCompound var4 = new NBTTagCompound();
var4.func_74782_a("Data", var3);
-
+ FMLCommonHandler.instance().handleWorldDataSave(p_75755_1_, var4);
try
{
File var5 = new File(this.field_75770_b, "level.dat_new");
@@ -174,7 +180,7 @@
NBTTagCompound var2 = p_75761_1_.func_76066_a();
NBTTagCompound var3 = new NBTTagCompound();
var3.func_74782_a("Data", var2);
-
+ FMLCommonHandler.instance().handleWorldDataSave(p_75761_1_, var3);
try
{
File var4 = new File(this.field_75770_b, "level.dat_new");

View file

@ -0,0 +1,44 @@
--- ../src-base/common/net/minecraft/src/WorldInfo.java
+++ ../src-work/common/net/minecraft/src/WorldInfo.java
@@ -1,4 +1,8 @@
package net.minecraft.src;
+
+import java.util.Map;
+
+import com.google.common.collect.Maps;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
@@ -26,6 +30,7 @@
private boolean field_76111_s;
private boolean field_76110_t;
private boolean field_76109_u;
+ private Map<String,NBTBase> additionalProperties;
protected WorldInfo()
{
@@ -372,4 +377,24 @@
{
this.field_76109_u = p_76091_1_;
}
+
+ /**
+ * Allow access to additional mod specific world based properties
+ * Used by FML to store mod list associated with a world, and maybe an id map
+ * Used by Forge to store the dimensions available to a world
+ * @param additionalProperties
+ */
+ public void setAdditionalProperties(Map<String,NBTBase> additionalProperties)
+ {
+ // one time set for this
+ if (this.additionalProperties == null)
+ {
+ this.additionalProperties = additionalProperties;
+ }
+ }
+
+ public NBTBase getAdditionalProperty(String additionalProperty)
+ {
+ return this.additionalProperties!=null? this.additionalProperties.get(additionalProperty) : null;
+ }
}