SSP Worlds updating from 1.6 will now pop a warning message before loading, and will capture a timestamped
zip file in the minecraft dir before starting to load. Allows for people to test updates.
This commit is contained in:
parent
189dc35060
commit
44a093e74b
7 changed files with 270 additions and 9 deletions
|
@ -0,0 +1,18 @@
|
||||||
|
--- ../src-base/minecraft/net/minecraft/client/gui/GuiSelectWorld.java
|
||||||
|
+++ ../src-work/minecraft/net/minecraft/client/gui/GuiSelectWorld.java
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
package net.minecraft.client.gui;
|
||||||
|
|
||||||
|
+import cpw.mods.fml.client.FMLClientHandler;
|
||||||
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
@@ -179,7 +180,7 @@
|
||||||
|
|
||||||
|
if (this.field_146297_k.func_71359_d().func_90033_f(s))
|
||||||
|
{
|
||||||
|
- this.field_146297_k.func_71371_a(s, s1, (WorldSettings)null);
|
||||||
|
+ FMLClientHandler.instance().tryLoadExistingWorld(this, s, s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,18 @@
|
||||||
package cpw.mods.fml.client;
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ExtendedServerListData {
|
public class ExtendedServerListData {
|
||||||
public final String type;
|
public final String type;
|
||||||
public final boolean isCompatible;
|
public final boolean isCompatible;
|
||||||
public final int modCount;
|
public final Map<String,String> modData;
|
||||||
public final boolean isBlocked;
|
public final boolean isBlocked;
|
||||||
|
|
||||||
public ExtendedServerListData(String type, boolean isCompatible, int modCount, boolean isBlocked)
|
public ExtendedServerListData(String type, boolean isCompatible, Map<String,String> modData, boolean isBlocked)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.isCompatible = isCompatible;
|
this.isCompatible = isCompatible;
|
||||||
this.modCount = modCount;
|
this.modData = modData;
|
||||||
this.isBlocked = isBlocked;
|
this.isBlocked = isBlocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
*/
|
*/
|
||||||
package cpw.mods.fml.client;
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -28,6 +30,7 @@ import net.minecraft.client.gui.Gui;
|
||||||
import net.minecraft.client.gui.GuiIngameMenu;
|
import net.minecraft.client.gui.GuiIngameMenu;
|
||||||
import net.minecraft.client.gui.GuiMainMenu;
|
import net.minecraft.client.gui.GuiMainMenu;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.gui.GuiSelectWorld;
|
||||||
import net.minecraft.client.gui.ServerListEntryNormal;
|
import net.minecraft.client.gui.ServerListEntryNormal;
|
||||||
import net.minecraft.client.multiplayer.GuiConnecting;
|
import net.minecraft.client.multiplayer.GuiConnecting;
|
||||||
import net.minecraft.client.multiplayer.ServerData;
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
|
@ -42,6 +45,8 @@ import net.minecraft.crash.CrashReport;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.launchwrapper.Launch;
|
import net.minecraft.launchwrapper.Launch;
|
||||||
|
import net.minecraft.nbt.CompressedStreamTools;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.network.INetHandler;
|
import net.minecraft.network.INetHandler;
|
||||||
import net.minecraft.network.NetHandlerPlayServer;
|
import net.minecraft.network.NetHandlerPlayServer;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
|
@ -56,7 +61,10 @@ import com.google.common.collect.BiMap;
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||||
import cpw.mods.fml.common.DummyModContainer;
|
import cpw.mods.fml.common.DummyModContainer;
|
||||||
|
@ -559,6 +567,46 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
playClientBlock = new CountDownLatch(1);
|
playClientBlock = new CountDownLatch(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getSavesDir()
|
||||||
|
{
|
||||||
|
return new File(client.field_71412_D, "saves");
|
||||||
|
}
|
||||||
|
public void tryLoadExistingWorld(GuiSelectWorld selectWorldGUI, String dirName, String saveName)
|
||||||
|
{
|
||||||
|
File dir = new File(getSavesDir(), dirName);
|
||||||
|
NBTTagCompound leveldat;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
leveldat = CompressedStreamTools.func_74796_a(new FileInputStream(new File(dir, "level.dat")));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
leveldat = CompressedStreamTools.func_74796_a(new FileInputStream(new File(dir, "level.dat_old")));
|
||||||
|
}
|
||||||
|
catch (Exception e1)
|
||||||
|
{
|
||||||
|
FMLLog.warning("There appears to be a problem loading the save %s, both level files are unreadable.", dirName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NBTTagCompound fmlData = leveldat.func_74775_l("FML");
|
||||||
|
if (fmlData.func_74764_b("ModItemData"))
|
||||||
|
{
|
||||||
|
showGuiScreen(new GuiOldSaveLoadConfirm(dirName, saveName, selectWorldGUI));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
launchIntegratedServerCallback(dirName, saveName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void launchIntegratedServerCallback(String dirName, String saveName)
|
||||||
|
{
|
||||||
|
client.func_71371_a(dirName, saveName, (WorldSettings)null);
|
||||||
|
}
|
||||||
|
|
||||||
public void showInGameModOptions(GuiIngameMenu guiIngameMenu)
|
public void showInGameModOptions(GuiIngameMenu guiIngameMenu)
|
||||||
{
|
{
|
||||||
showGuiScreen(new GuiIngameModOptions(guiIngameMenu));
|
showGuiScreen(new GuiIngameModOptions(guiIngameMenu));
|
||||||
|
@ -590,9 +638,16 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
{
|
{
|
||||||
JsonObject jsonData = extraServerListData.get(originalResponse);
|
JsonObject jsonData = extraServerListData.get(originalResponse);
|
||||||
String type = jsonData.get("type").getAsString();
|
String type = jsonData.get("type").getAsString();
|
||||||
int modCount = jsonData.get("modList").getAsJsonArray().size();
|
JsonArray modDataArray = jsonData.get("modList").getAsJsonArray();
|
||||||
boolean moddedClientAllowed = jsonData.has("clientModsAllowed") ? jsonData.get("clientModsAllowed").getAsBoolean() : true;
|
boolean moddedClientAllowed = jsonData.has("clientModsAllowed") ? jsonData.get("clientModsAllowed").getAsBoolean() : true;
|
||||||
serverDataTag.put(data, new ExtendedServerListData(type, true, modCount, !moddedClientAllowed));
|
Builder<String, String> modListBldr = ImmutableMap.<String,String>builder();
|
||||||
|
for (JsonElement obj : modDataArray)
|
||||||
|
{
|
||||||
|
JsonObject modObj = obj.getAsJsonObject();
|
||||||
|
modListBldr.put(modObj.get("modid").getAsString(), modObj.get("version").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
serverDataTag.put(data, new ExtendedServerListData(type, true, modListBldr.build(), !moddedClientAllowed));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -602,7 +657,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
{
|
{
|
||||||
moddedClientAllowed = !serverDescription.endsWith(":NOFML§r");
|
moddedClientAllowed = !serverDescription.endsWith(":NOFML§r");
|
||||||
}
|
}
|
||||||
serverDataTag.put(data, new ExtendedServerListData("VANILLA", false, -1, !moddedClientAllowed));
|
serverDataTag.put(data, new ExtendedServerListData("VANILLA", false, ImmutableMap.<String,String>of(), !moddedClientAllowed));
|
||||||
}
|
}
|
||||||
startupConnectionData.countDown();
|
startupConnectionData.countDown();
|
||||||
}
|
}
|
||||||
|
@ -621,12 +676,12 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
if ("FML".equals(extendedData.type) && extendedData.isCompatible)
|
if ("FML".equals(extendedData.type) && extendedData.isCompatible)
|
||||||
{
|
{
|
||||||
idx = 0;
|
idx = 0;
|
||||||
tooltip = String.format("Compatible FML modded server\n%d mods present", extendedData.modCount);
|
tooltip = String.format("Compatible FML modded server\n%d mods present", extendedData.modData.size());
|
||||||
}
|
}
|
||||||
else if ("FML".equals(extendedData.type) && !extendedData.isCompatible)
|
else if ("FML".equals(extendedData.type) && !extendedData.isCompatible)
|
||||||
{
|
{
|
||||||
idx = 16;
|
idx = 16;
|
||||||
tooltip = String.format("Incompatible FML modded server\n%d mods present", extendedData.modCount);
|
tooltip = String.format("Incompatible FML modded server\n%d mods present", extendedData.modData.size());
|
||||||
}
|
}
|
||||||
else if ("BUKKIT".equals(extendedData.type))
|
else if ("BUKKIT".equals(extendedData.type))
|
||||||
{
|
{
|
||||||
|
|
55
fml/src/main/java/cpw/mods/fml/client/GuiBackupFailed.java
Normal file
55
fml/src/main/java/cpw/mods/fml/client/GuiBackupFailed.java
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Forge Mod Loader
|
||||||
|
* Copyright (c) 2012-2013 cpw.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Lesser Public License v2.1
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* cpw - implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
|
||||||
|
public class GuiBackupFailed extends GuiScreen
|
||||||
|
{
|
||||||
|
private GuiScreen parent;
|
||||||
|
private File zipName;
|
||||||
|
public GuiBackupFailed(GuiScreen parent, File zipName)
|
||||||
|
{
|
||||||
|
this.parent = parent;
|
||||||
|
this.zipName = zipName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void func_73866_w_()
|
||||||
|
{
|
||||||
|
this.field_146292_n.add(new GuiButton(1, this.field_146294_l / 2 - 75, this.field_146295_m - 38, I18n.func_135052_a("gui.done")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void func_146284_a(GuiButton p_73875_1_)
|
||||||
|
{
|
||||||
|
if (p_73875_1_.field_146124_l && p_73875_1_.field_146127_k == 1)
|
||||||
|
{
|
||||||
|
FMLClientHandler.instance().showGuiScreen(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||||
|
{
|
||||||
|
this.func_146276_q_();
|
||||||
|
int offset = Math.max(85 - 2 * 10, 10);
|
||||||
|
this.func_73732_a(this.field_146289_q, String.format("There was an error saving the archive %s", zipName.getName()), this.field_146294_l / 2, offset, 0xFFFFFF);
|
||||||
|
offset += 10;
|
||||||
|
this.func_73732_a(this.field_146289_q, String.format("Please fix the problem and try again"), this.field_146294_l / 2, offset, 0xFFFFFF);
|
||||||
|
super.func_73863_a(p_73863_1_, p_73863_2_, p_73863_3_);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiLabel;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.gui.GuiSelectWorld;
|
||||||
|
import net.minecraft.client.gui.GuiYesNo;
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
import cpw.mods.fml.common.FMLLog;
|
||||||
|
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||||
|
import cpw.mods.fml.common.ZipperUtil;
|
||||||
|
|
||||||
|
public class GuiOldSaveLoadConfirm extends GuiYesNo {
|
||||||
|
|
||||||
|
private String dirName;
|
||||||
|
private String saveName;
|
||||||
|
private File zip;
|
||||||
|
public GuiOldSaveLoadConfirm(String dirName, String saveName, GuiScreen parent)
|
||||||
|
{
|
||||||
|
super(parent, "", "", 0);
|
||||||
|
this.dirName = dirName;
|
||||||
|
this.saveName = saveName;
|
||||||
|
this.zip = new File(FMLClientHandler.instance().getClient().field_71412_D,String.format("%s-%2$td%2$tm%2$ty%2$tH%2$tM%2$tS.zip", saveName, System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||||
|
{
|
||||||
|
this.func_146276_q_();
|
||||||
|
this.func_73732_a(this.field_146289_q, String.format("The world %s contains pre-update modding data", saveName), this.field_146294_l / 2, 50, 16777215);
|
||||||
|
this.func_73732_a(this.field_146289_q, String.format("There may be problems updating it to this version"), this.field_146294_l / 2, 70, 16777215);
|
||||||
|
this.func_73732_a(this.field_146289_q, String.format("FML will save a zip to %s", zip.getName()), this.field_146294_l / 2, 90, 16777215);
|
||||||
|
this.func_73732_a(this.field_146289_q, String.format("Do you wish to continue loading?"), this.field_146294_l / 2, 110, 16777215);
|
||||||
|
int k;
|
||||||
|
|
||||||
|
for (k = 0; k < this.field_146292_n.size(); ++k)
|
||||||
|
{
|
||||||
|
((GuiButton)this.field_146292_n.get(k)).func_146112_a(this.field_146297_k, p_73863_1_, p_73863_2_);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < this.field_146293_o.size(); ++k)
|
||||||
|
{
|
||||||
|
((GuiLabel)this.field_146293_o.get(k)).func_146159_a(this.field_146297_k, p_73863_1_, p_73863_2_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void func_146284_a(GuiButton p_146284_1_)
|
||||||
|
{
|
||||||
|
if (p_146284_1_.field_146127_k == 1)
|
||||||
|
{
|
||||||
|
ObfuscationReflectionHelper.setPrivateValue(GuiSelectWorld.class, (GuiSelectWorld)field_146355_a, false, "field_"+"146634_i");
|
||||||
|
FMLClientHandler.instance().showGuiScreen(field_146355_a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FMLLog.info("Capturing current state of world %s into file %s", saveName, zip.getAbsolutePath());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ZipperUtil.zip(new File(FMLClientHandler.instance().getSavesDir(), dirName), zip);
|
||||||
|
} catch (IOException e)
|
||||||
|
{
|
||||||
|
FMLLog.log(Level.WARN, e, "There was a problem saving the backup %s. Please fix and try again", zip.getName());
|
||||||
|
FMLClientHandler.instance().showGuiScreen(new GuiBackupFailed(field_146355_a, zip));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FMLClientHandler.instance().showGuiScreen(null);
|
||||||
|
FMLClientHandler.instance().launchIntegratedServerCallback(dirName, saveName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -371,7 +371,7 @@ public class FMLCommonHandler
|
||||||
}
|
}
|
||||||
handlerSet.add(handler);
|
handlerSet.add(handler);
|
||||||
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
|
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
|
||||||
// worldInfo.setAdditionalProperties(additionalProperties);
|
worldInfo.setAdditionalProperties(additionalProperties);
|
||||||
for (ModContainer mc : Loader.instance().getModList())
|
for (ModContainer mc : Loader.instance().getModList())
|
||||||
{
|
{
|
||||||
if (mc instanceof InjectedModContainer)
|
if (mc instanceof InjectedModContainer)
|
||||||
|
|
58
fml/src/main/java/cpw/mods/fml/common/ZipperUtil.java
Normal file
58
fml/src/main/java/cpw/mods/fml/common/ZipperUtil.java
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copied from http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure
|
||||||
|
* because the code looked very tidy and neat. Thanks, McDowell!
|
||||||
|
*
|
||||||
|
* @author McDowell
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ZipperUtil {
|
||||||
|
public static void zip(File directory, File zipfile) throws IOException
|
||||||
|
{
|
||||||
|
URI base = directory.toURI();
|
||||||
|
Deque<File> queue = new LinkedList<File>();
|
||||||
|
queue.push(directory);
|
||||||
|
OutputStream out = new FileOutputStream(zipfile);
|
||||||
|
Closeable res = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ZipOutputStream zout = new ZipOutputStream(out);
|
||||||
|
res = zout;
|
||||||
|
while (!queue.isEmpty())
|
||||||
|
{
|
||||||
|
directory = queue.pop();
|
||||||
|
for (File kid : directory.listFiles())
|
||||||
|
{
|
||||||
|
String name = base.relativize(kid.toURI()).getPath();
|
||||||
|
if (kid.isDirectory())
|
||||||
|
{
|
||||||
|
queue.push(kid);
|
||||||
|
name = name.endsWith("/") ? name : name + "/";
|
||||||
|
zout.putNextEntry(new ZipEntry(name));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
zout.putNextEntry(new ZipEntry(name));
|
||||||
|
Files.copy(kid, zout);
|
||||||
|
zout.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
res.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue