stuff
This commit is contained in:
parent
ce0c54cabb
commit
e19b260b8c
|
@ -1,4 +1,4 @@
|
|||
@echo off
|
||||
title MakeOfflineDownload
|
||||
java -cp "resources/MakeOfflineDownload.jar;resources/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeOfflineDownload "javascript/OfflineDownloadTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "javascript/EaglercraftL_1.9_Offline_en_US.html" "javascript/EaglercraftX_1.8_Offline_International.html" "javascript/lang"
|
||||
java -cp "resources/MakeOfflineDownload.jar;resources/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeOfflineDownload "javascript/OfflineDownloadTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "javascript/EaglercraftL_1.9_Offline_en_US.html" "javascript/EaglercraftL_1.9_Offline_International.html" "javascript/lang"
|
||||
pause
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -74,6 +74,10 @@ public class PlatformApplication {
|
|||
}
|
||||
|
||||
public static void setLocalStorage(String name, byte[] data) {
|
||||
setLocalStorage(name, data, true);
|
||||
}
|
||||
|
||||
public static void setLocalStorage(String name, byte[] data, boolean hooks) {
|
||||
if (data == null) {
|
||||
(new File("_eagstorage." + name + ".dat")).delete();
|
||||
} else {
|
||||
|
@ -86,6 +90,10 @@ public class PlatformApplication {
|
|||
}
|
||||
|
||||
public static byte[] getLocalStorage(String data) {
|
||||
return getLocalStorage(data, true);
|
||||
}
|
||||
|
||||
public static byte[] getLocalStorage(String data, boolean hooks) {
|
||||
File f = new File("_eagstorage." + data + ".dat");
|
||||
if (!f.isFile()) {
|
||||
return null;
|
||||
|
|
|
@ -238,6 +238,10 @@ public class PlatformInput {
|
|||
glfwSwapBuffers(win);
|
||||
}
|
||||
|
||||
public static boolean isVSyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean wasResized() {
|
||||
boolean b = windowResized;
|
||||
windowResized = false;
|
||||
|
|
|
@ -8,19 +8,27 @@ import org.json.JSONObject;
|
|||
import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftVersion;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapterHooks;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -31,6 +39,8 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
|
|||
|
||||
public final List<DefaultServer> defaultServers = new ArrayList();
|
||||
|
||||
private final DesktopClientConfigAdapterHooks hooks = new DesktopClientConfigAdapterHooks();
|
||||
|
||||
@Override
|
||||
public String getDefaultLocale() {
|
||||
return "en_US";
|
||||
|
@ -128,4 +138,33 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
|
|||
public boolean isAllowVoiceClient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowFNAWSkins() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalStorageNamespace() {
|
||||
return EaglercraftVersion.localStorageNamespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClientConfigAdapterHooks getHooks() {
|
||||
return hooks;
|
||||
}
|
||||
|
||||
private static class DesktopClientConfigAdapterHooks implements IClientConfigAdapterHooks {
|
||||
|
||||
@Override
|
||||
public void callLocalStorageSavedHook(String key, String base64) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String callLocalStorageLoadHook(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,16 +15,12 @@ public class Config {
|
|||
public static int tracingDistance = 128;
|
||||
public static Set<String> blockEntityWhitelist = new HashSet<>(Arrays.asList("minecraft:beacon"));
|
||||
public static int SleepDuration = 10;
|
||||
public static int hitboxLimit = 50;
|
||||
public static int hitboxLimit = 50;
|
||||
|
||||
public static boolean disableAlpha() {
|
||||
return Minecraft.getMinecraft().gameSettings.disableAlpha && !Minecraft.getMinecraft().gameSettings.shaders;
|
||||
}
|
||||
|
||||
public static boolean skipRenderUpdate() {
|
||||
return Minecraft.getMinecraft().gameSettings.skipHandRender && !Minecraft.getMinecraft().gameSettings.shaders;
|
||||
}
|
||||
|
||||
public static boolean audioEnabled() {
|
||||
return Minecraft.getMinecraft().gameSettings.enableSound;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,10 @@ public class Display {
|
|||
PlatformInput.setVSync(enable);
|
||||
}
|
||||
|
||||
public static boolean isVSyncSupported() {
|
||||
return PlatformInput.isVSyncSupported();
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
PlatformInput.update();
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ public class EaglercraftVersion {
|
|||
/// Customize these to fit your fork:
|
||||
|
||||
public static final String projectForkName = "Eaglercraft Lambda";
|
||||
public static final String projectForkVersion = "0.3.1";
|
||||
public static final String projectForkVendor = "hoosiertransfer";
|
||||
public static final String projectForkVersion = "0.3.5";
|
||||
public static final String projectForkVendor = "HoosierTransfer";
|
||||
|
||||
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
|
||||
|
||||
|
@ -18,8 +18,8 @@ public class EaglercraftVersion {
|
|||
|
||||
public static final String projectOriginName = "EaglercraftX";
|
||||
public static final String projectOriginAuthor = "lax1dude";
|
||||
public static final String projectOriginRevision = "1.9";
|
||||
public static final String projectOriginVersion = "u29";
|
||||
public static final String projectOriginRevision = "1.9.4";
|
||||
public static final String projectOriginVersion = "u30";
|
||||
|
||||
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class EaglercraftVersion {
|
|||
public static final boolean enableUpdateService = false;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class EaglercraftVersion {
|
|||
|
||||
// Miscellaneous variables:
|
||||
|
||||
public static final String mainMenuStringA = "Minecraft 1.8.8";
|
||||
public static final String mainMenuStringA = "Minecraft 1.9.4";
|
||||
public static final String mainMenuStringB = projectOriginName + " " +
|
||||
projectOriginRevision + "-" + projectOriginVersion + " ultimate";
|
||||
public static final String mainMenuStringC = "";
|
||||
|
@ -56,4 +56,6 @@ public class EaglercraftVersion {
|
|||
|
||||
public static final boolean forceDemoMode = false;
|
||||
|
||||
public static final String localStorageNamespace = "_eaglercraftX";
|
||||
|
||||
}
|
||||
|
|
|
@ -8,14 +8,21 @@ import org.json.JSONObject;
|
|||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -69,4 +76,10 @@ public interface IClientConfigAdapter {
|
|||
boolean isEnableSignatureBadge();
|
||||
|
||||
boolean isAllowVoiceClient();
|
||||
|
||||
boolean isAllowFNAWSkins();
|
||||
|
||||
String getLocalStorageNamespace();
|
||||
|
||||
IClientConfigAdapterHooks getHooks();
|
||||
}
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.teavm.opts;
|
||||
|
||||
import org.teavm.jso.JSIndexer;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
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
|
||||
* 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)
|
||||
* 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 JSEaglercraftXOptsRelaysArray extends JSObject {
|
||||
public interface IClientConfigAdapterHooks {
|
||||
|
||||
@JSIndexer
|
||||
JSEaglercraftXOptsRelay get(int idx);
|
||||
void callLocalStorageSavedHook(String key, String base64);
|
||||
|
||||
@JSProperty
|
||||
int getLength();
|
||||
String callLocalStorageLoadHook(String key);
|
||||
|
||||
}
|
|
@ -13,11 +13,34 @@ 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");
|
||||
|
||||
public static final Map<String,Integer> modelToID = new HashMap();
|
||||
public static final Map<String, Integer> modelToID = new HashMap();
|
||||
|
||||
public static int builtin_water_still_vertex_id = 0;
|
||||
public static int builtin_water_flow_vertex_id = 0;
|
||||
|
@ -31,41 +54,41 @@ public class BlockVertexIDs implements IResourceManagerReloadListener {
|
|||
modelToID.clear();
|
||||
String line;
|
||||
boolean firstLine = true;
|
||||
while((line = reader.readLine()) != null) {
|
||||
if((line = line.trim()).length() > 0) {
|
||||
if(firstLine) {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if ((line = line.trim()).length() > 0) {
|
||||
if (firstLine) {
|
||||
firstLine = false;
|
||||
continue;
|
||||
}
|
||||
String[] split = line.split(",");
|
||||
if(split.length == 2) {
|
||||
if (split.length == 2) {
|
||||
try {
|
||||
int i = Integer.parseInt(split[1]);
|
||||
if(i <= 0 || i > 254) {
|
||||
if (i <= 0 || i > 254) {
|
||||
logger.error("Error: {}: Only IDs 1 to 254 are configurable!", split[0]);
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
i -= 127;
|
||||
modelToID.put(split[0], i);
|
||||
switch(split[0]) {
|
||||
case "eagler:builtin/water_still_vertex_id":
|
||||
builtin_water_still_vertex_id = i;
|
||||
break;
|
||||
case "eagler:builtin/water_flow_vertex_id":
|
||||
builtin_water_flow_vertex_id = i;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (split[0]) {
|
||||
case "eagler:builtin/water_still_vertex_id":
|
||||
builtin_water_still_vertex_id = i;
|
||||
break;
|
||||
case "eagler:builtin/water_flow_vertex_id":
|
||||
builtin_water_flow_vertex_id = i;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}catch(NumberFormatException ex) {
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
}
|
||||
logger.error("Skipping bad vertex id entry: {}", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Could not load list of vertex ids!");
|
||||
logger.error(t);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,8 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
|
@ -83,14 +82,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;
|
||||
}
|
||||
|
@ -116,6 +121,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
|
||||
|
|
|
@ -12,14 +12,21 @@ import net.minecraft.client.resources.I18n;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -34,35 +41,42 @@ public class GuiScreenImportExportProfile extends GuiScreen {
|
|||
}
|
||||
|
||||
public void initGui() {
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 40, I18n.format("settingsBackup.importExport.import")));
|
||||
this.buttonList.add(new GuiButton(2, this.width / 2 - 100, this.height / 4 + 65, I18n.format("settingsBackup.importExport.export")));
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 40,
|
||||
I18n.format("settingsBackup.importExport.import")));
|
||||
this.buttonList.add(new GuiButton(2, this.width / 2 - 100, this.height / 4 + 65,
|
||||
I18n.format("settingsBackup.importExport.export")));
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 130, I18n.format("gui.cancel")));
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton par1GuiButton) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
mc.displayGuiScreen(back);
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
} else if (par1GuiButton.id == 1) {
|
||||
waitingForFile = true;
|
||||
EagRuntime.displayFileChooser(null, "epk");
|
||||
}else if(par1GuiButton.id == 2) {
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
mc.displayGuiScreen(new GuiScreenExportProfile(back));
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScreen() {
|
||||
if(waitingForFile && EagRuntime.fileChooserHasResult()) {
|
||||
if (waitingForFile && EagRuntime.fileChooserHasResult()) {
|
||||
waitingForFile = false;
|
||||
FileChooserResult result = EagRuntime.getFileChooserResult();
|
||||
if(result != null) {
|
||||
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) {
|
||||
} 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));
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("settingsBackup.importing.failed.1",
|
||||
"settingsBackup.importing.failed.2", back));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,9 +84,10 @@ public class GuiScreenImportExportProfile extends GuiScreen {
|
|||
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("settingsBackup.importExport.title"), this.width / 2, this.height / 4, 16777215);
|
||||
|
||||
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("settingsBackup.importExport.title"), this.width / 2,
|
||||
this.height / 4, 16777215);
|
||||
|
||||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,14 +14,21 @@ import net.minecraft.client.resources.I18n;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -50,30 +57,50 @@ public class GuiScreenImportProfile extends GuiScreen {
|
|||
}
|
||||
|
||||
public void initGui() {
|
||||
this.buttonList.add(importProfile = new GuiButton(2, this.width / 2 - 100, this.height / 4, I18n.format("settingsBackup.import.option.profile") + " " + I18n.format(doImportProfile ? "gui.yes" : "gui.no")));
|
||||
this.buttonList.add(importProfile = new GuiButton(2, this.width / 2 - 100, this.height / 4,
|
||||
I18n.format("settingsBackup.import.option.profile") + " "
|
||||
+ I18n.format(doImportProfile ? "gui.yes" : "gui.no")));
|
||||
importProfile.enabled = importer.hasProfile();
|
||||
this.buttonList.add(importSettings = new GuiButton(3, this.width / 2 - 100, this.height / 4 + 25, I18n.format("settingsBackup.import.option.settings") + " " + I18n.format(doImportSettings ? "gui.yes" : "gui.no")));
|
||||
this.buttonList.add(importSettings = new GuiButton(3, this.width / 2 - 100, this.height / 4 + 25,
|
||||
I18n.format("settingsBackup.import.option.settings") + " "
|
||||
+ I18n.format(doImportSettings ? "gui.yes" : "gui.no")));
|
||||
importSettings.enabled = importer.hasProfile();
|
||||
this.buttonList.add(importServers = new GuiButton(4, this.width / 2 - 100, this.height / 4 + 50, I18n.format("settingsBackup.import.option.servers") + " " + I18n.format(doImportServers ? "gui.yes" : "gui.no")));
|
||||
this.buttonList.add(importServers = new GuiButton(4, this.width / 2 - 100, this.height / 4 + 50,
|
||||
I18n.format("settingsBackup.import.option.servers") + " "
|
||||
+ I18n.format(doImportServers ? "gui.yes" : "gui.no")));
|
||||
importServers.enabled = importer.hasServers();
|
||||
this.buttonList.add(importResourcePacks = new GuiButton(5, this.width / 2 - 100, this.height / 4 + 75, I18n.format("settingsBackup.import.option.resourcePacks") + " " + I18n.format(doImportResourcePacks ? "gui.yes" : "gui.no")));
|
||||
this.buttonList.add(importResourcePacks = new GuiButton(5, this.width / 2 - 100, this.height / 4 + 75,
|
||||
I18n.format("settingsBackup.import.option.resourcePacks") + " "
|
||||
+ I18n.format(doImportResourcePacks ? "gui.yes" : "gui.no")));
|
||||
importResourcePacks.enabled = importer.hasResourcePacks() && EaglerFolderResourcePack.isSupported();
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 115, I18n.format("settingsBackup.import.option.import")));
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 115,
|
||||
I18n.format("settingsBackup.import.option.import")));
|
||||
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) {
|
||||
if (par1GuiButton.id == 0) {
|
||||
if (!doImportProfile && !doImportSettings && !doImportServers && !doImportResourcePacks) {
|
||||
mc.displayGuiScreen(back);
|
||||
}else {
|
||||
mc.loadingScreen.eaglerShow(I18n.format("settingsBackup.importing.1"), I18n.format("settingsBackup.importing.2"));
|
||||
} else {
|
||||
mc.loadingScreen.eaglerShow(I18n.format("settingsBackup.importing.1"),
|
||||
I18n.format("settingsBackup.importing.2"));
|
||||
try {
|
||||
List<String> list1 = new ArrayList(mc.gameSettings.resourcePacks);
|
||||
List<String> list1 = new ArrayList(mc.gameSettings.resourcePacks);
|
||||
List<String> list2 = new ArrayList(mc.gameSettings.field_183018_l);
|
||||
importer.importProfileAndSettings(doImportProfile, doImportSettings, doImportServers, doImportResourcePacks);
|
||||
boolean resourcePacksChanged = !mc.gameSettings.resourcePacks.equals(list1) || !mc.gameSettings.field_183018_l.equals(list2);
|
||||
if(resourcePacksChanged || (doImportResourcePacks && (list1.size() > 0 || list2.size() > 0))) {
|
||||
importer.importProfileAndSettings(doImportProfile, doImportSettings, doImportServers,
|
||||
doImportResourcePacks);
|
||||
boolean resourcePacksChanged = !mc.gameSettings.resourcePacks.equals(list1)
|
||||
|| !mc.gameSettings.field_183018_l.equals(list2);
|
||||
if (resourcePacksChanged || (doImportResourcePacks && (list1.size() > 0 || list2.size() > 0))) {
|
||||
mc.loadingScreen.eaglerShow(I18n.format("resourcePack.load.refreshing"),
|
||||
I18n.format("resourcePack.load.pleaseWait"));
|
||||
mc.getResourcePackRepository().reconstruct(mc.gameSettings);
|
||||
|
@ -82,29 +109,35 @@ public class GuiScreenImportProfile extends GuiScreen {
|
|||
mc.displayGuiScreen(back);
|
||||
} catch (IOException e) {
|
||||
EagRuntime.debugPrintStackTrace(e);
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("settingsBackup.importing.failed.1", "settingsBackup.importing.failed.2", back));
|
||||
mc.displayGuiScreen(new GuiScreenGenericErrorMessage("settingsBackup.importing.failed.1",
|
||||
"settingsBackup.importing.failed.2", back));
|
||||
}
|
||||
}
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
} else if (par1GuiButton.id == 1) {
|
||||
mc.displayGuiScreen(back);
|
||||
}else if(par1GuiButton.id == 2) {
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
doImportProfile = !doImportProfile;
|
||||
importProfile.displayString = I18n.format("settingsBackup.import.option.profile") + " " + I18n.format(doImportProfile ? "gui.yes" : "gui.no");
|
||||
}else if(par1GuiButton.id == 3) {
|
||||
importProfile.displayString = I18n.format("settingsBackup.import.option.profile") + " "
|
||||
+ I18n.format(doImportProfile ? "gui.yes" : "gui.no");
|
||||
} else if (par1GuiButton.id == 3) {
|
||||
doImportSettings = !doImportSettings;
|
||||
importSettings.displayString = I18n.format("settingsBackup.import.option.settings") + " " + I18n.format(doImportSettings ? "gui.yes" : "gui.no");
|
||||
}else if(par1GuiButton.id == 4) {
|
||||
importSettings.displayString = I18n.format("settingsBackup.import.option.settings") + " "
|
||||
+ I18n.format(doImportSettings ? "gui.yes" : "gui.no");
|
||||
} else if (par1GuiButton.id == 4) {
|
||||
doImportServers = !doImportServers;
|
||||
importServers.displayString = I18n.format("settingsBackup.import.option.servers") + " " + I18n.format(doImportServers ? "gui.yes" : "gui.no");
|
||||
}else if(par1GuiButton.id == 5) {
|
||||
importServers.displayString = I18n.format("settingsBackup.import.option.servers") + " "
|
||||
+ I18n.format(doImportServers ? "gui.yes" : "gui.no");
|
||||
} else if (par1GuiButton.id == 5) {
|
||||
doImportResourcePacks = !doImportResourcePacks;
|
||||
importResourcePacks.displayString = I18n.format("settingsBackup.import.option.resourcePacks") + " " + I18n.format(doImportResourcePacks ? "gui.yes" : "gui.no");
|
||||
importResourcePacks.displayString = I18n.format("settingsBackup.import.option.resourcePacks") + " "
|
||||
+ I18n.format(doImportResourcePacks ? "gui.yes" : "gui.no");
|
||||
}
|
||||
}
|
||||
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("settingsBackup.import.title"), this.width / 2, this.height / 4 - 25, 16777215);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("settingsBackup.import.title"), this.width / 2,
|
||||
this.height / 4 - 25, 16777215);
|
||||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,21 @@ import static net.lax1dude.eaglercraft.v1_8.sp.server.export.EPKCompiler.*;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -46,14 +53,16 @@ public class ProfileExporter {
|
|||
boolean doExportServers, boolean doExportResourcePacks) throws IOException {
|
||||
doExportResourcePacks &= EaglerFolderResourcePack.isSupported();
|
||||
EaglerOutputStream osb = new EaglerOutputStream();
|
||||
osb.write(new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)36,(byte)36}); // EAGPKG$$
|
||||
osb.write(new byte[]{(byte)6,(byte)118,(byte)101,(byte)114,(byte)50,(byte)46,(byte)48}); // 6 + ver2.0
|
||||
osb.write(
|
||||
new byte[] { (byte) 69, (byte) 65, (byte) 71, (byte) 80, (byte) 75, (byte) 71, (byte) 36, (byte) 36 }); // EAGPKG$$
|
||||
osb.write(new byte[] { (byte) 6, (byte) 118, (byte) 101, (byte) 114, (byte) 50, (byte) 46, (byte) 48 }); // 6 +
|
||||
// ver2.0
|
||||
Date d = new Date();
|
||||
|
||||
|
||||
byte[] filename = "profile.epk".getBytes(StandardCharsets.UTF_8);
|
||||
osb.write(filename.length);
|
||||
osb.write(filename);
|
||||
|
||||
|
||||
byte[] comment = ("\n\n # Eaglercraft profile backup - \"" + EaglerProfile.getName() + "\""
|
||||
+ "\n # Contains: " + (doExportProfile ? "profile " : "") + (doExportSettings ? "settings " : "")
|
||||
+ (doExportServers ? "servers " : "") + (doExportResourcePacks ? "resourcePacks" : "") + "\n\n")
|
||||
|
@ -62,116 +71,123 @@ public class ProfileExporter {
|
|||
osb.write((comment.length >> 8) & 255);
|
||||
osb.write(comment.length & 255);
|
||||
osb.write(comment);
|
||||
|
||||
|
||||
writeLong(d.getTime(), osb);
|
||||
|
||||
|
||||
int lengthIntegerOffset = osb.size();
|
||||
osb.write(new byte[]{(byte)255,(byte)255,(byte)255,(byte)255}); // this will be replaced with the file count
|
||||
|
||||
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:>
|
||||
|
||||
|
||||
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();
|
||||
|
||||
ret[lengthIntegerOffset] = (byte)((fileCount >> 24) & 0xFF);
|
||||
ret[lengthIntegerOffset + 1] = (byte)((fileCount >> 16) & 0xFF);
|
||||
ret[lengthIntegerOffset + 2] = (byte)((fileCount >> 8) & 0xFF);
|
||||
ret[lengthIntegerOffset + 3] = (byte)(fileCount & 0xFF);
|
||||
|
||||
ret[lengthIntegerOffset] = (byte) ((fileCount >> 24) & 0xFF);
|
||||
ret[lengthIntegerOffset + 1] = (byte) ((fileCount >> 16) & 0xFF);
|
||||
ret[lengthIntegerOffset + 2] = (byte) ((fileCount >> 8) & 0xFF);
|
||||
ret[lengthIntegerOffset + 3] = (byte) (fileCount & 0xFF);
|
||||
|
||||
logger.info("Export complete!");
|
||||
|
||||
|
||||
EagRuntime.downloadFileWithName(EaglerProfile.getName() + "-backup.epk", ret);
|
||||
}
|
||||
|
||||
|
@ -179,15 +195,15 @@ public class ProfileExporter {
|
|||
CRC32 checkSum = new CRC32();
|
||||
checkSum.update(contents);
|
||||
long sum = checkSum.getValue();
|
||||
|
||||
os.write(new byte[]{(byte)70,(byte)73,(byte)76,(byte)69}); // FILE
|
||||
|
||||
|
||||
os.write(new byte[] { (byte) 70, (byte) 73, (byte) 76, (byte) 69 }); // FILE
|
||||
|
||||
byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
|
||||
os.write(nameBytes.length);
|
||||
os.write(nameBytes);
|
||||
writeInt(contents.length + 5, os);
|
||||
writeInt((int)sum, os);
|
||||
|
||||
writeInt((int) sum, os);
|
||||
|
||||
os.write(contents);
|
||||
os.write(':');
|
||||
os.write('>');
|
||||
|
|
|
@ -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;
|
||||
|
@ -17,19 +18,26 @@ import net.minecraft.client.multiplayer.ServerList;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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 ProfileImporter {
|
||||
public class ProfileImporter implements Closeable {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("ProfileImporter");
|
||||
|
||||
|
@ -47,13 +55,13 @@ public class ProfileImporter {
|
|||
public void readHeader() throws IOException {
|
||||
logger.info("Reading EPK file header...");
|
||||
epkDecompiler = new EPKDecompiler(data);
|
||||
|
||||
|
||||
FileEntry etr = epkDecompiler.readFile();
|
||||
if (etr == null || !etr.type.equals("HEAD") || !etr.name.equals("file-type")
|
||||
|| !EPKDecompiler.readASCII(etr.data).equals("epk/profile188")) {
|
||||
throw new IOException("EPK file is not a profile backup!");
|
||||
}
|
||||
|
||||
|
||||
etr = epkDecompiler.readFile();
|
||||
if (etr == null || !etr.type.equals("HEAD") || !etr.name.equals("file-exports") || etr.data.length != 1) {
|
||||
throw new IOException("EPK file is not a profile backup!");
|
||||
|
@ -91,61 +99,67 @@ public class ProfileImporter {
|
|||
doImportServers &= headerHasServers;
|
||||
doImportResourcePacks &= headerHasResourcePacks && EaglerFolderResourcePack.isSupported();
|
||||
FileEntry etr;
|
||||
vigg: while((etr = epkDecompiler.readFile()) != null) {
|
||||
if(etr.type.equals("FILE")) {
|
||||
switch(etr.name) {
|
||||
case "_eaglercraftX.p":
|
||||
if(doImportProfile) {
|
||||
logger.info("Importing profile...");
|
||||
EaglerProfile.read(etr.data);
|
||||
EagRuntime.setStorage("p", etr.data);
|
||||
}
|
||||
break;
|
||||
case "_eaglercraftX.g":
|
||||
if(doImportSettings) {
|
||||
logger.info("Importing settings...");
|
||||
Minecraft.getMinecraft().gameSettings.loadOptions(etr.data);
|
||||
EagRuntime.setStorage("g", etr.data);
|
||||
}
|
||||
break;
|
||||
case "_eaglercraftX.r":
|
||||
if(doImportSettings) {
|
||||
logger.info("Importing relays...");
|
||||
RelayManager.relayManager.load(etr.data);
|
||||
EagRuntime.setStorage("r", etr.data);
|
||||
}
|
||||
break;
|
||||
case "_eaglercraftX.s":
|
||||
if(doImportServers) {
|
||||
logger.info("Importing servers...");
|
||||
ServerList.getServerList().loadServerList(etr.data);
|
||||
EagRuntime.setStorage("s", etr.data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(etr.name.startsWith("certs/")) {
|
||||
UpdateService.addCertificateToSet(etr.data);
|
||||
}else if(etr.name.startsWith(EaglerFolderResourcePack.RESOURCE_PACKS + "/")) {
|
||||
if(doImportResourcePacks) {
|
||||
logger.info("Deleting old resource packs...");
|
||||
(new VFile2(EaglerFolderResourcePack.RESOURCE_PACKS)).listFiles(true).forEach(VFile2::delete);
|
||||
logger.info("Importing resource packs...");
|
||||
int counter = 0;
|
||||
do {
|
||||
if(etr.name.startsWith(EaglerFolderResourcePack.RESOURCE_PACKS + "/")) {
|
||||
(new VFile2(etr.name)).setAllBytes(etr.data);
|
||||
if(++counter % 100 == 0) {
|
||||
logger.info("Imported {} files", counter);
|
||||
}
|
||||
}
|
||||
}while((etr = epkDecompiler.readFile()) != null);
|
||||
vigg: while ((etr = epkDecompiler.readFile()) != null) {
|
||||
if (etr.type.equals("FILE")) {
|
||||
switch (etr.name) {
|
||||
case "_eaglercraftX.p":
|
||||
if (doImportProfile) {
|
||||
logger.info("Importing profile...");
|
||||
EaglerProfile.read(etr.data);
|
||||
EagRuntime.setStorage("p", etr.data);
|
||||
}
|
||||
break vigg;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case "_eaglercraftX.g":
|
||||
if (doImportSettings) {
|
||||
logger.info("Importing settings...");
|
||||
Minecraft.getMinecraft().gameSettings.loadOptions(etr.data);
|
||||
EagRuntime.setStorage("g", etr.data);
|
||||
}
|
||||
break;
|
||||
case "_eaglercraftX.r":
|
||||
if (doImportSettings) {
|
||||
logger.info("Importing relays...");
|
||||
RelayManager.relayManager.load(etr.data);
|
||||
EagRuntime.setStorage("r", etr.data);
|
||||
}
|
||||
break;
|
||||
case "_eaglercraftX.s":
|
||||
if (doImportServers) {
|
||||
logger.info("Importing servers...");
|
||||
ServerList.getServerList().loadServerList(etr.data);
|
||||
EagRuntime.setStorage("s", etr.data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (etr.name.startsWith("certs/")) {
|
||||
UpdateService.addCertificateToSet(etr.data);
|
||||
} else if (etr.name.startsWith(EaglerFolderResourcePack.RESOURCE_PACKS + "/")) {
|
||||
if (doImportResourcePacks) {
|
||||
logger.info("Deleting old resource packs...");
|
||||
(new VFile2(EaglerFolderResourcePack.RESOURCE_PACKS)).listFiles(true)
|
||||
.forEach(VFile2::delete);
|
||||
logger.info("Importing resource packs...");
|
||||
int counter = 0;
|
||||
do {
|
||||
if (etr.name.startsWith(EaglerFolderResourcePack.RESOURCE_PACKS + "/")) {
|
||||
(new VFile2(etr.name)).setAllBytes(etr.data);
|
||||
if (++counter % 100 == 0) {
|
||||
logger.info("Imported {} files", counter);
|
||||
}
|
||||
}
|
||||
} while ((etr = epkDecompiler.readFile()) != null);
|
||||
}
|
||||
break vigg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("Import complete!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
epkDecompiler.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,14 +27,21 @@ import net.minecraft.util.MathHelper;
|
|||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -54,40 +61,43 @@ public class RenderHighPoly extends RenderPlayer {
|
|||
if (!abstractclientplayer.isUser() || this.renderManager.livingPlayer == abstractclientplayer) {
|
||||
double nameY = d1;
|
||||
HighPolySkin highPolySkin = abstractclientplayer.getEaglerSkinModel().highPoly;
|
||||
|
||||
if(highPolySkin == null) {
|
||||
|
||||
if (highPolySkin == null) {
|
||||
super.doRender(abstractclientplayer, d0, d1, d2, f, f1);
|
||||
return;
|
||||
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
} else if (highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
nameY += 0.1;
|
||||
}else if(highPolySkin == HighPolySkin.BABY_WINSTON) {
|
||||
} else if (highPolySkin == HighPolySkin.BABY_WINSTON) {
|
||||
nameY -= 1.0;
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.disableCull();
|
||||
|
||||
|
||||
try {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
float f2 = this.interpolateRotation(abstractclientplayer.prevRenderYawOffset, abstractclientplayer.renderYawOffset,
|
||||
float f2 = this.interpolateRotation(abstractclientplayer.prevRenderYawOffset,
|
||||
abstractclientplayer.renderYawOffset,
|
||||
f1);
|
||||
float f3 = this.interpolateRotation(abstractclientplayer.prevRotationYawHead, abstractclientplayer.rotationYawHead,
|
||||
float f3 = this.interpolateRotation(abstractclientplayer.prevRotationYawHead,
|
||||
abstractclientplayer.rotationYawHead,
|
||||
f1);
|
||||
float f4 = f3 - f2;
|
||||
if (abstractclientplayer.isRiding() && abstractclientplayer.ridingEntity instanceof EntityLivingBase) {
|
||||
EntityLivingBase entitylivingbase1 = (EntityLivingBase) abstractclientplayer.ridingEntity;
|
||||
f2 = this.interpolateRotation(entitylivingbase1.prevRenderYawOffset, entitylivingbase1.renderYawOffset,
|
||||
f2 = this.interpolateRotation(entitylivingbase1.prevRenderYawOffset,
|
||||
entitylivingbase1.renderYawOffset,
|
||||
f1);
|
||||
f4 = f3 - f2;
|
||||
float f5 = MathHelper.wrapAngleTo180_float(f4);
|
||||
if (f5 < -85.0F) {
|
||||
f5 = -85.0F;
|
||||
}
|
||||
|
||||
|
||||
if (f5 >= 85.0F) {
|
||||
f5 = 85.0F;
|
||||
}
|
||||
|
||||
|
||||
f2 = f3 - f5;
|
||||
if (f5 * f5 > 2500.0F) {
|
||||
f2 += f5 * 0.2F;
|
||||
|
@ -100,301 +110,326 @@ public class RenderHighPoly extends RenderPlayer {
|
|||
GlStateManager.enableRescaleNormal();
|
||||
this.preRenderCallback(abstractclientplayer, f1);
|
||||
float f6 = 0.0625F;
|
||||
GlStateManager.scale(HighPolySkin.highPolyScale, HighPolySkin.highPolyScale, HighPolySkin.highPolyScale);
|
||||
GlStateManager.scale(HighPolySkin.highPolyScale, HighPolySkin.highPolyScale,
|
||||
HighPolySkin.highPolyScale);
|
||||
mc.getTextureManager().bindTexture(highPolySkin.texture);
|
||||
|
||||
if(abstractclientplayer.isPlayerSleeping()) {
|
||||
if(highPolySkin == HighPolySkin.LAXATIVE_DUDE || highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
|
||||
if (abstractclientplayer.isPlayerSleeping()) {
|
||||
if (highPolySkin == HighPolySkin.LAXATIVE_DUDE || highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
GlStateManager.translate(0.0f, -3.7f, 0.0f);
|
||||
}else if(highPolySkin == HighPolySkin.BABY_WINSTON) {
|
||||
} else if (highPolySkin == HighPolySkin.BABY_WINSTON) {
|
||||
GlStateManager.translate(0.0f, -2.4f, 0.0f);
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.translate(0.0f, -3.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
float var15 = abstractclientplayer.prevLimbSwingAmount + (abstractclientplayer.limbSwingAmount - abstractclientplayer.prevLimbSwingAmount) * f1;
|
||||
|
||||
float var15 = abstractclientplayer.prevLimbSwingAmount
|
||||
+ (abstractclientplayer.limbSwingAmount - abstractclientplayer.prevLimbSwingAmount) * f1;
|
||||
float var16 = abstractclientplayer.limbSwing - abstractclientplayer.limbSwingAmount * (1.0F - f1);
|
||||
|
||||
if(highPolySkin == HighPolySkin.LONG_ARMS) {
|
||||
|
||||
if (highPolySkin == HighPolySkin.LONG_ARMS) {
|
||||
GlStateManager.rotate(MathHelper.sin(var16) * 20f * var15, 0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.rotate(MathHelper.cos(var16) * 7f * var15, 0.0f, 0.0f, 1.0f);
|
||||
}else if(highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
} else if (highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
GlStateManager.rotate(MathHelper.sin(var16) * 7f * var15, 0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.rotate(MathHelper.cos(var16) * 3f * var15, 0.0f, 0.0f, 1.0f);
|
||||
GlStateManager.rotate(-f3, 0.0f, 1.0f, 0.0f);
|
||||
float xd = (float)(abstractclientplayer.posX - abstractclientplayer.prevPosX);
|
||||
float xd = (float) (abstractclientplayer.posX - abstractclientplayer.prevPosX);
|
||||
GlStateManager.rotate(xd * 70.0f * var15, 0.0f, 0.0f, 1.0f);
|
||||
float zd = (float)(abstractclientplayer.posZ - abstractclientplayer.prevPosZ);
|
||||
float zd = (float) (abstractclientplayer.posZ - abstractclientplayer.prevPosZ);
|
||||
GlStateManager.rotate(zd * 70.0f * var15, 1.0f, 0.0f, 0.0f);
|
||||
GlStateManager.rotate(f3, 0.0f, 1.0f, 0.0f);
|
||||
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
} else if (highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
GlStateManager.rotate(-f3, 0.0f, 1.0f, 0.0f);
|
||||
float xd = (float)(abstractclientplayer.posX - abstractclientplayer.prevPosX);
|
||||
float xd = (float) (abstractclientplayer.posX - abstractclientplayer.prevPosX);
|
||||
GlStateManager.rotate(-xd * 40.0f * var15, 0.0f, 0.0f, 1.0f);
|
||||
float zd = (float)(abstractclientplayer.posZ - abstractclientplayer.prevPosZ);
|
||||
float zd = (float) (abstractclientplayer.posZ - abstractclientplayer.prevPosZ);
|
||||
GlStateManager.rotate(-zd * 40.0f * var15, 1.0f, 0.0f, 0.0f);
|
||||
GlStateManager.rotate(f3, 0.0f, 1.0f, 0.0f);
|
||||
}else if(highPolySkin == HighPolySkin.BABY_WINSTON) {
|
||||
} else if (highPolySkin == HighPolySkin.BABY_WINSTON) {
|
||||
GlStateManager.translate(0.0f, (MathHelper.cos(f10 % 100000.0f) + 1.0f) * var15 * 0.2f, 0.0f);
|
||||
GlStateManager.rotate(MathHelper.sin(var16) * 5f * var15, 0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.rotate(MathHelper.cos(var16) * 5f * var15, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
if (abstractclientplayer.hurtTime > 0 || abstractclientplayer.deathTime > 0) {
|
||||
GlStateManager.color(1.2f, 0.8F, 0.8F, 1.0F);
|
||||
}
|
||||
|
||||
if(DeferredStateManager.isInDeferredPass()) {
|
||||
|
||||
if (DeferredStateManager.isInDeferredPass()) {
|
||||
DeferredStateManager.setDefaultMaterialConstants();
|
||||
DeferredStateManager.setRoughnessConstant(0.5f);
|
||||
DeferredStateManager.setMetalnessConstant(0.05f);
|
||||
}
|
||||
|
||||
if(highPolySkin.bodyModel != null) {
|
||||
|
||||
if (highPolySkin.bodyModel != null) {
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.bodyModel));
|
||||
}
|
||||
float jumpFactor = 0.0f;
|
||||
|
||||
if(highPolySkin.headModel != null) {
|
||||
if(highPolySkin == HighPolySkin.BABY_CHARLES) {
|
||||
|
||||
if (highPolySkin.headModel != null) {
|
||||
if (highPolySkin == HighPolySkin.BABY_CHARLES) {
|
||||
long millis = System.currentTimeMillis();
|
||||
float partialTicks = (float) ((millis - abstractclientplayer.eaglerHighPolyAnimationTick) * 0.02);
|
||||
//long l50 = millis / 50l * 50l;
|
||||
//boolean runTick = par1EntityPlayer.eaglerHighPolyAnimationTick < l50 && millis >= l50;
|
||||
float partialTicks = (float) ((millis - abstractclientplayer.eaglerHighPolyAnimationTick)
|
||||
* 0.02);
|
||||
// long l50 = millis / 50l * 50l;
|
||||
// boolean runTick = par1EntityPlayer.eaglerHighPolyAnimationTick < l50 &&
|
||||
// millis >= l50;
|
||||
abstractclientplayer.eaglerHighPolyAnimationTick = millis;
|
||||
|
||||
if(partialTicks < 0.0f) {
|
||||
|
||||
if (partialTicks < 0.0f) {
|
||||
partialTicks = 0.0f;
|
||||
}
|
||||
if(partialTicks > 1.0f) {
|
||||
if (partialTicks > 1.0f) {
|
||||
partialTicks = 1.0f;
|
||||
}
|
||||
|
||||
float jumpFac = (float)(abstractclientplayer.posY - abstractclientplayer.prevPosY);
|
||||
if(jumpFac < 0.0f && !abstractclientplayer.isCollidedVertically) {
|
||||
|
||||
float jumpFac = (float) (abstractclientplayer.posY - abstractclientplayer.prevPosY);
|
||||
if (jumpFac < 0.0f && !abstractclientplayer.isCollidedVertically) {
|
||||
jumpFac = -jumpFac;
|
||||
jumpFac *= 0.1f;
|
||||
}
|
||||
jumpFac -= 0.05f;
|
||||
if(jumpFac > 0.1f && !abstractclientplayer.isCollidedVertically) {
|
||||
if (jumpFac > 0.1f && !abstractclientplayer.isCollidedVertically) {
|
||||
jumpFac = 0.1f;
|
||||
}else if(jumpFac < 0.0f) {
|
||||
} else if (jumpFac < 0.0f) {
|
||||
jumpFac = 0.0f;
|
||||
}else if(jumpFac > 0.1f && abstractclientplayer.isCollidedVertically) {
|
||||
} else if (jumpFac > 0.1f && abstractclientplayer.isCollidedVertically) {
|
||||
jumpFac = 0.1f;
|
||||
}else if(jumpFac > 0.4f) {
|
||||
} else if (jumpFac > 0.4f) {
|
||||
jumpFac = 0.4f;
|
||||
}
|
||||
jumpFac *= 10.0f;
|
||||
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat3 += (jumpFac / (jumpFac + 1.0f)) * 6.0f * partialTicks;
|
||||
|
||||
if(Float.isInfinite(abstractclientplayer.eaglerHighPolyAnimationFloat3)) {
|
||||
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat3 += (jumpFac / (jumpFac + 1.0f)) * 6.0f
|
||||
* partialTicks;
|
||||
|
||||
if (Float.isInfinite(abstractclientplayer.eaglerHighPolyAnimationFloat3)) {
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat3 = 1.0f;
|
||||
}else if(abstractclientplayer.eaglerHighPolyAnimationFloat3 > 1.0f) {
|
||||
} else if (abstractclientplayer.eaglerHighPolyAnimationFloat3 > 1.0f) {
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat3 = 1.0f;
|
||||
}else if(abstractclientplayer.eaglerHighPolyAnimationFloat3 < -1.0f) {
|
||||
} else if (abstractclientplayer.eaglerHighPolyAnimationFloat3 < -1.0f) {
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat3 = -1.0f;
|
||||
}
|
||||
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat2 += abstractclientplayer.eaglerHighPolyAnimationFloat3 * partialTicks;
|
||||
|
||||
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat2 += abstractclientplayer.eaglerHighPolyAnimationFloat3
|
||||
* partialTicks;
|
||||
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat5 += partialTicks;
|
||||
while(abstractclientplayer.eaglerHighPolyAnimationFloat5 > 0.05f) {
|
||||
while (abstractclientplayer.eaglerHighPolyAnimationFloat5 > 0.05f) {
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat5 -= 0.05f;
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat3 *= 0.99f;
|
||||
abstractclientplayer.eaglerHighPolyAnimationFloat2 *= 0.9f;
|
||||
}
|
||||
|
||||
jumpFactor = abstractclientplayer.eaglerHighPolyAnimationFloat2; //(abstractclientplayer.eaglerHighPolyAnimationFloat1 - abstractclientplayer.eaglerHighPolyAnimationFloat2) * partialTicks + abstractclientplayer.eaglerHighPolyAnimationFloat2;
|
||||
|
||||
jumpFactor = abstractclientplayer.eaglerHighPolyAnimationFloat2; // (abstractclientplayer.eaglerHighPolyAnimationFloat1
|
||||
// -
|
||||
// abstractclientplayer.eaglerHighPolyAnimationFloat2)
|
||||
// * partialTicks +
|
||||
// abstractclientplayer.eaglerHighPolyAnimationFloat2;
|
||||
jumpFactor -= 0.12f;
|
||||
if(jumpFactor < 0.0f) {
|
||||
if (jumpFactor < 0.0f) {
|
||||
jumpFactor = 0.0f;
|
||||
}
|
||||
jumpFactor = jumpFactor / (jumpFactor + 2.0f);
|
||||
if(jumpFactor > 1.0f) {
|
||||
if (jumpFactor > 1.0f) {
|
||||
jumpFactor = 1.0f;
|
||||
}
|
||||
}
|
||||
if(jumpFactor > 0.0f) {
|
||||
if (jumpFactor > 0.0f) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0f, jumpFactor * 3.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.headModel));
|
||||
|
||||
if(jumpFactor > 0.0f) {
|
||||
|
||||
if (jumpFactor > 0.0f) {
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
if(highPolySkin.limbsModel != null && highPolySkin.limbsModel.length > 0) {
|
||||
for(int i = 0; i < highPolySkin.limbsModel.length; ++i) {
|
||||
|
||||
if (highPolySkin.limbsModel != null && highPolySkin.limbsModel.length > 0) {
|
||||
for (int i = 0; i < highPolySkin.limbsModel.length; ++i) {
|
||||
DeferredStateManager.setRoughnessConstant(0.023f);
|
||||
DeferredStateManager.setMetalnessConstant(0.902f);
|
||||
float offset = 0.0f;
|
||||
if(highPolySkin.limbsOffset != null) {
|
||||
if(highPolySkin.limbsOffset.length == 1) {
|
||||
if (highPolySkin.limbsOffset != null) {
|
||||
if (highPolySkin.limbsOffset.length == 1) {
|
||||
offset = highPolySkin.limbsOffset[0];
|
||||
}else {
|
||||
} else {
|
||||
offset = highPolySkin.limbsOffset[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
if(offset != 0.0f || highPolySkin.limbsInitialRotation != 0.0f) {
|
||||
if(offset != 0.0f) {
|
||||
|
||||
if (offset != 0.0f || highPolySkin.limbsInitialRotation != 0.0f) {
|
||||
if (offset != 0.0f) {
|
||||
GlStateManager.translate(0.0f, offset, 0.0f);
|
||||
}
|
||||
if(highPolySkin.limbsInitialRotation != 0.0f) {
|
||||
if (highPolySkin.limbsInitialRotation != 0.0f) {
|
||||
GlStateManager.rotate(highPolySkin.limbsInitialRotation, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if(highPolySkin == HighPolySkin.LONG_ARMS) {
|
||||
if(abstractclientplayer.isSwingInProgress) {
|
||||
float var17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
|
||||
|
||||
if (highPolySkin == HighPolySkin.LONG_ARMS) {
|
||||
if (abstractclientplayer.isSwingInProgress) {
|
||||
float var17 = MathHelper
|
||||
.cos(-abstractclientplayer.getSwingProgress(f1) * (float) Math.PI * 2.0f - 1.2f)
|
||||
- 0.362f;
|
||||
var17 *= var17;
|
||||
GlStateManager.rotate(-var17 * 20.0f, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}else if(highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
if(abstractclientplayer.isSwingInProgress) {
|
||||
float var17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
|
||||
} else if (highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
if (abstractclientplayer.isSwingInProgress) {
|
||||
float var17 = MathHelper
|
||||
.cos(-abstractclientplayer.getSwingProgress(f1) * (float) Math.PI * 2.0f - 1.2f)
|
||||
- 0.362f;
|
||||
var17 *= var17;
|
||||
GlStateManager.rotate(var17 * 60.0f, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
GlStateManager.rotate(40.0f * var15, 1.0f, 0.0f, 0.0f);
|
||||
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
} else if (highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
float fff = (i == 0) ? 1.0f : -1.0f;
|
||||
float swing = (MathHelper.cos(f10 % 100000.0f) * fff + 0.2f) * var15;
|
||||
float swing2 = (MathHelper.cos(f10 % 100000.0f) * fff * 0.5f + 0.0f) * var15;
|
||||
GlStateManager.rotate(swing * 25.0f, 1.0f, 0.0f, 0.0f);
|
||||
if(abstractclientplayer.isSwingInProgress) {
|
||||
float var17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
|
||||
if (abstractclientplayer.isSwingInProgress) {
|
||||
float var17 = MathHelper
|
||||
.cos(-abstractclientplayer.getSwingProgress(f1) * (float) Math.PI * 2.0f - 1.2f)
|
||||
- 0.362f;
|
||||
var17 *= var17;
|
||||
GlStateManager.rotate(-var17 * 25.0f, 1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
// shear matrix
|
||||
tmpMatrix.setIdentity();
|
||||
tmpMatrix.m21 = swing2;
|
||||
tmpMatrix.m23 = swing2 * -0.2f;
|
||||
GlStateManager.multMatrix(tmpMatrix);
|
||||
}
|
||||
|
||||
if(i != 0) {
|
||||
|
||||
if (i != 0) {
|
||||
mc.getTextureManager().bindTexture(highPolySkin.texture);
|
||||
if (abstractclientplayer.hurtTime > 0 || abstractclientplayer.deathTime > 0) {
|
||||
GlStateManager.color(1.2f, 0.8F, 0.8F, 1.0F);
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.color(1.0f, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.limbsModel[i]));
|
||||
|
||||
if(i == 0) {
|
||||
|
||||
if (i == 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
|
||||
GlStateManager.translate(-0.287f, 0.05f, 0.0f);
|
||||
|
||||
if(highPolySkin == HighPolySkin.LONG_ARMS) {
|
||||
|
||||
if (highPolySkin == HighPolySkin.LONG_ARMS) {
|
||||
GlStateManager.translate(1.72f, 2.05f, -0.24f);
|
||||
ItemStack stk = abstractclientplayer.getHeldItem();
|
||||
if(stk != null) {
|
||||
if (stk != null) {
|
||||
Item itm = stk.getItem();
|
||||
if(itm != null) {
|
||||
if(itm == Items.bow) {
|
||||
if (itm != null) {
|
||||
if (itm == Items.bow) {
|
||||
GlStateManager.translate(-0.22f, 0.8f, 0.6f);
|
||||
GlStateManager.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
|
||||
}else if(itm instanceof ItemBlock && !((ItemBlock)itm).getBlock().isNormalCube()) {
|
||||
} else if (itm instanceof ItemBlock
|
||||
&& !((ItemBlock) itm).getBlock().isNormalCube()) {
|
||||
GlStateManager.translate(0.0f, -0.1f, 0.13f);
|
||||
}else if(!itm.isFull3D()) {
|
||||
} else if (!itm.isFull3D()) {
|
||||
GlStateManager.translate(-0.08f, -0.1f, 0.16f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
} else if (highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
|
||||
GlStateManager.translate(-0.029f, 1.2f, -3f);
|
||||
GlStateManager.rotate(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||
float var17 = -1.2f * var15;
|
||||
if(abstractclientplayer.isSwingInProgress) {
|
||||
float vvar17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
|
||||
if (abstractclientplayer.isSwingInProgress) {
|
||||
float vvar17 = MathHelper.cos(
|
||||
-abstractclientplayer.getSwingProgress(f1) * (float) Math.PI * 2.0f - 1.2f)
|
||||
- 0.362f;
|
||||
var17 = vvar17 < var17 ? vvar17 : var17;
|
||||
}
|
||||
GlStateManager.translate(-0.02f * var17, 0.42f * var17, var17 * 0.35f);
|
||||
GlStateManager.rotate(var17 * 30.0f, 1.0f, 0.0f, 0.0f);
|
||||
GlStateManager.rotate(110.0f, 1.0f, 0.0f, 0.0f);
|
||||
ItemStack stk = abstractclientplayer.getHeldItem();
|
||||
if(stk != null) {
|
||||
if (stk != null) {
|
||||
Item itm = stk.getItem();
|
||||
if(itm != null) {
|
||||
if(itm == Items.bow) {
|
||||
if (itm != null) {
|
||||
if (itm == Items.bow) {
|
||||
GlStateManager.translate(-0.18f, 1.0f, 0.4f);
|
||||
GlStateManager.rotate(-95.0f, 1.0f, 0.0f, 0.0f);
|
||||
}else if(itm instanceof ItemBlock && !((ItemBlock)itm).getBlock().isNormalCube()) {
|
||||
} else if (itm instanceof ItemBlock
|
||||
&& !((ItemBlock) itm).getBlock().isNormalCube()) {
|
||||
GlStateManager.translate(0.0f, -0.1f, 0.13f);
|
||||
}else if(!itm.isFull3D()) {
|
||||
} else if (!itm.isFull3D()) {
|
||||
GlStateManager.translate(-0.08f, -0.1f, 0.16f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
} else if (highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
|
||||
GlStateManager.translate(1.291f, 2.44f, -2.18f);
|
||||
GlStateManager.rotate(95.0f, 1.0f, 0.0f, 0.0f);
|
||||
ItemStack stk = abstractclientplayer.getHeldItem();
|
||||
if(stk != null) {
|
||||
if (stk != null) {
|
||||
Item itm = stk.getItem();
|
||||
if(itm != null) {
|
||||
if(itm == Items.bow) {
|
||||
if (itm != null) {
|
||||
if (itm == Items.bow) {
|
||||
GlStateManager.translate(-0.65f, 1.3f, -0.1f);
|
||||
GlStateManager.rotate(180.0f, 0.0f, 0.0f, 1.0f);
|
||||
GlStateManager.rotate(20.0f, 1.0f, 0.0f, 0.0f);
|
||||
}else if(itm instanceof ItemBlock && !((ItemBlock)itm).getBlock().isNormalCube()) {
|
||||
} else if (itm instanceof ItemBlock
|
||||
&& !((ItemBlock) itm).getBlock().isNormalCube()) {
|
||||
GlStateManager.translate(0.0f, -0.35f, 0.4f);
|
||||
}else if(!itm.isFull3D()) {
|
||||
} else if (!itm.isFull3D()) {
|
||||
GlStateManager.translate(-0.1f, -0.1f, 0.16f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DeferredStateManager.setDefaultMaterialConstants();
|
||||
renderHeldItem(abstractclientplayer, f1);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
if(highPolySkin.eyesModel != null && !DeferredStateManager.isEnableShadowRender()) {
|
||||
|
||||
if (highPolySkin.eyesModel != null && !DeferredStateManager.isEnableShadowRender()) {
|
||||
float ff = 0.00416f;
|
||||
int brightness = abstractclientplayer.getBrightnessForRender(0.0f);
|
||||
float blockLight = (brightness % 65536) * ff;
|
||||
float skyLight = (brightness / 65536) * ff;
|
||||
float sunCurve = (float)((abstractclientplayer.worldObj.getWorldTime() + 4000l) % 24000) / 24000.0f;
|
||||
sunCurve = MathHelper.clamp_float(9.8f - MathHelper.abs(sunCurve * 5.0f + sunCurve * sunCurve * 45.0f - 14.3f) * 0.7f, 0.0f, 1.0f);
|
||||
float sunCurve = (float) ((abstractclientplayer.worldObj.getWorldTime() + 4000l) % 24000)
|
||||
/ 24000.0f;
|
||||
sunCurve = MathHelper.clamp_float(
|
||||
9.8f - MathHelper.abs(sunCurve * 5.0f + sunCurve * sunCurve * 45.0f - 14.3f) * 0.7f, 0.0f,
|
||||
1.0f);
|
||||
skyLight = skyLight * (sunCurve * 0.85f + 0.15f);
|
||||
blockLight = blockLight * (sunCurve * 0.3f + 0.7f);
|
||||
float eyeBrightness = blockLight;
|
||||
if(skyLight > eyeBrightness) {
|
||||
if (skyLight > eyeBrightness) {
|
||||
eyeBrightness = skyLight;
|
||||
}
|
||||
eyeBrightness += blockLight * 0.2f;
|
||||
eyeBrightness = 1.0f - eyeBrightness;
|
||||
eyeBrightness = MathHelper.clamp_float(eyeBrightness * 1.9f - 1.0f, 0.0f, 1.0f);
|
||||
if(eyeBrightness > 0.1f) {
|
||||
if(DeferredStateManager.isInDeferredPass()) {
|
||||
if (eyeBrightness > 0.1f) {
|
||||
if (DeferredStateManager.isInDeferredPass()) {
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
DeferredStateManager.setDefaultMaterialConstants();
|
||||
DeferredStateManager.setEmissionConstant(eyeBrightness);
|
||||
}else {
|
||||
} else {
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_ONE, GL_ONE);
|
||||
GlStateManager.color(eyeBrightness * 7.0f, eyeBrightness * 7.0f, eyeBrightness * 7.0f, 1.0f);
|
||||
if(jumpFactor > 0.0f) {
|
||||
GlStateManager.color(eyeBrightness * 7.0f, eyeBrightness * 7.0f, eyeBrightness * 7.0f,
|
||||
1.0f);
|
||||
if (jumpFactor > 0.0f) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0f, jumpFactor * 3.0f, 0.0f);
|
||||
}
|
||||
|
@ -402,22 +437,22 @@ public class RenderHighPoly extends RenderPlayer {
|
|||
GlStateManager.disableTexture2D();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableCull();
|
||||
|
||||
|
||||
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.eyesModel));
|
||||
|
||||
|
||||
GlStateManager.enableTexture2D();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.disableCull();
|
||||
if(jumpFactor > 0.0f) {
|
||||
if (jumpFactor > 0.0f) {
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if(!DeferredStateManager.isInDeferredPass()) {
|
||||
if (!DeferredStateManager.isInDeferredPass()) {
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
logger.error("Couldn\'t render entity");
|
||||
logger.error(t);
|
||||
}
|
||||
|
@ -433,11 +468,11 @@ public class RenderHighPoly extends RenderPlayer {
|
|||
}
|
||||
|
||||
public void renderRightArm(AbstractClientPlayer clientPlayer) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void renderLeftArm(AbstractClientPlayer clientPlayer) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void renderHeldItem(AbstractClientPlayer clientPlayer, float partialTicks) {
|
||||
|
@ -468,4 +503,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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,7 +54,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;
|
||||
|
|
|
@ -429,11 +429,6 @@ public class ConnectionHandshake {
|
|||
RateLimitTracker.registerLockOut(PlatformNetworking.getCurrentURI());
|
||||
mc.displayGuiScreen(GuiDisconnected.createRateLimitKick(scr));
|
||||
} else if (errorCode == HandshakePacketTypes.SERVER_ERROR_CUSTOM_MESSAGE) {
|
||||
if (IChatComponent.Serializer.jsonToComponent(errStr).getUnformattedText().toLowerCase()
|
||||
.contains("banned from this server")) {
|
||||
EaglerProfile.updateUsernameCookies();
|
||||
reloadPage();
|
||||
}
|
||||
if (IChatComponent.Serializer.jsonToComponent(errStr).getUnformattedText().toLowerCase()
|
||||
.contains("reload page")) {
|
||||
EaglerProfile.updateUsernameCookieFromLocalStorage();
|
||||
|
|
|
@ -92,10 +92,6 @@ public class EaglercraftNetworkManager {
|
|||
}
|
||||
clientDisconnected = true;
|
||||
System.out.println("Closed channel: " + reason.getUnformattedText());
|
||||
if (reason.getUnformattedText().toLowerCase().contains("banned from this server")) {
|
||||
EaglerProfile.updateUsernameCookies();
|
||||
reloadPage();
|
||||
}
|
||||
if (reason.getUnformattedText().toLowerCase().contains("reload page")) {
|
||||
EaglerProfile.updateUsernameCookieFromLocalStorage();
|
||||
reloadPage();
|
||||
|
|
|
@ -13,14 +13,21 @@ import net.minecraft.client.resources.I18n;
|
|||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -44,7 +51,7 @@ public class GuiScreenNameWorldImport extends GuiScreen {
|
|||
this.importFormat = format;
|
||||
this.world = world;
|
||||
this.name = world.fileName;
|
||||
if(name.length() > 4 && (name.endsWith(".epk") || name.endsWith(".zip"))) {
|
||||
if (name.length() > 4 && (name.endsWith(".epk") || name.endsWith(".zip"))) {
|
||||
name = name.substring(0, name.length() - 4);
|
||||
}
|
||||
}
|
||||
|
@ -53,13 +60,17 @@ public class GuiScreenNameWorldImport extends GuiScreen {
|
|||
* Called from the main game loop to update the screen.
|
||||
*/
|
||||
public void updateScreen() {
|
||||
if(!timeToImport) {
|
||||
if (!timeToImport) {
|
||||
this.theGuiTextField.updateCursorCounter();
|
||||
}
|
||||
if(definetlyTimeToImport && !isImporting) {
|
||||
if (definetlyTimeToImport && !isImporting) {
|
||||
isImporting = true;
|
||||
SingleplayerServerController.importWorld(GuiCreateWorld.func_146317_a(mc.getSaveLoader(), this.theGuiTextField.getText().trim()), world.fileData, importFormat, (byte) ((loadSpawnChunks ? 2 : 0) | (enhancedGameRules ? 1 : 0)));
|
||||
mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(parentGuiScreen, "singleplayer.busy.importing." + (importFormat + 1), "singleplayer.failed.importing." + (importFormat + 1), SingleplayerServerController::isReady));
|
||||
SingleplayerServerController.importWorld(
|
||||
GuiCreateWorld.func_146317_a(mc.getSaveLoader(), this.theGuiTextField.getText().trim()),
|
||||
world.fileData, importFormat, (byte) ((loadSpawnChunks ? 2 : 0) | (enhancedGameRules ? 1 : 0)));
|
||||
mc.displayGuiScreen(new GuiScreenIntegratedServerBusy(parentGuiScreen,
|
||||
"singleplayer.busy.importing." + (importFormat + 1),
|
||||
"singleplayer.failed.importing." + (importFormat + 1), SingleplayerServerController::isReady));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,16 +78,23 @@ public class GuiScreenNameWorldImport extends GuiScreen {
|
|||
* Adds the buttons (and other controls) to the screen in question.
|
||||
*/
|
||||
public void initGui() {
|
||||
if(!timeToImport) {
|
||||
if (!timeToImport) {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, I18n.format("singleplayer.import.continue")));
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, I18n.format("gui.cancel")));
|
||||
this.theGuiTextField = new GuiTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 3, 200, 20);
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12,
|
||||
I18n.format("singleplayer.import.continue")));
|
||||
this.buttonList
|
||||
.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + 12, I18n.format("gui.cancel")));
|
||||
this.theGuiTextField = new GuiTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 3,
|
||||
200, 20);
|
||||
this.theGuiTextField.setFocused(true);
|
||||
this.theGuiTextField.setText(name);
|
||||
this.buttonList.add(loadSpawnChunksBtn = new GuiButton(2, this.width / 2 - 100, this.height / 4 + 24 + 12, I18n.format("singleplayer.import.loadSpawnChunks", loadSpawnChunks ? I18n.format("gui.yes") : I18n.format("gui.no"))));
|
||||
this.buttonList.add(enhancedGameRulesBtn = new GuiButton(3, this.width / 2 - 100, this.height / 4 + 48 + 12, I18n.format("singleplayer.import.enhancedGameRules", enhancedGameRules ? I18n.format("gui.yes") : I18n.format("gui.no"))));
|
||||
this.buttonList.add(loadSpawnChunksBtn = new GuiButton(2, this.width / 2 - 100, this.height / 4 + 24 + 12,
|
||||
I18n.format("singleplayer.import.loadSpawnChunks",
|
||||
loadSpawnChunks ? I18n.format("gui.yes") : I18n.format("gui.no"))));
|
||||
this.buttonList.add(enhancedGameRulesBtn = new GuiButton(3, this.width / 2 - 100, this.height / 4 + 48 + 12,
|
||||
I18n.format("singleplayer.import.enhancedGameRules",
|
||||
enhancedGameRules ? I18n.format("gui.yes") : I18n.format("gui.no"))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,10 +119,12 @@ public class GuiScreenNameWorldImport extends GuiScreen {
|
|||
timeToImport = true;
|
||||
} else if (par1GuiButton.id == 2) {
|
||||
loadSpawnChunks = !loadSpawnChunks;
|
||||
loadSpawnChunksBtn.displayString = I18n.format("singleplayer.import.loadSpawnChunks", loadSpawnChunks ? I18n.format("gui.yes") : I18n.format("gui.no"));
|
||||
loadSpawnChunksBtn.displayString = I18n.format("singleplayer.import.loadSpawnChunks",
|
||||
loadSpawnChunks ? I18n.format("gui.yes") : I18n.format("gui.no"));
|
||||
} else if (par1GuiButton.id == 3) {
|
||||
enhancedGameRules = !enhancedGameRules;
|
||||
enhancedGameRulesBtn.displayString = I18n.format("singleplayer.import.enhancedGameRules", enhancedGameRules ? I18n.format("gui.yes") : I18n.format("gui.no"));
|
||||
enhancedGameRulesBtn.displayString = I18n.format("singleplayer.import.enhancedGameRules",
|
||||
enhancedGameRules ? I18n.format("gui.yes") : I18n.format("gui.no"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +147,7 @@ public class GuiScreenNameWorldImport extends GuiScreen {
|
|||
*/
|
||||
protected void mouseClicked(int par1, int par2, int par3) {
|
||||
super.mouseClicked(par1, par2, par3);
|
||||
if(!timeToImport) {
|
||||
if (!timeToImport) {
|
||||
this.theGuiTextField.mouseClicked(par1, par2, par3);
|
||||
}
|
||||
}
|
||||
|
@ -137,16 +157,21 @@ public class GuiScreenNameWorldImport extends GuiScreen {
|
|||
*/
|
||||
public void drawScreen(int par1, int par2, float par3) {
|
||||
this.drawDefaultBackground();
|
||||
if(!timeToImport) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.import.title"), this.width / 2, this.height / 4 - 60 + 20, 16777215);
|
||||
this.drawString(this.fontRendererObj, I18n.format("singleplayer.import.enterName"), this.width / 2 - 100, this.height / 4 - 60 + 50, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("createWorld.seedNote"), this.width / 2, this.height / 4 + 90, -6250336);
|
||||
if (!timeToImport) {
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("singleplayer.import.title"), this.width / 2,
|
||||
this.height / 4 - 60 + 20, 16777215);
|
||||
this.drawString(this.fontRendererObj, I18n.format("singleplayer.import.enterName"), this.width / 2 - 100,
|
||||
this.height / 4 - 60 + 50, 10526880);
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("createWorld.seedNote"), this.width / 2,
|
||||
this.height / 4 + 90, -6250336);
|
||||
this.theGuiTextField.drawTextBox();
|
||||
}else {
|
||||
} else {
|
||||
definetlyTimeToImport = true;
|
||||
long dots = (System.currentTimeMillis() / 500l) % 4l;
|
||||
String str = I18n.format("singleplayer.import.reading", world.fileName);
|
||||
this.drawString(fontRendererObj, str + (dots > 0 ? "." : "") + (dots > 1 ? "." : "") + (dots > 2 ? "." : ""), (this.width - this.fontRendererObj.getStringWidth(str)) / 2, this.height / 3 + 10, 0xFFFFFF);
|
||||
this.drawString(fontRendererObj,
|
||||
str + (dots > 0 ? "." : "") + (dots > 1 ? "." : "") + (dots > 2 ? "." : ""),
|
||||
(this.width - this.fontRendererObj.getStringWidth(str)) / 2, this.height / 3 + 10, 0xFFFFFF);
|
||||
}
|
||||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
|
|
|
@ -165,7 +165,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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
|
@ -358,9 +357,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);
|
||||
}
|
||||
|
|
|
@ -501,7 +501,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;
|
||||
|
@ -12,170 +13,185 @@ import net.lax1dude.eaglercraft.v1_8.IOUtils;
|
|||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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 EPKDecompiler {
|
||||
public class EPKDecompiler implements Closeable {
|
||||
|
||||
public static class FileEntry {
|
||||
public final String type;
|
||||
public final String name;
|
||||
public final byte[] data;
|
||||
|
||||
protected FileEntry(String type, String name, byte[] data) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ByteArrayInputStream in2;
|
||||
private InputStream zis;
|
||||
private CRC32 crc32;
|
||||
private int numFiles;
|
||||
private boolean isFinished = false;
|
||||
|
||||
|
||||
public EPKDecompiler(byte[] data) throws IOException {
|
||||
in2 = new ByteArrayInputStream(data);
|
||||
|
||||
|
||||
byte[] header = new byte[8];
|
||||
IOUtils.readFully(in2, header);
|
||||
|
||||
if(Arrays.equals(header, new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)36,(byte)36})) {
|
||||
byte[] endCode = new byte[] { (byte)':', (byte)':', (byte)':', (byte)'Y',
|
||||
(byte)'E', (byte)'E', (byte)':', (byte)'>' };
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
if(data[data.length - 8 + i] != endCode[i]) {
|
||||
|
||||
if (Arrays.equals(header, new byte[] { (byte) 69, (byte) 65, (byte) 71, (byte) 80, (byte) 75, (byte) 71,
|
||||
(byte) 36, (byte) 36 })) {
|
||||
byte[] endCode = new byte[] { (byte) ':', (byte) ':', (byte) ':', (byte) 'Y',
|
||||
(byte) 'E', (byte) 'E', (byte) ':', (byte) '>' };
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (data[data.length - 8 + i] != endCode[i]) {
|
||||
throw new IOException("EPK file is missing EOF code (:::YEE:>)");
|
||||
}
|
||||
}
|
||||
in2 = new ByteArrayInputStream(data, 8, data.length - 16);
|
||||
InputStream is = in2;
|
||||
|
||||
|
||||
String vers = readASCII(is);
|
||||
if(!vers.startsWith("ver2.")) {
|
||||
if (!vers.startsWith("ver2.")) {
|
||||
throw new IOException("Unknown or invalid EPK version: " + vers);
|
||||
}
|
||||
|
||||
IOUtils.skipFully(is, is.read()); // skip filename
|
||||
IOUtils.skipFully(is, loadShort(is)); // skip comment
|
||||
IOUtils.skipFully(is, 8); // skip millis date
|
||||
|
||||
|
||||
numFiles = loadInt(is);
|
||||
|
||||
char compressionType = (char)is.read();
|
||||
|
||||
switch(compressionType) {
|
||||
case 'G':
|
||||
zis = EaglerZLIB.newGZIPInputStream(is);
|
||||
break;
|
||||
case 'Z':
|
||||
zis = EaglerZLIB.newInflaterInputStream(is);
|
||||
break;
|
||||
case '0':
|
||||
zis = is;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Invalid or unsupported EPK compression: " + compressionType);
|
||||
|
||||
char compressionType = (char) is.read();
|
||||
|
||||
switch (compressionType) {
|
||||
case 'G':
|
||||
zis = EaglerZLIB.newGZIPInputStream(is);
|
||||
break;
|
||||
case 'Z':
|
||||
zis = EaglerZLIB.newInflaterInputStream(is);
|
||||
break;
|
||||
case '0':
|
||||
zis = is;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Invalid or unsupported EPK compression: " + compressionType);
|
||||
}
|
||||
|
||||
|
||||
crc32 = new CRC32();
|
||||
}else if(Arrays.equals(header, new byte[]{(byte)69,(byte)65,(byte)71,(byte)80,(byte)75,(byte)71,(byte)33,(byte)33})) {
|
||||
} else if (Arrays.equals(header, new byte[] { (byte) 69, (byte) 65, (byte) 71, (byte) 80, (byte) 75, (byte) 71,
|
||||
(byte) 33, (byte) 33 })) {
|
||||
throw new IOException("FILE IS AN UNSUPPORTED LEGACY FORMAT!");
|
||||
}else {
|
||||
} else {
|
||||
throw new IOException("FILE IS NOT AN EPK FILE!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public FileEntry readFile() throws IOException {
|
||||
if(isFinished) {
|
||||
if (isFinished) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
byte[] typeBytes = new byte[4];
|
||||
IOUtils.readFully(zis, typeBytes);
|
||||
String type = readASCII(typeBytes);
|
||||
|
||||
if(numFiles == 0) {
|
||||
if(!"END$".equals(type)) {
|
||||
|
||||
if (numFiles == 0) {
|
||||
if (!"END$".equals(type)) {
|
||||
throw new IOException("EPK file is missing END code (END$)");
|
||||
}
|
||||
isFinished = true;
|
||||
return null;
|
||||
}else {
|
||||
if("END$".equals(type)) {
|
||||
} else {
|
||||
if ("END$".equals(type)) {
|
||||
throw new IOException("Unexpected END when there are still " + numFiles + " files remaining");
|
||||
}else {
|
||||
} else {
|
||||
String name = readASCII(zis);
|
||||
int len = loadInt(zis);
|
||||
byte[] data;
|
||||
|
||||
if("FILE".equals(type)) {
|
||||
if(len < 5) {
|
||||
|
||||
if ("FILE".equals(type)) {
|
||||
if (len < 5) {
|
||||
throw new IOException("File '" + name + "' is incomplete (no crc)");
|
||||
}
|
||||
|
||||
|
||||
int loadedCrc = loadInt(zis);
|
||||
|
||||
|
||||
data = new byte[len - 5];
|
||||
IOUtils.readFully(zis, data);
|
||||
|
||||
|
||||
crc32.reset();
|
||||
crc32.update(data, 0, data.length);
|
||||
if((int)crc32.getValue() != loadedCrc) {
|
||||
if ((int) crc32.getValue() != loadedCrc) {
|
||||
throw new IOException("File '" + name + "' has an invalid checksum");
|
||||
}
|
||||
|
||||
if(zis.read() != ':') {
|
||||
|
||||
if (zis.read() != ':') {
|
||||
throw new IOException("File '" + name + "' is incomplete");
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
data = new byte[len];
|
||||
IOUtils.readFully(zis, data);
|
||||
}
|
||||
|
||||
if(zis.read() != '>') {
|
||||
|
||||
if (zis.read() != '>') {
|
||||
throw new IOException("Object '" + name + "' is incomplete");
|
||||
}
|
||||
|
||||
|
||||
--numFiles;
|
||||
return new FileEntry(type, name, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final int loadShort(InputStream is) throws IOException {
|
||||
return (is.read() << 8) | is.read();
|
||||
}
|
||||
|
||||
|
||||
public static final int loadInt(InputStream is) throws IOException {
|
||||
return (is.read() << 24) | (is.read() << 16) | (is.read() << 8) | is.read();
|
||||
}
|
||||
|
||||
|
||||
public static final String readASCII(byte[] bytesIn) throws IOException {
|
||||
char[] charIn = new char[bytesIn.length];
|
||||
for(int i = 0; i < bytesIn.length; ++i) {
|
||||
charIn[i] = (char)((int)bytesIn[i] & 0xFF);
|
||||
}
|
||||
return new String(charIn);
|
||||
}
|
||||
|
||||
public static final String readASCII(InputStream bytesIn) throws IOException {
|
||||
int len = bytesIn.read();
|
||||
char[] charIn = new char[len];
|
||||
for(int i = 0; i < len; ++i) {
|
||||
charIn[i] = (char)(bytesIn.read() & 0xFF);
|
||||
for (int i = 0; i < bytesIn.length; ++i) {
|
||||
charIn[i] = (char) ((int) bytesIn[i] & 0xFF);
|
||||
}
|
||||
return new String(charIn);
|
||||
}
|
||||
|
||||
public static final String readASCII(InputStream bytesIn) throws IOException {
|
||||
int len = bytesIn.read();
|
||||
char[] charIn = new char[len];
|
||||
for (int i = 0; i < len; ++i) {
|
||||
charIn[i] = (char) (bytesIn.read() & 0xFF);
|
||||
}
|
||||
return new String(charIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
zis.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@ import net.minecraft.nbt.CompressedStreamTools;
|
|||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
|
@ -48,44 +47,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,7 @@ import net.minecraft.nbt.CompressedStreamTools;
|
|||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
|
@ -58,124 +57,126 @@ 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));
|
||||
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);
|
||||
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!");
|
||||
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());
|
||||
|
@ -194,130 +195,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();
|
||||
}
|
||||
|
|
|
@ -257,9 +257,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());
|
||||
|
|
|
@ -19,14 +19,21 @@ import net.minecraft.client.Minecraft;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -34,16 +41,16 @@ import net.minecraft.client.Minecraft;
|
|||
public class RelayUpdateChecker {
|
||||
|
||||
private static class RelayEntry {
|
||||
|
||||
|
||||
private final String uri;
|
||||
private boolean queued;
|
||||
private boolean handshake;
|
||||
private RelayServerSocket currentSocket;
|
||||
|
||||
|
||||
private RelayEntry(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static final List<RelayEntry> relaysList = new ArrayList();
|
||||
|
@ -56,16 +63,16 @@ public class RelayUpdateChecker {
|
|||
private static final String magic = "~!REQUEST_UPDATE_CERT";
|
||||
|
||||
public static void runTick() {
|
||||
if(!EagRuntime.getConfiguration().isCheckRelaysForUpdates()) {
|
||||
if (!EagRuntime.getConfiguration().isCheckRelaysForUpdates()) {
|
||||
return;
|
||||
}
|
||||
if(!hasInit) {
|
||||
if (!hasInit) {
|
||||
hasInit = true;
|
||||
for(net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry etr : EagRuntime.getConfiguration().getRelays()) {
|
||||
for (net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry etr : EagRuntime.getConfiguration().getRelays()) {
|
||||
relaysList.add(new RelayEntry(etr.address));
|
||||
}
|
||||
byte[] b = PlatformApplication.getLocalStorage("lastRelayUpdate");
|
||||
if(b != null) {
|
||||
byte[] b = PlatformApplication.getLocalStorage("lastRelayUpdate", false);
|
||||
if (b != null) {
|
||||
try {
|
||||
lastUpdateCheck = (new DataInputStream(new EaglerInputStream(b))).readLong();
|
||||
} catch (IOException e) {
|
||||
|
@ -74,33 +81,33 @@ public class RelayUpdateChecker {
|
|||
}
|
||||
long millis = System.currentTimeMillis();
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if((mc.theWorld == null || mc.isSingleplayer()) && millis - lastUpdateCheck > updateCheckRate) {
|
||||
if ((mc.theWorld == null || mc.isSingleplayer()) && millis - lastUpdateCheck > updateCheckRate) {
|
||||
lastUpdateCheck = millis;
|
||||
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) {
|
||||
relaysList.get(i).queued = true;
|
||||
}
|
||||
}
|
||||
for(int i = 0, l = relaysList.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relaysList.size(); i < l; ++i) {
|
||||
RelayEntry etr = relaysList.get(i);
|
||||
if(etr.currentSocket != null) {
|
||||
if (etr.currentSocket != null) {
|
||||
updateRelay(etr);
|
||||
if(etr.currentSocket != null) {
|
||||
if (etr.currentSocket != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int i = 0, l = relaysList.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relaysList.size(); i < l; ++i) {
|
||||
RelayEntry etr = relaysList.get(i);
|
||||
if(etr.queued) {
|
||||
if (etr.queued) {
|
||||
etr.queued = false;
|
||||
connect(etr);
|
||||
if(etr.currentSocket != null) {
|
||||
if (etr.currentSocket != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -111,30 +118,31 @@ public class RelayUpdateChecker {
|
|||
try {
|
||||
socket.handshake = false;
|
||||
socket.currentSocket = PlatformWebRTC.openRelayConnection(socket.uri, 10000);
|
||||
if(socket.currentSocket.isClosed()) {
|
||||
if (socket.currentSocket.isClosed()) {
|
||||
socket.currentSocket = null;
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateRelay(RelayEntry socket) {
|
||||
try {
|
||||
if(socket.currentSocket.isClosed()) {
|
||||
if (socket.currentSocket.isClosed()) {
|
||||
socket.currentSocket = null;
|
||||
}else if(socket.currentSocket.isOpen()) {
|
||||
if(!socket.handshake) {
|
||||
} else if (socket.currentSocket.isOpen()) {
|
||||
if (!socket.handshake) {
|
||||
socket.handshake = true;
|
||||
socket.currentSocket.writePacket(new IPacket00Handshake(0x02, RelayManager.preferredRelayVersion, magic));
|
||||
}else {
|
||||
socket.currentSocket
|
||||
.writePacket(new IPacket00Handshake(0x02, RelayManager.preferredRelayVersion, magic));
|
||||
} else {
|
||||
// close immediately
|
||||
if(socket.currentSocket.nextPacket() != null) {
|
||||
if (socket.currentSocket.nextPacket() != null) {
|
||||
socket.currentSocket.close();
|
||||
socket.currentSocket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,21 @@ import net.lax1dude.eaglercraft.v1_8.crypto.SHA256Digest;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -37,6 +44,7 @@ public class UpdateCertificate {
|
|||
|
||||
public final String type;
|
||||
public final String addr;
|
||||
|
||||
private DLSource(String type, String addr) {
|
||||
this.type = type;
|
||||
this.addr = addr;
|
||||
|
@ -78,44 +86,48 @@ public class UpdateCertificate {
|
|||
|
||||
public final DLSource[] bundleDataSources;
|
||||
|
||||
public static UpdateCertificate parseAndVerifyCertificate(byte[] certData) throws IOException, CertificateInvalidException {
|
||||
public static UpdateCertificate parseAndVerifyCertificate(byte[] certData)
|
||||
throws IOException, CertificateInvalidException {
|
||||
InputStream is = new EaglerInputStream(certData);
|
||||
if(is.read() != 'E' || is.read() != 'A' || is.read() != 'G' || is.read() != 'S' || is.read() != 'I' || is.read() != 'G') {
|
||||
if (is.read() != 'E' || is.read() != 'A' || is.read() != 'G' || is.read() != 'S' || is.read() != 'I'
|
||||
|| is.read() != 'G') {
|
||||
throw new IOException("Data is not a certificate!");
|
||||
}
|
||||
|
||||
|
||||
int vers = is.read() << 8;
|
||||
vers |= is.read();
|
||||
if(vers != 1) {
|
||||
if (vers != 1) {
|
||||
throw new IOException("Invalid certificate version: " + vers);
|
||||
}
|
||||
|
||||
|
||||
byte[] rsa2048sum = new byte[256];
|
||||
IOUtils.readFully(is, rsa2048sum);
|
||||
|
||||
byte[] rsa2048sumDec = (new BigInteger(rsa2048sum)).modPow(new BigInteger("65537"), EaglercraftVersion.updateSignatureModulus).toByteArray();
|
||||
|
||||
if(rsa2048sumDec.length > 256) {
|
||||
|
||||
byte[] rsa2048sumDec = (new BigInteger(rsa2048sum))
|
||||
.modPow(new BigInteger("65537"), EaglercraftVersion.updateSignatureModulus).toByteArray();
|
||||
|
||||
if (rsa2048sumDec.length > 256) {
|
||||
throw new IOException("Invalid decrypted hash length: " + rsa2048sum.length);
|
||||
}
|
||||
|
||||
if(rsa2048sumDec.length < 256) {
|
||||
|
||||
if (rsa2048sumDec.length < 256) {
|
||||
byte[] tmp = rsa2048sumDec;
|
||||
rsa2048sumDec = new byte[256];
|
||||
System.arraycopy(tmp, 0, rsa2048sumDec, 256 - tmp.length, tmp.length);
|
||||
}
|
||||
|
||||
|
||||
int payloadLen = is.read() << 8;
|
||||
payloadLen |= is.read();
|
||||
|
||||
|
||||
byte[] signaturePayload = new byte[payloadLen];
|
||||
IOUtils.readFully(is, signaturePayload);
|
||||
|
||||
|
||||
SHA256Digest sha256 = new SHA256Digest();
|
||||
sha256.update(new byte[] { (byte) 170, (byte) 191, (byte) 203, (byte) 188, (byte) 47, (byte) 37, (byte) 17,
|
||||
(byte) 187, (byte) 169, (byte) 225, (byte) 247, (byte) 193, (byte) 100, (byte) 101, (byte) 233,
|
||||
(byte) 106, (byte) 80, (byte) 204, (byte) 192, (byte) 140, (byte) 19, (byte) 18, (byte) 165, (byte) 252,
|
||||
(byte) 138, (byte) 187, (byte) 229, (byte) 148, (byte) 118, (byte) 208, (byte) 179, (byte) 233 }, 0, 32);
|
||||
(byte) 138, (byte) 187, (byte) 229, (byte) 148, (byte) 118, (byte) 208, (byte) 179, (byte) 233 }, 0,
|
||||
32);
|
||||
sha256.update(signaturePayload, 0, signaturePayload.length);
|
||||
byte[] hash2048 = new byte[256];
|
||||
sha256.doFinal(hash2048, 0);
|
||||
|
@ -140,15 +152,24 @@ public class UpdateCertificate {
|
|||
(byte) 88, (byte) 215, (byte) 216, (byte) 253, (byte) 235, (byte) 7, (byte) 60 }, 0, 32);
|
||||
sha256.update(signaturePayload, 0, signaturePayload.length);
|
||||
sha256.doFinal(hash2048, 96);
|
||||
|
||||
hash2048[0] = (byte)((signaturePayload.length >> 8) & 0xFF);
|
||||
hash2048[1] = (byte)(signaturePayload.length & 0xFF);
|
||||
|
||||
if(!Arrays.equals(hash2048, rsa2048sumDec)) {
|
||||
|
||||
hash2048[0] = (byte) ((signaturePayload.length >> 8) & 0xFF);
|
||||
hash2048[1] = (byte) (signaturePayload.length & 0xFF);
|
||||
|
||||
if (!Arrays.equals(hash2048, rsa2048sumDec)) {
|
||||
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 {
|
||||
|
@ -168,14 +189,14 @@ public class UpdateCertificate {
|
|||
IOUtils.skipFully(dis, dis.read());
|
||||
int sourceCount = dis.readInt();
|
||||
this.bundleDataSources = new DLSource[sourceCount];
|
||||
for(int i = 0; i < sourceCount; ++i) {
|
||||
for (int i = 0; i < sourceCount; ++i) {
|
||||
IOUtils.skipFully(dis, 4);
|
||||
bundleDataSources[i] = new DLSource(dis.readUTF(), dis.readUTF());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBundleDataValid(byte[] bundleData) {
|
||||
if(bundleData.length != bundleDataLength) {
|
||||
if (bundleData.length != bundleDataLength) {
|
||||
return false;
|
||||
}
|
||||
SHA256Digest sha256 = new SHA256Digest();
|
||||
|
@ -217,9 +238,9 @@ public class UpdateCertificate {
|
|||
&& sigVersion == other.sigVersion;
|
||||
}
|
||||
|
||||
public ListMultimap<String,String> getSourceMultimap() {
|
||||
ListMultimap<String,String> ret = ListMultimapBuilder.hashKeys().arrayListValues().build();
|
||||
for(int i = 0; i < bundleDataSources.length; ++i) {
|
||||
public ListMultimap<String, String> getSourceMultimap() {
|
||||
ListMultimap<String, String> ret = ListMultimapBuilder.hashKeys().arrayListValues().build();
|
||||
for (int i = 0; i < bundleDataSources.length; ++i) {
|
||||
ret.put(bundleDataSources[i].type, bundleDataSources[i].addr);
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -17,14 +17,21 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -58,57 +65,63 @@ public class UpdateService {
|
|||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o != null && (o == this || ((o instanceof RawKnownCertHolder) && Arrays.equals(((RawKnownCertHolder)o).data, data)));
|
||||
return o != null && (o == this
|
||||
|| ((o instanceof RawKnownCertHolder) && Arrays.equals(((RawKnownCertHolder) o).data, data)));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean supported() {
|
||||
return EaglercraftVersion.enableUpdateService && EagRuntime.getConfiguration().allowUpdateSvc() && PlatformUpdateSvc.supported();
|
||||
return EaglercraftVersion.enableUpdateService && EagRuntime.getConfiguration().allowUpdateSvc()
|
||||
&& PlatformUpdateSvc.supported();
|
||||
}
|
||||
|
||||
public static void initialize() {
|
||||
if(!supported()) {
|
||||
if (!supported()) {
|
||||
logger.info("Update service is not supported on this client");
|
||||
return;
|
||||
}
|
||||
PlatformUpdateSvc.initialize();
|
||||
if(PlatformUpdateSvc.getClientSignatureData() != null) {
|
||||
if (PlatformUpdateSvc.getClientSignatureData() != null) {
|
||||
logger.info("Testing client update certificate...");
|
||||
try {
|
||||
myUpdateCert = UpdateCertificate.parseAndVerifyCertificate(PlatformUpdateSvc.getClientSignatureData());
|
||||
if(!EaglercraftVersion.updateBundlePackageName.equalsIgnoreCase(myUpdateCert.bundlePackageName)) {
|
||||
throw new CertificateInvalidException("Certificate package name does not match current client package name!");
|
||||
if (!EaglercraftVersion.updateBundlePackageName.equalsIgnoreCase(myUpdateCert.bundlePackageName)) {
|
||||
throw new CertificateInvalidException(
|
||||
"Certificate package name does not match current client package name!");
|
||||
}
|
||||
if(EaglercraftVersion.updateBundlePackageVersionInt != myUpdateCert.bundleVersionInteger) {
|
||||
throw new CertificateInvalidException("Certificate client version does not match current client version!");
|
||||
if (EaglercraftVersion.updateBundlePackageVersionInt != myUpdateCert.bundleVersionInteger) {
|
||||
throw new CertificateInvalidException(
|
||||
"Certificate client version does not match current client version!");
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
myUpdateCert = null;
|
||||
logger.error("Client update certificate is invalid!");
|
||||
logger.error(t);
|
||||
}
|
||||
if(myUpdateCert != null && PlatformUpdateSvc.getClientBundleData() != null) {
|
||||
if (myUpdateCert != null && PlatformUpdateSvc.getClientBundleData() != null) {
|
||||
isBundleDataValid = myUpdateCert.isBundleDataValid(PlatformUpdateSvc.getClientBundleData());
|
||||
if(!isBundleDataValid) {
|
||||
logger.error("Client checksum does not match certificate! \"Download Offline\" button will download a fresh client");
|
||||
if (!isBundleDataValid) {
|
||||
logger.error(
|
||||
"Client checksum does not match certificate! \"Download Offline\" button will download a fresh client");
|
||||
}
|
||||
}
|
||||
}
|
||||
byte[] latestUpdate = PlatformApplication.getLocalStorage(EaglercraftVersion.updateLatestLocalStorageKey);
|
||||
if(latestUpdate != null) {
|
||||
byte[] latestUpdate = PlatformApplication.getLocalStorage(EaglercraftVersion.updateLatestLocalStorageKey,
|
||||
false);
|
||||
if (latestUpdate != null) {
|
||||
addCertificateToSet(latestUpdate, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getClientSignatureData() {
|
||||
if(myUpdateCert != null) {
|
||||
if (myUpdateCert != null) {
|
||||
return PlatformUpdateSvc.getClientSignatureData();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] getClientBundleData() {
|
||||
if(isBundleDataValid) {
|
||||
if (isBundleDataValid) {
|
||||
return PlatformUpdateSvc.getClientBundleData();
|
||||
}
|
||||
return null;
|
||||
|
@ -124,14 +137,16 @@ public class UpdateService {
|
|||
|
||||
private static void addCertificateToSet(byte[] certificateData, boolean saveLatest) {
|
||||
if (EagRuntime.getConfiguration().allowUpdateDL()) {
|
||||
synchronized(availableUpdates) {
|
||||
synchronized (availableUpdates) {
|
||||
try {
|
||||
if(certificateData.length > 32767) {
|
||||
throw new CertificateInvalidException("Certificate is too large! (" + certificateData.length + " bytes)");
|
||||
if (certificateData.length > 32767) {
|
||||
throw new CertificateInvalidException(
|
||||
"Certificate is too large! (" + certificateData.length + " bytes)");
|
||||
}
|
||||
if(!fastUpdateKnownCheckSet.add(new RawKnownCertHolder(certificateData))) {
|
||||
if (!fastUpdateKnownCheckSet.add(new RawKnownCertHolder(certificateData))) {
|
||||
if (EagRuntime.getConfiguration().isLogInvalidCerts()) {
|
||||
logger.info("Ignoring {} byte certificate that has already been processed", certificateData.length);
|
||||
logger.info("Ignoring {} byte certificate that has already been processed",
|
||||
certificateData.length);
|
||||
}
|
||||
freeMemory();
|
||||
return;
|
||||
|
@ -139,8 +154,9 @@ public class UpdateService {
|
|||
UpdateCertificate cert = UpdateCertificate.parseAndVerifyCertificate(certificateData);
|
||||
if (EaglercraftVersion.updateBundlePackageName.equalsIgnoreCase(cert.bundlePackageName)) {
|
||||
if (myUpdateCert == null || !Arrays.equals(cert.bundleDataHash, myUpdateCert.bundleDataHash)) {
|
||||
if(availableUpdates.add(cert)) {
|
||||
logger.info("Found new update: {} - {}", cert.bundleDisplayName, cert.bundleDisplayVersion);
|
||||
if (availableUpdates.add(cert)) {
|
||||
logger.info("Found new update: {} - {}", cert.bundleDisplayName,
|
||||
cert.bundleDisplayVersion);
|
||||
if (cert.bundleVersionInteger > EaglercraftVersion.updateBundlePackageVersionInt
|
||||
&& (latestUpdateFound == null
|
||||
|| cert.bundleVersionInteger > latestUpdateFound.bundleVersionInteger
|
||||
|
@ -149,12 +165,14 @@ public class UpdateService {
|
|||
&& !dismissedUpdates.contains(cert)) {
|
||||
latestUpdateFound = cert;
|
||||
if (saveLatest) {
|
||||
PlatformApplication.setLocalStorage(EaglercraftVersion.updateLatestLocalStorageKey,
|
||||
certificateData);
|
||||
PlatformApplication.setLocalStorage(
|
||||
EaglercraftVersion.updateLatestLocalStorageKey,
|
||||
certificateData, false);
|
||||
}
|
||||
}
|
||||
}else if(EagRuntime.getConfiguration().isLogInvalidCerts()) {
|
||||
logger.info("Ignoring already indexed update: {} - {}", cert.bundleDisplayName, cert.bundleDisplayVersion);
|
||||
} else if (EagRuntime.getConfiguration().isLogInvalidCerts()) {
|
||||
logger.info("Ignoring already indexed update: {} - {}", cert.bundleDisplayName,
|
||||
cert.bundleDisplayVersion);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -166,7 +184,8 @@ public class UpdateService {
|
|||
}
|
||||
} catch (Throwable t) {
|
||||
if (EagRuntime.getConfiguration().isLogInvalidCerts()) {
|
||||
logger.error("Invalid update certificate recieved! The certificate may be from a different client");
|
||||
logger.error(
|
||||
"Invalid update certificate recieved! The certificate may be from a different client");
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
|
@ -175,11 +194,13 @@ public class UpdateService {
|
|||
}
|
||||
|
||||
private static void freeMemory() {
|
||||
if(fastUpdateKnownCheckSet.size() > 127) {
|
||||
if (fastUpdateKnownCheckSet.size() > 127) {
|
||||
List<RawKnownCertHolder> lst = new ArrayList(fastUpdateKnownCheckSet);
|
||||
fastUpdateKnownCheckSet.clear();
|
||||
lst.sort((c1, c2) -> { return (int)(c2.age - c1.age); });
|
||||
for(int i = 0; i < 64; ++i) {
|
||||
lst.sort((c1, c2) -> {
|
||||
return (int) (c2.age - c1.age);
|
||||
});
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
fastUpdateKnownCheckSet.add(lst.get(i));
|
||||
}
|
||||
}
|
||||
|
@ -202,19 +223,19 @@ public class UpdateService {
|
|||
}
|
||||
|
||||
public static void dismiss(UpdateCertificate cert) {
|
||||
if(latestUpdateFound == cert) {
|
||||
if (latestUpdateFound == cert) {
|
||||
latestUpdateFound = null;
|
||||
}
|
||||
dismissedUpdates.add(cert);
|
||||
}
|
||||
|
||||
public static void quine() {
|
||||
if(myUpdateCert != null) {
|
||||
if (myUpdateCert != null) {
|
||||
byte[] data = getClientBundleData();
|
||||
if(data != null) {
|
||||
if (data != null) {
|
||||
logger.info("Generating signed offline download...");
|
||||
PlatformUpdateSvc.quine(myUpdateCert, data);
|
||||
}else {
|
||||
} else {
|
||||
logger.error("Client checksum does not match certificate! Downloading a fresh client...");
|
||||
PlatformUpdateSvc.startClientUpdateFrom(myUpdateCert);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import net.hoosiertransfer.Config;
|
|||
|
||||
import net.lax1dude.eaglercraft.v1_8.Display;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerXBungeeVersion;
|
||||
import net.lax1dude.eaglercraft.v1_8.HString;
|
||||
import net.lax1dude.eaglercraft.v1_8.IOUtils;
|
||||
|
@ -819,7 +820,17 @@ public class Minecraft implements IThreadListener {
|
|||
long l = System.nanoTime();
|
||||
this.mcProfiler.startSection("tick");
|
||||
|
||||
for (int j = 0; j < this.timer.elapsedTicks; ++j) {
|
||||
if (this.timer.elapsedTicks > 1) {
|
||||
long watchdog = System.currentTimeMillis();
|
||||
for (int j = 0; j < this.timer.elapsedTicks; ++j) {
|
||||
this.runTick();
|
||||
long millis = System.currentTimeMillis();
|
||||
if (millis - watchdog > 50l) {
|
||||
watchdog = millis;
|
||||
EagUtils.sleep(0l);
|
||||
}
|
||||
}
|
||||
} else if (this.timer.elapsedTicks == 1) {
|
||||
this.runTick();
|
||||
}
|
||||
|
||||
|
@ -907,7 +918,11 @@ public class Minecraft implements IThreadListener {
|
|||
|
||||
public void updateDisplay() {
|
||||
this.mcProfiler.startSection("display_update");
|
||||
Display.setVSync(this.gameSettings.enableVsync);
|
||||
if (Display.isVSyncSupported()) {
|
||||
Display.setVSync(this.gameSettings.enableVsync);
|
||||
} else {
|
||||
this.gameSettings.enableVsync = false;
|
||||
}
|
||||
Display.update();
|
||||
this.mcProfiler.endSection();
|
||||
this.checkWindowResize();
|
||||
|
|
|
@ -59,6 +59,7 @@ import net.minecraft.util.ResourceLocation;
|
|||
*/
|
||||
public class SoundHandler implements IResourceManagerReloadListener, ITickable {
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private static final Logger tipLogger = LogManager.getLogger("EaglercraftX");
|
||||
public static final SoundPoolEntry missing_sound = new SoundPoolEntry(new ResourceLocation("meta:missing_sound"),
|
||||
0.0D, 0.0D, false);
|
||||
private final SoundRegistry sndRegistry = new SoundRegistry();
|
||||
|
@ -84,6 +85,12 @@ public class SoundHandler implements IResourceManagerReloadListener, ITickable {
|
|||
this.loadSoundResource(new ResourceLocation(s, (String) entry.getKey()),
|
||||
(SoundList) entry.getValue());
|
||||
}
|
||||
|
||||
if (this.sndRegistry
|
||||
.getObject(new ResourceLocation("minecraft:sounds/music/game/calm1.ogg")) == null) {
|
||||
tipLogger.info(
|
||||
"Download this resource pack if you want music: https://bafybeiayojww5jfyzvlmtuk7l5ufkt7nlfto7mhwmzf2vs4bvsjd5ouiuq.ipfs.nftstorage.link/?filename=Music_For_Eaglercraft.zip");
|
||||
}
|
||||
} catch (RuntimeException runtimeexception) {
|
||||
logger.warn("Invalid sounds.json", runtimeexception);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package net.minecraft.client.gui;
|
||||
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
|
@ -14,32 +15,30 @@ public class GuiClientSettings extends GuiScreen {
|
|||
this.options = settings;
|
||||
}
|
||||
|
||||
/**+
|
||||
* Adds the buttons (and other controls) to the screen in
|
||||
* question. Called when the GUI is displayed and when the
|
||||
* window resizes, the buttonList is cleared beforehand.
|
||||
*/
|
||||
/**
|
||||
* +
|
||||
* Adds the buttons (and other controls) to the screen in
|
||||
* question. Called when the GUI is displayed and when the
|
||||
* window resizes, the buttonList is cleared beforehand.
|
||||
*/
|
||||
public void initGui() {
|
||||
int i = 0;
|
||||
this.title = "Client Specific Settings";
|
||||
this.buttonList.add(new GuiButton(GameSettings.Options.HIDE_PASSWORD.returnEnumOrdinal(),
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.HIDE_PASSWORD)));
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.HIDE_PASSWORD)));
|
||||
++i;
|
||||
this.buttonList.add(new GuiButton(GameSettings.Options.ENABLE_SOUND.returnEnumOrdinal(),
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.ENABLE_SOUND)));
|
||||
++i;
|
||||
this.buttonList.add(new GuiButton(GameSettings.Options.SKIP_SOME_RENDERING.returnEnumOrdinal(),
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.SKIP_SOME_RENDERING)));
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.ENABLE_SOUND)));
|
||||
++i;
|
||||
this.buttonList.add(new GuiButton(GameSettings.Options.DISABLE_ALPHA.returnEnumOrdinal(),
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.DISABLE_ALPHA)));
|
||||
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
|
||||
this.options.getKeyBinding(GameSettings.Options.DISABLE_ALPHA)));
|
||||
++i;
|
||||
++i;
|
||||
this.buttonList.add(new GuiButton(200, this.width / 2 - 100, this.height / 6 + 24 * (i >> 1),
|
||||
I18n.format("gui.done", new Object[0])));
|
||||
I18n.format("gui.done", new Object[0])));
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton parGuiButton) {
|
||||
|
@ -58,11 +57,6 @@ public class GuiClientSettings extends GuiScreen {
|
|||
parGuiButton.displayString = this.options.getKeyBinding(GameSettings.Options.ENABLE_SOUND);
|
||||
}
|
||||
|
||||
if (parGuiButton.id == GameSettings.Options.SKIP_SOME_RENDERING.returnEnumOrdinal()) {
|
||||
this.options.setOptionValue(GameSettings.Options.SKIP_SOME_RENDERING, 1);
|
||||
parGuiButton.displayString = this.options.getKeyBinding(GameSettings.Options.SKIP_SOME_RENDERING);
|
||||
}
|
||||
|
||||
if (parGuiButton.id == GameSettings.Options.DISABLE_ALPHA.returnEnumOrdinal()) {
|
||||
this.options.setOptionValue(GameSettings.Options.DISABLE_ALPHA, 1);
|
||||
parGuiButton.displayString = this.options.getKeyBinding(GameSettings.Options.DISABLE_ALPHA);
|
||||
|
@ -75,5 +69,5 @@ public class GuiClientSettings extends GuiScreen {
|
|||
this.drawCenteredString(this.fontRendererObj, this.title, this.width / 2, 20, 16777215);
|
||||
super.drawScreen(i, j, f);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -55,10 +55,6 @@ public class GuiDisconnected extends GuiScreen {
|
|||
this.parentScreen = screen;
|
||||
this.reason = I18n.format(reasonLocalizationKey, new Object[0]);
|
||||
this.message = chatComp;
|
||||
if (reason.toLowerCase().contains("banned from this server")) {
|
||||
EaglerProfile.updateUsernameCookies();
|
||||
reloadPage();
|
||||
}
|
||||
|
||||
if (reason.toLowerCase().contains("reload page")) {
|
||||
EaglerProfile.updateUsernameCookieFromLocalStorage();
|
||||
|
|
|
@ -1039,7 +1039,7 @@ public class GuiIngame extends Gui {
|
|||
ent.prevRenderYawOffset = f5;
|
||||
GlStateManager.popMatrix();
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
GlStateManager.disableDepth();
|
||||
// GlStateManager.disableDepth();
|
||||
GlStateManager.disableRescaleNormal();
|
||||
GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit);
|
||||
GlStateManager.disableTexture2D();
|
||||
|
|
|
@ -38,6 +38,7 @@ import net.lax1dude.eaglercraft.v1_8.update.UpdateCertificate;
|
|||
import net.lax1dude.eaglercraft.v1_8.update.UpdateService;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
|
@ -286,7 +287,8 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback {
|
|||
*/
|
||||
private void addSingleplayerMultiplayerButtons(int parInt1, int parInt2) {
|
||||
this.buttonList
|
||||
.add(new GuiButton(1, this.width / 2 - 100, parInt1, I18n.format("menu.singleplayer", new Object[0])));
|
||||
.add(new GuiButton(1, this.width / 2 - 100, parInt1,
|
||||
I18n.format("menu.singleplayer", new Object[0])));
|
||||
this.buttonList.add(new GuiButton(2, this.width / 2 - 100, parInt1 + parInt2 * 1,
|
||||
I18n.format("menu.multiplayer", new Object[0])));
|
||||
if (EaglercraftVersion.mainMenuEnableGithubButton) {
|
||||
|
@ -567,10 +569,12 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback {
|
|||
|| (this.openGLWarning2 != null && this.openGLWarning2.length() > 0));
|
||||
|
||||
if (isForkLabel) {
|
||||
drawRect(this.field_92022_t - 3, this.field_92021_u - 3, this.field_92020_v + 3, this.field_92019_w,
|
||||
drawRect(this.field_92022_t - 3, this.field_92021_u - 3, this.field_92020_v + 3,
|
||||
this.field_92019_w,
|
||||
1428160512);
|
||||
if (this.openGLWarning1 != null)
|
||||
this.drawString(this.fontRendererObj, this.openGLWarning1, this.field_92022_t, this.field_92021_u, -1);
|
||||
this.drawString(this.fontRendererObj, this.openGLWarning1, this.field_92022_t, this.field_92021_u,
|
||||
-1);
|
||||
if (this.openGLWarning2 != null)
|
||||
this.drawString(this.fontRendererObj, this.openGLWarning2, (this.width - this.field_92024_r) / 2,
|
||||
this.field_92021_u + 12, -1);
|
||||
|
|
|
@ -396,7 +396,7 @@ public class GuiMultiplayer extends GuiScreen implements GuiYesNoCallback {
|
|||
}
|
||||
}
|
||||
|
||||
private void connectToServer(ServerData server) {
|
||||
public void connectToServer(ServerData server) {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(this, this.mc, server));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import net.lax1dude.eaglercraft.v1_8.socket.RateLimitTracker;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiDisconnected;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
|
@ -239,7 +240,7 @@ public class GuiConnecting extends GuiScreen {
|
|||
this.networkManager.closeChannel(new ChatComponentText("Aborted"));
|
||||
}
|
||||
|
||||
this.mc.displayGuiScreen(this.previousGuiScreen);
|
||||
this.mc.displayGuiScreen(new GuiMainMenu());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -276,29 +276,25 @@ public class EntityRenderer implements IResourceManagerReloadListener {
|
|||
if (this.mc.getRenderViewEntity() == null) {
|
||||
this.mc.setRenderViewEntity(this.mc.thePlayer);
|
||||
}
|
||||
if (!Config.skipRenderUpdate()) {
|
||||
float f3 = this.mc.theWorld.getLightBrightness(
|
||||
DeferredStateManager.isDeferredRenderer() ? new BlockPos(this.mc.getRenderViewEntity()).up()
|
||||
: new BlockPos(this.mc.getRenderViewEntity()));
|
||||
float f4 = (float) this.mc.gameSettings.renderDistanceChunks / 32.0F;
|
||||
float f2 = f3 * (1.0F - f4) + f4;
|
||||
this.fogColor1 += (f2 - this.fogColor1) * 0.1F;
|
||||
}
|
||||
float f3 = this.mc.theWorld.getLightBrightness(
|
||||
DeferredStateManager.isDeferredRenderer() ? new BlockPos(this.mc.getRenderViewEntity()).up()
|
||||
: new BlockPos(this.mc.getRenderViewEntity()));
|
||||
float f4 = (float) this.mc.gameSettings.renderDistanceChunks / 32.0F;
|
||||
float f2 = f3 * (1.0F - f4) + f4;
|
||||
this.fogColor1 += (f2 - this.fogColor1) * 0.1F;
|
||||
++this.rendererUpdateCount;
|
||||
this.addRainParticles();
|
||||
if (!Config.skipRenderUpdate()) {
|
||||
this.itemRenderer.updateEquippedItem();
|
||||
this.bossColorModifierPrev = this.bossColorModifier;
|
||||
if (BossStatus.hasColorModifier) {
|
||||
this.bossColorModifier += 0.05F;
|
||||
if (this.bossColorModifier > 1.0F) {
|
||||
this.bossColorModifier = 1.0F;
|
||||
}
|
||||
|
||||
BossStatus.hasColorModifier = false;
|
||||
} else if (this.bossColorModifier > 0.0F) {
|
||||
this.bossColorModifier -= 0.0125F;
|
||||
this.itemRenderer.updateEquippedItem();
|
||||
this.bossColorModifierPrev = this.bossColorModifier;
|
||||
if (BossStatus.hasColorModifier) {
|
||||
this.bossColorModifier += 0.05F;
|
||||
if (this.bossColorModifier > 1.0F) {
|
||||
this.bossColorModifier = 1.0F;
|
||||
}
|
||||
|
||||
BossStatus.hasColorModifier = false;
|
||||
} else if (this.bossColorModifier > 0.0F) {
|
||||
this.bossColorModifier -= 0.0125F;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Map;
|
|||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.hoosiertransfer.Config;
|
||||
import net.hoosiertransfer.CullingMod;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
|
@ -28,7 +29,6 @@ import net.minecraft.client.model.ModelSlime;
|
|||
import net.minecraft.client.model.ModelSquid;
|
||||
import net.minecraft.client.model.ModelWolf;
|
||||
import net.minecraft.client.model.ModelZombie;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.culling.ICamera;
|
||||
|
@ -231,6 +231,12 @@ public class RenderManager {
|
|||
this.skinMap.put("default", this.playerRenderer);
|
||||
this.skinMap.put("slim", new RenderPlayer(this, true, false));
|
||||
this.skinMap.put("zombie", new RenderPlayer(this, false, true));
|
||||
if (EagRuntime.getConfiguration().isAllowFNAWSkins()) {
|
||||
this.eaglerRenderer = new RenderHighPoly(this, this.playerRenderer.getMainModel(),
|
||||
this.playerRenderer.shadowSize);
|
||||
} else {
|
||||
this.eaglerRenderer = this.playerRenderer;
|
||||
}
|
||||
this.eaglerRenderer = new RenderHighPoly(this, this.playerRenderer.getMainModel(),
|
||||
this.playerRenderer.shadowSize);
|
||||
this.skinMap.put("eagler",
|
||||
|
|
|
@ -34,7 +34,6 @@ public class LayerElytra implements LayerRenderer<AbstractClientPlayer> {
|
|||
GlStateManager.enableBlend();
|
||||
this.renderPlayer.bindTexture(TEXTURE_ELYTRA);
|
||||
|
||||
// GlStateManager.pushMatrix();
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.translate(0.0F, 0.0F, 0.125F);
|
||||
this.modelElytra.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw,
|
||||
|
@ -43,15 +42,6 @@ public class LayerElytra implements LayerRenderer<AbstractClientPlayer> {
|
|||
this.modelElytra.render(entitylivingbaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw,
|
||||
headPitch,
|
||||
scale);
|
||||
|
||||
if (itemstack.isItemEnchanted()) {
|
||||
LayerArmorBase.renderEnchantedGlint(this.renderPlayer, entitylivingbaseIn,
|
||||
this.modelElytra, limbSwing,
|
||||
limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch,
|
||||
scale);
|
||||
DeferredStateManager.setHDRTranslucentPassBlendFunc();
|
||||
}
|
||||
// GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -231,8 +231,6 @@ public class GameSettings {
|
|||
|
||||
public boolean disableAlpha = false;
|
||||
|
||||
public boolean skipHandRender = false;
|
||||
|
||||
public GameSettings(Minecraft mcIn) {
|
||||
this.keyBindings = (KeyBinding[]) ArrayUtils.addAll(new KeyBinding[] { this.keyBindAttack, this.keyBindUseItem,
|
||||
this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump,
|
||||
|
@ -368,10 +366,6 @@ public class GameSettings {
|
|||
* through the list i.e. render distances.
|
||||
*/
|
||||
public void setOptionValue(GameSettings.Options parOptions, int parInt1) {
|
||||
if (parOptions == GameSettings.Options.SKIP_SOME_RENDERING) {
|
||||
this.skipHandRender = !this.skipHandRender;
|
||||
}
|
||||
|
||||
if (parOptions == GameSettings.Options.DISABLE_ALPHA) {
|
||||
this.disableAlpha = !this.disableAlpha;
|
||||
}
|
||||
|
@ -547,8 +541,6 @@ public class GameSettings {
|
|||
|
||||
public boolean getOptionOrdinalValue(GameSettings.Options parOptions) {
|
||||
switch (parOptions) {
|
||||
case SKIP_SOME_RENDERING:
|
||||
return this.skipHandRender;
|
||||
case DISABLE_ALPHA:
|
||||
return this.disableAlpha;
|
||||
case ENABLE_SOUND:
|
||||
|
@ -705,10 +697,6 @@ public class GameSettings {
|
|||
return flag ? "Hide Password: " + I18n.format("options.on", new Object[0])
|
||||
: "Hide Password: " + I18n.format("options.off", new Object[0]);
|
||||
}
|
||||
if (parOptions == GameSettings.Options.SKIP_SOME_RENDERING) {
|
||||
return flag ? "Skip Some Rendering: " + I18n.format("options.on", new Object[0])
|
||||
: "Skip Some Rendering: " + I18n.format("options.off", new Object[0]);
|
||||
}
|
||||
if (parOptions == GameSettings.Options.DISABLE_ALPHA) {
|
||||
return !flag ? "Render Alpha: " + I18n.format("options.on", new Object[0])
|
||||
: "Render Alpha: " + I18n.format("options.off", new Object[0]);
|
||||
|
@ -776,10 +764,6 @@ public class GameSettings {
|
|||
this.mouseSensitivity = this.parseFloat(astring[1]);
|
||||
}
|
||||
|
||||
if (astring[0].equals("skipHandRender")) {
|
||||
this.skipHandRender = astring[1].equals("true");
|
||||
}
|
||||
|
||||
if (astring[0].equals("disableAlpha")) {
|
||||
this.disableAlpha = astring[1].equals("true");
|
||||
}
|
||||
|
@ -1173,7 +1157,6 @@ public class GameSettings {
|
|||
}
|
||||
printwriter.println("hidePassword:" + this.hidePassword);
|
||||
printwriter.println("enableSound:" + this.getOptionOrdinalValue(GameSettings.Options.ENABLE_SOUND));
|
||||
printwriter.println("skipHandRender:" + this.skipHandRender);
|
||||
printwriter.println("disableAlpha:" + this.disableAlpha);
|
||||
|
||||
printwriter.println("resourcePacks:" + toJSONArray(this.resourcePacks));
|
||||
|
@ -1325,8 +1308,8 @@ public class GameSettings {
|
|||
}
|
||||
|
||||
public static enum Options {
|
||||
DISABLE_ALPHA("options.alpha", false, true), SKIP_SOME_RENDERING("options.skipHandRender", false, true),
|
||||
INVERT_MOUSE("options.invertMouse", false, true), SENSITIVITY("options.sensitivity", true, false),
|
||||
DISABLE_ALPHA("options.alpha", false, true), INVERT_MOUSE("options.invertMouse", false, true),
|
||||
SENSITIVITY("options.sensitivity", true, false),
|
||||
FOV("options.fov", true, false, 30.0F, 110.0F, 1.0F), GAMMA("options.gamma", true, false),
|
||||
SATURATION("options.saturation", true, false),
|
||||
RENDER_SCALE("options.renderScale", true, false, 40.0F, 100.0F, 1.0F),
|
||||
|
|
|
@ -868,7 +868,7 @@ public abstract class ServerConfigurationManager {
|
|||
|
||||
worldIn.theItemInWorldManager.initializeGameType(parWorld.getWorldInfo().getGameType());
|
||||
} else {
|
||||
parEntityPlayerMP2.theItemInWorldManager.setGameType(lanGamemode);
|
||||
worldIn.theItemInWorldManager.setGameType(lanGamemode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,14 +29,21 @@ import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
|
|||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -44,7 +51,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
|
|||
public class PlatformApplication {
|
||||
|
||||
public static void openLink(String url) {
|
||||
if(url.indexOf(':') == -1) {
|
||||
if (url.indexOf(':') == -1) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
Window.current().open(url, "_blank", "noopener,noreferrer");
|
||||
|
@ -53,15 +60,15 @@ public class PlatformApplication {
|
|||
public static void setClipboard(String text) {
|
||||
try {
|
||||
setClipboard0(text);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
PlatformRuntime.logger.error("Exception setting clipboard data");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getClipboard() {
|
||||
try {
|
||||
return getClipboard0();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
PlatformRuntime.logger.error("Exception getting clipboard data");
|
||||
return "";
|
||||
}
|
||||
|
@ -71,63 +78,97 @@ public class PlatformApplication {
|
|||
private static interface StupidFunctionResolveString extends JSObject {
|
||||
void resolveStr(String s);
|
||||
}
|
||||
|
||||
|
||||
@Async
|
||||
private static native String getClipboard0();
|
||||
|
||||
|
||||
private static void getClipboard0(final AsyncCallback<String> cb) {
|
||||
final long start = System.currentTimeMillis();
|
||||
getClipboard1(new StupidFunctionResolveString() {
|
||||
@Override
|
||||
public void resolveStr(String s) {
|
||||
if(System.currentTimeMillis() - start > 500l) {
|
||||
if (System.currentTimeMillis() - start > 500l) {
|
||||
PlatformInput.unpressCTRL = true;
|
||||
}
|
||||
cb.complete(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@JSBody(params = { "cb" }, script = "if(!window.navigator.clipboard || !window.navigator.clipboard.readText) cb(\"\"); else window.navigator.clipboard.readText().then(function(s) { cb(s); }, function(s) { cb(\"\"); });")
|
||||
|
||||
@JSBody(params = {
|
||||
"cb" }, script = "if(!window.navigator.clipboard || !window.navigator.clipboard.readText) cb(\"\"); else window.navigator.clipboard.readText().then(function(s) { cb(s); }, function(s) { cb(\"\"); });")
|
||||
private static native void getClipboard1(StupidFunctionResolveString cb);
|
||||
|
||||
|
||||
@JSBody(params = { "str" }, script = "if(window.navigator.clipboard) window.navigator.clipboard.writeText(str);")
|
||||
private static native void setClipboard0(String str);
|
||||
|
||||
|
||||
public static void setLocalStorage(String name, byte[] data) {
|
||||
setLocalStorage(name, data, true);
|
||||
}
|
||||
|
||||
public static void setLocalStorage(String name, byte[] data, boolean hooks) {
|
||||
IClientConfigAdapter adapter = PlatformRuntime.getClientConfigAdapter();
|
||||
String eagName = adapter.getLocalStorageNamespace() + "." + name;
|
||||
String b64 = Base64.encodeBase64String(data);
|
||||
try {
|
||||
Storage s = Window.current().getLocalStorage();
|
||||
if(s != null) {
|
||||
if(data != null) {
|
||||
s.setItem("_eaglercraftX." + name, Base64.encodeBase64String(data));
|
||||
}else {
|
||||
s.removeItem("_eaglercraftX." + name);
|
||||
if (s != null) {
|
||||
if (data != null) {
|
||||
s.setItem(eagName, b64);
|
||||
} else {
|
||||
s.removeItem(eagName);
|
||||
}
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
if (hooks) {
|
||||
adapter.getHooks().callLocalStorageSavedHook(name, b64);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getLocalStorage(String name) {
|
||||
try {
|
||||
Storage s = Window.current().getLocalStorage();
|
||||
if(s != null) {
|
||||
String str = s.getItem("_eaglercraftX." + name);
|
||||
if(str != null) {
|
||||
return Base64.decodeBase64(str);
|
||||
}else {
|
||||
return getLocalStorage(name, true);
|
||||
}
|
||||
|
||||
public static byte[] getLocalStorage(String name, boolean hooks) {
|
||||
IClientConfigAdapter adapter = PlatformRuntime.getClientConfigAdapter();
|
||||
String eagName = adapter.getLocalStorageNamespace() + "." + name;
|
||||
byte[] hooked = null;
|
||||
if (hooks) {
|
||||
String hookedStr = adapter.getHooks().callLocalStorageLoadHook(eagName);
|
||||
if (hookedStr != null) {
|
||||
try {
|
||||
hooked = Base64.decodeBase64(hookedStr);
|
||||
} catch (Throwable t) {
|
||||
PlatformRuntime.logger.error("Invalid Base64 recieved from local storage hook!");
|
||||
hooked = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hooked == null) {
|
||||
try {
|
||||
Storage s = Window.current().getLocalStorage();
|
||||
if (s != null) {
|
||||
String str = s.getItem(eagName);
|
||||
if (str != null) {
|
||||
return Base64.decodeBase64(str);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}else {
|
||||
} catch (Throwable t) {
|
||||
return null;
|
||||
}
|
||||
}catch(Throwable t) {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final DateFormat dateFormatSS = EagRuntime.fixDateFormat(new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss"));
|
||||
|
||||
|
||||
private static final DateFormat dateFormatSS = EagRuntime
|
||||
.fixDateFormat(new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss"));
|
||||
|
||||
public static String saveScreenshot() {
|
||||
String name = "screenshot_" + dateFormatSS.format(new Date()).toString() + ".png";
|
||||
int w = PlatformRuntime.canvas.getWidth();
|
||||
|
@ -140,10 +181,11 @@ public class PlatformApplication {
|
|||
saveScreenshot(name, copyCanvas);
|
||||
return name;
|
||||
}
|
||||
|
||||
@JSBody(params = { "name", "cvs" }, script = "var a=document.createElement(\"a\");a.href=cvs.toDataURL(\"image/png\");a.download=name;a.click();")
|
||||
|
||||
@JSBody(params = { "name",
|
||||
"cvs" }, script = "var a=document.createElement(\"a\");a.href=cvs.toDataURL(\"image/png\");a.download=name;a.click();")
|
||||
private static native void saveScreenshot(String name, HTMLCanvasElement cvs);
|
||||
|
||||
|
||||
public static void showPopup(final String msg) {
|
||||
Window.setTimeout(new TimerHandler() {
|
||||
@Override
|
||||
|
@ -165,10 +207,11 @@ public class PlatformApplication {
|
|||
@Override
|
||||
public void accept(String name, ArrayBuffer buffer) {
|
||||
fileChooserHasResult = true;
|
||||
if(name == null) {
|
||||
if (name == null) {
|
||||
fileChooserResultObject = null;
|
||||
}else {
|
||||
fileChooserResultObject = new FileChooserResult(name, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buffer)));
|
||||
} else {
|
||||
fileChooserResultObject = new FileChooserResult(name,
|
||||
TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buffer)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,8 +220,7 @@ public class PlatformApplication {
|
|||
private static volatile boolean fileChooserHasResult = false;
|
||||
private static volatile FileChooserResult fileChooserResultObject = null;
|
||||
|
||||
@JSBody(params = { "inputElement", "callback" }, script =
|
||||
"if(inputElement.files.length > 0) {"
|
||||
@JSBody(params = { "inputElement", "callback" }, script = "if(inputElement.files.length > 0) {"
|
||||
+ "const value = inputElement.files[0];"
|
||||
+ "value.arrayBuffer().then(function(arr){ callback(value.name, arr); })"
|
||||
+ ".catch(function(){ callback(null, null); });"
|
||||
|
@ -194,9 +236,9 @@ public class PlatformApplication {
|
|||
public static void displayFileChooser(String mime, String ext) {
|
||||
final HTMLInputElement inputElement = (HTMLInputElement) Window.current().getDocument().createElement("input");
|
||||
inputElement.setType("file");
|
||||
if(mime == null) {
|
||||
if (mime == null) {
|
||||
setAcceptSelection(inputElement, "." + ext);
|
||||
}else {
|
||||
} else {
|
||||
setAcceptSelection(inputElement, mime);
|
||||
}
|
||||
setMultipleSelection(inputElement, false);
|
||||
|
@ -231,15 +273,16 @@ public class PlatformApplication {
|
|||
|
||||
public static void openCreditsPopup(String text) {
|
||||
Window currentWin = Window.current();
|
||||
|
||||
int w = (int)(850 * currentWin.getDevicePixelRatio());
|
||||
int h = (int)(700 * currentWin.getDevicePixelRatio());
|
||||
|
||||
|
||||
int w = (int) (850 * currentWin.getDevicePixelRatio());
|
||||
int h = (int) (700 * currentWin.getDevicePixelRatio());
|
||||
|
||||
int x = (currentWin.getScreen().getWidth() - w) / 2;
|
||||
int y = (currentWin.getScreen().getHeight() - h) / 2;
|
||||
|
||||
Window newWin = Window.current().open("", "_blank", "top=" + y + ",left=" + x + ",width=" + w + ",height=" + h + ",menubar=0,status=0,titlebar=0,toolbar=0");
|
||||
if(newWin == null) {
|
||||
|
||||
Window newWin = Window.current().open("", "_blank", "top=" + y + ",left=" + x + ",width=" + w + ",height=" + h
|
||||
+ ",menubar=0,status=0,titlebar=0,toolbar=0");
|
||||
if (newWin == null) {
|
||||
Window.alert("ERROR: Popup blocked!\n\nPlease make sure you have popups enabled for this site!");
|
||||
return;
|
||||
}
|
||||
|
@ -247,8 +290,9 @@ public class PlatformApplication {
|
|||
newWin.focus();
|
||||
documentWrite(newWin.getDocument(), "<!DOCTYPE html><html><head><meta charset=\"UTF-8\" />"
|
||||
+ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><title>EaglercraftX 1.8 Credits</title>"
|
||||
+ "<link type=\"image/png\" rel=\"shortcut icon\" href=\"" + PlatformApplication.faviconURLTeaVM() + "\" />"
|
||||
+ "</head><body><pre style=\"font:15px Consolas,monospace;\">" + text + "</pre></body></html>");
|
||||
+ "<link type=\"image/png\" rel=\"shortcut icon\" href=\"" + PlatformApplication.faviconURLTeaVM()
|
||||
+ "\" />"
|
||||
+ "</head><body><pre style=\"font:15px Consolas,monospace;\">" + text + "</pre></body></html>");
|
||||
}
|
||||
|
||||
public static void clearFileChooserResult() {
|
||||
|
@ -256,11 +300,11 @@ public class PlatformApplication {
|
|||
fileChooserResultObject = null;
|
||||
}
|
||||
|
||||
@JSBody(params = { "name", "buf" }, script =
|
||||
"var hr = window.URL.createObjectURL(new Blob([buf], {type: \"octet/stream\"}));" +
|
||||
"var a = document.createElement(\"a\");" +
|
||||
"a.href = hr; a.download = name; a.click();" +
|
||||
"window.URL.revokeObjectURL(hr);")
|
||||
@JSBody(params = { "name",
|
||||
"buf" }, script = "var hr = window.URL.createObjectURL(new Blob([buf], {type: \"octet/stream\"}));" +
|
||||
"var a = document.createElement(\"a\");" +
|
||||
"a.href = hr; a.download = name; a.click();" +
|
||||
"window.URL.revokeObjectURL(hr);")
|
||||
private static final native void downloadBytesImpl(String str, ArrayBuffer buf);
|
||||
|
||||
public static final void downloadFileWithName(String str, byte[] dat) {
|
||||
|
|
|
@ -30,41 +30,50 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
|||
import net.minecraft.util.MathHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
* 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 PlatformAudio {
|
||||
|
||||
|
||||
static final Logger logger = LogManager.getLogger("BrowserAudio");
|
||||
|
||||
|
||||
static AudioContext audioctx = null;
|
||||
static MediaStreamAudioDestinationNode recDest = null;
|
||||
private static final Map<String, BrowserAudioResource> soundCache = new HashMap();
|
||||
|
||||
|
||||
private static long cacheFreeTimer = 0l;
|
||||
|
||||
|
||||
protected static class BrowserAudioResource implements IAudioResource {
|
||||
|
||||
|
||||
protected AudioBuffer buffer;
|
||||
protected long cacheHit = 0l;
|
||||
|
||||
|
||||
protected BrowserAudioResource(AudioBuffer buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected static class BrowserAudioHandle implements IAudioHandle, EventListener<MediaEvent> {
|
||||
|
||||
|
||||
protected final BrowserAudioResource resource;
|
||||
protected AudioBufferSourceNode source;
|
||||
protected final PannerNode panner;
|
||||
|
@ -72,7 +81,7 @@ public class PlatformAudio {
|
|||
protected float pitch;
|
||||
protected boolean isPaused = false;
|
||||
protected boolean isEnded = false;
|
||||
|
||||
|
||||
public BrowserAudioHandle(BrowserAudioResource resource, AudioBufferSourceNode source, PannerNode panner,
|
||||
GainNode gain, float pitch) {
|
||||
this.resource = resource;
|
||||
|
@ -85,13 +94,13 @@ public class PlatformAudio {
|
|||
|
||||
@Override
|
||||
public void pause(boolean setPaused) {
|
||||
if(setPaused) {
|
||||
if(!isPaused) {
|
||||
if (setPaused) {
|
||||
if (!isPaused) {
|
||||
isPaused = true;
|
||||
source.getPlaybackRate().setValue(0.0f);
|
||||
}
|
||||
}else {
|
||||
if(isPaused) {
|
||||
} else {
|
||||
if (isPaused) {
|
||||
isPaused = false;
|
||||
source.getPlaybackRate().setValue(pitch);
|
||||
}
|
||||
|
@ -100,7 +109,7 @@ public class PlatformAudio {
|
|||
|
||||
@Override
|
||||
public void restart() {
|
||||
if(isEnded) {
|
||||
if (isEnded) {
|
||||
isEnded = false;
|
||||
AudioBufferSourceNode src = audioctx.createBufferSource();
|
||||
resource.cacheHit = System.currentTimeMillis();
|
||||
|
@ -110,7 +119,7 @@ public class PlatformAudio {
|
|||
src.connect(panner == null ? gain : panner);
|
||||
source = src;
|
||||
source.start();
|
||||
}else {
|
||||
} else {
|
||||
source.getPlaybackRate().setValue(pitch);
|
||||
source.start(0.0);
|
||||
}
|
||||
|
@ -118,7 +127,7 @@ public class PlatformAudio {
|
|||
|
||||
@Override
|
||||
public void move(float x, float y, float z) {
|
||||
if(panner != null) {
|
||||
if (panner != null) {
|
||||
panner.setPosition(x, y, z);
|
||||
}
|
||||
}
|
||||
|
@ -126,26 +135,28 @@ public class PlatformAudio {
|
|||
@Override
|
||||
public void pitch(float f) {
|
||||
pitch = f;
|
||||
if(!isPaused) {
|
||||
if (!isPaused) {
|
||||
source.getPlaybackRate().setValue(pitch);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gain(float f) {
|
||||
if(panner != null) {
|
||||
if (panner != null) {
|
||||
float v1 = f * 16.0f;
|
||||
if(v1 < 16.0f) v1 = 16.0f;
|
||||
if (v1 < 16.0f)
|
||||
v1 = 16.0f;
|
||||
panner.setMaxDistance(v1);
|
||||
}
|
||||
float v2 = f;
|
||||
if(v2 > 1.0f) v2 = 1.0f;
|
||||
if (v2 > 1.0f)
|
||||
v2 = 1.0f;
|
||||
gain.getGain().setValue(v2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
if(!isEnded) {
|
||||
if (!isEnded) {
|
||||
isEnded = true;
|
||||
source.stop();
|
||||
}
|
||||
|
@ -160,26 +171,27 @@ public class PlatformAudio {
|
|||
public void handleEvent(MediaEvent evt) {
|
||||
isEnded = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void initialize() {
|
||||
|
||||
|
||||
try {
|
||||
audioctx = AudioContext.create();
|
||||
recDest = audioctx.createMediaStreamDestination();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
throw new PlatformRuntime.RuntimeInitializationFailureException("Could not initialize audio context!", t);
|
||||
}
|
||||
|
||||
|
||||
PlatformInput.clearEvenBuffers();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static GainNode micGain;
|
||||
|
||||
public static void setMicVol(float vol) {
|
||||
if (micGain == null) return;
|
||||
if (micGain == null)
|
||||
return;
|
||||
micGain.getGain().setValue(vol);
|
||||
}
|
||||
|
||||
|
@ -206,23 +218,25 @@ public class PlatformAudio {
|
|||
|
||||
public static IAudioResource loadAudioData(String filename, boolean holdInCache) {
|
||||
BrowserAudioResource buffer;
|
||||
synchronized(soundCache) {
|
||||
synchronized (soundCache) {
|
||||
buffer = soundCache.get(filename);
|
||||
}
|
||||
if(buffer == null) {
|
||||
if (buffer == null) {
|
||||
byte[] file = PlatformAssets.getResourceBytes(filename);
|
||||
if(file == null) return null;
|
||||
buffer = new BrowserAudioResource(decodeAudioAsync(TeaVMUtils.unwrapUnsignedByteArray(file).getBuffer(), filename));
|
||||
if(holdInCache) {
|
||||
synchronized(soundCache) {
|
||||
if (file == null)
|
||||
return null;
|
||||
buffer = new BrowserAudioResource(
|
||||
decodeAudioAsync(TeaVMUtils.unwrapUnsignedByteArray(file).getBuffer(), filename));
|
||||
if (holdInCache) {
|
||||
synchronized (soundCache) {
|
||||
soundCache.put(filename, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(buffer.buffer != null) {
|
||||
if (buffer.buffer != null) {
|
||||
buffer.cacheHit = System.currentTimeMillis();
|
||||
return buffer;
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -233,33 +247,35 @@ public class PlatformAudio {
|
|||
|
||||
public static IAudioResource loadAudioDataNew(String filename, boolean holdInCache, IAudioCacheLoader loader) {
|
||||
BrowserAudioResource buffer;
|
||||
synchronized(soundCache) {
|
||||
synchronized (soundCache) {
|
||||
buffer = soundCache.get(filename);
|
||||
}
|
||||
if(buffer == null) {
|
||||
if (buffer == null) {
|
||||
byte[] file = loader.loadFile(filename);
|
||||
if(file == null) return null;
|
||||
if (file == null)
|
||||
return null;
|
||||
Uint8Array buf = Uint8Array.create(file.length);
|
||||
buf.set(file);
|
||||
buffer = new BrowserAudioResource(decodeAudioAsync(buf.getBuffer(), filename));
|
||||
if(holdInCache) {
|
||||
synchronized(soundCache) {
|
||||
if (holdInCache) {
|
||||
synchronized (soundCache) {
|
||||
soundCache.put(filename, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(buffer.buffer != null) {
|
||||
if (buffer.buffer != null) {
|
||||
buffer.cacheHit = System.currentTimeMillis();
|
||||
return buffer;
|
||||
}else {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Async
|
||||
public static native AudioBuffer decodeAudioAsync(ArrayBuffer buffer, String errorFileName);
|
||||
|
||||
private static void decodeAudioAsync(ArrayBuffer buffer, final String errorFileName, final AsyncCallback<AudioBuffer> cb) {
|
||||
|
||||
private static void decodeAudioAsync(ArrayBuffer buffer, final String errorFileName,
|
||||
final AsyncCallback<AudioBuffer> cb) {
|
||||
audioctx.decodeAudioData(buffer, new DecodeSuccessCallback() {
|
||||
@Override
|
||||
public void onSuccess(AudioBuffer decodedData) {
|
||||
|
@ -276,12 +292,12 @@ public class PlatformAudio {
|
|||
|
||||
public static void clearAudioCache() {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - cacheFreeTimer > 30000l) {
|
||||
if (millis - cacheFreeTimer > 30000l) {
|
||||
cacheFreeTimer = millis;
|
||||
synchronized(soundCache) {
|
||||
synchronized (soundCache) {
|
||||
Iterator<BrowserAudioResource> itr = soundCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
if(millis - itr.next().cacheHit > 600000l) { // 10 minutes
|
||||
while (itr.hasNext()) {
|
||||
if (millis - itr.next().cacheHit > 600000l) { // 10 minutes
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
|
@ -290,28 +306,29 @@ public class PlatformAudio {
|
|||
}
|
||||
|
||||
public static void flushAudioCache() {
|
||||
synchronized(soundCache) {
|
||||
synchronized (soundCache) {
|
||||
soundCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean available() {
|
||||
return true; // this is not used
|
||||
}
|
||||
|
||||
|
||||
public static IAudioHandle beginPlayback(IAudioResource track, float x, float y, float z,
|
||||
float volume, float pitch) {
|
||||
BrowserAudioResource internalTrack = (BrowserAudioResource) track;
|
||||
internalTrack.cacheHit = System.currentTimeMillis();
|
||||
|
||||
|
||||
AudioBufferSourceNode src = audioctx.createBufferSource();
|
||||
src.setBuffer(internalTrack.buffer);
|
||||
src.getPlaybackRate().setValue(pitch);
|
||||
|
||||
|
||||
PannerNode panner = audioctx.createPanner();
|
||||
panner.setPosition(x, y, z);
|
||||
float v1 = volume * 16.0f;
|
||||
if(v1 < 16.0f) v1 = 16.0f;
|
||||
if (v1 < 16.0f)
|
||||
v1 = 16.0f;
|
||||
panner.setMaxDistance(v1);
|
||||
panner.setRolloffFactor(1.0f);
|
||||
panner.setDistanceModel("linear");
|
||||
|
@ -320,41 +337,43 @@ public class PlatformAudio {
|
|||
panner.setConeOuterAngle(0.0f);
|
||||
panner.setConeOuterGain(0.0f);
|
||||
panner.setOrientation(0.0f, 1.0f, 0.0f);
|
||||
|
||||
|
||||
GainNode gain = audioctx.createGain();
|
||||
float v2 = volume;
|
||||
if(v2 > 1.0f) v2 = 1.0f;
|
||||
if (v2 > 1.0f)
|
||||
v2 = 1.0f;
|
||||
gain.getGain().setValue(v2);
|
||||
|
||||
|
||||
src.connect(panner);
|
||||
panner.connect(gain);
|
||||
gain.connect(audioctx.getDestination());
|
||||
gain.connect(recDest);
|
||||
|
||||
src.start();
|
||||
|
||||
|
||||
return new BrowserAudioHandle(internalTrack, src, panner, gain, pitch);
|
||||
}
|
||||
|
||||
public static IAudioHandle beginPlaybackStatic(IAudioResource track, float volume, float pitch) {
|
||||
BrowserAudioResource internalTrack = (BrowserAudioResource) track;
|
||||
internalTrack.cacheHit = System.currentTimeMillis();
|
||||
|
||||
|
||||
AudioBufferSourceNode src = audioctx.createBufferSource();
|
||||
src.setBuffer(internalTrack.buffer);
|
||||
src.getPlaybackRate().setValue(pitch);
|
||||
|
||||
|
||||
GainNode gain = audioctx.createGain();
|
||||
float v2 = volume;
|
||||
if(v2 > 1.0f) v2 = 1.0f;
|
||||
if (v2 > 1.0f)
|
||||
v2 = 1.0f;
|
||||
gain.getGain().setValue(v2);
|
||||
|
||||
|
||||
src.connect(gain);
|
||||
gain.connect(audioctx.getDestination());
|
||||
gain.connect(recDest);
|
||||
|
||||
|
||||
src.start();
|
||||
|
||||
|
||||
return new BrowserAudioHandle(internalTrack, src, null, gain, pitch);
|
||||
}
|
||||
|
||||
|
@ -367,5 +386,5 @@ public class PlatformAudio {
|
|||
l.setPosition(x, y, z);
|
||||
l.setOrientation(-var3 * var4, -var5, -var2 * var4, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.teavm.jso.webgl.WebGLRenderbuffer;
|
|||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.EarlyLoadScreen;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGL2RenderingContext;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGL2RenderingContext.*;
|
||||
import static org.teavm.jso.webgl.WebGLRenderingContext.COLOR_ATTACHMENT0;
|
||||
|
@ -33,8 +32,6 @@ import static org.teavm.jso.webgl.WebGLRenderingContext.FRAMEBUFFER;
|
|||
import static org.teavm.jso.webgl.WebGLRenderingContext.NEAREST;
|
||||
import static org.teavm.jso.webgl.WebGLRenderingContext.RENDERBUFFER;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.RenderResolution;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
|
@ -123,6 +120,7 @@ public class PlatformInput {
|
|||
public static boolean lockKeys = false;
|
||||
|
||||
private static boolean vsync = true;
|
||||
private static boolean vsyncSupport = false;
|
||||
|
||||
@JSBody(params = {}, script = "window.onbeforeunload = () => {return false;};")
|
||||
private static native void onBeforeCloseRegister();
|
||||
|
@ -274,7 +272,17 @@ public class PlatformInput {
|
|||
mouseDY = 0.0D;
|
||||
}
|
||||
});
|
||||
onBeforeCloseRegister();
|
||||
try {
|
||||
onBeforeCloseRegister();
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
|
||||
try {
|
||||
asyncRequestAnimationFrame();
|
||||
vsyncSupport = true;
|
||||
} catch (Throwable t) {
|
||||
PlatformRuntime.logger.error("VSync is not supported on this browser!");
|
||||
}
|
||||
|
||||
fullscreenQuery = fullscreenMediaQuery();
|
||||
if (keyboardLockSupported = checkKeyboardLockSupported()) {
|
||||
|
@ -322,6 +330,9 @@ public class PlatformInput {
|
|||
vsync = enable;
|
||||
}
|
||||
|
||||
@JSBody(params = { "doc" }, script = "return (doc.visibilityState === \"visible\");")
|
||||
private static native boolean getVisibilityState(JSObject doc);
|
||||
|
||||
public static void update() {
|
||||
double r = win.getDevicePixelRatio();
|
||||
int w = (int) (PlatformRuntime.parent.getClientWidth());
|
||||
|
@ -342,10 +353,14 @@ public class PlatformInput {
|
|||
PlatformRuntime.lastFrame = t;
|
||||
}
|
||||
}
|
||||
if (vsync) {
|
||||
asyncRequestAnimationFrame();
|
||||
if (getVisibilityState(win.getDocument())) {
|
||||
if (vsyncSupport && vsync) {
|
||||
asyncRequestAnimationFrame();
|
||||
} else {
|
||||
EagUtils.sleep(0l);
|
||||
}
|
||||
} else {
|
||||
EagUtils.sleep(0l);
|
||||
EagUtils.sleep(50l);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,6 +385,10 @@ public class PlatformInput {
|
|||
}, 50);
|
||||
}
|
||||
|
||||
public static boolean isVSyncSupported() {
|
||||
return vsyncSupport;
|
||||
}
|
||||
|
||||
static void initFramebuffer(WebGL2RenderingContext ctx, WebGLFramebuffer fbo, int sw, int sh) {
|
||||
context = ctx;
|
||||
mainFramebuffer = fbo;
|
||||
|
@ -628,7 +647,7 @@ public class PlatformInput {
|
|||
keyEvents.clear();
|
||||
}
|
||||
|
||||
@JSBody(params = {}, script = "return window.matchMedia('(display-mode: fullscreen)');")
|
||||
@JSBody(params = {}, script = "return window.matchMedia(\"(display-mode: fullscreen)\");")
|
||||
private static native JSObject fullscreenMediaQuery();
|
||||
|
||||
@JSBody(params = { "mediaQuery" }, script = "return mediaQuery.matches;")
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -13,19 +13,27 @@ import org.teavm.jso.dom.html.HTMLDocument;
|
|||
import org.teavm.jso.dom.html.HTMLElement;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -33,15 +41,15 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
public class DebugConsoleWindow {
|
||||
|
||||
private static class LogMessage {
|
||||
|
||||
|
||||
private final boolean err;
|
||||
private final String msg;
|
||||
|
||||
|
||||
public LogMessage(boolean err, String msg) {
|
||||
this.err = err;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static final int bufferSpoolSize = 256;
|
||||
|
@ -63,13 +71,15 @@ public class DebugConsoleWindow {
|
|||
destroyWindow();
|
||||
}
|
||||
});
|
||||
if("true".equals(parent.getLocalStorage().getItem("_eaglercraftX.showDebugConsole"))) {
|
||||
if ("true".equals(parent.getLocalStorage()
|
||||
.getItem(PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole"))) {
|
||||
showDebugConsole0();
|
||||
}
|
||||
}
|
||||
|
||||
public static void showDebugConsole() {
|
||||
parent.getLocalStorage().setItem("_eaglercraftX.showDebugConsole", "true");
|
||||
parent.getLocalStorage().setItem(
|
||||
PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole", "true");
|
||||
showDebugConsole0();
|
||||
}
|
||||
|
||||
|
@ -77,26 +87,29 @@ public class DebugConsoleWindow {
|
|||
private static native void documentWrite(HTMLDocument doc, String str);
|
||||
|
||||
private static void showDebugConsole0() {
|
||||
if(logger == null) {
|
||||
int w = (int)(1000 * parent.getDevicePixelRatio());
|
||||
int h = (int)(400 * parent.getDevicePixelRatio());
|
||||
if (logger == null) {
|
||||
int w = (int) (1000 * parent.getDevicePixelRatio());
|
||||
int h = (int) (400 * parent.getDevicePixelRatio());
|
||||
int x = (parent.getScreen().getWidth() - w) / 2;
|
||||
int y = (parent.getScreen().getHeight() - h) / 2;
|
||||
logger = parent.open("", "_blank", "top=" + y + ",left=" + x + ",width=" + w + ",height=" + h + ",menubar=0,status=0,titlebar=0,toolbar=0");
|
||||
if(logger == null) {
|
||||
logger = parent.open("", "_blank", "top=" + y + ",left=" + x + ",width=" + w + ",height=" + h
|
||||
+ ",menubar=0,status=0,titlebar=0,toolbar=0");
|
||||
if (logger == null) {
|
||||
LogManager.getLogger("DebugConsoleWindow").error("Logger popup was blocked!");
|
||||
Window.alert("ERROR: Popup blocked!\n\nPlease make sure you have popups enabled for this site!");
|
||||
return;
|
||||
}
|
||||
logger.focus();
|
||||
documentWrite(logger.getDocument(), "<!DOCTYPE html><html><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />"
|
||||
+ "<title>Debug Console</title><link type=\"image/png\" rel=\"shortcut icon\" href=\"" + PlatformApplication.faviconURLTeaVM() + "\" />"
|
||||
+ "</head><body style=\"overflow-x:hidden;overflow-y:scroll;padding:0px;\"><p id=\"loggerMessageContainer\" style=\"overflow-wrap:break-word;white-space:pre-wrap;font:14px monospace;padding:10px;\"></p></body></html>");
|
||||
documentWrite(logger.getDocument(),
|
||||
"<!DOCTYPE html><html><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />"
|
||||
+ "<title>Debug Console</title><link type=\"image/png\" rel=\"shortcut icon\" href=\""
|
||||
+ PlatformApplication.faviconURLTeaVM() + "\" />"
|
||||
+ "</head><body style=\"overflow-x:hidden;overflow-y:scroll;padding:0px;\"><p id=\"loggerMessageContainer\" style=\"overflow-wrap:break-word;white-space:pre-wrap;font:14px monospace;padding:10px;\"></p></body></html>");
|
||||
loggerDoc = logger.getDocument();
|
||||
loggerBody = loggerDoc.getBody();
|
||||
loggerMessageContainer = loggerDoc.getElementById("loggerMessageContainer");
|
||||
synchronized(messageBuffer) {
|
||||
for(LogMessage msg : messageBuffer) {
|
||||
synchronized (messageBuffer) {
|
||||
for (LogMessage msg : messageBuffer) {
|
||||
appendLogMessage(msg.msg + "\n", msg.err ? "#DD0000" : "#000000");
|
||||
}
|
||||
messageBuffer.clear();
|
||||
|
@ -105,7 +118,7 @@ public class DebugConsoleWindow {
|
|||
EventListener<Event> unloadListener = new EventListener<Event>() {
|
||||
@Override
|
||||
public void handleEvent(Event evt) {
|
||||
if(logger != null) {
|
||||
if (logger != null) {
|
||||
logger = null;
|
||||
parent.getLocalStorage().setItem("_eaglercraftX.showDebugConsole", "false");
|
||||
}
|
||||
|
@ -113,17 +126,17 @@ public class DebugConsoleWindow {
|
|||
};
|
||||
logger.addEventListener("beforeunload", unloadListener);
|
||||
logger.addEventListener("unload", unloadListener);
|
||||
}else {
|
||||
} else {
|
||||
logger.focus();
|
||||
}
|
||||
}
|
||||
|
||||
public static void addLogMessage(String text, boolean isErr) {
|
||||
if(logger == null) {
|
||||
synchronized(messageBuffer) {
|
||||
if(logger == null) {
|
||||
if (logger == null) {
|
||||
synchronized (messageBuffer) {
|
||||
if (logger == null) {
|
||||
messageBuffer.add(new LogMessage(isErr, text));
|
||||
while(messageBuffer.size() > bufferSpoolSize) {
|
||||
while (messageBuffer.size() > bufferSpoolSize) {
|
||||
messageBuffer.remove(0);
|
||||
}
|
||||
return;
|
||||
|
@ -136,7 +149,7 @@ public class DebugConsoleWindow {
|
|||
private static void appendLogMessageAndScroll(String text, String color) {
|
||||
boolean b = isScrollToEnd(logger, loggerDoc);
|
||||
appendLogMessage(text, color);
|
||||
if(b) {
|
||||
if (b) {
|
||||
scrollToEnd0(logger, loggerDoc);
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +160,7 @@ public class DebugConsoleWindow {
|
|||
el.getStyle().setProperty("color", color);
|
||||
loggerMessageContainer.appendChild(el);
|
||||
HTMLCollection children = loggerMessageContainer.getChildren();
|
||||
while(children.getLength() > windowMaxMessages) {
|
||||
while (children.getLength() > windowMaxMessages) {
|
||||
children.get(0).delete();
|
||||
}
|
||||
}
|
||||
|
@ -155,11 +168,12 @@ public class DebugConsoleWindow {
|
|||
@JSBody(params = { "win", "doc" }, script = "return (win.innerHeight + win.pageYOffset) >= doc.body.offsetHeight;")
|
||||
private static native boolean isScrollToEnd(Window win, HTMLDocument doc);
|
||||
|
||||
@JSBody(params = { "win", "doc" }, script = "setTimeout(function(){win.scrollTo(0, doc.body.scrollHeight || doc.body.clientHeight);}, 1);")
|
||||
@JSBody(params = { "win",
|
||||
"doc" }, script = "setTimeout(function(){win.scrollTo(0, doc.body.scrollHeight || doc.body.clientHeight);}, 1);")
|
||||
private static native void scrollToEnd0(Window win, HTMLDocument doc);
|
||||
|
||||
public static void destroyWindow() {
|
||||
if(logger != null) {
|
||||
if (logger != null) {
|
||||
Window w = logger;
|
||||
logger = null;
|
||||
w.close();
|
||||
|
|
|
@ -10,26 +10,34 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayManager;
|
|||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.core.JSArrayReader;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapterHooks;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsHooks;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsRelay;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsRelaysArray;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsRoot;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsServer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsServersArray;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -41,7 +49,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
private String defaultLocale = "en_US";
|
||||
private List<DefaultServer> defaultServers = new ArrayList();
|
||||
private List<RelayEntry> relays = new ArrayList();
|
||||
private String serverToJoin = null;
|
||||
private String serverToJoin = null;
|
||||
private String worldsDB = "worlds";
|
||||
private String resourcePacksDB = "resourcePacks";
|
||||
private JSONObject integratedServerOpts;
|
||||
|
@ -56,25 +64,37 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
private boolean checkRelaysForUpdates = false;
|
||||
private boolean enableSignatureBadge = false;
|
||||
private boolean allowVoiceClient = true;
|
||||
private boolean allowFNAWSkins = true;
|
||||
private String localStorageNamespace = "_eaglercraftX";
|
||||
private final TeaVMClientConfigAdapterHooks hooks = new TeaVMClientConfigAdapterHooks();
|
||||
|
||||
public void loadNative(JSObject jsObject) {
|
||||
integratedServerOpts = new JSONObject();
|
||||
JSEaglercraftXOptsRoot eaglercraftXOpts = (JSEaglercraftXOptsRoot)jsObject;
|
||||
|
||||
JSEaglercraftXOptsRoot eaglercraftXOpts = (JSEaglercraftXOptsRoot) jsObject;
|
||||
|
||||
defaultLocale = eaglercraftXOpts.getLang("en_US");
|
||||
serverToJoin = eaglercraftXOpts.getJoinServer(null);
|
||||
worldsDB = eaglercraftXOpts.getWorldsDB("worlds");
|
||||
resourcePacksDB = eaglercraftXOpts.getResourcePacksDB("resourcePacks");
|
||||
checkShaderGLErrors = eaglercraftXOpts.getCheckShaderGLErrors(false);
|
||||
demoMode = EaglercraftVersion.forceDemoMode || eaglercraftXOpts.getDemoMode(false);
|
||||
isAllowUpdateSvc = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftXOpts.getAllowUpdateSvc(true);
|
||||
isAllowUpdateDL = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftXOpts.getAllowUpdateDL(true);
|
||||
isAllowUpdateSvc = EaglercraftVersion.enableUpdateService && !demoMode
|
||||
&& eaglercraftXOpts.getAllowUpdateSvc(true);
|
||||
isAllowUpdateDL = EaglercraftVersion.enableUpdateService && !demoMode
|
||||
&& eaglercraftXOpts.getAllowUpdateDL(true);
|
||||
isEnableDownloadOfflineButton = eaglercraftXOpts.getEnableDownloadOfflineButton(true);
|
||||
downloadOfflineButtonLink = eaglercraftXOpts.getDownloadOfflineButtonLink(null);
|
||||
useSpecialCursors = eaglercraftXOpts.getHtml5CursorSupport(false);
|
||||
logInvalidCerts = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftXOpts.getLogInvalidCerts(false);
|
||||
logInvalidCerts = EaglercraftVersion.enableUpdateService && !demoMode
|
||||
&& eaglercraftXOpts.getLogInvalidCerts(false);
|
||||
enableSignatureBadge = eaglercraftXOpts.getEnableSignatureBadge(false);
|
||||
allowVoiceClient = eaglercraftXOpts.getAllowVoiceClient(true);
|
||||
allowFNAWSkins = eaglercraftXOpts.getAllowFNAWSkins(true);
|
||||
localStorageNamespace = eaglercraftXOpts.getLocalStorageNamespace(EaglercraftVersion.localStorageNamespace);
|
||||
JSEaglercraftXOptsHooks hooksObj = eaglercraftXOpts.getHooks();
|
||||
if (hooksObj != null) {
|
||||
hooks.loadHooks(hooksObj);
|
||||
}
|
||||
|
||||
integratedServerOpts.put("worldsDB", worldsDB);
|
||||
integratedServerOpts.put("demoMode", demoMode);
|
||||
|
@ -82,31 +102,32 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
integratedServerOpts.put("allowUpdateSvc", isAllowUpdateSvc);
|
||||
integratedServerOpts.put("allowUpdateDL", isAllowUpdateDL);
|
||||
integratedServerOpts.put("allowVoiceClient", allowVoiceClient);
|
||||
|
||||
JSEaglercraftXOptsServersArray serversArray = eaglercraftXOpts.getServers();
|
||||
if(serversArray != null) {
|
||||
for(int i = 0, l = serversArray.getLength(); i < l; ++i) {
|
||||
integratedServerOpts.put("allowFNAWSkins", allowFNAWSkins);
|
||||
|
||||
JSArrayReader<JSEaglercraftXOptsServer> serversArray = eaglercraftXOpts.getServers();
|
||||
if (serversArray != null) {
|
||||
for (int i = 0, l = serversArray.getLength(); i < l; ++i) {
|
||||
JSEaglercraftXOptsServer serverEntry = serversArray.get(i);
|
||||
String serverAddr = serverEntry.getAddr();
|
||||
if(serverAddr != null) {
|
||||
if (serverAddr != null) {
|
||||
String serverName = serverEntry.getName("Default Server #" + i);
|
||||
defaultServers.add(new DefaultServer(serverName, serverAddr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSEaglercraftXOptsRelaysArray relaysArray = eaglercraftXOpts.getRelays();
|
||||
if(relaysArray != null) {
|
||||
|
||||
JSArrayReader<JSEaglercraftXOptsRelay> relaysArray = eaglercraftXOpts.getRelays();
|
||||
if (relaysArray != null) {
|
||||
boolean gotAPrimary = false;
|
||||
for(int i = 0, l = relaysArray.getLength(); i < l; ++i) {
|
||||
for (int i = 0, l = relaysArray.getLength(); i < l; ++i) {
|
||||
JSEaglercraftXOptsRelay relay = relaysArray.get(i);
|
||||
String addr = relay.getAddr();
|
||||
if(addr != null) {
|
||||
if (addr != null) {
|
||||
boolean p = relay.getPrimary();
|
||||
if(p) {
|
||||
if(gotAPrimary) {
|
||||
if (p) {
|
||||
if (gotAPrimary) {
|
||||
p = false;
|
||||
}else {
|
||||
} else {
|
||||
gotAPrimary = true;
|
||||
}
|
||||
}
|
||||
|
@ -114,19 +135,21 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean officialUpdates = !demoMode && EaglercraftVersion.updateBundlePackageName.equals("net.lax1dude.eaglercraft.v1_8.client");
|
||||
|
||||
boolean officialUpdates = !demoMode
|
||||
&& EaglercraftVersion.updateBundlePackageName.equals("net.lax1dude.eaglercraft.v1_8.client");
|
||||
if (relays.size() <= 0) {
|
||||
int choice = ThreadLocalRandom.current().nextInt(3);
|
||||
relays.add(new RelayEntry("wss://relay.deev.is/", "lax1dude relay #1", choice == 0));
|
||||
relays.add(new RelayEntry("wss://relay.lax1dude.net/", "lax1dude relay #2", choice == 1));
|
||||
relays.add(new RelayEntry("wss://relay.shhnowisnottheti.me/", "ayunami relay #1", choice == 2));
|
||||
checkRelaysForUpdates = !demoMode && eaglercraftXOpts.getCheckRelaysForUpdates(officialUpdates);
|
||||
}else {
|
||||
if(officialUpdates) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
} else {
|
||||
if (officialUpdates) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
String addr = relays.get(i).address;
|
||||
if(!addr.contains("deev.is") && !addr.contains("lax1dude.net") && !addr.contains("shhnowisnottheti.me")) {
|
||||
if (!addr.contains("deev.is") && !addr.contains("lax1dude.net")
|
||||
&& !addr.contains("shhnowisnottheti.me")) {
|
||||
officialUpdates = false;
|
||||
break;
|
||||
}
|
||||
|
@ -134,9 +157,9 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
}
|
||||
checkRelaysForUpdates = !demoMode && eaglercraftXOpts.getCheckRelaysForUpdates(officialUpdates);
|
||||
}
|
||||
|
||||
|
||||
RelayManager.relayManager.load(EagRuntime.getStorage("r"));
|
||||
|
||||
|
||||
if (RelayManager.relayManager.count() <= 0) {
|
||||
RelayManager.relayManager.loadDefaults();
|
||||
RelayManager.relayManager.save();
|
||||
|
@ -150,24 +173,30 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
worldsDB = eaglercraftOpts.optString("worldsDB", "worlds");
|
||||
resourcePacksDB = eaglercraftOpts.optString("resourcePacksDB", "resourcePacks");
|
||||
checkShaderGLErrors = eaglercraftOpts.optBoolean("checkShaderGLErrors", false);
|
||||
if(EaglercraftVersion.forceDemoMode) {
|
||||
if (EaglercraftVersion.forceDemoMode) {
|
||||
eaglercraftOpts.put("demoMode", true);
|
||||
}
|
||||
demoMode = EaglercraftVersion.forceDemoMode || eaglercraftOpts.optBoolean("demoMode", false);
|
||||
isAllowUpdateSvc = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftOpts.optBoolean("allowUpdateSvc", true);
|
||||
isAllowUpdateDL = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftOpts.optBoolean("allowUpdateDL", true);
|
||||
isAllowUpdateSvc = EaglercraftVersion.enableUpdateService && !demoMode
|
||||
&& eaglercraftOpts.optBoolean("allowUpdateSvc", true);
|
||||
isAllowUpdateDL = EaglercraftVersion.enableUpdateService && !demoMode
|
||||
&& eaglercraftOpts.optBoolean("allowUpdateDL", true);
|
||||
isEnableDownloadOfflineButton = eaglercraftOpts.optBoolean("enableDownloadOfflineButton", true);
|
||||
downloadOfflineButtonLink = eaglercraftOpts.optString("downloadOfflineButtonLink", null);
|
||||
useSpecialCursors = eaglercraftOpts.optBoolean("html5CursorSupport", false);
|
||||
logInvalidCerts = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftOpts.optBoolean("logInvalidCerts", false);
|
||||
logInvalidCerts = EaglercraftVersion.enableUpdateService && !demoMode
|
||||
&& eaglercraftOpts.optBoolean("logInvalidCerts", false);
|
||||
enableSignatureBadge = eaglercraftOpts.optBoolean("enableSignatureBadge", false);
|
||||
allowVoiceClient = eaglercraftOpts.optBoolean("allowVoiceClient", true);
|
||||
allowFNAWSkins = eaglercraftOpts.optBoolean("allowFNAWSkins", true);
|
||||
localStorageNamespace = eaglercraftOpts.optString("localStorageNamespace",
|
||||
EaglercraftVersion.localStorageNamespace);
|
||||
JSONArray serversArray = eaglercraftOpts.optJSONArray("servers");
|
||||
if(serversArray != null) {
|
||||
for(int i = 0, l = serversArray.length(); i < l; ++i) {
|
||||
if (serversArray != null) {
|
||||
for (int i = 0, l = serversArray.length(); i < l; ++i) {
|
||||
JSONObject serverEntry = serversArray.getJSONObject(i);
|
||||
String serverAddr = serverEntry.optString("addr", null);
|
||||
if(serverAddr != null) {
|
||||
if (serverAddr != null) {
|
||||
String serverName = serverEntry.optString("name", "Default Server #" + i);
|
||||
defaultServers.add(new DefaultServer(serverName, serverAddr));
|
||||
}
|
||||
|
@ -175,15 +204,15 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
}
|
||||
|
||||
JSONArray relaysArray = eaglercraftOpts.optJSONArray("relays");
|
||||
if(relaysArray != null) {
|
||||
if (relaysArray != null) {
|
||||
boolean gotAPrimary = false;
|
||||
for (int i = 0, l = relaysArray.length(); i < l; ++i) {
|
||||
JSONObject relay = relaysArray.getJSONObject(i);
|
||||
boolean p = relay.optBoolean("primary");
|
||||
if(p) {
|
||||
if(gotAPrimary) {
|
||||
if (p) {
|
||||
if (gotAPrimary) {
|
||||
p = false;
|
||||
}else {
|
||||
} else {
|
||||
gotAPrimary = true;
|
||||
}
|
||||
}
|
||||
|
@ -191,18 +220,20 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
boolean officialUpdates = !demoMode && EaglercraftVersion.updateBundlePackageName.equals("net.lax1dude.eaglercraft.v1_8.client");
|
||||
boolean officialUpdates = !demoMode
|
||||
&& EaglercraftVersion.updateBundlePackageName.equals("net.lax1dude.eaglercraft.v1_8.client");
|
||||
if (relays.size() <= 0) {
|
||||
int choice = ThreadLocalRandom.current().nextInt(3);
|
||||
relays.add(new RelayEntry("wss://relay.deev.is/", "lax1dude relay #1", choice == 0));
|
||||
relays.add(new RelayEntry("wss://relay.lax1dude.net/", "lax1dude relay #2", choice == 1));
|
||||
relays.add(new RelayEntry("wss://relay.shhnowisnottheti.me/", "ayunami relay #1", choice == 2));
|
||||
checkRelaysForUpdates = !demoMode && eaglercraftOpts.optBoolean("checkRelaysForUpdates", officialUpdates);
|
||||
}else {
|
||||
if(officialUpdates) {
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
} else {
|
||||
if (officialUpdates) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
String addr = relays.get(i).address;
|
||||
if(!addr.contains("deev.is") && !addr.contains("lax1dude.net") && !addr.contains("shhnowisnottheti.me")) {
|
||||
if (!addr.contains("deev.is") && !addr.contains("lax1dude.net")
|
||||
&& !addr.contains("shhnowisnottheti.me")) {
|
||||
officialUpdates = false;
|
||||
break;
|
||||
}
|
||||
|
@ -210,9 +241,9 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
}
|
||||
checkRelaysForUpdates = !demoMode && eaglercraftOpts.optBoolean("checkRelaysForUpdates", officialUpdates);
|
||||
}
|
||||
|
||||
|
||||
RelayManager.relayManager.load(EagRuntime.getStorage("r"));
|
||||
|
||||
|
||||
if (RelayManager.relayManager.count() <= 0) {
|
||||
RelayManager.relayManager.loadDefaults();
|
||||
RelayManager.relayManager.save();
|
||||
|
@ -309,6 +340,21 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
return allowVoiceClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowFNAWSkins() {
|
||||
return allowFNAWSkins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalStorageNamespace() {
|
||||
return localStorageNamespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClientConfigAdapterHooks getHooks() {
|
||||
return hooks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
|
@ -327,8 +373,10 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
jsonObject.put("checkRelaysForUpdates", checkRelaysForUpdates);
|
||||
jsonObject.put("enableSignatureBadge", enableSignatureBadge);
|
||||
jsonObject.put("allowVoiceClient", allowVoiceClient);
|
||||
jsonObject.put("allowFNAWSkins", allowFNAWSkins);
|
||||
jsonObject.put("localStorageNamespace", localStorageNamespace);
|
||||
JSONArray serversArr = new JSONArray();
|
||||
for(int i = 0, l = defaultServers.size(); i < l; ++i) {
|
||||
for (int i = 0, l = defaultServers.size(); i < l; ++i) {
|
||||
DefaultServer srv = defaultServers.get(i);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("addr", srv.addr);
|
||||
|
@ -337,7 +385,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
|
|||
}
|
||||
jsonObject.put("servers", serversArr);
|
||||
JSONArray relaysArr = new JSONArray();
|
||||
for(int i = 0, l = relays.size(); i < l; ++i) {
|
||||
for (int i = 0, l = relays.size(); i < l; ++i) {
|
||||
RelayEntry rl = relays.get(i);
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("addr", rl.address);
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.teavm.interop.Async;
|
||||
import org.teavm.interop.AsyncCallback;
|
||||
import org.teavm.jso.JSFunctor;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.browser.Window;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapterHooks;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.teavm.opts.JSEaglercraftXOptsHooks;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* 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 class TeaVMClientConfigAdapterHooks implements IClientConfigAdapterHooks {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("TeaVMClientConfigAdapterHooks");
|
||||
|
||||
private LocalStorageSaveHook saveHook = null;
|
||||
private LocalStorageLoadHook loadHook = null;
|
||||
|
||||
@JSFunctor
|
||||
private static interface LocalStorageSaveHook extends JSObject {
|
||||
void call(String key, String base64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callLocalStorageSavedHook(String key, String base64) {
|
||||
if (saveHook != null) {
|
||||
callHookSafe("localStorageSaved", () -> {
|
||||
saveHook.call(key, base64);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@JSFunctor
|
||||
private static interface LocalStorageLoadHook extends JSObject {
|
||||
String call(String key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String callLocalStorageLoadHook(String key) {
|
||||
if (loadHook != null) {
|
||||
return (String) callHookSafeWithReturn("localStorageLoaded", () -> {
|
||||
return loadHook.call(key);
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void callHookSafe(String identifer, Runnable hooker) {
|
||||
Window.setTimeout(() -> {
|
||||
try {
|
||||
hooker.run();
|
||||
} catch (Throwable t) {
|
||||
logger.error("Caught exception while invoking eaglercraftXOpts \"{}\" hook!", identifer);
|
||||
logger.error(t);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@Async
|
||||
private static native Object callHookSafeWithReturn(String identifer, Supplier<Object> hooker);
|
||||
|
||||
private static void callHookSafeWithReturn(String identifer, Supplier<Object> hooker,
|
||||
final AsyncCallback<Object> cb) {
|
||||
Window.setTimeout(() -> {
|
||||
Object res = null;
|
||||
try {
|
||||
res = hooker.get();
|
||||
} catch (Throwable t) {
|
||||
logger.error("Caught exception while invoking eaglercraftXOpts \"{}\" hook!", identifer);
|
||||
logger.error(t);
|
||||
} finally {
|
||||
cb.complete(res);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
public void loadHooks(JSEaglercraftXOptsHooks hooks) {
|
||||
saveHook = (LocalStorageSaveHook) hooks.getLocalStorageSavedHook();
|
||||
loadHook = (LocalStorageLoadHook) hooks.getLocalStorageLoadedHook();
|
||||
}
|
||||
}
|
|
@ -7,14 +7,21 @@ import org.teavm.jso.JSProperty;
|
|||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -22,7 +29,7 @@ import org.teavm.jso.JSProperty;
|
|||
public interface JSEaglercraftXOptsAssetsURIsArray extends JSObject {
|
||||
|
||||
@JSIndexer
|
||||
JSEaglercraftXOptsAssetsURI get(int idx);
|
||||
JSEaglercraftXOptsHooks get(int idx);
|
||||
|
||||
@JSProperty
|
||||
int getLength();
|
||||
|
|
|
@ -1,30 +1,36 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.teavm.opts;
|
||||
|
||||
import org.teavm.jso.JSIndexer;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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 JSEaglercraftXOptsServersArray extends JSObject {
|
||||
public abstract class JSEaglercraftXOptsHooks implements JSObject {
|
||||
|
||||
@JSIndexer
|
||||
JSEaglercraftXOptsServer get(int idx);
|
||||
@JSBody(script = "return (typeof this.localStorageSaved === \"function\") ? this.localStorageSaved : null;")
|
||||
public native JSObject getLocalStorageSavedHook();
|
||||
|
||||
@JSProperty
|
||||
int getLength();
|
||||
@JSBody(script = "return (typeof this.localStorageLoaded === \"function\") ? this.localStorageLoaded : null;")
|
||||
public native JSObject getLocalStorageLoadedHook();
|
||||
|
||||
}
|
|
@ -2,18 +2,26 @@ package net.lax1dude.eaglercraft.v1_8.internal.teavm.opts;
|
|||
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.core.JSArrayReader;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -27,7 +35,7 @@ public abstract class JSEaglercraftXOptsRoot implements JSObject {
|
|||
public native String getAssetsURI();
|
||||
|
||||
@JSBody(script = "return (typeof this.assetsURI === \"object\") ? this.assetsURI : null;")
|
||||
public native JSEaglercraftXOptsAssetsURIsArray getAssetsURIArray();
|
||||
public native JSArrayReader<JSEaglercraftXOptsAssetsURI> getAssetsURIArray();
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.lang === \"string\") ? this.lang : def;")
|
||||
public native String getLang(String defaultValue);
|
||||
|
@ -41,45 +49,68 @@ public abstract class JSEaglercraftXOptsRoot implements JSObject {
|
|||
@JSBody(params = { "def" }, script = "return (typeof this.worldsDB === \"string\") ? this.worldsDB : def;")
|
||||
public native String getWorldsDB(String defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.resourcePacksDB === \"string\") ? this.resourcePacksDB : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.resourcePacksDB === \"string\") ? this.resourcePacksDB : def;")
|
||||
public native String getResourcePacksDB(String defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.demoMode === \"boolean\") ? this.demoMode : def;")
|
||||
public native boolean getDemoMode(boolean defaultValue);
|
||||
|
||||
@JSBody(script = "return (typeof this.servers === \"object\") ? this.servers : null;")
|
||||
public native JSEaglercraftXOptsServersArray getServers();
|
||||
public native JSArrayReader<JSEaglercraftXOptsServer> getServers();
|
||||
|
||||
@JSBody(script = "return (typeof this.relays === \"object\") ? this.relays : null;")
|
||||
public native JSEaglercraftXOptsRelaysArray getRelays();
|
||||
public native JSArrayReader<JSEaglercraftXOptsRelay> getRelays();
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.checkShaderGLErrors === \"boolean\") ? this.checkShaderGLErrors : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.checkShaderGLErrors === \"boolean\") ? this.checkShaderGLErrors : def;")
|
||||
public native boolean getCheckShaderGLErrors(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.enableDownloadOfflineButton === \"boolean\") ? this.enableDownloadOfflineButton : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.enableDownloadOfflineButton === \"boolean\") ? this.enableDownloadOfflineButton : def;")
|
||||
public native boolean getEnableDownloadOfflineButton(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.downloadOfflineButtonLink === \"string\") ? this.downloadOfflineButtonLink : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.downloadOfflineButtonLink === \"string\") ? this.downloadOfflineButtonLink : def;")
|
||||
public native String getDownloadOfflineButtonLink(String defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.html5CursorSupport === \"boolean\") ? this.html5CursorSupport : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.html5CursorSupport === \"boolean\") ? this.html5CursorSupport : def;")
|
||||
public native boolean getHtml5CursorSupport(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.allowUpdateSvc === \"boolean\") ? this.allowUpdateSvc : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.allowUpdateSvc === \"boolean\") ? this.allowUpdateSvc : def;")
|
||||
public native boolean getAllowUpdateSvc(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.allowUpdateDL === \"boolean\") ? this.allowUpdateDL : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.allowUpdateDL === \"boolean\") ? this.allowUpdateDL : def;")
|
||||
public native boolean getAllowUpdateDL(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.logInvalidCerts === \"boolean\") ? this.logInvalidCerts : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.logInvalidCerts === \"boolean\") ? this.logInvalidCerts : def;")
|
||||
public native boolean getLogInvalidCerts(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.enableSignatureBadge === \"boolean\") ? this.enableSignatureBadge : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.enableSignatureBadge === \"boolean\") ? this.enableSignatureBadge : def;")
|
||||
public native boolean getEnableSignatureBadge(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.checkRelaysForUpdates === \"boolean\") ? this.checkRelaysForUpdates : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.checkRelaysForUpdates === \"boolean\") ? this.checkRelaysForUpdates : def;")
|
||||
public native boolean getCheckRelaysForUpdates(boolean defaultValue);
|
||||
|
||||
@JSBody(params = { "def" }, script = "return (typeof this.allowVoiceClient === \"boolean\") ? this.allowVoiceClient : def;")
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.allowVoiceClient === \"boolean\") ? this.allowVoiceClient : def;")
|
||||
public native boolean getAllowVoiceClient(boolean defaultValue);
|
||||
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.allowFNAWSkins === \"boolean\") ? this.allowFNAWSkins : def;")
|
||||
public native boolean getAllowFNAWSkins(boolean defaultValue);
|
||||
|
||||
@JSBody(script = "return (typeof this.hooks === \"object\") ? this.hooks : null;")
|
||||
public native JSEaglercraftXOptsHooks getHooks();
|
||||
|
||||
@JSBody(params = {
|
||||
"def" }, script = "return (typeof this.localStorageNamespace === \"string\") ? this.localStorageNamespace : def;")
|
||||
public native String getLocalStorageNamespace(String defaultValue);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,16 +18,24 @@ import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerIntegratedServerWorker;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.server.internal.ServerPlatformSingleplayer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2023-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* 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)
|
||||
* 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.
|
||||
*
|
||||
|
@ -41,25 +49,28 @@ public class WorkerMain {
|
|||
__println(systemOut, false, "WorkerMain: [INFO] eaglercraftx worker thread is starting...");
|
||||
String startArgs = getStartArgs();
|
||||
__println(systemOut, false, "WorkerMain: [INFO] reading configuration");
|
||||
if(startArgs == null) {
|
||||
if (startArgs == null) {
|
||||
throw new NullPointerException("startup arguments is null!");
|
||||
}
|
||||
((TeaVMClientConfigAdapter)TeaVMClientConfigAdapter.instance).loadJSON(new JSONObject(startArgs));
|
||||
((TeaVMClientConfigAdapter) TeaVMClientConfigAdapter.instance).loadJSON(new JSONObject(startArgs));
|
||||
__println(systemOut, false, "WorkerMain: [INFO] initializing server runtime");
|
||||
EaglerIntegratedServerWorker.enableLoggingRedirector(true);
|
||||
ServerPlatformSingleplayer.initializeContext();
|
||||
__println(systemOut, false, "WorkerMain: [INFO] starting worker thread");
|
||||
PlatformRuntime.setThreadName("IntegratedServer");
|
||||
EaglerIntegratedServerWorker.serverMain();
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
System.setOut(systemOut);
|
||||
System.setErr(systemErr);
|
||||
__println(systemErr, true, "WorkerMain: [ERROR] uncaught exception thrown!");
|
||||
EaglerIntegratedServerWorker.sendLogMessagePacket(EagRuntime.getStackTrace(t), true);
|
||||
EagRuntime.debugPrintStackTraceToSTDERR(t);
|
||||
EaglerIntegratedServerWorker.sendIPCPacket(new IPCPacket15Crashed("UNCAUGHT EXCEPTION CAUGHT IN WORKER PROCESS!\n\n" + EagRuntime.getStackTrace(t)));
|
||||
EaglerIntegratedServerWorker.sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacketFFProcessKeepAlive.EXITED));
|
||||
}finally {
|
||||
EaglerIntegratedServerWorker.sendIPCPacket(new IPCPacket15Crashed(
|
||||
"UNCAUGHT EXCEPTION CAUGHT IN WORKER PROCESS!\n\n" + EagRuntime.getStackTrace(t)));
|
||||
EaglerIntegratedServerWorker
|
||||
.sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacketFFProcessKeepAlive.EXITED));
|
||||
|
||||
} finally {
|
||||
__println(systemErr, true, "WorkerMain: [ERROR] eaglercraftx worker thread has exited");
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +79,7 @@ public class WorkerMain {
|
|||
stream.println(msg);
|
||||
try {
|
||||
EaglerIntegratedServerWorker.sendLogMessagePacket(msg, err);
|
||||
}catch(Throwable t) {
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue