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:
parent
a554846e57
commit
550e622bc7
6 changed files with 236 additions and 1 deletions
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
fml/common/cpw/mods/fml/common/WorldAccessContainer.java
Normal file
14
fml/common/cpw/mods/fml/common/WorldAccessContainer.java
Normal 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);
|
||||
}
|
59
fml/patches/common/net/minecraft/src/SaveHandler.java.patch
Normal file
59
fml/patches/common/net/minecraft/src/SaveHandler.java.patch
Normal 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");
|
44
fml/patches/common/net/minecraft/src/WorldInfo.java.patch
Normal file
44
fml/patches/common/net/minecraft/src/WorldInfo.java.patch
Normal 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;
|
||||
+ }
|
||||
}
|
Loading…
Reference in a new issue