Update #36 - Fix incorrect use of arithmetic shift, more capes

This commit is contained in:
lax1dude 2024-06-23 17:02:58 -07:00
parent 7425179b36
commit cc1fe13421
60 changed files with 421 additions and 210 deletions

View File

@ -163,9 +163,11 @@ The default eaglercraftXOpts values is this:
- `allowFNAWSkins:` can be used to disable the high poly FNAW skins
- `localStorageNamespace:` can be used to change the prefix of the local storage keys (Default: `"_eaglercraftX"`)
- `enableMinceraft:` can be used to disable the "Minceraft" title screen
- `crashOnUncaughtExceptions:` display crash reports when `window.onerror` is fired
- `hooks:` can be used to define JavaScript callbacks for certain events
* `localStorageSaved:` JavaScript callback to save local storage keys
* `localStorageLoaded:` JavaScript callback to load local storage keys
* `crashReportShow:` JavaScript callback when a crash report is shown
### Using Hooks
@ -193,6 +195,17 @@ Be aware that the client will still save the key to the browser's local storage
On a normal client you will only ever need to handle local storage keys called `p` (profile), `g` (game settings), `s` (server list), `r` (shared world relays), in your hooks functions. Feel free to just ignore any other keys. It is guaranteed that the data the client stores will always be valid base64, so it is best practice to decode it to raw binary first if possible to reduce it's size before saving it to something like a MySQL database in your backend if you are trying to implement some kind of profile syncing system for your website. The keys already have GZIP compression applied to them by default so don't bother trying to compress them yourself a second time because it won't reduce their size.
### Crash Report Hook
The `crashReportShow` hook can be used to capture crash reports and append additional text to them. It takes two parameters, the crash report as a string and a callback function for appending text. Do not use the callback function outside the body of the hook.
hooks: {
crashReportShow: function(report, customMessageCB) {
// 'report' is crash report as a string
customMessageCB("Hello from crashReportShow hook!");
}
}
## Developing a Client
There is currently no system in place to make forks of 1.8 and merge commits made to the patch files in this repository with the patch files or workspace of the fork, you're on your own if you try to keep a fork of this repo for reasons other than to contribute to it

View File

@ -1 +1 @@
u35
u36

View File

@ -741,12 +741,13 @@
+ }
+
> CHANGE 6 : 17 @ 6 : 54
> CHANGE 6 : 18 @ 6 : 54
~ Minecraft.getMinecraft().getRenderManager().setEnableFNAWSkins(this.gameSettings.enableFNAWSkins);
~ session.reset();
~ SingleplayerServerController.launchEaglercraftServer(folderName, gameSettings.difficulty.getDifficultyId(),
~ Math.max(gameSettings.renderDistanceChunks, 2), worldSettingsIn);
~ EagRuntime.setMCServerWindowGlobal("singleplayer");
~ this.displayGuiScreen(new GuiScreenIntegratedServerBusy(
~ new GuiScreenSingleplayerConnecting(new GuiMainMenu(), "Connecting to " + folderName),
~ "singleplayer.busy.startingIntegratedServer", "singleplayer.failed.startingIntegratedServer",
@ -787,7 +788,26 @@
~ return EaglercraftGPU.glGetString(7937) + " GL version " + EaglercraftGPU.glGetString(7938) + ", "
~ + EaglercraftGPU.glGetString(7936);
> DELETE 2 @ 2 : 12
> CHANGE 2 : 5 @ 2 : 5
~ theCrash.getCategory().addCrashSectionCallable("Is Eagler Shaders", new Callable<String>() {
~ public String call() throws Exception {
~ return Minecraft.this.gameSettings.shaders ? "Yes" : "No";
> CHANGE 2 : 6 @ 2 : 5
~ theCrash.getCategory().addCrashSectionCallable("Is Dynamic Lights", new Callable<String>() {
~ public String call() throws Exception {
~ return !Minecraft.this.gameSettings.shaders && Minecraft.this.gameSettings.enableDynamicLights ? "Yes"
~ : "No";
> INSERT 2 : 7 @ 2
+ theCrash.getCategory().addCrashSectionCallable("In Ext. Pipeline", new Callable<String>() {
+ public String call() throws Exception {
+ return GlStateManager.isExtensionPipeline() ? "Yes" : "No";
+ }
+ });
> CHANGE 2 : 3 @ 2 : 6
@ -812,7 +832,11 @@
> DELETE 2 @ 2 : 219
> CHANGE 13 : 14 @ 13 : 14
> INSERT 6 : 7 @ 6
+ EagRuntime.setMCServerWindowGlobal(serverDataIn != null ? serverDataIn.serverIP : null);
> CHANGE 7 : 8 @ 7 : 8
~ return SingleplayerServerController.isWorldRunning();

View File

@ -342,7 +342,14 @@
> DELETE 1 @ 1 : 3
> CHANGE 7 : 12 @ 7 : 8
> CHANGE 3 : 7 @ 3 : 5
~ if (enableBlur) {
~ this.drawGradientRect(0, 0, this.width, this.height, -2130706433, 16777215);
~ this.drawGradientRect(0, 0, this.width, this.height, 0, Integer.MIN_VALUE);
~ }
> CHANGE 2 : 7 @ 2 : 3
~ boolean minc = (double) this.updateCounter < 1.0E-4D;
~ if (this.isDefault) {

View File

@ -33,6 +33,6 @@
> INSERT 1 : 2 @ 1
+ this.mapTextureData[i] = (c & 0xFF00FF00) | ((c & 0x00FF0000) >> 16) | ((c & 0x000000FF) << 16);
+ this.mapTextureData[i] = (c & 0xFF00FF00) | ((c & 0x00FF0000) >>> 16) | ((c & 0x000000FF) << 16);
> EOF

View File

@ -126,9 +126,9 @@
> CHANGE 9 : 16 @ 9 : 65
~ GlStateManager.enableShaderBlendAdd();
~ float f1 = 1.0F - (float) (i >> 24 & 255) / 255.0F;
~ float f2 = (float) (i >> 16 & 255) / 255.0F;
~ float f3 = (float) (i >> 8 & 255) / 255.0F;
~ float f1 = 1.0F - (float) (i >>> 24 & 255) / 255.0F;
~ float f2 = (float) (i >>> 16 & 255) / 255.0F;
~ float f3 = (float) (i >>> 8 & 255) / 255.0F;
~ float f4 = (float) (i & 255) / 255.0F;
~ GlStateManager.setShaderBlendSrc(f1, f1, f1, 1.0F);
~ GlStateManager.setShaderBlendAdd(f2 * f1 + 0.4F, f3 * f1, f4 * f1, 0.0f);

View File

@ -274,4 +274,8 @@ public class PlatformApplication {
}
public static void setMCServerWindowGlobal(String str) {
}
}

View File

@ -73,7 +73,7 @@ public class PlatformAssets {
if(!a) {
j = j | 0xFF000000;
}
pixels[i] = (j & 0xFF00FF00) | ((j & 0x00FF0000) >> 16) |
pixels[i] = (j & 0xFF00FF00) | ((j & 0x00FF0000) >>> 16) |
((j & 0x000000FF) << 16);
}
return new ImageData(w, h, pixels, a);

View File

@ -143,7 +143,7 @@ public class PlatformRuntime {
windowIcons[i].getRGB(0, 0, w, h, px, 0, w);
for(int j = 0; j < px.length; ++j) {
px[j] = (px[j] & 0xFF00FF00) | ((px[j] >> 16) & 0xFF) | ((px[j] & 0xFF) << 16); // swap R/B
px[j] = (px[j] & 0xFF00FF00) | ((px[j] >>> 16) & 0xFF) | ((px[j] & 0xFF) << 16); // swap R/B
}
java.nio.ByteBuffer iconBuffer = st.malloc(w * h * 4);

View File

@ -2,6 +2,7 @@ package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.json.JSONObject;
@ -164,5 +165,10 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
return null;
}
@Override
public void callCrashReportHook(String crashReport, Consumer<String> customMessageCB) {
}
}
}

View File

@ -226,6 +226,9 @@ public class EagRuntime {
return PlatformRuntime.maxMemory();
}
/**
* Note to skids: This doesn't do anything in TeaVM runtime!
*/
public static long totalMemory() {
return PlatformRuntime.totalMemory();
}
@ -322,4 +325,8 @@ public class EagRuntime {
input.setCalendar(getLocaleCalendar());
return input;
}
public static void setMCServerWindowGlobal(String url) {
PlatformApplication.setMCServerWindowGlobal(url);
}
}

View File

@ -10,7 +10,7 @@ public class EaglercraftVersion {
/// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u35";
public static final String projectForkVersion = "u36";
public static final String projectForkVendor = "lax1dude";
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
@ -20,7 +20,7 @@ public class EaglercraftVersion {
public static final String projectOriginName = "EaglercraftX";
public static final String projectOriginAuthor = "lax1dude";
public static final String projectOriginRevision = "1.8";
public static final String projectOriginVersion = "u35";
public static final String projectOriginVersion = "u36";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
@ -31,7 +31,7 @@ public class EaglercraftVersion {
public static final boolean enableUpdateService = true;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 35;
public static final int updateBundlePackageVersionInt = 36;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;

View File

@ -1,5 +1,7 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.function.Consumer;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
@ -21,4 +23,6 @@ public interface IClientConfigAdapterHooks {
String callLocalStorageLoadHook(String key);
void callCrashReportHook(String crashReport, Consumer<String> customMessageCB);
}

View File

@ -72,14 +72,14 @@ public class AcceleratedEffectRenderer implements IAcceleratedParticleEngine {
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a) {
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, r, g, b, a);
(lightMapData >>> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, r, g, b, a);
}
@Override
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba) {
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, rgba);
(lightMapData >>> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, rgba);
}
}

View File

@ -47,10 +47,10 @@ public class EaglerFontRenderer extends FontRenderer {
if ((color & 0xFC000000) == 0) {
color |= 0xFF000000;
}
this.red = (float) (color >> 16 & 255) / 255.0F;
this.blue = (float) (color >> 8 & 255) / 255.0F;
this.red = (float) (color >>> 16 & 255) / 255.0F;
this.blue = (float) (color >>> 8 & 255) / 255.0F;
this.green = (float) (color & 255) / 255.0F;
this.alpha = (float) (color >> 24 & 255) / 255.0F;
this.alpha = (float) (color >>> 24 & 255) / 255.0F;
this.posX = x;
this.posY = y;
this.textColor = color;

View File

@ -72,8 +72,8 @@ public class ByteBufEaglercraftImpl extends AbstractByteBuf {
@Override
protected void _setMedium(int index, int value) {
internal.put(index, (byte)((value >> 16) & 0xFF));
internal.put(index + 1, (byte)((value >> 8) & 0xFF));
internal.put(index, (byte)((value >>> 16) & 0xFF));
internal.put(index + 1, (byte)((value >>> 8) & 0xFF));
internal.put(index + 2, (byte)(value & 0xFF));
}

View File

@ -118,14 +118,14 @@ public class ImageData {
if((spx & 0xFF000000) == 0xFF000000 || (dpx & 0xFF000000) == 0) {
pixels[di] = spx;
}else {
int sa = (spx >> 24) & 0xFF;
int da = (dpx >> 24) & 0xFF;
int r = ((spx >> 16) & 0xFF) * sa / 255;
int g = ((spx >> 8) & 0xFF) * sa / 255;
int sa = (spx >>> 24) & 0xFF;
int da = (dpx >>> 24) & 0xFF;
int r = ((spx >>> 16) & 0xFF) * sa / 255;
int g = ((spx >>> 8) & 0xFF) * sa / 255;
int b = (spx & 0xFF) * sa / 255;
int aa = (255 - sa) * da;
r += ((dpx >> 16) & 0xFF) * aa / 65025;
g += ((dpx >> 8) & 0xFF) * aa / 65025;
r += ((dpx >>> 16) & 0xFF) * aa / 65025;
g += ((dpx >>> 8) & 0xFF) * aa / 65025;
b += (dpx & 0xFF) * aa / 65025;
sa += da;
if(sa > 0xFF) sa = 0xFF;
@ -138,14 +138,14 @@ public class ImageData {
public ImageData swapRB() {
for(int i = 0; i < pixels.length; ++i) {
int j = pixels[i];
pixels[i] = (j & 0xFF00FF00) | ((j & 0x00FF0000) >> 16) |
pixels[i] = (j & 0xFF00FF00) | ((j & 0x00FF0000) >>> 16) |
((j & 0x000000FF) << 16);
}
return this;
}
public static int swapRB(int c) {
return (c & 0xFF00FF00) | ((c & 0x00FF0000) >> 16) | ((c & 0x000000FF) << 16);
return (c & 0xFF00FF00) | ((c & 0x00FF0000) >>> 16) | ((c & 0x000000FF) << 16);
}
}

View File

@ -413,7 +413,7 @@ public class InstancedFontRenderer {
buf.putShort((short)y);
buf.put((byte)cx);
buf.put((byte)cy);
color = ((color >> 1) & 0x7F000000) | (color & 0xFFFFFF);
color = ((color >>> 1) & 0x7F000000) | (color & 0xFFFFFF);
if(italic) {
color |= 0x80000000;
}
@ -438,7 +438,7 @@ public class InstancedFontRenderer {
buf.putShort((short)y);
buf.put((byte)cx);
buf.put((byte)cy);
color = ((color >> 1) & 0x7F000000) | (color & 0xFFFFFF);
color = ((color >>> 1) & 0x7F000000) | (color & 0xFFFFFF);
if(italic) {
color |= 0x80000000;
}

View File

@ -267,8 +267,8 @@ public class WorldRenderer {
if (!this.needsUpdate) {
j = this.intBuffer.get(i);
int k = (int) ((float) (j & 255) * red);
int l = (int) ((float) (j >> 8 & 255) * green);
int i1 = (int) ((float) (j >> 16 & 255) * blue);
int l = (int) ((float) (j >>> 8 & 255) * green);
int i1 = (int) ((float) (j >>> 16 & 255) * blue);
j = j & -16777216;
j = j | i1 << 16 | l << 8 | k;
}
@ -280,10 +280,10 @@ public class WorldRenderer {
*/
private void putColor(int argb, int parInt2) {
int i = this.getColorIndex(parInt2);
int j = argb >> 16 & 255;
int k = argb >> 8 & 255;
int j = argb >>> 16 & 255;
int k = argb >>> 8 & 255;
int l = argb & 255;
int i1 = argb >> 24 & 255;
int i1 = argb >>> 24 & 255;
this.putColorRGBA(i, j, k, l, i1);
}

View File

@ -63,8 +63,8 @@ public class CapePackets {
}
public static byte[] writeMyCapePreset(int capeId) {
return new byte[] { (byte) PACKET_MY_CAPE_PRESET, (byte) (capeId >> 24), (byte) (capeId >> 16),
(byte) (capeId >> 8), (byte) (capeId & 0xFF) };
return new byte[] { (byte) PACKET_MY_CAPE_PRESET, (byte) (capeId >>> 24), (byte) (capeId >>> 16),
(byte) (capeId >>> 8), (byte) (capeId & 0xFF) };
}
public static byte[] writeMyCapeCustom(CustomCape customCape) {

View File

@ -39,9 +39,14 @@ public enum DefaultCapes {
SNOWMAN(17, "Snowman", new ResourceLocation("eagler:capes/17.snowman.png")),
SPADE(18, "Spade", new ResourceLocation("eagler:capes/18.spade.png")),
BIRTHDAY(19, "Birthday", new ResourceLocation("eagler:capes/19.birthday.png")),
DB(20, "dB", new ResourceLocation("eagler:capes/20.db.png"));
DB(20, "dB", new ResourceLocation("eagler:capes/20.db.png")),
_15TH_ANNIVERSARY(21, "15th Anniversary", new ResourceLocation("eagler:capes/21.15th_anniversary.png")),
VANILLA(22, "Vanilla", new ResourceLocation("eagler:capes/22.vanilla.png")),
TIKTOK(23, "TikTok", new ResourceLocation("eagler:capes/23.tiktok.png")),
PURPLE_HEART(24, "Purple Heart", new ResourceLocation("eagler:capes/24.purple_heart.png")),
CHERRY_BLOSSOM(25, "Cherry Blossom", new ResourceLocation("eagler:capes/25.cherry_blossom.png"));
public static final DefaultCapes[] defaultCapesMap = new DefaultCapes[21];
public static final DefaultCapes[] defaultCapesMap = new DefaultCapes[26];
public final int id;
public final String name;

View File

@ -345,9 +345,9 @@ public class GuiScreenEditProfile extends GuiScreen {
for(int i = 0, j, k; i < 4096; ++i) {
j = i << 2;
k = loadedSkin.pixels[i];
rawSkin[j] = (byte)(k >> 24);
rawSkin[j + 1] = (byte)(k >> 16);
rawSkin[j + 2] = (byte)(k >> 8);
rawSkin[j] = (byte)(k >>> 24);
rawSkin[j + 1] = (byte)(k >>> 16);
rawSkin[j + 2] = (byte)(k >>> 8);
rawSkin[j + 3] = (byte)(k & 0xFF);
}
for(int y = 20; y < 32; ++y) {

View File

@ -59,7 +59,7 @@ public class ProfileExporter {
+ (doExportServers ? "servers " : "") + (doExportResourcePacks ? "resourcePacks" : "") + "\n\n")
.getBytes(StandardCharsets.UTF_8);
osb.write((comment.length >> 8) & 255);
osb.write((comment.length >>> 8) & 255);
osb.write(comment.length & 255);
osb.write(comment);
@ -164,9 +164,9 @@ public class ProfileExporter {
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] = (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!");

View File

@ -42,8 +42,8 @@ public class SkinConverter {
i = (y * 23 + x) * 3;
j = skinIn.pixels[y * skinIn.width + x];
if((j & 0xFF000000) != 0) {
skinOut[i] = (byte)(j >> 16);
skinOut[i + 1] = (byte)(j >> 8);
skinOut[i] = (byte)(j >>> 16);
skinOut[i + 1] = (byte)(j >>> 8);
skinOut[i + 2] = (byte)(j & 0xFF);
}else {
skinOut[i] = skinOut[i + 1] = skinOut[i + 2] = 0;
@ -54,8 +54,8 @@ public class SkinConverter {
i = ((y + 6) * 23 + 22) * 3;
j = skinIn.pixels[(y + 11) * skinIn.width + 22];
if((j & 0xFF000000) != 0) {
skinOut[i] = (byte)(j >> 16);
skinOut[i + 1] = (byte)(j >> 8);
skinOut[i] = (byte)(j >>> 16);
skinOut[i + 1] = (byte)(j >>> 8);
skinOut[i + 2] = (byte)(j & 0xFF);
}else {
skinOut[i] = skinOut[i + 1] = skinOut[i + 2] = 0;

View File

@ -81,8 +81,8 @@ public class SkinPackets {
}
public static byte[] writeMySkinPreset(int skinId) {
return new byte[] { (byte) PACKET_MY_SKIN_PRESET, (byte) (skinId >> 24), (byte) (skinId >> 16),
(byte) (skinId >> 8), (byte) (skinId & 0xFF) };
return new byte[] { (byte) PACKET_MY_SKIN_PRESET, (byte) (skinId >>> 24), (byte) (skinId >>> 16),
(byte) (skinId >>> 8), (byte) (skinId & 0xFF) };
}
public static byte[] writeMySkinCustom(CustomSkin customSkin) {

View File

@ -191,12 +191,12 @@ public class ConnectionHandshake {
int passLen = password.length();
digest.update((byte)((passLen >> 8) & 0xFF));
digest.update((byte)((passLen >>> 8) & 0xFF));
digest.update((byte)(passLen & 0xFF));
for(int i = 0; i < passLen; ++i) {
char codePoint = password.charAt(i);
digest.update((byte)((codePoint >> 8) & 0xFF));
digest.update((byte)((codePoint >>> 8) & 0xFF));
digest.update((byte)(codePoint & 0xFF));
}

View File

@ -57,9 +57,9 @@ public class SkullCommand {
for(int i = 0, j, k; i < 4096; ++i) {
j = i << 2;
k = loaded.pixels[i];
rawSkin[j] = (byte)(k >> 24);
rawSkin[j + 1] = (byte)(k >> 16);
rawSkin[j + 2] = (byte)(k >> 8);
rawSkin[j] = (byte)(k >>> 24);
rawSkin[j + 1] = (byte)(k >>> 16);
rawSkin[j + 2] = (byte)(k >>> 8);
rawSkin[j + 3] = (byte)(k & 0xFF);
}
mc.thePlayer.sendQueue.addToSendQueue(new C17PacketCustomPayload("EAG|Skins-1.8", SkinPackets.writeCreateCustomSkull(rawSkin)));

View File

@ -8,8 +8,10 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayServer;
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayServerSocket;
import net.lax1dude.eaglercraft.v1_8.sp.socket.NetHandlerSingleplayerLogin;
import net.minecraft.client.LoadingScreenRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiDisconnected;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.resources.I18n;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.login.client.C00PacketLoginStart;
@ -54,6 +56,7 @@ public class GuiScreenLANConnecting extends GuiScreen {
this.parent = parent;
this.code = code;
this.relay = relay;
Minecraft.getMinecraft().setServerData(new ServerData("Shared World", "shared:" + relay.address, false));
}
public boolean doesGuiPauseGame() {

View File

@ -32,7 +32,7 @@ import net.lax1dude.eaglercraft.v1_8.sp.relay.pkt.*;
*/
public class LANServerController {
public static final Logger logger = LogManager.getLogger("IntegratedServerLAN");
public static final Logger logger = LogManager.getLogger("LANServerController");
public static final List<String> currentICEServers = new ArrayList();

View File

@ -154,7 +154,7 @@ public class IPacket {
is.write(0);
}else {
int l = txt.length();
is.write((l >> 8) & 0xFF);
is.write((l >>> 8) & 0xFF);
is.write(l & 0xFF);
for(int i = 0; i < l; ++i) {
is.write((int)txt.charAt(i));

View File

@ -41,8 +41,8 @@ public class EaglerChunkLoader extends AnvilChunkLoader {
char[] path = new char[12];
for(int i = 5; i >= 0; --i) {
path[i] = hex.charAt((unsignedX >> (i * 4)) & 0xF);
path[i + 6] = hex.charAt((unsignedZ >> (i * 4)) & 0xF);
path[i] = hex.charAt((unsignedX >>> (i << 2)) & 0xF);
path[i + 6] = hex.charAt((unsignedZ >>> (i << 2)) & 0xF);
}
return new String(path);

View File

@ -49,7 +49,7 @@ public class EPKCompiler {
EagRuntime.fixDateFormat(new SimpleDateFormat("hh:mm:ss aa")).format(d) + "\n\n # world name: " + name + "\n\n")
.getBytes(StandardCharsets.UTF_8);
os.write((comment.length >> 8) & 255);
os.write((comment.length >>> 8) & 255);
os.write(comment.length & 255);
os.write(comment);
@ -134,9 +134,9 @@ public class EPKCompiler {
byte[] ret = os.toByteArray();
ret[lengthIntegerOffset] = (byte)((totalFileCount >> 24) & 0xFF);
ret[lengthIntegerOffset + 1] = (byte)((totalFileCount >> 16) & 0xFF);
ret[lengthIntegerOffset + 2] = (byte)((totalFileCount >> 8) & 0xFF);
ret[lengthIntegerOffset] = (byte)(totalFileCount >>> 24);
ret[lengthIntegerOffset + 1] = (byte)(totalFileCount >>> 16);
ret[lengthIntegerOffset + 2] = (byte)(totalFileCount >>> 8);
ret[lengthIntegerOffset + 3] = (byte)(totalFileCount & 0xFF);
return ret;
@ -147,21 +147,21 @@ public class EPKCompiler {
}
public static void writeInt(int i, OutputStream os) throws IOException {
os.write((i >> 24) & 0xFF);
os.write((i >> 16) & 0xFF);
os.write((i >> 8) & 0xFF);
os.write((i >>> 24) & 0xFF);
os.write((i >>> 16) & 0xFF);
os.write((i >>> 8) & 0xFF);
os.write(i & 0xFF);
}
public static void writeLong(long i, OutputStream os) throws IOException {
os.write((int)((i >> 56) & 0xFF));
os.write((int)((i >> 48) & 0xFF));
os.write((int)((i >> 40) & 0xFF));
os.write((int)((i >> 32) & 0xFF));
os.write((int)((i >> 24) & 0xFF));
os.write((int)((i >> 16) & 0xFF));
os.write((int)((i >> 8) & 0xFF));
os.write((int)(i & 0xFF));
os.write((int)((i >>> 56l) & 0xFFl));
os.write((int)((i >>> 48l) & 0xFFl));
os.write((int)((i >>> 40l) & 0xFFl));
os.write((int)((i >>> 32l) & 0xFFl));
os.write((int)((i >>> 24l) & 0xFFl));
os.write((int)((i >>> 16l) & 0xFFl));
os.write((int)((i >>> 8l) & 0xFFl));
os.write((int)(i & 0xFFl));
}
}

View File

@ -89,9 +89,9 @@ public class IntegratedCapePackets {
byte[] ret = new byte[1 + 16 + 4];
ret[0] = (byte)PACKET_OTHER_CAPE_PRESET;
IntegratedSkinPackets.UUIDToBytes(uuid, ret, 1);
ret[17] = (byte)(presetId >> 24);
ret[18] = (byte)(presetId >> 16);
ret[19] = (byte)(presetId >> 8);
ret[17] = (byte)(presetId >>> 24);
ret[18] = (byte)(presetId >>> 16);
ret[19] = (byte)(presetId >>> 8);
ret[20] = (byte)(presetId & 0xFF);
return ret;
}

View File

@ -143,9 +143,9 @@ public class IntegratedSkinPackets {
byte[] ret = new byte[1 + 16 + 4];
ret[0] = (byte)PACKET_OTHER_SKIN_PRESET;
UUIDToBytes(uuid, ret, 1);
ret[17] = (byte)(presetId >> 24);
ret[18] = (byte)(presetId >> 16);
ret[19] = (byte)(presetId >> 8);
ret[17] = (byte)(presetId >>> 24);
ret[18] = (byte)(presetId >>> 16);
ret[19] = (byte)(presetId >>> 8);
ret[20] = (byte)(presetId & 0xFF);
return ret;
}
@ -197,21 +197,21 @@ public class IntegratedSkinPackets {
public static void UUIDToBytes(EaglercraftUUID uuid, byte[] bytes, int off) {
long msb = uuid.getMostSignificantBits();
long lsb = uuid.getLeastSignificantBits();
bytes[off] = (byte)(msb >> 56l);
bytes[off + 1] = (byte)(msb >> 48l);
bytes[off + 2] = (byte)(msb >> 40l);
bytes[off + 3] = (byte)(msb >> 32l);
bytes[off + 4] = (byte)(msb >> 24l);
bytes[off + 5] = (byte)(msb >> 16l);
bytes[off + 6] = (byte)(msb >> 8l);
bytes[off] = (byte)(msb >>> 56l);
bytes[off + 1] = (byte)(msb >>> 48l);
bytes[off + 2] = (byte)(msb >>> 40l);
bytes[off + 3] = (byte)(msb >>> 32l);
bytes[off + 4] = (byte)(msb >>> 24l);
bytes[off + 5] = (byte)(msb >>> 16l);
bytes[off + 6] = (byte)(msb >>> 8l);
bytes[off + 7] = (byte)(msb & 0xFFl);
bytes[off + 8] = (byte)(lsb >> 56l);
bytes[off + 9] = (byte)(lsb >> 48l);
bytes[off + 10] = (byte)(lsb >> 40l);
bytes[off + 11] = (byte)(lsb >> 32l);
bytes[off + 12] = (byte)(lsb >> 24l);
bytes[off + 13] = (byte)(lsb >> 16l);
bytes[off + 14] = (byte)(lsb >> 8l);
bytes[off + 8] = (byte)(lsb >>> 56l);
bytes[off + 9] = (byte)(lsb >>> 48l);
bytes[off + 10] = (byte)(lsb >>> 40l);
bytes[off + 11] = (byte)(lsb >>> 32l);
bytes[off + 12] = (byte)(lsb >>> 24l);
bytes[off + 13] = (byte)(lsb >>> 16l);
bytes[off + 14] = (byte)(lsb >>> 8l);
bytes[off + 15] = (byte)(lsb & 0xFFl);
}

View File

@ -239,9 +239,9 @@ public class IntegratedServerPlayerNetworkManager {
byte[] compressedData;
try {
temporaryOutputStream.write(2);
temporaryOutputStream.write((len >> 24) & 0xFF);
temporaryOutputStream.write((len >> 16) & 0xFF);
temporaryOutputStream.write((len >> 8) & 0xFF);
temporaryOutputStream.write((len >>> 24) & 0xFF);
temporaryOutputStream.write((len >>> 16) & 0xFF);
temporaryOutputStream.write((len >>> 8) & 0xFF);
temporaryOutputStream.write(len & 0xFF);
try(OutputStream os = EaglerZLIB.newDeflaterOutputStream(temporaryOutputStream)) {
temporaryBuffer.readBytes(os, len);

View File

@ -127,13 +127,13 @@ public class GuiUpdateVersionSlot extends GuiSlot {
if(strs.size() > 2 && screen.mx > xx + iconSize && screen.my > yy + 8 && screen.mx < xx + getListWidth() - 5 && screen.my < yy + 25) {
screen.tooltip = cert.bundleVersionComment;
}
char[] hexStr1 = new char[] { hexChars[(cert.bundleDataHash[0] >> 4) & 0xF],
hexChars[cert.bundleDataHash[1] & 0xF], hexChars[(cert.bundleDataHash[1] >> 4) & 0xF],
hexChars[cert.bundleDataHash[1] & 0xF], hexChars[(cert.bundleDataHash[2] >> 4) & 0xF],
char[] hexStr1 = new char[] { hexChars[(cert.bundleDataHash[0] >>> 4) & 0xF],
hexChars[cert.bundleDataHash[1] & 0xF], hexChars[(cert.bundleDataHash[1] >>> 4) & 0xF],
hexChars[cert.bundleDataHash[1] & 0xF], hexChars[(cert.bundleDataHash[2] >>> 4) & 0xF],
hexChars[cert.bundleDataHash[2] & 0xF] };
char[] hexStr2 = new char[] { hexChars[(cert.bundleDataHash[29] >> 4) & 0xF],
hexChars[cert.bundleDataHash[29] & 0xF], hexChars[(cert.bundleDataHash[30] >> 4) & 0xF],
hexChars[cert.bundleDataHash[30] & 0xF], hexChars[(cert.bundleDataHash[31] >> 4) & 0xF],
char[] hexStr2 = new char[] { hexChars[(cert.bundleDataHash[29] >>> 4) & 0xF],
hexChars[cert.bundleDataHash[29] & 0xF], hexChars[(cert.bundleDataHash[30] >>> 4) & 0xF],
hexChars[cert.bundleDataHash[30] & 0xF], hexChars[(cert.bundleDataHash[31] >>> 4) & 0xF],
hexChars[cert.bundleDataHash[31] & 0xF] };
screen.drawString(mc.fontRendererObj,
"Author: " + EnumChatFormatting.GRAY + cert.bundleAuthorName + EnumChatFormatting.WHITE + " Hash: "

View File

@ -141,7 +141,7 @@ public class UpdateCertificate {
sha256.update(signaturePayload, 0, signaturePayload.length);
sha256.doFinal(hash2048, 96);
hash2048[0] = (byte)((signaturePayload.length >> 8) & 0xFF);
hash2048[0] = (byte)((signaturePayload.length >>> 8) & 0xFF);
hash2048[1] = (byte)(signaturePayload.length & 0xFF);
if(!Arrays.equals(hash2048, rsa2048sumDec)) {

View File

@ -559,9 +559,9 @@ public class GuiVoiceMenu extends Gui {
}
public static int attenuate(int cin, float r, float g, float b, float a) {
float var10 = (float) (cin >> 24 & 255) / 255.0F;
float var6 = (float) (cin >> 16 & 255) / 255.0F;
float var7 = (float) (cin >> 8 & 255) / 255.0F;
float var10 = (float) (cin >>> 24 & 255) / 255.0F;
float var6 = (float) (cin >>> 16 & 255) / 255.0F;
float var7 = (float) (cin >>> 8 & 255) / 255.0F;
float var8 = (float) (cin & 255) / 255.0F;
var10 *= a;
var6 *= r;

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

View File

@ -46,7 +46,7 @@ uniform float u_blockConstant1f;
#define DO_COMPILE_STATE_WAVING_BLOCKS
#define FAKE_SIN(valueIn, valueOut)\
valueOut = abs(1.0 - fract(valueIn * 0.159155) * 2.0);\
valueOut = valueOut * valueOut * (3.0 - 2.0 * valueOut) * 2.0 - 1.0;
valueOut = valueOut * valueOut * (6.0 - 4.0 * valueOut) - 1.0;
#define LIB_INCLUDE_WAVING_BLOCKS_FUNCTION
#endif

View File

@ -53,7 +53,7 @@ uniform vec4 u_wavingBlockParam4f;
#define DO_COMPILE_STATE_WAVING_BLOCKS
#define FAKE_SIN(valueIn, valueOut)\
valueOut = abs(1.0 - fract(valueIn * 0.159155) * 2.0);\
valueOut = valueOut * valueOut * (3.0 - 2.0 * valueOut) * 2.0 - 1.0;
valueOut = valueOut * valueOut * (6.0 - 4.0 * valueOut) - 1.0;
#define LIB_INCLUDE_WAVING_BLOCKS_FUNCTION
#endif

View File

@ -39,7 +39,7 @@ uniform float u_baseScale1f;
#define FAKE_SIN(valueIn, valueOut)\
valueOut = abs(1.0 - fract(valueIn * 0.159155) * 2.0);\
valueOut = valueOut * valueOut * (3.0 - 2.0 * valueOut) * 2.0 - 1.0;
valueOut = valueOut * valueOut * (6.0 - 4.0 * valueOut) - 1.0;
void main() {
v_occlusion1f = max(textureLod(u_sunOcclusionValue, vec2(0.5, 0.5), 0.0).r * 1.5 - 0.5, 0.0);

View File

@ -1 +1 @@
{"pluginName":"EaglercraftXBungee","pluginVersion":"1.2.6","pluginButton":"Download \"EaglerXBungee-1.2.6.jar\"","pluginFilename":"EaglerXBungee.zip"}
{"pluginName":"EaglercraftXBungee","pluginVersion":"1.2.7","pluginButton":"Download \"EaglerXBungee-1.2.7.jar\"","pluginFilename":"EaglerXBungee.zip"}

View File

@ -1,4 +1,5 @@
"use strict";
${classes_js}
// %%%%%%%%% launch options %%%%%%%%%%%%
@ -26,8 +27,6 @@ if(typeof window !== "undefined") {
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
${classes_js}
if(typeof window !== "undefined") { window.eaglercraftXOpts.enableSignatureBadge = true; window.eaglercraftXOpts.assetsURI = ${assets_epk}; }
if(typeof window !== "undefined") setTimeout(() => {

View File

@ -26,6 +26,7 @@
localesURI: "lang/",
worldsDB: "worlds",
logInvalidCerts: true,
crashOnUncaughtExceptions: true,
servers: [
{ addr: "ws://localhost:8081/", name: "Local test server" }
],

View File

@ -309,4 +309,7 @@ public class PlatformApplication {
public static boolean isShowingDebugConsole() {
return DebugConsoleWindow.isShowingDebugConsole();
}
@JSBody(params = { "str" }, script = "window.minecraftServer = str;")
public static native void setMCServerWindowGlobal(String str);
}

View File

@ -605,6 +605,10 @@ public class PlatformInput {
Window.clearTimeout(mouseUngrabTimeout);
mouseUngrabTimeout = -1;
}
try {
win.getDocument().exitPointerLock();
}catch(Throwable t) {
}
}
public static void pressAnyKeyScreen() {

View File

@ -87,6 +87,7 @@ public class PlatformRuntime {
win = Window.current();
doc = win.getDocument();
DebugConsoleWindow.initialize(win);
PlatformApplication.setMCServerWindowGlobal(null);
logger.info("Creating main game canvas");

View File

@ -348,11 +348,11 @@ public class EaglerArrayByteBuffer implements ByteBuffer {
@Override
public ByteBuffer putLong(long value) {
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
dataView.setUint32(position, (int) (value & 0xFFFFFFFF), true);
dataView.setUint8(position + 4, (short) ((value >> 32) & 0xFF));
dataView.setUint8(position + 5, (short) ((value >> 40) & 0xFF));
dataView.setUint8(position + 6, (short) ((value >> 48) & 0xFF));
dataView.setUint8(position + 7, (short) ((value >> 56) & 0xFF));
dataView.setUint32(position, (int) (value & 0xFFFFFFFFl), true);
dataView.setUint8(position + 4, (short) ((value >>> 32l) & 0xFFl));
dataView.setUint8(position + 5, (short) ((value >>> 40l) & 0xFFl));
dataView.setUint8(position + 6, (short) ((value >>> 48l) & 0xFFl));
dataView.setUint8(position + 7, (short) ((value >>> 56l) & 0xFFl));
position += 8;
return this;
}
@ -368,11 +368,11 @@ public class EaglerArrayByteBuffer implements ByteBuffer {
@Override
public ByteBuffer putLong(int index, long value) {
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
dataView.setUint32(index, (int) (value & 0xFFFFFFFF), true);
dataView.setUint8(index + 4, (short) ((value >> 32) & 0xFF));
dataView.setUint8(index + 5, (short) ((value >> 40) & 0xFF));
dataView.setUint8(index + 6, (short) ((value >> 48) & 0xFF));
dataView.setUint8(index + 7, (short) ((value >> 56) & 0xFF));
dataView.setUint32(index, (int) (value & 0xFFFFFFFFl), true);
dataView.setUint8(index + 4, (short) ((value >>> 32l) & 0xFFl));
dataView.setUint8(index + 5, (short) ((value >>> 40l) & 0xFFl));
dataView.setUint8(index + 6, (short) ((value >>> 48l) & 0xFFl));
dataView.setUint8(index + 7, (short) ((value >>> 56l) & 0xFFl));
return this;
}

View File

@ -3,6 +3,8 @@ package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.json.JSONException;
import org.teavm.jso.JSBody;
@ -76,6 +78,7 @@ public class ClientMain {
try {
JSEaglercraftXOptsRoot eaglercraftOpts = (JSEaglercraftXOptsRoot)opts;
crashOnUncaughtExceptions = eaglercraftOpts.getCrashOnUncaughtExceptions(false);
configRootElementId = eaglercraftOpts.getContainer();
if(configRootElementId == null) {
@ -119,36 +122,38 @@ public class ClientMain {
return;
}
systemOut.println("ClientMain: [INFO] registering crash handlers");
if(crashOnUncaughtExceptions) {
systemOut.println("ClientMain: [INFO] registering crash handlers");
setWindowErrorHandler(new WindowErrorHandler() {
setWindowErrorHandler(new WindowErrorHandler() {
@Override
public void call(String message, String file, int line, int col, JSError error) {
StringBuilder str = new StringBuilder();
@Override
public void call(String message, String file, int line, int col, JSError error) {
StringBuilder str = new StringBuilder();
str.append("Native Browser Exception\n");
str.append("----------------------------------\n");
str.append(" Line: ").append((file == null ? "unknown" : file) + ":" + line + ":" + col).append('\n');
str.append(" Type: ").append(error == null ? "generic" : error.getName()).append('\n');
str.append("Native Browser Exception\n");
str.append("----------------------------------\n");
str.append(" Line: ").append((file == null ? "unknown" : file) + ":" + line + ":" + col).append('\n');
str.append(" Type: ").append(error == null ? "generic" : error.getName()).append('\n');
if(error != null) {
str.append(" Desc: ").append(error.getMessage() == null ? "null" : error.getMessage()).append('\n');
}
if(message != null) {
if(error == null || error.getMessage() == null || !message.endsWith(error.getMessage())) {
str.append(" Desc: ").append(message).append('\n');
if(error != null) {
str.append(" Desc: ").append(error.getMessage() == null ? "null" : error.getMessage()).append('\n');
}
if(message != null) {
if(error == null || error.getMessage() == null || !message.endsWith(error.getMessage())) {
str.append(" Desc: ").append(message).append('\n');
}
}
str.append("----------------------------------\n\n");
str.append(error.getStack() == null ? "No stack trace is available" : error.getStack()).append('\n');
showCrashScreen(str.toString());
}
str.append("----------------------------------\n\n");
str.append(error.getStack() == null ? "No stack trace is available" : error.getStack()).append('\n');
showCrashScreen(str.toString());
}
});
});
}
systemOut.println("ClientMain: [INFO] initializing eaglercraftx runtime");
@ -212,6 +217,7 @@ public class ClientMain {
public static HTMLElement configRootElement = null;
public static EPKFileEntry[] configEPKFiles = null;
public static String configLocalesFolder = null;
public static boolean crashOnUncaughtExceptions = false;
@JSFunctor
private static interface WindowErrorHandler extends JSObject {
@ -236,61 +242,97 @@ public class ClientMain {
private static boolean isCrashed = false;
public static void showCrashScreen(String t) {
StringBuilder strBeforeBuilder = new StringBuilder();
strBeforeBuilder.append("Game Crashed! I have fallen and I can't get up!\n\n");
strBeforeBuilder.append(t);
strBeforeBuilder.append('\n').append('\n');
String strBefore = strBeforeBuilder.toString();
HTMLDocument doc = Window.current().getDocument();
if(configRootElement == null) {
configRootElement = doc.getElementById(configRootElementId);
}
HTMLElement el = configRootElement;
StringBuilder str = new StringBuilder();
str.append("eaglercraft.version = \"").append(EaglercraftVersion.projectForkVersion).append("\"\n");
str.append("eaglercraft.minecraft = \"1.8.8\"\n");
str.append("eaglercraft.brand = \"" + EaglercraftVersion.projectForkVendor + "\"\n");
str.append("eaglercraft.username = \"").append(EaglerProfile.getName()).append("\"\n");
str.append('\n');
str.append(addWebGLToCrash());
str.append('\n');
str.append("window.eaglercraftXOpts = ");
str.append(TeaVMClientConfigAdapter.instance.toString()).append('\n');
str.append('\n');
str.append("currentTime = ");
str.append(EagRuntime.fixDateFormat(new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z")).format(new Date())).append('\n');
str.append('\n');
addDebugNav(str, "userAgent");
addDebugNav(str, "vendor");
addDebugNav(str, "language");
addDebugNav(str, "hardwareConcurrency");
addDebugNav(str, "deviceMemory");
addDebugNav(str, "platform");
addDebugNav(str, "product");
addDebugNavPlugins(str);
str.append('\n');
addDebug(str, "localStorage");
addDebug(str, "sessionStorage");
addDebug(str, "indexedDB");
str.append('\n');
str.append("rootElement.clientWidth = ").append(el == null ? "undefined" : el.getClientWidth()).append('\n');
str.append("rootElement.clientHeight = ").append(el == null ? "undefined" : el.getClientHeight()).append('\n');
addDebug(str, "innerWidth");
addDebug(str, "innerHeight");
addDebug(str, "outerWidth");
addDebug(str, "outerHeight");
addDebug(str, "devicePixelRatio");
addDebugScreen(str, "availWidth");
addDebugScreen(str, "availHeight");
addDebugScreen(str, "colorDepth");
addDebugScreen(str, "pixelDepth");
str.append('\n');
addDebug(str, "minecraftServer");
str.append('\n');
addDebugLocation(str, "href");
str.append('\n');
String strAfter = str.toString();
String strFinal = strBefore + strAfter;
List<String> additionalInfo = new LinkedList();
try {
TeaVMClientConfigAdapter.instance.getHooks().callCrashReportHook(strFinal, additionalInfo::add);
}catch(Throwable tt) {
System.err.println("Uncaught exception invoking crash report hook!");
EagRuntime.debugPrintStackTraceToSTDERR(tt);
}
if(!isCrashed) {
isCrashed = true;
HTMLDocument doc = Window.current().getDocument();
if(configRootElement == null) {
configRootElement = doc.getElementById(configRootElementId);
if(additionalInfo.size() > 0) {
try {
StringBuilder builderFinal = new StringBuilder();
builderFinal.append(strBefore);
builderFinal.append("Got the following messages from the crash report hook registered in eaglercraftXOpts:\n\n");
for(String str2 : additionalInfo) {
builderFinal.append("----------[ CRASH HOOK ]----------\n");
builderFinal.append(str2).append('\n');
builderFinal.append("----------------------------------\n\n");
}
builderFinal.append(strAfter);
strFinal = builderFinal.toString();
}catch(Throwable tt) {
System.err.println("Uncaught exception concatenating crash report hook messages!");
EagRuntime.debugPrintStackTraceToSTDERR(tt);
}
}
HTMLElement el = configRootElement;
StringBuilder str = new StringBuilder();
str.append("Game Crashed! I have fallen and I can't get up!\n\n");
str.append(t);
str.append('\n').append('\n');
str.append("eaglercraft.version = \"").append(EaglercraftVersion.projectForkVersion).append("\"\n");
str.append("eaglercraft.minecraft = \"1.8.8\"\n");
str.append("eaglercraft.brand = \"" + EaglercraftVersion.projectForkVendor + "\"\n");
str.append("eaglercraft.username = \"").append(EaglerProfile.getName()).append("\"\n");
str.append('\n');
str.append(addWebGLToCrash());
str.append('\n');
str.append("window.eaglercraftXOpts = ");
str.append(TeaVMClientConfigAdapter.instance.toString()).append('\n');
str.append('\n');
str.append("currentTime = ");
str.append(EagRuntime.fixDateFormat(new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z")).format(new Date())).append('\n');
str.append('\n');
addDebugNav(str, "userAgent");
addDebugNav(str, "vendor");
addDebugNav(str, "language");
addDebugNav(str, "hardwareConcurrency");
addDebugNav(str, "deviceMemory");
addDebugNav(str, "platform");
addDebugNav(str, "product");
str.append('\n');
str.append("rootElement.clientWidth = ").append(el == null ? "undefined" : el.getClientWidth()).append('\n');
str.append("rootElement.clientHeight = ").append(el == null ? "undefined" : el.getClientHeight()).append('\n');
addDebug(str, "innerWidth");
addDebug(str, "innerHeight");
addDebug(str, "outerWidth");
addDebug(str, "outerHeight");
addDebug(str, "devicePixelRatio");
addDebugScreen(str, "availWidth");
addDebugScreen(str, "availHeight");
addDebugScreen(str, "colorDepth");
addDebugScreen(str, "pixelDepth");
str.append('\n');
addDebug(str, "currentContext");
str.append('\n');
addDebugLocation(str, "href");
str.append('\n');
if(el == null) {
Window.alert("Root element not found, crash report was printed to console");
System.err.println(str.toString());
System.err.println(strFinal);
return;
}
@ -303,7 +345,7 @@ public class ClientMain {
div.setAttribute("style", "z-index:100;position:absolute;top:135px;left:10%;right:10%;bottom:50px;background-color:white;border:1px solid #cccccc;overflow-x:hidden;overflow-y:scroll;overflow-wrap:break-word;white-space:pre-wrap;font: 14px monospace;padding:10px;");
el.appendChild(img);
el.appendChild(div);
div.appendChild(doc.createTextNode(str.toString()));
div.appendChild(doc.createTextNode(strFinal));
PlatformRuntime.removeEventHandlers();
@ -314,10 +356,29 @@ public class ClientMain {
for(int i = 0; i < s.length; ++i) {
System.err.println(" " + s[i]);
}
if(additionalInfo.size() > 0) {
for(String str2 : additionalInfo) {
if(str2 != null) {
System.err.println();
System.err.println(" ----------[ CRASH HOOK ]----------");
s = str2.split("[\\r\\n]+");
for(int i = 0; i < s.length; ++i) {
System.err.println(" " + s[i]);
}
System.err.println(" ----------------------------------");
}
}
}
}
}
private static String webGLCrashStringCache = null;
private static String addWebGLToCrash() {
if(webGLCrashStringCache != null) {
return webGLCrashStringCache;
}
StringBuilder ret = new StringBuilder();
WebGLRenderingContext ctx = PlatformRuntime.webgl;
@ -328,7 +389,11 @@ public class ClientMain {
cvs.setWidth(64);
cvs.setHeight(64);
ctx = (WebGLRenderingContext)cvs.getContext("webgl");
ctx = (WebGLRenderingContext)cvs.getContext("webgl2");
if(ctx == null) {
ctx = (WebGLRenderingContext)cvs.getContext("webgl");
}
}
if(ctx != null) {
@ -345,12 +410,13 @@ public class ClientMain {
//ret.append('\n').append("\nwebgl.anisotropicGlitch = ").append(DetectAnisotropicGlitch.hasGlitch()).append('\n'); //TODO
ret.append('\n').append("webgl.ext.HDR16f = ").append(ctx.getExtension("EXT_color_buffer_half_float") != null).append('\n');
ret.append("webgl.ext.HDR32f = ").append(ctx.getExtension("EXT_color_buffer_float") != null).append('\n');
ret.append("webgl.ext.HDR32f_linear = ").append(ctx.getExtension("OES_texture_float_linear") != null).append('\n');
}else {
ret.append("Failed to query GPU info!\n");
}
return ret.toString();
return webGLCrashStringCache = ret.toString();
}
public static void showIncompatibleScreen(String t) {
@ -486,6 +552,13 @@ public class ClientMain {
@JSBody(params = { "v" }, script = "try { return \"\"+window.location[v]; } catch(e) { return \"<error>\"; }")
private static native String getStringLocation(String var);
@JSBody(params = { }, script = "try { var retObj = new Array; if(typeof window.navigator.plugins === \"object\")"
+ "{ var len = window.navigator.plugins.length; if(len > 0) { for(var idx = 0; idx < len; ++idx) {"
+ "var thePlugin = window.navigator.plugins[idx]; retObj.push({ name: thePlugin.name,"
+ "filename: thePlugin.filename, desc: thePlugin.description }); } } } return JSON.stringify(retObj);"
+ "} catch(e) { return \"<error>\"; }")
private static native String getStringNavPlugins();
private static void addDebug(StringBuilder str, String var) {
str.append("window.").append(var).append(" = ").append(getString(var)).append('\n');
}
@ -494,6 +567,10 @@ public class ClientMain {
str.append("window.navigator.").append(var).append(" = ").append(getStringNav(var)).append('\n');
}
private static void addDebugNavPlugins(StringBuilder str) {
str.append("window.navigator.plugins = ").append(getStringNavPlugins()).append('\n');
}
private static void addDebugScreen(StringBuilder str, String var) {
str.append("window.screen.").append(var).append(" = ").append(getStringScreen(var)).append('\n');
}

View File

@ -64,13 +64,15 @@ public class DebugConsoleWindow {
destroyWindow();
}
});
if("true".equals(parent.getLocalStorage().getItem(PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole"))) {
if(parent.getLocalStorage() != null && "true".equals(parent.getLocalStorage().getItem(PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole"))) {
showDebugConsole0();
}
}
public static void showDebugConsole() {
parent.getLocalStorage().setItem(PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole", "true");
if(parent.getLocalStorage() != null) {
parent.getLocalStorage().setItem(PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole", "true");
}
showDebugConsole0();
}
@ -108,7 +110,9 @@ public class DebugConsoleWindow {
public void handleEvent(Event evt) {
if(logger != null) {
logger = null;
parent.getLocalStorage().setItem("_eaglercraftX.showDebugConsole", "false");
if(parent.getLocalStorage() != null) {
parent.getLocalStorage().setItem(PlatformRuntime.getClientConfigAdapter().getLocalStorageNamespace() + ".showDebugConsole", "false");
}
}
}
};

View File

@ -61,6 +61,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
private String localStorageNamespace = "_eaglercraftX";
private final TeaVMClientConfigAdapterHooks hooks = new TeaVMClientConfigAdapterHooks();
private boolean enableMinceraft = true;
private boolean crashOnUncaughtExceptions = false;
public void loadNative(JSObject jsObject) {
integratedServerOpts = new JSONObject();
@ -83,6 +84,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
allowFNAWSkins = !demoMode && eaglercraftXOpts.getAllowFNAWSkins(true);
localStorageNamespace = eaglercraftXOpts.getLocalStorageNamespace(EaglercraftVersion.localStorageNamespace);
enableMinceraft = eaglercraftXOpts.getEnableMinceraft(true);
crashOnUncaughtExceptions = eaglercraftXOpts.getCrashOnUncaughtExceptions(false);
JSEaglercraftXOptsHooks hooksObj = eaglercraftXOpts.getHooks();
if(hooksObj != null) {
hooks.loadHooks(hooksObj);
@ -95,6 +97,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
integratedServerOpts.put("allowUpdateDL", isAllowUpdateDL);
integratedServerOpts.put("allowVoiceClient", allowVoiceClient);
integratedServerOpts.put("allowFNAWSkins", allowFNAWSkins);
integratedServerOpts.put("crashOnUncaughtExceptions", crashOnUncaughtExceptions);
JSArrayReader<JSEaglercraftXOptsServer> serversArray = eaglercraftXOpts.getServers();
if(serversArray != null) {
@ -178,6 +181,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
allowFNAWSkins = eaglercraftOpts.optBoolean("allowFNAWSkins", true);
localStorageNamespace = eaglercraftOpts.optString("localStorageNamespace", EaglercraftVersion.localStorageNamespace);
enableMinceraft = eaglercraftOpts.optBoolean("enableMinceraft", true);
crashOnUncaughtExceptions = eaglercraftOpts.optBoolean("crashOnUncaughtExceptions", false);
JSONArray serversArray = eaglercraftOpts.optJSONArray("servers");
if(serversArray != null) {
for(int i = 0, l = serversArray.length(); i < l; ++i) {
@ -366,6 +370,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
jsonObject.put("allowFNAWSkins", allowFNAWSkins);
jsonObject.put("localStorageNamespace", localStorageNamespace);
jsonObject.put("enableMinceraft", enableMinceraft);
jsonObject.put("crashOnUncaughtExceptions", crashOnUncaughtExceptions);
JSONArray serversArr = new JSONArray();
for(int i = 0, l = defaultServers.size(); i < l; ++i) {
DefaultServer srv = defaultServers.get(i);

View File

@ -1,5 +1,6 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.teavm.interop.Async;
@ -34,6 +35,7 @@ public class TeaVMClientConfigAdapterHooks implements IClientConfigAdapterHooks
private LocalStorageSaveHook saveHook = null;
private LocalStorageLoadHook loadHook = null;
private CrashReportHook crashHook = null;
@JSFunctor
private static interface LocalStorageSaveHook extends JSObject {
@ -65,6 +67,25 @@ public class TeaVMClientConfigAdapterHooks implements IClientConfigAdapterHooks
}
}
@JSFunctor
private static interface CrashReportHook extends JSObject {
void call(String crashReport, CustomMessageCB customMessageCB);
}
@JSFunctor
private static interface CustomMessageCB extends JSObject {
void call(String msg);
}
@Override
public void callCrashReportHook(String crashReport, Consumer<String> customMessageCB) {
if(crashHook != null) {
callHookSafeSync("crashReportShow", () -> {
crashHook.call(crashReport, (msg) -> customMessageCB.accept(msg));
});
}
}
private static void callHookSafe(String identifer, Runnable hooker) {
Window.setTimeout(() -> {
try {
@ -76,6 +97,22 @@ public class TeaVMClientConfigAdapterHooks implements IClientConfigAdapterHooks
}, 0);
}
@Async
private static native void callHookSafeSync(String identifer, Runnable hooker);
private static void callHookSafeSync(String identifer, Runnable hooker, final AsyncCallback<Void> cb) {
Window.setTimeout(() -> {
try {
hooker.run();
}catch(Throwable t) {
logger.error("Caught exception while invoking eaglercraftXOpts \"{}\" hook!", identifer);
logger.error(t);
}finally {
cb.complete(null);
}
}, 0);
}
@Async
private static native Object callHookSafeWithReturn(String identifer, Supplier<Object> hooker);
@ -96,5 +133,6 @@ public class TeaVMClientConfigAdapterHooks implements IClientConfigAdapterHooks
public void loadHooks(JSEaglercraftXOptsHooks hooks) {
saveHook = (LocalStorageSaveHook)hooks.getLocalStorageSavedHook();
loadHook = (LocalStorageLoadHook)hooks.getLocalStorageLoadedHook();
crashHook = (CrashReportHook)hooks.getCrashReportHook();
}
}

View File

@ -26,4 +26,7 @@ public abstract class JSEaglercraftXOptsHooks implements JSObject {
@JSBody(script = "return (typeof this.localStorageLoaded === \"function\") ? this.localStorageLoaded : null;")
public native JSObject getLocalStorageLoadedHook();
@JSBody(script = "return (typeof this.crashReportShow === \"function\") ? this.crashReportShow : null;")
public native JSObject getCrashReportHook();
}

View File

@ -96,4 +96,7 @@ public abstract class JSEaglercraftXOptsRoot implements JSObject {
@JSBody(params = { "def" }, script = "return (typeof this.enableMinceraft === \"boolean\") ? this.enableMinceraft : def;")
public native boolean getEnableMinceraft(boolean defaultValue);
@JSBody(params = { "def" }, script = "return (typeof this.crashOnUncaughtExceptions === \"boolean\") ? this.crashOnUncaughtExceptions : def;")
public native boolean getCrashOnUncaughtExceptions(boolean defaultValue);
}