mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #30 - Fixed various client bugs
This commit is contained in:
@ -49,6 +49,10 @@ public class Display {
|
||||
PlatformInput.setVSync(enable);
|
||||
}
|
||||
|
||||
public static boolean isVSyncSupported() {
|
||||
return PlatformInput.isVSyncSupported();
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
PlatformInput.update();
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ public class EaglercraftVersion {
|
||||
/// Customize these to fit your fork:
|
||||
|
||||
public static final String projectForkName = "EaglercraftX";
|
||||
public static final String projectForkVersion = "u29";
|
||||
public static final String projectForkVersion = "u30";
|
||||
public static final String projectForkVendor = "lax1dude";
|
||||
|
||||
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
|
||||
@ -20,7 +20,7 @@ public class EaglercraftVersion {
|
||||
public static final String projectOriginName = "EaglercraftX";
|
||||
public static final String projectOriginAuthor = "lax1dude";
|
||||
public static final String projectOriginRevision = "1.8";
|
||||
public static final String projectOriginVersion = "u29";
|
||||
public static final String projectOriginVersion = "u30";
|
||||
|
||||
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
|
||||
|
||||
@ -31,7 +31,7 @@ public class EaglercraftVersion {
|
||||
public static final boolean enableUpdateService = true;
|
||||
|
||||
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
|
||||
public static final int updateBundlePackageVersionInt = 29;
|
||||
public static final int updateBundlePackageVersionInt = 30;
|
||||
|
||||
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;
|
||||
|
||||
@ -60,4 +60,6 @@ public class EaglercraftVersion {
|
||||
|
||||
public static final boolean forceDemoMode = false;
|
||||
|
||||
public static final String localStorageNamespace = "_eaglercraftX";
|
||||
|
||||
}
|
||||
|
@ -69,4 +69,11 @@ public interface IClientConfigAdapter {
|
||||
boolean isEnableSignatureBadge();
|
||||
|
||||
boolean isAllowVoiceClient();
|
||||
|
||||
boolean isAllowFNAWSkins();
|
||||
|
||||
String getLocalStorageNamespace();
|
||||
|
||||
IClientConfigAdapterHooks getHooks();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public interface IClientConfigAdapterHooks {
|
||||
|
||||
void callLocalStorageSavedHook(String key, String base64);
|
||||
|
||||
String callLocalStorageLoadHook(String key);
|
||||
|
||||
}
|
@ -13,6 +13,21 @@ import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.client.resources.IResourceManagerReloadListener;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class BlockVertexIDs implements IResourceManagerReloadListener {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("BlockVertexIDsCSV");
|
||||
|
@ -61,7 +61,7 @@ public class EaglerSkinTexture implements ITextureObject {
|
||||
}
|
||||
System.arraycopy(pixels, 0, this.pixels, 0, pixels.length);
|
||||
if(textureId != -1) {
|
||||
TextureUtil.uploadTextureImageAllocate(textureId, new ImageData(width, height, pixels, true), false, false);
|
||||
TextureUtil.uploadTextureImageSub(textureId, new ImageData(width, height, pixels, true), 0, 0, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,14 +73,20 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
}
|
||||
|
||||
private void updateOptions() {
|
||||
DefaultSkins[] arr = DefaultSkins.defaultSkinsMap;
|
||||
if(!EagRuntime.getConfiguration().isAllowFNAWSkins()) {
|
||||
DefaultSkins[] arrNoFNAW = new DefaultSkins[arr.length - 5];
|
||||
System.arraycopy(arr, 0, arrNoFNAW, 0, arrNoFNAW.length);
|
||||
arr = arrNoFNAW;
|
||||
}
|
||||
int numCustom = EaglerProfile.customSkins.size();
|
||||
String[] n = new String[numCustom + DefaultSkins.defaultSkinsMap.length];
|
||||
String[] n = new String[numCustom + arr.length];
|
||||
for(int i = 0; i < numCustom; ++i) {
|
||||
n[i] = EaglerProfile.customSkins.get(i).name;
|
||||
}
|
||||
int numDefault = DefaultSkins.defaultSkinsMap.length;
|
||||
int numDefault = arr.length;
|
||||
for(int j = 0; j < numDefault; ++j) {
|
||||
n[numCustom + j] = DefaultSkins.defaultSkinsMap[j].name;
|
||||
n[numCustom + j] = arr[j].name;
|
||||
}
|
||||
dropDownOptions = n;
|
||||
}
|
||||
@ -106,6 +112,10 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
GlStateManager.translate(skinX + 2, skinY - 9, 0.0f);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
if(selectedSlot > dropDownOptions.length - 1) {
|
||||
selectedSlot = 0;
|
||||
}
|
||||
|
||||
int numberOfCustomSkins = EaglerProfile.customSkins.size();
|
||||
int skid = selectedSlot - numberOfCustomSkins;
|
||||
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model : DefaultSkins.getSkinFromId(skid).model;
|
||||
|
@ -56,11 +56,15 @@ public class GuiScreenImportExportProfile extends GuiScreen {
|
||||
FileChooserResult result = EagRuntime.getFileChooserResult();
|
||||
if(result != null) {
|
||||
mc.loadingScreen.eaglerShow(I18n.format("settingsBackup.importing.1"), "settingsBackup.importing.2");
|
||||
ProfileImporter importer = new ProfileImporter(result.fileData);
|
||||
try {
|
||||
ProfileImporter importer = new ProfileImporter(result.fileData);
|
||||
importer.readHeader();
|
||||
mc.displayGuiScreen(new GuiScreenImportProfile(importer, back));
|
||||
}catch(IOException ex) {
|
||||
try {
|
||||
importer.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
EagRuntime.debugPrintStackTrace(ex);
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("settingsBackup.importing.failed.1", "settingsBackup.importing.failed.2", back));
|
||||
}
|
||||
|
@ -62,6 +62,14 @@ public class GuiScreenImportProfile extends GuiScreen {
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 140, I18n.format("gui.cancel")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
try {
|
||||
importer.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if(!doImportProfile && !doImportSettings && !doImportServers && !doImportResourcePacks) {
|
||||
|
@ -69,98 +69,97 @@ public class ProfileExporter {
|
||||
osb.write(new byte[]{(byte)255,(byte)255,(byte)255,(byte)255}); // this will be replaced with the file count
|
||||
|
||||
osb.write('G');
|
||||
OutputStream os = EaglerZLIB.newGZIPOutputStream(osb);
|
||||
|
||||
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
|
||||
os.write(new byte[]{(byte)9,(byte)102,(byte)105,(byte)108,(byte)101,(byte)45,(byte)116,(byte)121,
|
||||
(byte)112,(byte)101}); // 9 + file-type
|
||||
os.write(new byte[]{(byte)0,(byte)0,(byte)0,(byte)14,(byte)101,(byte)112,(byte)107,(byte)47,(byte)112,(byte)114,(byte)111,
|
||||
(byte)102,(byte)105,(byte)108,(byte)101,(byte)49,(byte)56,(byte)56}); // 14 + epk/profile188
|
||||
os.write('>');
|
||||
|
||||
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
|
||||
os.write(new byte[]{(byte)12,(byte)102,(byte)105,(byte)108,(byte)101,(byte)45,(byte)101,(byte)120,
|
||||
(byte)112,(byte)111,(byte)114,(byte)116,(byte)115,(byte)0,(byte)0,(byte)0,(byte)1}); // 12 + file-exports + 1
|
||||
os.write((doExportProfile ? 1 : 0) | (doExportSettings ? 2 : 0) | (doExportServers ? 4 : 0) | (doExportResourcePacks ? 8 : 0));
|
||||
os.write('>');
|
||||
|
||||
int fileCount = 2;
|
||||
|
||||
if(doExportProfile) {
|
||||
byte[] profileData = EaglerProfile.write();
|
||||
if(profileData == null) {
|
||||
throw new IOException("Could not write profile data!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.p", profileData, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
if(doExportSettings) {
|
||||
logger.info("Exporting game settings...");
|
||||
byte[] gameSettings = Minecraft.getMinecraft().gameSettings.writeOptions();
|
||||
if(gameSettings == null) {
|
||||
throw new IOException("Could not write game settings!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.g", gameSettings, os);
|
||||
++fileCount;
|
||||
logger.info("Exporting relay settings...");
|
||||
byte[] relays = RelayManager.relayManager.write();
|
||||
if(relays == null) {
|
||||
throw new IOException("Could not write relay settings!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.r", relays, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
if(doExportServers) {
|
||||
logger.info("Exporting server list...");
|
||||
byte[] servers = ServerList.getServerList().writeServerList();
|
||||
if(servers == null) {
|
||||
throw new IOException("Could not write server list!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.s", servers, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
logger.info("Exporting certificates...");
|
||||
UpdateCertificate cert = UpdateService.getClientCertificate();
|
||||
if(cert != null) {
|
||||
exportFileToEPK("certs/main.cert", cert.rawCertData, os);
|
||||
++fileCount;
|
||||
}
|
||||
Collection<UpdateCertificate> updatesExport = UpdateService.getAvailableUpdates();
|
||||
int cc = 0;
|
||||
for(UpdateCertificate cert2 : updatesExport) {
|
||||
exportFileToEPK("certs/c" + (cc++) + ".cert", cert2.rawCertData, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
if(doExportResourcePacks) {
|
||||
logger.info("Exporting resource packs...");
|
||||
byte[] packManifest = (new VFile2(EaglerFolderResourcePack.RESOURCE_PACKS + "/manifest.json")).getAllBytes();
|
||||
if(packManifest != null) {
|
||||
exportFileToEPK(EaglerFolderResourcePack.RESOURCE_PACKS + "/manifest.json", packManifest, os);
|
||||
try(OutputStream os = EaglerZLIB.newGZIPOutputStream(osb)) {
|
||||
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
|
||||
os.write(new byte[]{(byte)9,(byte)102,(byte)105,(byte)108,(byte)101,(byte)45,(byte)116,(byte)121,
|
||||
(byte)112,(byte)101}); // 9 + file-type
|
||||
os.write(new byte[]{(byte)0,(byte)0,(byte)0,(byte)14,(byte)101,(byte)112,(byte)107,(byte)47,(byte)112,(byte)114,(byte)111,
|
||||
(byte)102,(byte)105,(byte)108,(byte)101,(byte)49,(byte)56,(byte)56}); // 14 + epk/profile188
|
||||
os.write('>');
|
||||
|
||||
os.write(new byte[]{(byte)72,(byte)69,(byte)65,(byte)68}); // HEAD
|
||||
os.write(new byte[]{(byte)12,(byte)102,(byte)105,(byte)108,(byte)101,(byte)45,(byte)101,(byte)120,
|
||||
(byte)112,(byte)111,(byte)114,(byte)116,(byte)115,(byte)0,(byte)0,(byte)0,(byte)1}); // 12 + file-exports + 1
|
||||
os.write((doExportProfile ? 1 : 0) | (doExportSettings ? 2 : 0) | (doExportServers ? 4 : 0) | (doExportResourcePacks ? 8 : 0));
|
||||
os.write('>');
|
||||
|
||||
|
||||
if(doExportProfile) {
|
||||
byte[] profileData = EaglerProfile.write();
|
||||
if(profileData == null) {
|
||||
throw new IOException("Could not write profile data!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.p", profileData, os);
|
||||
++fileCount;
|
||||
VFile2 baseDir = new VFile2(EaglerFolderResourcePack.RESOURCE_PACKS);
|
||||
List<VFile2> files = baseDir.listFiles(true);
|
||||
logger.info("({} files to export)", files.size());
|
||||
for(int i = 0, l = files.size(); i < l; ++i) {
|
||||
VFile2 f = files.get(i);
|
||||
if(f.getPath().equals(EaglerFolderResourcePack.RESOURCE_PACKS + "/manifest.json")) {
|
||||
continue;
|
||||
}
|
||||
exportFileToEPK(f.getPath(), f.getAllBytes(), os);
|
||||
}
|
||||
|
||||
if(doExportSettings) {
|
||||
logger.info("Exporting game settings...");
|
||||
byte[] gameSettings = Minecraft.getMinecraft().gameSettings.writeOptions();
|
||||
if(gameSettings == null) {
|
||||
throw new IOException("Could not write game settings!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.g", gameSettings, os);
|
||||
++fileCount;
|
||||
logger.info("Exporting relay settings...");
|
||||
byte[] relays = RelayManager.relayManager.write();
|
||||
if(relays == null) {
|
||||
throw new IOException("Could not write relay settings!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.r", relays, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
if(doExportServers) {
|
||||
logger.info("Exporting server list...");
|
||||
byte[] servers = ServerList.getServerList().writeServerList();
|
||||
if(servers == null) {
|
||||
throw new IOException("Could not write server list!");
|
||||
}
|
||||
exportFileToEPK("_eaglercraftX.s", servers, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
logger.info("Exporting certificates...");
|
||||
UpdateCertificate cert = UpdateService.getClientCertificate();
|
||||
if(cert != null) {
|
||||
exportFileToEPK("certs/main.cert", cert.rawCertData, os);
|
||||
++fileCount;
|
||||
}
|
||||
Collection<UpdateCertificate> updatesExport = UpdateService.getAvailableUpdates();
|
||||
int cc = 0;
|
||||
for(UpdateCertificate cert2 : updatesExport) {
|
||||
exportFileToEPK("certs/c" + (cc++) + ".cert", cert2.rawCertData, os);
|
||||
++fileCount;
|
||||
}
|
||||
|
||||
if(doExportResourcePacks) {
|
||||
logger.info("Exporting resource packs...");
|
||||
byte[] packManifest = (new VFile2(EaglerFolderResourcePack.RESOURCE_PACKS + "/manifest.json")).getAllBytes();
|
||||
if(packManifest != null) {
|
||||
exportFileToEPK(EaglerFolderResourcePack.RESOURCE_PACKS + "/manifest.json", packManifest, os);
|
||||
++fileCount;
|
||||
if(i > 0 && i % 100 == 0) {
|
||||
logger.info("Exported {} files", i);
|
||||
VFile2 baseDir = new VFile2(EaglerFolderResourcePack.RESOURCE_PACKS);
|
||||
List<VFile2> files = baseDir.listFiles(true);
|
||||
logger.info("({} files to export)", files.size());
|
||||
for(int i = 0, l = files.size(); i < l; ++i) {
|
||||
VFile2 f = files.get(i);
|
||||
if(f.getPath().equals(EaglerFolderResourcePack.RESOURCE_PACKS + "/manifest.json")) {
|
||||
continue;
|
||||
}
|
||||
exportFileToEPK(f.getPath(), f.getAllBytes(), os);
|
||||
++fileCount;
|
||||
if(i > 0 && i % 100 == 0) {
|
||||
logger.info("Exported {} files", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os.write(new byte[]{(byte)69,(byte)78,(byte)68,(byte)36}); // END$
|
||||
}
|
||||
|
||||
os.write(new byte[]{(byte)69,(byte)78,(byte)68,(byte)36}); // END$
|
||||
os.close();
|
||||
|
||||
osb.write(new byte[]{(byte)58,(byte)58,(byte)58,(byte)89,(byte)69,(byte)69,(byte)58,(byte)62}); // :::YEE:>
|
||||
|
||||
byte[] ret = osb.toByteArray();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
@ -29,7 +30,7 @@ import net.minecraft.client.multiplayer.ServerList;
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class ProfileImporter {
|
||||
public class ProfileImporter implements Closeable {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("ProfileImporter");
|
||||
|
||||
@ -148,4 +149,9 @@ public class ProfileImporter {
|
||||
}
|
||||
logger.info("Import complete!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
epkDecompiler.close();
|
||||
}
|
||||
}
|
||||
|
@ -468,4 +468,13 @@ public class RenderHighPoly extends RenderPlayer {
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public void renderLivingAt(AbstractClientPlayer abstractclientplayer, double d0, double d1, double d2) {
|
||||
if (abstractclientplayer.isEntityAlive() && abstractclientplayer.isPlayerSleeping()) {
|
||||
super.renderLivingAt(abstractclientplayer, d0 - (double) abstractclientplayer.renderOffsetX,
|
||||
d1 - (double) abstractclientplayer.renderOffsetY, d2 - (double) abstractclientplayer.renderOffsetZ);
|
||||
} else {
|
||||
super.renderLivingAt(abstractclientplayer, d0, d1, d2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public enum SkinModel {
|
||||
private SkinModel(int id, HighPolySkin highPoly) {
|
||||
this.id = id;
|
||||
this.width = 256;
|
||||
this.height = 128;
|
||||
this.height = 256;
|
||||
this.profileSkinType = "eagler";
|
||||
this.sanitize = true;
|
||||
this.highPoly = highPoly;
|
||||
|
@ -156,7 +156,6 @@ public class GuiShareToLan extends GuiScreen {
|
||||
this.mc.ingameGUI.getChatGUI().printChatMessage(new ChatComponentText(I18n.format("lanServer.opened")
|
||||
.replace("$relay$", LANServerController.getCurrentURI()).replace("$code$", code)));
|
||||
} else {
|
||||
SingleplayerServerController.configureLAN(mc.theWorld.getWorldInfo().getGameType(), false);
|
||||
this.mc.displayGuiScreen(new GuiScreenNoRelays(this, "noRelay.titleFail"));
|
||||
}
|
||||
}
|
||||
|
@ -340,9 +340,11 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
||||
}
|
||||
EaglerInputStream bi = new EaglerInputStream(fullData);
|
||||
int i = (bi.read() << 24) | (bi.read() << 16) | (bi.read() << 8) | bi.read();
|
||||
InputStream inflaterInputStream = EaglerZLIB.newInflaterInputStream(bi);
|
||||
fullData = new byte[i];
|
||||
int r = IOUtils.readFully(inflaterInputStream, fullData);
|
||||
int r;
|
||||
try(InputStream inflaterInputStream = EaglerZLIB.newInflaterInputStream(bi)) {
|
||||
r = IOUtils.readFully(inflaterInputStream, fullData);
|
||||
}
|
||||
if (i != r) {
|
||||
logger.warn("Decompressed packet expected size {} differs from actual size {}!", i, r);
|
||||
}
|
||||
|
@ -479,7 +479,7 @@ public class EaglerIntegratedServerWorker {
|
||||
|
||||
while(true) {
|
||||
mainLoop();
|
||||
EagUtils.sleep(1l);
|
||||
EagUtils.sleep(0l);
|
||||
}
|
||||
}catch(Throwable tt) {
|
||||
if(tt instanceof ReportedException) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.sp.server.export;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
@ -24,7 +25,7 @@ import net.lax1dude.eaglercraft.v1_8.IOUtils;
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EPKDecompiler {
|
||||
public class EPKDecompiler implements Closeable {
|
||||
|
||||
public static class FileEntry {
|
||||
public final String type;
|
||||
@ -178,4 +179,9 @@ public class EPKDecompiler {
|
||||
return new String(charIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
zis.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,44 +40,45 @@ public class WorldConverterEPK {
|
||||
folderName += "_";
|
||||
worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
}
|
||||
EPKDecompiler dc = new EPKDecompiler(archiveContents);
|
||||
EPKDecompiler.FileEntry f = null;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
String hasReadType = null;
|
||||
boolean has152Format = false;
|
||||
int cnt = 0;
|
||||
while((f = dc.readFile()) != null) {
|
||||
byte[] b = f.data;
|
||||
if(hasReadType == null) {
|
||||
if (f.type.equals("HEAD") && f.name.equals("file-type")
|
||||
&& ((hasReadType = EPKDecompiler.readASCII(f.data)).equals("epk/world188")
|
||||
|| (has152Format = hasReadType.equals("epk/world152")))) {
|
||||
if(has152Format) {
|
||||
logger.warn("World type detected as 1.5.2, it will be converted to 1.8.8 format");
|
||||
try(EPKDecompiler dc = new EPKDecompiler(archiveContents)) {
|
||||
EPKDecompiler.FileEntry f = null;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
String hasReadType = null;
|
||||
boolean has152Format = false;
|
||||
int cnt = 0;
|
||||
while((f = dc.readFile()) != null) {
|
||||
byte[] b = f.data;
|
||||
if(hasReadType == null) {
|
||||
if (f.type.equals("HEAD") && f.name.equals("file-type")
|
||||
&& ((hasReadType = EPKDecompiler.readASCII(f.data)).equals("epk/world188")
|
||||
|| (has152Format = hasReadType.equals("epk/world152")))) {
|
||||
if(has152Format) {
|
||||
logger.warn("World type detected as 1.5.2, it will be converted to 1.8.8 format");
|
||||
}
|
||||
continue;
|
||||
}else {
|
||||
throw new IOException("file does not contain a singleplayer 1.5.2 or 1.8.8 world!");
|
||||
}
|
||||
continue;
|
||||
}else {
|
||||
throw new IOException("file does not contain a singleplayer 1.5.2 or 1.8.8 world!");
|
||||
}
|
||||
}
|
||||
if(f.type.equals("FILE")) {
|
||||
if(f.name.equals("level.dat") || f.name.equals("level.dat_old")) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
|
||||
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
|
||||
EaglerOutputStream tmp = new EaglerOutputStream();
|
||||
CompressedStreamTools.writeCompressed(worldDatNBT, tmp);
|
||||
b = tmp.toByteArray();
|
||||
}
|
||||
VFile2 ff = new VFile2(worldDir, f.name);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
++cnt;
|
||||
if(prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
logger.info("Extracted {} files, {} bytes from EPK...", cnt, prog);
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.1", prog);
|
||||
if(f.type.equals("FILE")) {
|
||||
if(f.name.equals("level.dat") || f.name.equals("level.dat_old")) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
|
||||
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
|
||||
EaglerOutputStream tmp = new EaglerOutputStream();
|
||||
CompressedStreamTools.writeCompressed(worldDatNBT, tmp);
|
||||
b = tmp.toByteArray();
|
||||
}
|
||||
VFile2 ff = new VFile2(worldDir, f.name);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
++cnt;
|
||||
if(prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
logger.info("Extracted {} files, {} bytes from EPK...", cnt, prog);
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.1", prog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,111 +50,113 @@ public class WorldConverterMCA {
|
||||
folderName += "_";
|
||||
worldDir = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
}
|
||||
ZipInputStream zis = new ZipInputStream(new EaglerInputStream(archiveContents));
|
||||
ZipEntry folderNameFile = null;
|
||||
List<char[]> fileNames = new ArrayList<>();
|
||||
while((folderNameFile = zis.getNextEntry()) != null) {
|
||||
if (folderNameFile.getName().contains("__MACOSX/")) continue;
|
||||
if (folderNameFile.isDirectory()) continue;
|
||||
String lowerName = folderNameFile.getName().toLowerCase();
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr"))) continue;
|
||||
fileNames.add(folderNameFile.getName().toCharArray());
|
||||
try(ZipInputStream zis = new ZipInputStream(new EaglerInputStream(archiveContents))) {
|
||||
ZipEntry folderNameFile = null;
|
||||
while((folderNameFile = zis.getNextEntry()) != null) {
|
||||
if (folderNameFile.getName().contains("__MACOSX/")) continue;
|
||||
if (folderNameFile.isDirectory()) continue;
|
||||
String lowerName = folderNameFile.getName().toLowerCase();
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr"))) continue;
|
||||
fileNames.add(folderNameFile.getName().toCharArray());
|
||||
}
|
||||
}
|
||||
final int[] i = new int[] { 0 };
|
||||
while(fileNames.get(0).length > i[0] && fileNames.stream().allMatch(w -> w[i[0]] == fileNames.get(0)[i[0]])) i[0]++;
|
||||
int folderPrefixOffset = i[0];
|
||||
zis = new ZipInputStream(new EaglerInputStream(archiveContents));
|
||||
ZipEntry f = null;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
byte[] bb = new byte[16384];
|
||||
while ((f = zis.getNextEntry()) != null) {
|
||||
if (f.getName().contains("__MACOSX/")) continue;
|
||||
if (f.isDirectory()) continue;
|
||||
String lowerName = f.getName().toLowerCase();
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr") || lowerName.endsWith(".bmp"))) continue;
|
||||
EaglerOutputStream baos = new EaglerOutputStream();
|
||||
int len;
|
||||
while ((len = zis.read(bb)) != -1) {
|
||||
baos.write(bb, 0, len);
|
||||
}
|
||||
baos.close();
|
||||
byte[] b = baos.toByteArray();
|
||||
String fileName = f.getName().substring(folderPrefixOffset);
|
||||
if (fileName.equals("level.dat") || fileName.equals("level.dat_old")) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
|
||||
NBTTagCompound gameRulesNBT = worldDatNBT.getCompoundTag("Data").getCompoundTag("GameRules");
|
||||
gameRulesNBT.setString("loadSpawnChunks", (gameRules & 2) != 0 ? "true" : "false");
|
||||
String s = (gameRules & 1) != 0 ? "true" : "false";
|
||||
gameRulesNBT.setString("bedSpawnPoint", s);
|
||||
gameRulesNBT.setString("clickToRide", "false");
|
||||
gameRulesNBT.setString("clickToSit", s);
|
||||
gameRulesNBT.setString("colorCodes", s);
|
||||
gameRulesNBT.setString("doSignEditing", s);
|
||||
worldDatNBT.getCompoundTag("Data").setTag("GameRules", gameRulesNBT);
|
||||
|
||||
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
|
||||
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
|
||||
EaglerOutputStream bo = new EaglerOutputStream();
|
||||
CompressedStreamTools.writeCompressed(worldDatNBT, bo);
|
||||
b = bo.toByteArray();
|
||||
VFile2 ff = new VFile2(worldDir, fileName);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
} else if ((fileName.endsWith(".mcr") || fileName.endsWith(".mca")) && (fileName.startsWith("region/") || fileName.startsWith("DIM1/region/") || fileName.startsWith("DIM-1/region/"))) {
|
||||
VFile2 chunkFolder = new VFile2(worldDir, fileName.startsWith("DIM1") ? "level1" : (fileName.startsWith("DIM-1") ? "level-1" : "level0"));
|
||||
RegionFile mca = new RegionFile(new RandomAccessMemoryFile(b, b.length));
|
||||
int loadChunksCount = 0;
|
||||
for(int j = 0; j < 32; ++j) {
|
||||
for(int k = 0; k < 32; ++k) {
|
||||
if(mca.isChunkSaved(j, k)) {
|
||||
NBTTagCompound chunkNBT;
|
||||
NBTTagCompound chunkLevel;
|
||||
try {
|
||||
chunkNBT = CompressedStreamTools.read(mca.getChunkDataInputStream(j, k));
|
||||
if(!chunkNBT.hasKey("Level", 10)) {
|
||||
throw new IOException("Chunk is missing level data!");
|
||||
try(ZipInputStream zis = new ZipInputStream(new EaglerInputStream(archiveContents))) {
|
||||
ZipEntry f = null;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
byte[] bb = new byte[16384];
|
||||
while ((f = zis.getNextEntry()) != null) {
|
||||
if (f.getName().contains("__MACOSX/")) continue;
|
||||
if (f.isDirectory()) continue;
|
||||
String lowerName = f.getName().toLowerCase();
|
||||
if (!(lowerName.endsWith(".dat") || lowerName.endsWith(".dat_old") || lowerName.endsWith(".mca") || lowerName.endsWith(".mcr") || lowerName.endsWith(".bmp"))) continue;
|
||||
EaglerOutputStream baos = new EaglerOutputStream();
|
||||
int len;
|
||||
while ((len = zis.read(bb)) != -1) {
|
||||
baos.write(bb, 0, len);
|
||||
}
|
||||
baos.close();
|
||||
byte[] b = baos.toByteArray();
|
||||
String fileName = f.getName().substring(folderPrefixOffset);
|
||||
if (fileName.equals("level.dat") || fileName.equals("level.dat_old")) {
|
||||
NBTTagCompound worldDatNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
|
||||
NBTTagCompound gameRulesNBT = worldDatNBT.getCompoundTag("Data").getCompoundTag("GameRules");
|
||||
gameRulesNBT.setString("loadSpawnChunks", (gameRules & 2) != 0 ? "true" : "false");
|
||||
String s = (gameRules & 1) != 0 ? "true" : "false";
|
||||
gameRulesNBT.setString("bedSpawnPoint", s);
|
||||
gameRulesNBT.setString("clickToRide", "false");
|
||||
gameRulesNBT.setString("clickToSit", s);
|
||||
gameRulesNBT.setString("colorCodes", s);
|
||||
gameRulesNBT.setString("doSignEditing", s);
|
||||
worldDatNBT.getCompoundTag("Data").setTag("GameRules", gameRulesNBT);
|
||||
|
||||
worldDatNBT.getCompoundTag("Data").setString("LevelName", newName);
|
||||
worldDatNBT.getCompoundTag("Data").setLong("LastPlayed", System.currentTimeMillis());
|
||||
EaglerOutputStream bo = new EaglerOutputStream();
|
||||
CompressedStreamTools.writeCompressed(worldDatNBT, bo);
|
||||
b = bo.toByteArray();
|
||||
VFile2 ff = new VFile2(worldDir, fileName);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
} else if ((fileName.endsWith(".mcr") || fileName.endsWith(".mca")) && (fileName.startsWith("region/") || fileName.startsWith("DIM1/region/") || fileName.startsWith("DIM-1/region/"))) {
|
||||
VFile2 chunkFolder = new VFile2(worldDir, fileName.startsWith("DIM1") ? "level1" : (fileName.startsWith("DIM-1") ? "level-1" : "level0"));
|
||||
RegionFile mca = new RegionFile(new RandomAccessMemoryFile(b, b.length));
|
||||
int loadChunksCount = 0;
|
||||
for(int j = 0; j < 32; ++j) {
|
||||
for(int k = 0; k < 32; ++k) {
|
||||
if(mca.isChunkSaved(j, k)) {
|
||||
NBTTagCompound chunkNBT;
|
||||
NBTTagCompound chunkLevel;
|
||||
try {
|
||||
chunkNBT = CompressedStreamTools.read(mca.getChunkDataInputStream(j, k));
|
||||
if(!chunkNBT.hasKey("Level", 10)) {
|
||||
throw new IOException("Chunk is missing level data!");
|
||||
}
|
||||
chunkLevel = chunkNBT.getCompoundTag("Level");
|
||||
}catch(Throwable t) {
|
||||
logger.error("{}: Could not read chunk: {}, {}", fileName, j, k);
|
||||
logger.error(t);
|
||||
continue;
|
||||
}
|
||||
chunkLevel = chunkNBT.getCompoundTag("Level");
|
||||
}catch(Throwable t) {
|
||||
logger.error("{}: Could not read chunk: {}, {}", fileName, j, k);
|
||||
logger.error(t);
|
||||
continue;
|
||||
int chunkX = chunkLevel.getInteger("xPos");
|
||||
int chunkZ = chunkLevel.getInteger("zPos");
|
||||
VFile2 chunkOut = new VFile2(chunkFolder, EaglerChunkLoader.getChunkPath(chunkX, chunkZ) + ".dat");
|
||||
if(chunkOut.exists()) {
|
||||
logger.error("{}: Chunk already exists: {}", fileName, chunkOut.getPath());
|
||||
continue;
|
||||
}
|
||||
EaglerOutputStream bao = new EaglerOutputStream();
|
||||
CompressedStreamTools.writeCompressed(chunkNBT, bao);
|
||||
b = bao.toByteArray();
|
||||
chunkOut.setAllBytes(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.2", prog);
|
||||
}
|
||||
++loadChunksCount;
|
||||
}
|
||||
int chunkX = chunkLevel.getInteger("xPos");
|
||||
int chunkZ = chunkLevel.getInteger("zPos");
|
||||
VFile2 chunkOut = new VFile2(chunkFolder, EaglerChunkLoader.getChunkPath(chunkX, chunkZ) + ".dat");
|
||||
if(chunkOut.exists()) {
|
||||
logger.error("{}: Chunk already exists: {}", fileName, chunkOut.getPath());
|
||||
continue;
|
||||
}
|
||||
EaglerOutputStream bao = new EaglerOutputStream();
|
||||
CompressedStreamTools.writeCompressed(chunkNBT, bao);
|
||||
b = bao.toByteArray();
|
||||
chunkOut.setAllBytes(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.2", prog);
|
||||
}
|
||||
++loadChunksCount;
|
||||
}
|
||||
}
|
||||
logger.info("{}: Imported {} chunks successfully ({} bytes)", fileName, loadChunksCount, prog);
|
||||
} else if (fileName.startsWith("playerdata/") || fileName.startsWith("stats/")) {
|
||||
//TODO: LAN player inventories
|
||||
} else if (fileName.startsWith("data/") || fileName.startsWith("players/") || fileName.startsWith("eagler/skulls/")) {
|
||||
VFile2 ff = new VFile2(worldDir, fileName);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
} else if (!fileName.equals("level.dat_mcr") && !fileName.equals("session.lock")) {
|
||||
logger.info("Skipping file: {}", fileName);
|
||||
}
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.2", prog);
|
||||
}
|
||||
logger.info("{}: Imported {} chunks successfully ({} bytes)", fileName, loadChunksCount, prog);
|
||||
} else if (fileName.startsWith("playerdata/") || fileName.startsWith("stats/")) {
|
||||
//TODO: LAN player inventories
|
||||
} else if (fileName.startsWith("data/") || fileName.startsWith("players/") || fileName.startsWith("eagler/skulls/")) {
|
||||
VFile2 ff = new VFile2(worldDir, fileName);
|
||||
ff.setAllBytes(b);
|
||||
prog += b.length;
|
||||
} else if (!fileName.equals("level.dat_mcr") && !fileName.equals("session.lock")) {
|
||||
logger.info("Skipping file: {}", fileName);
|
||||
}
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.importing.2", prog);
|
||||
}
|
||||
}
|
||||
logger.info("MCA was successfully extracted into directory \"{}\"", worldDir.getPath());
|
||||
@ -172,129 +174,130 @@ public class WorldConverterMCA {
|
||||
|
||||
public static byte[] exportWorld(String folderName) throws IOException {
|
||||
EaglerOutputStream bao = new EaglerOutputStream();
|
||||
ZipOutputStream zos = new ZipOutputStream(bao);
|
||||
zos.setComment("contains backup of world '" + folderName + "'");
|
||||
VFile2 worldFolder = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
logger.info("Exporting world directory \"{}\" as MCA", worldFolder.getPath());
|
||||
VFile2 vf = new VFile2(worldFolder, "level.dat");
|
||||
byte[] b;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
boolean safe = false;
|
||||
if(vf.exists()) {
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/level.dat"));
|
||||
b = vf.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
safe = true;
|
||||
}
|
||||
vf = new VFile2(worldFolder, "level.dat_old");
|
||||
if(vf.exists()) {
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/level.dat_old"));
|
||||
b = vf.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
safe = true;
|
||||
}
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
String[] srcFolderNames = new String[] { "level0", "level-1", "level1" };
|
||||
String[] dstFolderNames = new String[] { "/region/", "/DIM-1/region/", "/DIM1/region/" };
|
||||
List<VFile2> fileList;
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
vf = new VFile2(worldFolder, srcFolderNames[i]);
|
||||
fileList = vf.listFiles(true);
|
||||
String regionFolder = folderName + dstFolderNames[i];
|
||||
logger.info("Converting chunks in \"{}\" as MCA to \"{}\"...", vf.getPath(), regionFolder);
|
||||
Map<String,RegionFile> regionFiles = new HashMap();
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 chunkFile = fileList.get(k);
|
||||
NBTTagCompound chunkNBT;
|
||||
NBTTagCompound chunkLevel;
|
||||
try {
|
||||
b = chunkFile.getAllBytes();
|
||||
chunkNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
if(!chunkNBT.hasKey("Level", 10)) {
|
||||
throw new IOException("Chunk is missing level data!");
|
||||
VFile2 worldFolder;
|
||||
try(ZipOutputStream zos = new ZipOutputStream(bao)) {
|
||||
zos.setComment("contains backup of world '" + folderName + "'");
|
||||
worldFolder = EaglerIntegratedServerWorker.saveFormat.getSaveLoader(folderName, false).getWorldDirectory();
|
||||
logger.info("Exporting world directory \"{}\" as MCA", worldFolder.getPath());
|
||||
VFile2 vf = new VFile2(worldFolder, "level.dat");
|
||||
byte[] b;
|
||||
int lastProgUpdate = 0;
|
||||
int prog = 0;
|
||||
boolean safe = false;
|
||||
if(vf.exists()) {
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/level.dat"));
|
||||
b = vf.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
safe = true;
|
||||
}
|
||||
vf = new VFile2(worldFolder, "level.dat_old");
|
||||
if(vf.exists()) {
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/level.dat_old"));
|
||||
b = vf.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
safe = true;
|
||||
}
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
String[] srcFolderNames = new String[] { "level0", "level-1", "level1" };
|
||||
String[] dstFolderNames = new String[] { "/region/", "/DIM-1/region/", "/DIM1/region/" };
|
||||
List<VFile2> fileList;
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
vf = new VFile2(worldFolder, srcFolderNames[i]);
|
||||
fileList = vf.listFiles(true);
|
||||
String regionFolder = folderName + dstFolderNames[i];
|
||||
logger.info("Converting chunks in \"{}\" as MCA to \"{}\"...", vf.getPath(), regionFolder);
|
||||
Map<String,RegionFile> regionFiles = new HashMap();
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 chunkFile = fileList.get(k);
|
||||
NBTTagCompound chunkNBT;
|
||||
NBTTagCompound chunkLevel;
|
||||
try {
|
||||
b = chunkFile.getAllBytes();
|
||||
chunkNBT = CompressedStreamTools.readCompressed(new EaglerInputStream(b));
|
||||
if(!chunkNBT.hasKey("Level", 10)) {
|
||||
throw new IOException("Chunk is missing level data!");
|
||||
}
|
||||
chunkLevel = chunkNBT.getCompoundTag("Level");
|
||||
}catch(IOException t) {
|
||||
logger.error("Could not read chunk: {}", chunkFile.getPath());
|
||||
logger.error(t);
|
||||
continue;
|
||||
}
|
||||
chunkLevel = chunkNBT.getCompoundTag("Level");
|
||||
}catch(IOException t) {
|
||||
logger.error("Could not read chunk: {}", chunkFile.getPath());
|
||||
logger.error(t);
|
||||
int chunkX = chunkLevel.getInteger("xPos");
|
||||
int chunkZ = chunkLevel.getInteger("zPos");
|
||||
String regionFileName = "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mca";
|
||||
RegionFile rf = regionFiles.get(regionFileName);
|
||||
if(rf == null) {
|
||||
rf = new RegionFile(new RandomAccessMemoryFile(new byte[65536], 0));
|
||||
regionFiles.put(regionFileName, rf);
|
||||
}
|
||||
try(DataOutputStream dos = rf.getChunkDataOutputStream(chunkX & 31, chunkZ & 31)) {
|
||||
CompressedStreamTools.write(chunkNBT, dos);
|
||||
}catch(IOException t) {
|
||||
logger.error("Could not write chunk to {}: {}", regionFileName, chunkFile.getPath());
|
||||
logger.error(t);
|
||||
continue;
|
||||
}
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
if(regionFiles.isEmpty()) {
|
||||
logger.info("No region files were generated");
|
||||
continue;
|
||||
}
|
||||
int chunkX = chunkLevel.getInteger("xPos");
|
||||
int chunkZ = chunkLevel.getInteger("zPos");
|
||||
String regionFileName = "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mca";
|
||||
RegionFile rf = regionFiles.get(regionFileName);
|
||||
if(rf == null) {
|
||||
rf = new RegionFile(new RandomAccessMemoryFile(new byte[65536], 0));
|
||||
regionFiles.put(regionFileName, rf);
|
||||
}
|
||||
try(DataOutputStream dos = rf.getChunkDataOutputStream(chunkX & 31, chunkZ & 31)) {
|
||||
CompressedStreamTools.write(chunkNBT, dos);
|
||||
}catch(IOException t) {
|
||||
logger.error("Could not write chunk to {}: {}", regionFileName, chunkFile.getPath());
|
||||
logger.error(t);
|
||||
continue;
|
||||
for(Entry<String,RegionFile> etr : regionFiles.entrySet()) {
|
||||
String regionPath = regionFolder + etr.getKey();
|
||||
logger.info("Writing region file: {}", regionPath);
|
||||
zos.putNextEntry(new ZipEntry(regionPath));
|
||||
zos.write(etr.getValue().getFile().getByteArray());
|
||||
}
|
||||
}
|
||||
logger.info("Copying extra world data...");
|
||||
fileList = (new VFile2(worldFolder, "data")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/data/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
if(regionFiles.isEmpty()) {
|
||||
logger.info("No region files were generated");
|
||||
continue;
|
||||
fileList = (new VFile2(worldFolder, "players")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/players/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
for(Entry<String,RegionFile> etr : regionFiles.entrySet()) {
|
||||
String regionPath = regionFolder + etr.getKey();
|
||||
logger.info("Writing region file: {}", regionPath);
|
||||
zos.putNextEntry(new ZipEntry(regionPath));
|
||||
zos.write(etr.getValue().getFile().getByteArray());
|
||||
fileList = (new VFile2(worldFolder, "eagler/skulls")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/eagler/skulls/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("Copying extra world data...");
|
||||
fileList = (new VFile2(worldFolder, "data")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/data/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
fileList = (new VFile2(worldFolder, "players")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/players/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
fileList = (new VFile2(worldFolder, "eagler/skulls")).listFiles(false);
|
||||
for(int k = 0, l = fileList.size(); k < l; ++k) {
|
||||
VFile2 dataFile = fileList.get(k);
|
||||
zos.putNextEntry(new ZipEntry(folderName + "/eagler/skulls/" + dataFile.getName()));
|
||||
b = dataFile.getAllBytes();
|
||||
zos.write(b);
|
||||
prog += b.length;
|
||||
if (prog - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = prog;
|
||||
EaglerIntegratedServerWorker.sendProgress("singleplayer.busy.exporting.2", prog);
|
||||
}
|
||||
}
|
||||
zos.close();
|
||||
logger.info("World directory \"{}\" was successfully exported as MCA", worldFolder.getPath());
|
||||
return bao.toByteArray();
|
||||
}
|
||||
|
@ -243,9 +243,9 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
temporaryOutputStream.write((len >> 16) & 0xFF);
|
||||
temporaryOutputStream.write((len >> 8) & 0xFF);
|
||||
temporaryOutputStream.write(len & 0xFF);
|
||||
OutputStream os = EaglerZLIB.newDeflaterOutputStream(temporaryOutputStream);
|
||||
temporaryBuffer.readBytes(os, len);
|
||||
os.close();
|
||||
try(OutputStream os = EaglerZLIB.newDeflaterOutputStream(temporaryOutputStream)) {
|
||||
temporaryBuffer.readBytes(os, len);
|
||||
}
|
||||
compressedData = temporaryOutputStream.toByteArray();
|
||||
}catch(IOException ex) {
|
||||
logger.error("Failed to compress packet {}!", pkt.getClass().getSimpleName());
|
||||
|
@ -64,7 +64,7 @@ public class RelayUpdateChecker {
|
||||
for(net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry etr : EagRuntime.getConfiguration().getRelays()) {
|
||||
relaysList.add(new RelayEntry(etr.address));
|
||||
}
|
||||
byte[] b = PlatformApplication.getLocalStorage("lastRelayUpdate");
|
||||
byte[] b = PlatformApplication.getLocalStorage("lastRelayUpdate", false);
|
||||
if(b != null) {
|
||||
try {
|
||||
lastUpdateCheck = (new DataInputStream(new EaglerInputStream(b))).readLong();
|
||||
@ -79,7 +79,7 @@ public class RelayUpdateChecker {
|
||||
try {
|
||||
EaglerOutputStream bao = new EaglerOutputStream(8);
|
||||
(new DataOutputStream(bao)).writeLong(lastUpdateCheck);
|
||||
PlatformApplication.setLocalStorage("lastRelayUpdate", bao.toByteArray());
|
||||
PlatformApplication.setLocalStorage("lastRelayUpdate", bao.toByteArray(), false);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
for (int i = 0, l = relaysList.size(); i < l; ++i) {
|
||||
|
@ -148,7 +148,16 @@ public class UpdateCertificate {
|
||||
throw new CertificateInvalidException("SHA256 checksum of signature payload is invalid!");
|
||||
}
|
||||
|
||||
return new UpdateCertificate(certData, EaglerZLIB.newGZIPInputStream(new EaglerInputStream(signaturePayload)), vers);
|
||||
UpdateCertificate cert;
|
||||
try(InputStream gis = EaglerZLIB.newGZIPInputStream(new EaglerInputStream(signaturePayload))) {
|
||||
cert = new UpdateCertificate(certData, gis, vers);
|
||||
}
|
||||
|
||||
if(System.currentTimeMillis() < cert.sigTimestamp) {
|
||||
throw new CertificateInvalidException("Update certificate timestamp is from the future!?");
|
||||
}
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
private UpdateCertificate(byte[] certData, InputStream is, int sigVers) throws IOException {
|
||||
|
@ -94,7 +94,7 @@ public class UpdateService {
|
||||
}
|
||||
}
|
||||
}
|
||||
byte[] latestUpdate = PlatformApplication.getLocalStorage(EaglercraftVersion.updateLatestLocalStorageKey);
|
||||
byte[] latestUpdate = PlatformApplication.getLocalStorage(EaglercraftVersion.updateLatestLocalStorageKey, false);
|
||||
if(latestUpdate != null) {
|
||||
addCertificateToSet(latestUpdate, false);
|
||||
}
|
||||
@ -150,7 +150,7 @@ public class UpdateService {
|
||||
latestUpdateFound = cert;
|
||||
if (saveLatest) {
|
||||
PlatformApplication.setLocalStorage(EaglercraftVersion.updateLatestLocalStorageKey,
|
||||
certificateData);
|
||||
certificateData, false);
|
||||
}
|
||||
}
|
||||
}else if(EagRuntime.getConfiguration().isLogInvalidCerts()) {
|
||||
|
Reference in New Issue
Block a user