From 3409da13de3890f01daecd03bb1f114e8fbbc3c9 Mon Sep 17 00:00:00 2001 From: HoosierTransfer <97118529+HoosierTransfer@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:36:37 -0400 Subject: [PATCH] update to u35 --- .../resources/assets/eagler/glsl/core.fsh | 2 +- .../eagler/glsl/deferred/deferred_core.vsh | 1 + .../eagler/glsl/deferred/deferred_fog.fsh | 2 +- .../eagler/glsl/deferred/forward_core.fsh | 2 +- .../deferred/forward_glass_highlights.fsh | 2 +- .../glsl/deferred/realistic_water_render.fsh | 2 +- .../glsl/deferred/shader_pack_info.json | 2 +- .../accel_particle_dynamiclights.fsh | 10 +- .../accel_particle_dynamiclights.vsh | 2 +- .../glsl/dynamiclights/core_dynamiclights.fsh | 16 +- .../glsl/dynamiclights/core_dynamiclights.vsh | 2 +- .../textures/blocks/furnace_front_on_n.png | Bin 5783 -> 3020 bytes .../textures/blocks/furnace_front_on_s.png | Bin 942 -> 315 bytes .../gui/title/background/enable_blur.txt | 2 + .../eaglercraft/v1_8/EaglerInputStream.java | 51 ++- .../eaglercraft/v1_8/EaglercraftVersion.java | 6 +- .../net/lax1dude/eaglercraft/v1_8/Mouse.java | 2 - .../v1_8/internal/IClientConfigAdapter.java | 2 + .../ext/deferred/EaglerDeferredPipeline.java | 1 - .../texture/EaglerBitwisePackedTexture.java | 62 ++- .../deferred/texture/PBRTextureMapUtils.java | 102 ++--- .../DynamicLightBucketLoader.java | 1 - .../dynamiclights/DynamicLightInstance.java | 13 +- .../DynamicLightsPipelineCompiler.java | 1 - .../DynamicLightsStateManager.java | 52 +-- .../DynamicLightsAccelParticleShader.java | 6 +- .../java/net/minecraft/client/Minecraft.java | 1 + .../net/minecraft/client/gui/GuiMainMenu.java | 104 +++-- .../client/multiplayer/ServerData.java | 7 +- .../v1_8/internal/PlatformApplication.java | 6 +- .../v1_8/internal/PlatformAssets.java | 87 +++-- .../v1_8/internal/PlatformAudio.java | 3 +- .../v1_8/internal/PlatformNetworking.java | 5 +- .../v1_8/internal/PlatformRuntime.java | 221 ++++++----- .../v1_8/internal/PlatformUpdateSvc.java | 36 +- .../v1_8/internal/PlatformWebRTC.java | 363 ++++++++++-------- .../v1_8/internal/RenderResolution.java | 47 --- .../teavm/TeaVMClientConfigAdapter.java | 9 + .../v1_8/internal/teavm/TeaVMServerQuery.java | 72 ++-- .../internal/teavm/TeaVMUpdateThread.java | 122 +++--- .../v1_8/internal/teavm/TeaVMUtils.java | 211 +++++++--- .../teavm/opts/JSEaglercraftXOptsRoot.java | 4 + .../internal/ClientPlatformSingleplayer.java | 101 ++--- .../internal/ServerPlatformSingleplayer.java | 49 +-- 44 files changed, 1031 insertions(+), 761 deletions(-) create mode 100644 resources/resources/assets/minecraft/textures/gui/title/background/enable_blur.txt delete mode 100644 src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/RenderResolution.java diff --git a/resources/resources/assets/eagler/glsl/core.fsh b/resources/resources/assets/eagler/glsl/core.fsh index eb9fcd1..5a01a79 100644 --- a/resources/resources/assets/eagler/glsl/core.fsh +++ b/resources/resources/assets/eagler/glsl/core.fsh @@ -170,7 +170,7 @@ void main() { #ifdef COMPILE_ENABLE_FOG vec3 fogPos = v_position4f.xyz / v_position4f.w; - float dist = sqrt(dot(fogPos, fogPos)); + float dist = length(fogPos); float fogDensity = u_fogParameters4f.y; float fogStart = u_fogParameters4f.z; float fogEnd = u_fogParameters4f.w; diff --git a/resources/resources/assets/eagler/glsl/deferred/deferred_core.vsh b/resources/resources/assets/eagler/glsl/deferred/deferred_core.vsh index e0de2f8..30ebf7c 100644 --- a/resources/resources/assets/eagler/glsl/deferred/deferred_core.vsh +++ b/resources/resources/assets/eagler/glsl/deferred/deferred_core.vsh @@ -112,4 +112,5 @@ void main() { #endif gl_Position = u_projectionMat4f * pos; + } diff --git a/resources/resources/assets/eagler/glsl/deferred/deferred_fog.fsh b/resources/resources/assets/eagler/glsl/deferred/deferred_fog.fsh index b179645..8130c07 100644 --- a/resources/resources/assets/eagler/glsl/deferred/deferred_fog.fsh +++ b/resources/resources/assets/eagler/glsl/deferred/deferred_fog.fsh @@ -69,7 +69,7 @@ void main() { fragPos4f.xyz /= fragPos4f.w; fragPos4f.w = 1.0; - float l = sqrt(dot(fragPos4f.xyz, fragPos4f.xyz)); + float l = length(fragPos4f.xyz); #ifdef COMPILE_FOG_LINEAR float f = (l - u_linearFogParam2f.x) / (u_linearFogParam2f.y - u_linearFogParam2f.x); #else diff --git a/resources/resources/assets/eagler/glsl/deferred/forward_core.fsh b/resources/resources/assets/eagler/glsl/deferred/forward_core.fsh index 65f98d0..4e6a375 100644 --- a/resources/resources/assets/eagler/glsl/deferred/forward_core.fsh +++ b/resources/resources/assets/eagler/glsl/deferred/forward_core.fsh @@ -431,7 +431,7 @@ void main() { float type = u_fogParameters4f.x - atmos; fogBlend4f = mix(u_fogColorLight4f, u_fogColorDark4f, lightmapCoords2f.g); - float l = sqrt(dot(v_position4f.xyz, v_position4f.xyz)); + float l = length(v_position4f.xyz); if(type == 1.0) { f = (l - u_fogParameters4f.z) / (u_fogParameters4f.w - u_fogParameters4f.z); }else { diff --git a/resources/resources/assets/eagler/glsl/deferred/forward_glass_highlights.fsh b/resources/resources/assets/eagler/glsl/deferred/forward_glass_highlights.fsh index 72925fd..5f0100f 100644 --- a/resources/resources/assets/eagler/glsl/deferred/forward_glass_highlights.fsh +++ b/resources/resources/assets/eagler/glsl/deferred/forward_glass_highlights.fsh @@ -292,7 +292,7 @@ void main() { fogFade = mix(u_fogColorDark4f.a, u_fogColorLight4f.a, lightmapCoords2f.g); float f; - float l = sqrt(dot(v_position4f.xyz, v_position4f.xyz)); + float l = length(v_position4f.xyz); if(type == 1.0) { f = (l - u_fogParameters4f.z) / (u_fogParameters4f.w - u_fogParameters4f.z); }else { diff --git a/resources/resources/assets/eagler/glsl/deferred/realistic_water_render.fsh b/resources/resources/assets/eagler/glsl/deferred/realistic_water_render.fsh index f5f9869..5413ff5 100644 --- a/resources/resources/assets/eagler/glsl/deferred/realistic_water_render.fsh +++ b/resources/resources/assets/eagler/glsl/deferred/realistic_water_render.fsh @@ -397,7 +397,7 @@ void main() { float type = u_fogParameters4f.x - atmos; fogBlend4f = mix(u_fogColorLight4f, u_fogColorDark4f, lightmapCoords2f.g); - float f, l = sqrt(dot(v_position4f.xyz, v_position4f.xyz)); + float f, l = length(v_position4f.xyz); if(type == 1.0) { f = (l - u_fogParameters4f.z) / (u_fogParameters4f.w - u_fogParameters4f.z); }else { diff --git a/resources/resources/assets/eagler/glsl/deferred/shader_pack_info.json b/resources/resources/assets/eagler/glsl/deferred/shader_pack_info.json index 6b573da..af5f511 100644 --- a/resources/resources/assets/eagler/glsl/deferred/shader_pack_info.json +++ b/resources/resources/assets/eagler/glsl/deferred/shader_pack_info.json @@ -1,7 +1,7 @@ { "name": "§eHigh Performance PBR", "desc": "Pack made from scratch specifically for this client, designed to give what I call the best balance between quality and performance possible in a browser but obviously that's just my opinion", - "vers": "1.2.0", + "vers": "1.2.1", "author": "lax1dude", "api_vers": 1, "features": [ diff --git a/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh b/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh index f061bca..c8289e8 100644 --- a/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh +++ b/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.fsh @@ -48,7 +48,9 @@ void main() { } vec4 light; + float blockLight = v_lightmap2f.x; float diffuse = 0.0; + float len; if(u_dynamicLightCount1i > 0) { vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f; worldPosition4f.xyz /= worldPosition4f.w; @@ -57,11 +59,13 @@ void main() { for(int i = 0; i < safeLightCount; ++i) { light = u_dynamicLightArray[i]; light.xyz = light.xyz - worldPosition4f.xyz; - diffuse += max(dot(normalize(light.xyz), normalVector3f) * 0.8 + 0.2, 0.0) * max(light.w - sqrt(dot(light.xyz, light.xyz)), 0.0); + len = length(light.xyz); + diffuse += max(dot(light.xyz / len, normalVector3f) * 0.8 + 0.2, 0.0) * max(light.w - len, 0.0); } + blockLight = min(blockLight + diffuse * 0.066667, 1.0); } - color *= texture(u_lightmapTexture, vec2(min(v_lightmap2f.x + diffuse * 0.066667, 1.0), v_lightmap2f.y)); + color *= texture(u_lightmapTexture, vec2(blockLight, v_lightmap2f.y)); output4f = color; -} \ No newline at end of file +} diff --git a/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh b/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh index 57e5784..202bd15 100644 --- a/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh +++ b/resources/resources/assets/eagler/glsl/dynamiclights/accel_particle_dynamiclights.vsh @@ -58,4 +58,4 @@ void main() { v_position4f = u_modelViewMatrix4f * vec4(pos3f, 1.0); gl_Position = u_projectionMatrix4f * v_position4f; -} \ No newline at end of file +} diff --git a/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh b/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh index f2a0aec..aa3bc51 100644 --- a/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh +++ b/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.fsh @@ -152,6 +152,12 @@ void main() { #ifdef COMPILE_ENABLE_LIGHTMAP float diffuse = 0.0; +#ifdef COMPILE_LIGHTMAP_ATTRIB + float blockLight = v_lightmap2f.x; +#else + float blockLight = u_textureCoords02.x; +#endif + float len; vec4 light; if(u_dynamicLightCount1i > 0) { vec4 worldPosition4f = u_inverseViewMatrix4f * v_position4f; @@ -161,13 +167,15 @@ void main() { for(int i = 0; i < safeLightCount; ++i) { light = u_dynamicLightArray[i]; light.xyz = light.xyz - worldPosition4f.xyz; - diffuse += max(dot(normalize(light.xyz), normalVector3f) * 0.8 + 0.2, 0.0) * max(light.w - sqrt(dot(light.xyz, light.xyz)), 0.0); + len = length(light.xyz); + diffuse += max(dot(light.xyz / len, normalVector3f) * 0.8 + 0.2, 0.0) * max(light.w - len, 0.0); } + blockLight = min(blockLight + diffuse * 0.066667, 1.0); } #ifdef COMPILE_LIGHTMAP_ATTRIB - color *= texture(u_samplerLightmap, vec2(min(v_lightmap2f.x + diffuse * 0.066667, 1.0), v_lightmap2f.y)); + color *= texture(u_samplerLightmap, vec2(blockLight, v_lightmap2f.y)); #else - color *= texture(u_samplerLightmap, vec2(min(u_textureCoords02.x + diffuse * 0.066667, 1.0), u_textureCoords02.y)); + color *= texture(u_samplerLightmap, vec2(blockLight, u_textureCoords02.y)); #endif #endif @@ -207,4 +215,4 @@ void main() { #endif output4f = color; -} \ No newline at end of file +} diff --git a/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh b/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh index 5531b1e..023b204 100644 --- a/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh +++ b/resources/resources/assets/eagler/glsl/dynamiclights/core_dynamiclights.vsh @@ -77,4 +77,4 @@ void main() { #endif gl_Position = u_projectionMat4f * v_position4f; -} \ No newline at end of file +} diff --git a/resources/resources/assets/minecraft/textures/blocks/furnace_front_on_n.png b/resources/resources/assets/minecraft/textures/blocks/furnace_front_on_n.png index ff8e9bd07b13032d6b05c2748369d805f45d0c72..dcc4eeaab5d6904f768b06dec7cce8bf1f461e90 100644 GIT binary patch literal 3020 zcmZ8jc{tnI8vZ2`jeUtdMToAW)ZALqB8dc5ZKwj+JMTGvob$Zr``&MfwY+F5BB&q;0Dy?uS%TF* zQvNa+|Ni>M(4~DJKz>%HMxc*v>f!qb0iUxDegGf@|I0u?dWPKohHOT_+1$-o$Q<>y zc`MCY(HseZteY z+R}RZY&3KGkrh!lE`uoAIP{SHL~RHW8h(Yr86FEi^ykVW7!phaR4M-e)>GQRyxYbl z-vwKPL9714JV`UL%0qD6=zy3C_shgk-)=U|!1htr;4S1)>-viUKrJ7TT zt>qHP68F=M(iGMOz>!J=4Dh*obHV&24aS@|9Elb`k&#WtUi0n>5=#{)u~;4A#lZc0 zFJ)!D7K!ICDXp&2_D0q`w@cSK(m6WNT*Lg$zsVI3aALpHd<>vBgpxMzMge9Fpoyub&ew~?-b1I_ zD?pHjiSc+uRZ?>yZ}iFv(aD~sc7t)c=);HFv+vm^ zP7Sg{VJib?h@-SG$jTdOd-V@{Hgtq7x@PrLFq&(SZMo*3IgDG!u&VMidQ$T69HHr% zbI?^2!SYytt%{uSP>)ust7)p{vc*H|T;^lj99GA! zXpWPsU&zdKuLyt`p%D^ESuTU7fNpdk?#j~^JC1P`$!DTFMat#`#KU=kHKhgd7zda0 zxrH%aIW9^x8n_Yw2`oe$^c|2y3WP(x@f5KPc67uBea+nFHfh;QW-g=Jk~GjzO&^k3 z#o^e-!6|V*nQ;r1^=zDI*^aQB9*A}$fYF^Q#7^24c>yfE8(1i@2+z7G%-#`-Q9UDm zUhS<$2bxZoK7~^$%1O2pFR#MQD<<=)W6q3cl8H9ZPVdbGq$_>FM~5Bb$IJtO{w~iv zU+W!#&oQTh3%z7si3k5Afsx9VrKC~CijYx-<^RYT3am^8ihKfFs6DQUmGH7GHuimf z(xPOgQ<6;t0&8pS1=%L*k%0%DeTb4bRy{sP-(}l_i2Uv8Kc5_-At7lU81_TcTQhf< z#$czadBz2G<}J$rNz2-;u@sBUrNbCJR4=n&rq}&9auQ%2Vh2o0_}F&JE9gYu2M@}y zz}6uiAQ+QwsGGB;-6H#c?)=-il+zF-Q)cY_3Z$K7BE+7hGdykICO{J(d`OQtu(3`O z?vwjf1N+`|&I1W`vv`ldCCDI0j@~X}3wT*^l=1PNm7QMnc00;4!njQV1!x)gTxoQU z2Kwy2xxWo43O0ry_n+kP{a8rmY=O8Xz9?{|ZI$~9>e+lo4}6^alFkgM&2%@`Qy_vZ^$rQ?0#=bd(B z^vZ6ZE7E>9$6A_=AN7Ix>ULz78D+rjA3VJy;BLRM1ZKP{L!InIxL0<(ODCxLu zOkP(J@x4EBjWOr98ymcl4Wext(ME)Ei}y`Gb<@Mtg527JwO7*^sRzKTkLGxKX>jC@ z3yh3yq`3SdAi|EU2C1Uu`7UKNKXy>WSmT5yaKpf**YQ+FSSfYJTQt|db{o#g1D>`e znZm@IGT?ft!V2nuR?9~va+6}qJ4IWM;Lyc_0h0#F`*Yncp@jG!wRaUt3X?7KYp=BX z^()Fup6K%I{jBNFfG6Ks=g8ZLyL(hSnEachrQ6Z$-43VB!5!l_CF34Q?n_}A&c}7J zk9H>VW7Td)SozN5{g|NuA;k%#8pafs996B9i&b%?5U5549;MA|wR_bYH8a`aVJ5QG znz>-dpskWHi_U%?Y?GQU*fnKOa9E2KiCT2wTA3+_gPkT;tLk?MH?b?ig?GeiEiEEX3bj)_bIXHuAT8 zHgqGgQLc=mNGbQ@to>{28|ukm)ZX2J8*=jJYNdW+_J&kz}a39AT8u?76Z+8pXsQJY?RfxLdl3KU2cJ$=wiW;X=w;< zI1o2qM?+m@WcNRttN@FzS&yLpS$(mP!2TGQ37cc?UinLfH=M+KUTrmm3YULGo7*Xn3#QLAH{0vU6=oeKcQ_$c~w|k zbMsvRpb`bZ@p0S{^wDJkI<;b|qDx*Cr$UIpr`znj^_fDs2FtsSgV3x$d$-nK_mU+s zgj~Pk+%u2HNg!Z$$?`nb8MrW}cRp#VS*mvIqiDJJkxB2%Onhda`vXmIvCIEbnUXJS z^mjM0p`;kU`cwO$358Qp)*)X?@Rb=VhPqA8P2ts{gShFJQzH?*V_TL*qL|dKu0x|K zYdwd!dGUF`Cj|aa+saK&2sTTK`<&~@Tj;#vMp2Ow5Y}}~w-4!dq9zGfY{pMW|w1DiYPre#0mD-s;y04&y1 z$@cuM9x2UJIEGa7li2X?&{iQ*x$wWtS@}Y2Rwx9;>TQU*F`|DkW_6aX0XX*{#W>xE5! zp-t@cuC+CHXsj;LeGNq(E=)uS9h5HmG+$EUNgLFsjYjUrK1jxQYC$veFZ;VE$usg&s{=#0#aEI(yo*wiIG8m`Y8AFL=Ng?}^HEXgnW4X&j znuLZJOWDWPSjL#`sn2si|Np(ccwSxCyX*X2zw7}101jTdXmIuC z69oVO0i5hV-@>U;WdOi2$4dsf)*(4-xpuxHef51vSVO!0{nP!D9)=0k!Y;TvXE+sn z60eJ~!q|v`=DPVp4}235Qo4Jp>F6U~7roC{OXs9BG&6qVQ#M%~v$EmlJ)KZSW4(rW z(#{iEqCqwUY5I?3N&CY!!#t4}m!3hJ$fN{%QQro)FEg?ap1kw^kWj@oDQY)4F&l9xN^_t`6&_XFeuI z_07&SoY;C64sW0#6Xf}l=wlj}2rhU<|1Z9)INzIF0wLc%_%_FhI?a}!#(Ss+Uk^?F zU`I9Zz{UVntV$RSyZ-twrWs8PSa=oe*RVBmv{n#ZD{T-?r{f-x#|e>W2>O=fh@IkZ*eS%nG4{ z?AQ~%k>D?PLxrxbYlS3jcRvP)*ws2-R2(VRq{;NdH%R~VO2eA zH&Uat^4J7NXme>KMZ2PF4zIHz9*GO7J0$V>lowf%&{D~&sI-E0gfrPf2R@4h zarK(>KZWa{;|x%^R8D@4Kf2AY6Wz=6fwmN1>>g2crpQ%8HlJ5Qu{}H^OKI@QkLdtT z=Q8vsh9F+M83 zS$ywbr+$q(alVFZ;+esN#_Y9^KRSEIE{$c;SRe`Cv%Hc<5JjRTl9YL08L(Fe-d>%71JBr4%=N0A~|H zX|rj)Sy57{<{%7va&>0}@Mdg-z=r4jCO#=YsvlNa?b-(uZ^4TFq zWAlW?;7Egvw2%iU1ziKGM%%u6n5TllDrVg?9PNco-g5HvOCAusD7IJEK|DRp%a-y( zgqZ%#`E3gTj1RzW`|U#)Ksyn`=J$rwFtFl0Tv3&Z8T|fGEYtmYQTO{dd>%aYv{qP>nz1E>MM>xrVJ7VVf({6 z{`mONG}Or=xi+K2WtUP`mzn2r|GR0q8bP;4#zL^Ll=(wwrC}Ltmj(@`(nM({!(TTA z0a3TqHs<;22rHRikFc!0&!37?Z*jxxzBLz3Inzc3;HC9Hwom~`^{=Uh~d8o1ev4E6k3= zAOBt{D{C;`f)DFspJ8)Xh{DjxJhHnNXHM)0Y)2Y}IcNipna8fz*T;f*a?|LkM`88? z2{O_hzo9bVv*G7#-a0~V1dn6~f7OaGPKfyIc4B1CZf(&%6)OISQ}c37SNs@5vGG5%>eqz1=Wo?I#lJ;M%+{R z!DX-8M=LerF4HzVtW)J(V=gcv4w%6a-yRAGeriUBFK>rEe3dla%;44I?D3aYon_1> z=Af~v=N5APNNh)-wZQCL@?AEV?Yeg*IW`I>qIt0_99#Y;>Hm^XR42+ix`U>D zlOMfob2gSVz%{|eWvnms+lv;T<)DWIbYvg2aAV7M&2R={jRXLVK;y?5z$PJq#0W~< z$H;BFr2S_1I~rFpYMxM2D>ol2iK`8@M{c*cubMouyk~cbG)19y?8+Jq8lWVeXX8Fb zf^j2cO#~3Xs%8Mjn>$(WMyNitA+I0+p6OEtZE(Gq1{i|1%Wr-+^f&OIh$%;ZW_fRAWVu8ZJRfd#3CSh}IhDLo;@?KTwWD(QMXDAqVTGm6pR zG?2>;4`my<^9GzKvQyb=A^5JJomjvgE0{o+I(>?CpLXvH>5H27$%nw1Ecjg?o&BI{da7(H>P4%3Lqt zc9Kz%oSl(>`)OPL3B0ErRzzo{`)`tly*TIKRYRqRsBGlnD41Mlccun}ZmQ^Io5$>G z%g4GMKRVKBcAt07;?7?}p#IDV*j9}oUsZLqUe>%-EqGv*^^+Gn-z;jyeFJgo^%b&lxO93O8d;bf9iH(<+`n$Z_?8=o>D- z>Qh@&z(buD_P`;VtDJ-vDXwjmj3*b8mN(?~nW}weH*}UTNgQQ91^hGYnL(%ug=SUO zk&Mc|d~ld8D3UxvJKhG@8E?BOLGL`J}QO$8tp+ z$cD5G{?@(eg_SYO!^C`o;mUeRmOQ*~b_HaoSrRT^ghPhwM?bPGU$7Dje6+hZ5`>jT zp6EOfpkdWAQ=B=H_Ci6}fzevFSRLLk;*^diXtX$vsV9n*t|C#^BsibiU7tc* zyTGUGqeP+nbC@)Qb8nPt8oL!DkYTxn3&k^p<|P=oZ?AW4bds#{?C8w2)U*+7-MF& z@;yF~_Yu0ulstT5_9j8?p9kSl4C0Oy5f;{V2#zH__y`1dwjq5{P zDm*>JtFV`GZF<^xoy4{$nv8d9*ICcc=1R9=cY|mZFT%dOgh-V!96#9<*nDbUcS3{& zvb6r6)Jr$1)(qkG&6m9fLsbo)uV9p|v!Gi4Y?!foKwT%&(=$P^p@GtB>)=g2X95E} zGbKG8Ahx^7(IOL;@R|@U`z+S-{`I!9!m~5J9bNrCxr5F~Vw8Az?{NdL_1P3M$Cy{3sdoahQuX)|xQKnjVu4E;FYYKY z0=4*5;?86Q3NGS(ekMH+8Xdjtdk>z2>dGk8tO0!Nh0gdSJ?E(F2*;;PloR*%)P&(B z1oa6z$E&$3lZ|90_7IO`WFXSt>cL zqOsn{p91G+j__g~yP9;SBBAn}-P>}5)T+*X!?uV`|`#NyEhFYr>BJ*`ASbKH&^gij9=$EZ+~I8#HhTb z`eon-Ey9r|Q0ykzmC|o^dl3V??Mcn8McvsIE{eV*t0Wh$E!-;?x}ykCG4YioLJPac z^J-BAh+PZm-M|e5R)Ch;S1kB7|jZBLisW9Wt-yt~jujYOBYTJaISf<*vu5mw5^-}_#nRnw4(eKXp|H-I$6ej%QeQw65PXW$V@%*EU=ZKPRe^1 z(^gO=C$>l=AD{iK3UyK*3rg9jOn9vjl6g>bK6&No)r6S1LOV=VT){Z7V_<5$^>?<+ zusJR&88P;Q6od6fU)^--$^i;oAn@R!vqiJ>ikX^)((}v5R;Wj-nAdNzs*eb!IEnvt zJc^KaO7!LsvZF4swfdt^5bXqUbq}jFIdp6kajaIK?PSM>^+0FP7dknvFC}nM97h73 zK5rw&pJ{75mOezd6L$%v(#JbP9h^=TsPwF7=ufR(82TMgdQ3SbJanU|ZD^G-KMu@l ziHc-GUzhqQ=nQEggFmq;rJYFi+e~+H-%o!Boh6E0VMYyT?CmV8K*-Q9?!%AhAgTve z?D>?_2N6(IX-4B&3#1bfk7!8bTA7m3;2@X%V-3WM;2t~1`7W0^vS7*R29ei?J#BJR zkn?+^;hDMmY#Z8{+nVu<(42DfL0!2yJlJNKr_g9h`Eu_8AD)g&C}AEmsZU3MokC=w9O$MR9=ITkClt!9-pAJ}=)$7y(eK$o8H;>M{&b*LNKh=v6nEZXlxcLLZ#(#CBr^NE%vtdOL|=@R znkARm-nP4*d9S`h08?7C>!r&o73+_6|C(;46|2FFR`GOmQy$y) zcq*bu?s8Ar@gtXM;&rJNYrv4@k)812dRK?{Tq2_dFT?Q{8W4Jzf1=);T3K0RWC;XjcFL literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^4Gav73><7gR`t)i(r%hyF{ZEKb=E8jM+udM{K<66`qUe`7iJ@z$>A9)U}G%FBe~-)0@Vc}$|+@!IUY z`VF<53VsZQOdY}wa~K}62&gw$Fdi9BLgm}Pv-W(<{P-ic=c7sG*}so0(?0L7Jt%W~ z;(YmI67m0DW}SP<#S~Fm@o(1Nw68M9WvY|U*Yd7Etc(&Y<;@lj7cev;Av!?8gp^bP0l+XkK&yP$E diff --git a/resources/resources/assets/minecraft/textures/gui/title/background/enable_blur.txt b/resources/resources/assets/minecraft/textures/gui/title/background/enable_blur.txt new file mode 100644 index 0000000..3fd898d --- /dev/null +++ b/resources/resources/assets/minecraft/textures/gui/title/background/enable_blur.txt @@ -0,0 +1,2 @@ +# Change to 0 to disable blur +enable_blur=1 \ No newline at end of file diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglerInputStream.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglerInputStream.java index d35b115..a133b2e 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglerInputStream.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglerInputStream.java @@ -9,14 +9,21 @@ import java.util.Arrays; /** * 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. * @@ -121,20 +128,24 @@ public class EaglerInputStream extends InputStream { } public static byte[] inputStreamToBytes(InputStream is) throws IOException { - if (is instanceof EaglerInputStream) { - return ((EaglerInputStream) is).getAsArray(); - } else if (is instanceof ByteArrayInputStream) { - byte[] ret = new byte[is.available()]; - is.read(ret); - return ret; - } else { - EaglerOutputStream os = new EaglerOutputStream(1024); - byte[] buf = new byte[1024]; - int i; - while ((i = is.read(buf)) != -1) { - os.write(buf, 0, i); + try { + if (is instanceof EaglerInputStream) { + return ((EaglerInputStream) is).getAsArray(); + } else if (is instanceof ByteArrayInputStream) { + byte[] ret = new byte[is.available()]; + is.read(ret); + return ret; + } else { + EaglerOutputStream os = new EaglerOutputStream(1024); + byte[] buf = new byte[1024]; + int i; + while ((i = is.read(buf)) != -1) { + os.write(buf, 0, i); + } + return os.toByteArray(); } - return os.toByteArray(); + } finally { + is.close(); } } diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java index 28ed123..001a2f3 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftVersion.java @@ -9,7 +9,7 @@ public class EaglercraftVersion { /// Customize these to fit your fork: public static final String projectForkName = "Eaglercraft Lambda"; - public static final String projectForkVersion = "0.5.0"; + public static final String projectForkVersion = "0.5.1"; public static final String projectForkVendor = "HoosierTransfer"; public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; @@ -19,7 +19,7 @@ public class EaglercraftVersion { public static final String projectOriginName = "EaglercraftX"; public static final String projectOriginAuthor = "lax1dude"; public static final String projectOriginRevision = "1.9.4"; - public static final String projectOriginVersion = "u34"; + public static final String projectOriginVersion = "u35"; 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 = true; public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client"; - public static final int updateBundlePackageVersionInt = 34; + public static final int updateBundlePackageVersionInt = 35; public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/Mouse.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/Mouse.java index ba25cc4..222cac3 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/Mouse.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/Mouse.java @@ -3,8 +3,6 @@ package net.lax1dude.eaglercraft.v1_8; import net.lax1dude.eaglercraft.v1_8.internal.EnumCursorType; import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput; -import net.lax1dude.eaglercraft.v1_8.internal.RenderResolution; - /** * Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights * Reserved. diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/internal/IClientConfigAdapter.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/internal/IClientConfigAdapter.java index 8af37d5..5320bbf 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/internal/IClientConfigAdapter.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/internal/IClientConfigAdapter.java @@ -81,5 +81,7 @@ public interface IClientConfigAdapter { String getLocalStorageNamespace(); + boolean isEnableMinceraft(); + IClientConfigAdapterHooks getHooks(); } diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/EaglerDeferredPipeline.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/EaglerDeferredPipeline.java index 62e4d2f..6d644b6 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/EaglerDeferredPipeline.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/EaglerDeferredPipeline.java @@ -66,7 +66,6 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ExtGLEnums.*; import java.io.DataInputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/EaglerBitwisePackedTexture.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/EaglerBitwisePackedTexture.java index 5d37d21..0f2a3fe 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/EaglerBitwisePackedTexture.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/EaglerBitwisePackedTexture.java @@ -3,19 +3,27 @@ package net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.texture; import java.io.IOException; import java.io.InputStream; +import net.lax1dude.eaglercraft.v1_8.IOUtils; import net.lax1dude.eaglercraft.v1_8.opengl.ImageData; /** * Copyright (c) 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. * @@ -25,23 +33,24 @@ public class EaglerBitwisePackedTexture { private static int getFromBits(int idxx, int bits, byte[] bytes) { int startByte = idxx >> 3; int endByte = (idxx + bits - 1) >> 3; - if(startByte == endByte) { - return (((int)bytes[startByte] & 0xff) >> (8 - (idxx & 7) - bits)) & ((1 << bits) - 1); - }else { - return (((((int)bytes[startByte] & 0xff) << 8) | ((int)bytes[endByte] & 0xff)) >> (16 - (idxx & 7) - bits)) & ((1 << bits) - 1); + if (startByte == endByte) { + return (((int) bytes[startByte] & 0xff) >> (8 - (idxx & 7) - bits)) & ((1 << bits) - 1); + } else { + return (((((int) bytes[startByte] & 0xff) << 8) | ((int) bytes[endByte] & 0xff)) >> (16 - (idxx & 7) + - bits)) & ((1 << bits) - 1); } } public static ImageData loadTexture(InputStream is, int alpha) throws IOException { - if(is.read() != '%' || is.read() != 'E' || is.read() != 'B' || is.read() != 'P') { + if (is.read() != '%' || is.read() != 'E' || is.read() != 'B' || is.read() != 'P') { throw new IOException("Not an EBP file!"); } int v = is.read(); - if(v != 1) { + if (v != 1) { throw new IOException("Unknown EBP version: " + v); } v = is.read(); - if(v != 3) { + if (v != 3) { throw new IOException("Invalid component count: " + v); } int w = is.read() | (is.read() << 8); @@ -49,30 +58,41 @@ public class EaglerBitwisePackedTexture { ImageData img = new ImageData(w, h, true); alpha <<= 24; v = is.read(); - if(v == 0) { - for(int i = 0, l = w * h; i < l; ++i) { + if (v == 0) { + for (int i = 0, l = w * h; i < l; ++i) { img.pixels[i] = is.read() | (is.read() << 8) | (is.read() << 16) | alpha; } - }else if(v == 1) { + } else if (v == 1) { int paletteSize = is.read(); int[] palette = new int[paletteSize + 1]; palette[0] = alpha; - for(int i = 0; i < paletteSize; ++i) { + for (int i = 0; i < paletteSize; ++i) { palette[i + 1] = is.read() | (is.read() << 8) | (is.read() << 16) | alpha; } int bpp = is.read(); byte[] readSet = new byte[is.read() | (is.read() << 8) | (is.read() << 16)]; is.read(readSet); - for(int i = 0, l = w * h; i < l; ++i) { + for (int i = 0, l = w * h; i < l; ++i) { img.pixels[i] = palette[getFromBits(i * bpp, bpp, readSet)]; } - }else { + } else { throw new IOException("Unknown EBP storage type: " + v); } - if(is.read() != ':' || is.read() != '>') { + if (is.read() != ':' || is.read() != '>') { throw new IOException("Invalid footer! (:>)"); } return img; } + public static ImageData loadTextureSafe(InputStream is, int alpha) throws IOException { + ImageData bufferedimage; + try { + bufferedimage = loadTexture(is, alpha); + } finally { + IOUtils.closeQuietly(is); + } + + return bufferedimage; + } + } diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/PBRTextureMapUtils.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/PBRTextureMapUtils.java index 2e4b77d..af70112 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/PBRTextureMapUtils.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/deferred/texture/PBRTextureMapUtils.java @@ -13,14 +13,21 @@ 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 + * 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. * @@ -29,7 +36,8 @@ public class PBRTextureMapUtils { public static final ImageData defaultNormalsTexture = new ImageData(1, 1, new int[] { 0 }, true); - public static final PBRMaterialConstants blockMaterialConstants = new PBRMaterialConstants(new ResourceLocation("eagler:glsl/deferred/material_block_constants.csv")); + public static final PBRMaterialConstants blockMaterialConstants = new PBRMaterialConstants( + new ResourceLocation("eagler:glsl/deferred/material_block_constants.csv")); public static final Logger logger = LogManager.getLogger("PBRTextureMap"); @@ -39,42 +47,49 @@ public class PBRTextureMapUtils { String resourcePack = mainImage.getResourcePackName(); String fname = baseLocation.getResourcePath(); int idx = fname.lastIndexOf('.'); - if(idx != -1) { + if (idx != -1) { fname = fname.substring(0, idx) + ext + fname.substring(idx); - }else { + } else { fname += ext; } try { List ress = resMgr.getAllResources(new ResourceLocation(domain, fname)); - for(int k = 0, l = ress.size(); k < l; ++k) { + for (int k = 0, l = ress.size(); k < l; ++k) { IResource res = ress.get(k); - if(res.getResourcePackName().equals(resourcePack)) { + if (res.getResourcePackName().equals(resourcePack)) { ImageData toRet = TextureUtil.readBufferedImage(res.getInputStream()); - if(ext.equals("_s")) { - for(int i = 0, j; i < toRet.pixels.length; ++i) { + if (ext.equals("_s")) { + for (int i = 0, j; i < toRet.pixels.length; ++i) { // swap B and A, because labPBR support int a = (toRet.pixels[i] >>> 24) & 0xFF; - if(a == 0xFF) a = 0; + if (a == 0xFF) + a = 0; toRet.pixels[i] = (toRet.pixels[i] & 0x0000FFFF) | Math.min(a << 18, 0xFF0000) | 0xFF000000; } } return toRet; } } - }catch(Throwable t) { + } catch (Throwable t) { } - if("Default".equals(resourcePack)) { + if ("Default".equals(resourcePack)) { idx = fname.lastIndexOf('.'); - if(idx != -1) { + if (idx != -1) { fname = fname.substring(0, idx); } try { - return TextureUtil.readBufferedImage(resMgr.getResource(new ResourceLocation("eagler:glsl/deferred/assets_pbr/" + fname + ".png")).getInputStream()); - }catch(Throwable t) { + return TextureUtil.readBufferedImage( + resMgr.getResource(new ResourceLocation("eagler:glsl/deferred/assets_pbr/" + fname + ".png")) + .getInputStream()); + } catch (Throwable t) { } try { - return EaglerBitwisePackedTexture.loadTexture(resMgr.getResource(new ResourceLocation("eagler:glsl/deferred/assets_pbr/" + fname + ".ebp")).getInputStream(), 255); - }catch(Throwable t) { + return EaglerBitwisePackedTexture.loadTextureSafe( + resMgr.getResource(new ResourceLocation("eagler:glsl/deferred/assets_pbr/" + fname + ".ebp")) + .getInputStream(), + 255); + + } catch (Throwable t) { // dead code because teavm t.toString(); } @@ -86,53 +101,54 @@ public class PBRTextureMapUtils { int resX = -1; int resY = -1; int iw, ih; - for(int i = 0; i < imageSets.length; ++i) { + for (int i = 0; i < imageSets.length; ++i) { iw = imageSets[i][lvl].width; ih = imageSets[i][lvl].height; - if(iw != ih) { + if (iw != ih) { } - if(iw > resX) { + if (iw > resX) { resX = iw; } - if(ih > resY) { + if (ih > resY) { resY = ih; } } - if(resX == -1 || resY == -1) { + if (resX == -1 || resY == -1) { throw new IllegalArgumentException("No images were provided!"); } - for(int i = 0; i < imageSets.length; ++i) { + for (int i = 0; i < imageSets.length; ++i) { ImageData in = imageSets[i][lvl]; ImageData out = null; - if(in.width != resX || in.height != resY) { + if (in.width != resX || in.height != resY) { out = new ImageData(resX, resY, true); - if(in.width == 1 && in.height == 1) { + if (in.width == 1 && in.height == 1) { int px = in.pixels[0]; - for(int j = 0; j < out.pixels.length; ++j) { + for (int j = 0; j < out.pixels.length; ++j) { out.pixels[j] = px; } - }else { - for(int y = 0; y < resY; ++y) { - for(int x = 0; x < resX; ++x) { - out.pixels[y * resX + x] = in.pixels[((y * in.height / resY)) * in.width + (x * in.width / resX)]; + } else { + for (int y = 0; y < resY; ++y) { + for (int x = 0; x < resX; ++x) { + out.pixels[y * resX + x] = in.pixels[((y * in.height / resY)) * in.width + + (x * in.width / resX)]; } } } } - if(out != null) { + if (out != null) { imageSets[i][lvl] = out; } } } public static ImageData generateMaterialTextureFor(String iconName) { - if(iconName.startsWith("minecraft:")) { + if (iconName.startsWith("minecraft:")) { iconName = iconName.substring(10); } Integer in = blockMaterialConstants.spriteNameToMaterialConstants.get(iconName); - if(in == null) { + if (in == null) { return new ImageData(1, 1, new int[] { blockMaterialConstants.defaultMaterial }, true); - }else { + } else { return new ImageData(1, 1, new int[] { in.intValue() }, true); } } @@ -141,15 +157,15 @@ public class PBRTextureMapUtils { int[][] ret = new int[level + 1][]; ret[0] = aint[0]; if (level > 0) { - for(int i = 1; i <= level; ++i) { - if(aint[i] != null) { + for (int i = 1; i <= level; ++i) { + if (aint[i] != null) { ret[i] = aint[i]; - }else { + } else { int lvlW = width >> i, lvl2W = lvlW << 1; int len = lvlW * lvlW; ret[i] = new int[len]; int x, y, s1, s2, s3, s4, c1, c2, c3, c4; - for(int j = 0; j < len; ++j) { + for (int j = 0; j < len; ++j) { x = (j % len) << 1; y = (j / len) << 1; s1 = ret[i - 1][x + y * lvl2W]; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java index f8a8514..6b56bc3 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightBucketLoader.java @@ -4,7 +4,6 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*; import static net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.ExtGLEnums.*; -import java.util.ArrayList; import java.util.Comparator; import java.util.List; diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightInstance.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightInstance.java index 8a5720b..f40f699 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightInstance.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightInstance.java @@ -24,32 +24,23 @@ package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights; */ class DynamicLightInstance { - public final String lightName; - long lastCacheHit = 0l; - double posX; double posY; double posZ; float radius; - public DynamicLightInstance(String lightName) { - this.lightName = lightName; + public DynamicLightInstance() { } public void updateLight(double posX, double posY, double posZ, float radius) { - this.lastCacheHit = System.currentTimeMillis(); this.posX = posX; this.posY = posY; this.posZ = posZ; this.radius = radius; } - public void destroy() { - - } - public float getRadiusInWorld() { return radius; } -} \ No newline at end of file +} diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsPipelineCompiler.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsPipelineCompiler.java index c2c5eec..ec95820 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsPipelineCompiler.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsPipelineCompiler.java @@ -8,7 +8,6 @@ import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionSta import net.lax1dude.eaglercraft.v1_8.opengl.IExtPipelineCompiler; import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource; import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program.DynamicLightsExtPipelineShader; -import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f; import net.minecraft.client.renderer.GLAllocation; /** diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsStateManager.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsStateManager.java index e5c6bfa..3d4f82c 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsStateManager.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/DynamicLightsStateManager.java @@ -1,10 +1,9 @@ package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights; -import java.util.HashMap; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Map; import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionPipeline; import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; @@ -38,14 +37,15 @@ import net.minecraft.util.MathHelper; public class DynamicLightsStateManager { static final DynamicLightsPipelineCompiler deferredExtPipeline = new DynamicLightsPipelineCompiler(); - static final Map lightRenderers = new HashMap(); + private static List lightInstancePool = new ArrayList(); + private static int instancePoolIndex = 0; + private static int maxListLengthTracker = 0; static final List lightRenderList = new LinkedList(); static final Matrix4f inverseViewMatrix = new Matrix4f(); static int inverseViewMatrixSerial = 0; static DynamicLightBucketLoader bucketLoader = null; static DynamicLightsAcceleratedEffectRenderer accelParticleRenderer = null; static int lastTotal = 0; - static long renderTimeout = 5000l; private static long lastTick = 0l; public static final void enableDynamicLightsRender() { @@ -59,6 +59,9 @@ public class DynamicLightsStateManager { accelParticleRenderer = new DynamicLightsAcceleratedEffectRenderer(); accelParticleRenderer.initialize(); } + lightRenderList.clear(); + instancePoolIndex = 0; + maxListLengthTracker = 0; } public static final void bindAcceleratedEffectRenderer(EffectRenderer renderer) { @@ -79,6 +82,8 @@ public class DynamicLightsStateManager { } destroyAll(); lightRenderList.clear(); + instancePoolIndex = 0; + maxListLengthTracker = 0; } public static final boolean isDynamicLightsRender() { @@ -109,21 +114,27 @@ public class DynamicLightsStateManager { public static final void renderDynamicLight(String lightName, double posX, double posY, double posZ, float radius) { if (bucketLoader != null) { - DynamicLightInstance dl = lightRenderers.get(lightName); - if (dl == null) { - lightRenderers.put(lightName, dl = new DynamicLightInstance(lightName)); + DynamicLightInstance dl; + if (instancePoolIndex < lightInstancePool.size()) { + dl = lightInstancePool.get(instancePoolIndex); + } else { + lightInstancePool.add(dl = new DynamicLightInstance()); } + ++instancePoolIndex; dl.updateLight(posX, posY, posZ, radius); lightRenderList.add(dl); } } public static final void clearRenderList() { + if (instancePoolIndex > maxListLengthTracker) { + maxListLengthTracker = instancePoolIndex; + } lightRenderList.clear(); + instancePoolIndex = 0; } public static final void commitLightSourceBuckets(double renderPosX, double renderPosY, double renderPosZ) { - updateTimers(); lastTotal = lightRenderList.size(); if (bucketLoader != null) { bucketLoader.clearBuckets(); @@ -141,7 +152,8 @@ public class DynamicLightsStateManager { bucketLoader.setRenderPos(renderPosX, renderPosY, renderPosZ); bucketLoader.truncateOverflowingBuffers(); } - lightRenderList.clear(); + updateTimers(); + clearRenderList(); } public static final void setupInverseViewMatrix() { @@ -151,29 +163,25 @@ public class DynamicLightsStateManager { private static final void updateTimers() { long millis = System.currentTimeMillis(); - if (millis - lastTick > 1000l) { + if (millis - lastTick > 5000l) { lastTick = millis; - Iterator itr = lightRenderers.values().iterator(); - while (itr.hasNext()) { - DynamicLightInstance dl = itr.next(); - if (millis - dl.lastCacheHit > renderTimeout) { - dl.destroy(); - itr.remove(); + if (maxListLengthTracker < (lightInstancePool.size() >> 1)) { + List newPool = new ArrayList(Math.max(maxListLengthTracker, 16)); + for (int i = 0; i < maxListLengthTracker; ++i) { + newPool.add(lightInstancePool.get(i)); } + lightInstancePool = newPool; } + maxListLengthTracker = 0; } } public static final void destroyAll() { - Iterator itr = lightRenderers.values().iterator(); - while (itr.hasNext()) { - itr.next().destroy(); - } - lightRenderers.clear(); + lightInstancePool = new ArrayList(); } public static String getF3String() { return "DynamicLightsTotal: " + lastTotal; } -} \ No newline at end of file +} diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/program/DynamicLightsAccelParticleShader.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/program/DynamicLightsAccelParticleShader.java index a9b8501..7ed1221 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/program/DynamicLightsAccelParticleShader.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/opengl/ext/dynamiclights/program/DynamicLightsAccelParticleShader.java @@ -1,11 +1,7 @@ package net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.program; import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; -import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_FRAGMENT_SHADER; -import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_VERTEX_SHADER; - -import java.util.ArrayList; -import java.util.List; +import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*; import net.lax1dude.eaglercraft.v1_8.internal.IProgramGL; import net.lax1dude.eaglercraft.v1_8.internal.IShaderGL; diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java index 91a0411..6ab971e 100644 --- a/src/main/java/net/minecraft/client/Minecraft.java +++ b/src/main/java/net/minecraft/client/Minecraft.java @@ -613,6 +613,7 @@ public class Minecraft implements IThreadListener { } ShaderSource.clearCache(); + GuiMainMenu.doResourceReloadHack(); this.mcLanguageManager.parseLanguageMetadata(arraylist); if (this.renderGlobal != null) { diff --git a/src/main/java/net/minecraft/client/gui/GuiMainMenu.java b/src/main/java/net/minecraft/client/gui/GuiMainMenu.java index 316df4d..5bb8c64 100644 --- a/src/main/java/net/minecraft/client/gui/GuiMainMenu.java +++ b/src/main/java/net/minecraft/client/gui/GuiMainMenu.java @@ -5,23 +5,23 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import net.lax1dude.eaglercraft.v1_8.EagRuntime; +import net.lax1dude.eaglercraft.v1_8.EagUtils; import net.lax1dude.eaglercraft.v1_8.EaglerInputStream; import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom; import net.lax1dude.eaglercraft.v1_8.EaglercraftVersion; -import net.lax1dude.eaglercraft.v1_8.Mouse; import com.google.common.base.Charsets; import com.google.common.collect.Lists; import net.lax1dude.eaglercraft.v1_8.crypto.MD5Digest; import net.lax1dude.eaglercraft.v1_8.crypto.SHA1Digest; -import net.lax1dude.eaglercraft.v1_8.internal.EnumCursorType; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU; @@ -38,7 +38,6 @@ 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; @@ -82,8 +81,6 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { private float updateCounter; private boolean isDefault; private static final int lendef = 5987; - private static final byte[] md5def = new byte[] { -61, -53, -36, 27, 24, 27, 103, -31, -58, -116, 113, -60, -67, -8, - -77, 30 }; private static final byte[] sha1def = new byte[] { -107, 77, 108, 49, 11, -100, -8, -119, -1, -100, -85, -55, 18, -69, -107, 113, -93, -101, -79, 32 }; private String splashText; @@ -101,6 +98,8 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { private static final ResourceLocation splashTexts = new ResourceLocation("texts/splashes.txt"); private static final ResourceLocation minecraftTitleTextures = new ResourceLocation( "textures/gui/title/minecraft.png"); + private static final ResourceLocation minecraftTitleBlurFlag = new ResourceLocation( + "textures/gui/title/background/enable_blur.txt"); private static final ResourceLocation eaglerGuiTextures = new ResourceLocation("eagler:gui/eagler_gui.png"); /** * + @@ -122,8 +121,13 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { private static ResourceLocation backgroundTexture = null; private GuiUpdateCheckerOverlay updateCheckerOverlay; private GuiButton downloadOfflineButton; + private boolean enableBlur = true; + private boolean shouldReload = false; + + private static GuiMainMenu instance = null; public GuiMainMenu() { + instance = this; this.splashText = "missingno"; updateCheckerOverlay = new GuiUpdateCheckerOverlay(false, this); BufferedReader bufferedreader = null; @@ -164,31 +168,59 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { } this.updateCounter = RANDOM.nextFloat(); + reloadResourceFlags(); + } + private void reloadResourceFlags() { if (Minecraft.getMinecraft().isDemo()) { this.isDefault = false; } else { - MD5Digest md5 = new MD5Digest(); - SHA1Digest sha1 = new SHA1Digest(); - byte[] md5out = new byte[16]; - byte[] sha1out = new byte[20]; - try { - byte[] bytes = EaglerInputStream.inputStreamToBytesQuiet(Minecraft.getMinecraft().getResourceManager() - .getResource(minecraftTitleTextures).getInputStream()); - if (bytes != null) { - md5.update(bytes, 0, bytes.length); - sha1.update(bytes, 0, bytes.length); - md5.doFinal(md5out, 0); - sha1.doFinal(sha1out, 0); - this.isDefault = bytes.length == lendef && Arrays.equals(md5out, md5def) - && Arrays.equals(sha1out, sha1def); - } else { + if (!EagRuntime.getConfiguration().isEnableMinceraft()) { + this.isDefault = false; + } else { + try { + byte[] bytes = EaglerInputStream.inputStreamToBytesQuiet(Minecraft.getMinecraft() + .getResourceManager().getResource(minecraftTitleTextures).getInputStream()); + if (bytes != null && bytes.length == lendef) { + SHA1Digest sha1 = new SHA1Digest(); + byte[] sha1out = new byte[20]; + sha1.update(bytes, 0, bytes.length); + sha1.doFinal(sha1out, 0); + this.isDefault = Arrays.equals(sha1out, sha1def); + } else { + this.isDefault = false; + } + } catch (IOException e) { this.isDefault = false; } - } catch (IOException e) { - this.isDefault = false; } } + + this.enableBlur = true; + + try { + byte[] bytes = EaglerInputStream.inputStreamToBytesQuiet( + Minecraft.getMinecraft().getResourceManager().getResource(minecraftTitleBlurFlag).getInputStream()); + if (bytes != null) { + String[] blurCfg = EagUtils.linesArray(new String(bytes, StandardCharsets.UTF_8)); + for (int i = 0; i < blurCfg.length; ++i) { + String s = blurCfg[i]; + if (s.startsWith("enable_blur=")) { + s = s.substring(12).trim(); + this.enableBlur = s.equals("1") || s.equals("true"); + break; + } + } + } + } catch (IOException e) { + ; + } + } + + public static void doResourceReloadHack() { + if (instance != null) { + instance.shouldReload = true; + } } /** @@ -200,6 +232,10 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { if (downloadOfflineButton != null) { downloadOfflineButton.enabled = !UpdateService.shouldDisableDownloadButton(); } + if (shouldReload) { + reloadResourceFlags(); + shouldReload = false; + } } /** @@ -393,19 +429,25 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { GlStateManager.matrixMode(GL_PROJECTION); GlStateManager.pushMatrix(); GlStateManager.loadIdentity(); - GlStateManager.gluPerspective(120.0F, 1.0F, 0.05F, 10.0F); + if (enableBlur) { + GlStateManager.gluPerspective(120.0F, 1.0F, 0.05F, 10.0F); + } else { + GlStateManager.gluPerspective(85.0F, (float) width / (float) height, 0.05F, 10.0F); + } GlStateManager.matrixMode(GL_MODELVIEW); GlStateManager.pushMatrix(); GlStateManager.loadIdentity(); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F); - GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F); + if (enableBlur) { + GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F); + } GlStateManager.enableBlend(); GlStateManager.disableAlpha(); GlStateManager.disableCull(); GlStateManager.depthMask(false); GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1, 0); - byte b0 = 8; + byte b0 = enableBlur ? (byte) 8 : (byte) 1; for (int i = 0; i < b0 * b0; ++i) { GlStateManager.pushMatrix(); @@ -545,7 +587,11 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { */ public void drawScreen(int i, int j, float f) { GlStateManager.disableAlpha(); - this.renderSkybox(i, j, f); + if (enableBlur) { + this.renderSkybox(i, j, f); + } else { + this.drawPanorama(i, j, f); + } GlStateManager.enableAlpha(); short short1 = 274; int k = this.width / 2 - short1 / 2; @@ -554,7 +600,11 @@ public class GuiMainMenu extends GuiScreen implements GuiYesNoCallback { this.drawGradientRect(0, 0, this.width, this.height, 0, Integer.MIN_VALUE); this.mc.getTextureManager().bindTexture(minecraftTitleTextures); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - if (this.isDefault || (double) this.updateCounter < 1.0E-4D) { + boolean minc = (double) this.updateCounter < 1.0E-4D; + if (this.isDefault) { + minc = !minc; + } + if (minc) { this.drawTexturedModalRect(k + 0, b0 + 0, 0, 0, 99, 44); this.drawTexturedModalRect(k + 99, b0 + 0, 129, 0, 27, 44); this.drawTexturedModalRect(k + 99 + 26, b0 + 0, 126, 0, 3, 44); diff --git a/src/main/java/net/minecraft/client/multiplayer/ServerData.java b/src/main/java/net/minecraft/client/multiplayer/ServerData.java index 8336de4..424788f 100644 --- a/src/main/java/net/minecraft/client/multiplayer/ServerData.java +++ b/src/main/java/net/minecraft/client/multiplayer/ServerData.java @@ -189,7 +189,12 @@ public class ServerData { this.serverMOTD = motd.length() > 0 ? (motd.length() > 1 ? motd.getString(0) + "\n" + motd.getString(1) : motd.getString(0)) : ""; - this.populationInfo = "" + motdData.getInt("online") + "/" + motdData.getInt("max"); + int max = motdData.getInt("max"); + if (max > 0) { + this.populationInfo = "" + motdData.getInt("online") + "/" + max; + } else { + this.populationInfo = "" + motdData.getInt("online"); + } this.playerList = null; JSONArray players = motdData.optJSONArray("players"); if (players.length() > 0) { diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformApplication.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformApplication.java index 1f43838..2c3070c 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformApplication.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformApplication.java @@ -19,7 +19,6 @@ import org.teavm.jso.dom.html.HTMLCanvasElement; import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLInputElement; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import net.lax1dude.eaglercraft.v1_8.Base64; import net.lax1dude.eaglercraft.v1_8.EagRuntime; @@ -210,8 +209,7 @@ public class PlatformApplication { if (name == null) { fileChooserResultObject = null; } else { - fileChooserResultObject = new FileChooserResult(name, - TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buffer))); + fileChooserResultObject = new FileChooserResult(name, TeaVMUtils.wrapByteArrayBuffer(buffer)); } } @@ -308,7 +306,7 @@ public class PlatformApplication { private static final native void downloadBytesImpl(String str, ArrayBuffer buf); public static final void downloadFileWithName(String str, byte[] dat) { - downloadBytesImpl(str, TeaVMUtils.unwrapUnsignedByteArray(dat).getBuffer()); + downloadBytesImpl(str, TeaVMUtils.unwrapArrayBuffer(dat)); } public static void showDebugConsole() { diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java index 0e2d783..cef5208 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java @@ -27,96 +27,109 @@ import net.lax1dude.eaglercraft.v1_8.opengl.ImageData; /** * 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. * */ public class PlatformAssets { - + private static final byte[] MISSING_FILE = new byte[0]; - - static final Map assets = new HashMap(); - + + static final Map assets = new HashMap(); + public static final byte[] getResourceBytes(String path) { - if(path.startsWith("/")) { + if (path.startsWith("/")) { path = path.substring(1); } byte[] data = assets.get(path); - if(data == null && path.startsWith("assets/minecraft/lang/") && !path.endsWith(".mcmeta")) { + if (data == null && path.startsWith("assets/minecraft/lang/") && !path.endsWith(".mcmeta")) { ArrayBuffer file = PlatformRuntime.downloadRemoteURI( ClientMain.configLocalesFolder + "/" + path.substring(22)); - if(file != null && file.getByteLength() > 0) { - data = TeaVMUtils.arrayBufferToBytes(file); + if (file != null && file.getByteLength() > 0) { + data = TeaVMUtils.wrapByteArrayBuffer(file); assets.put(path, data); return data; - }else { + } else { assets.put(path, MISSING_FILE); return null; } - }else { + } else { return data == MISSING_FILE ? null : data; } } - + public static final ImageData loadImageFile(InputStream data) { byte[] b = EaglerInputStream.inputStreamToBytesQuiet(data); - if(b != null) { + if (b != null) { return loadImageFile(b); - }else { + } else { return null; } } - + private static HTMLCanvasElement imageLoadCanvas = null; private static CanvasRenderingContext2D imageLoadContext = null; - + public static ImageData loadImageFile(byte[] data) { - return loadImageFile(TeaVMUtils.unwrapUnsignedByteArray(data).getBuffer()); + return loadImageFile(TeaVMUtils.unwrapArrayBuffer(data)); } - - @JSBody(params = { }, script = "return { willReadFrequently: true };") + + @JSBody(params = {}, script = "return { willReadFrequently: true };") public static native JSObject youEagler(); - + + @JSBody(params = { "ctx" }, script = "ctx.imageSmoothingEnabled = false;") + private static native void disableImageSmoothing(CanvasRenderingContext2D ctx); + @Async private static native ImageData loadImageFile(ArrayBuffer data); - + private static void loadImageFile(ArrayBuffer data, final AsyncCallback ret) { final Document doc = Window.current().getDocument(); final HTMLImageElement toLoad = (HTMLImageElement) doc.createElement("img"); toLoad.addEventListener("load", new EventListener() { @Override public void handleEvent(Event evt) { - if(imageLoadCanvas == null) { + if (imageLoadCanvas == null) { imageLoadCanvas = (HTMLCanvasElement) doc.createElement("canvas"); } - if(imageLoadCanvas.getWidth() < toLoad.getWidth()) { + if (imageLoadCanvas.getWidth() < toLoad.getWidth()) { imageLoadCanvas.setWidth(toLoad.getWidth()); } - if(imageLoadCanvas.getHeight() < toLoad.getHeight()) { + if (imageLoadCanvas.getHeight() < toLoad.getHeight()) { imageLoadCanvas.setHeight(toLoad.getHeight()); } - if(imageLoadContext == null) { + if (imageLoadContext == null) { imageLoadContext = (CanvasRenderingContext2D) imageLoadCanvas.getContext("2d", youEagler()); + disableImageSmoothing(imageLoadContext); } imageLoadContext.clearRect(0, 0, toLoad.getWidth(), toLoad.getHeight()); imageLoadContext.drawImage(toLoad, 0, 0, toLoad.getWidth(), toLoad.getHeight()); - org.teavm.jso.canvas.ImageData pxlsDat = imageLoadContext.getImageData(0, 0, toLoad.getWidth(), toLoad.getHeight()); + org.teavm.jso.canvas.ImageData pxlsDat = imageLoadContext.getImageData(0, 0, toLoad.getWidth(), + toLoad.getHeight()); Uint8ClampedArray pxls = pxlsDat.getData(); int totalPixels = pxlsDat.getWidth() * pxlsDat.getHeight(); TeaVMUtils.freeDataURL(toLoad.getSrc()); - if(pxls.getByteLength() < totalPixels << 2) { + if (pxls.getByteLength() < totalPixels << 2) { ret.complete(null); return; } - ret.complete(new ImageData(pxlsDat.getWidth(), pxlsDat.getHeight(), TeaVMUtils.wrapIntArray(Int32Array.create(pxls.getBuffer())), true)); + ret.complete(new ImageData(pxlsDat.getWidth(), pxlsDat.getHeight(), + TeaVMUtils.wrapIntArrayBuffer(pxls.getBuffer()), true)); } }); toLoad.addEventListener("error", new EventListener() { @@ -127,11 +140,11 @@ public class PlatformAssets { } }); String src = TeaVMUtils.getDataURL(data, "image/png"); - if(src != null) { + if (src != null) { toLoad.setSrc(src); - }else { + } else { ret.complete(null); } } - + } diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java index 38669ab..c2a1a56 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAudio.java @@ -225,8 +225,7 @@ public class PlatformAudio { byte[] file = PlatformAssets.getResourceBytes(filename); if (file == null) return null; - buffer = new BrowserAudioResource( - decodeAudioAsync(TeaVMUtils.unwrapUnsignedByteArray(file).getBuffer(), filename)); + buffer = new BrowserAudioResource(decodeAudioAsync(TeaVMUtils.unwrapArrayBuffer(file), filename)); if (holdInCache) { synchronized (soundCache) { soundCache.put(filename, buffer); diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformNetworking.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformNetworking.java index 9731650..999a7c9 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformNetworking.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformNetworking.java @@ -12,7 +12,6 @@ import org.teavm.jso.dom.events.Event; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.dom.events.MessageEvent; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import org.teavm.jso.websocket.WebSocket; import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMServerQuery; @@ -132,7 +131,7 @@ public class PlatformNetworking { } } else { synchronized (readPackets) { - readPackets.add(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray()))); + readPackets.add(TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray())); } } } @@ -195,7 +194,7 @@ public class PlatformNetworking { public static void writePlayPacket(byte[] pkt) { if (sock != null && !sockIsConnecting) { - nativeBinarySend(sock, TeaVMUtils.unwrapUnsignedByteArray(pkt).getBuffer()); + nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer(pkt)); } } diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java index c946b3d..aa2eceb 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java @@ -28,7 +28,6 @@ import org.teavm.jso.dom.html.HTMLCanvasElement; import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLElement; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import org.teavm.jso.webaudio.MediaStream; import org.teavm.jso.webgl.WebGLFramebuffer; @@ -56,25 +55,31 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack; import net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums; -import net.lax1dude.eaglercraft.v1_8.internal.RenderResolution; - /** - * Copyright (c) 2022-2024 lax1dude, hoosiertransfer, ayunami2000. All Rights Reserved. + * Copyright (c) 2022-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. * */ public class PlatformRuntime { - + static final Logger logger = LogManager.getLogger("BrowserRuntime"); public static Window win = null; @@ -82,89 +87,90 @@ public class PlatformRuntime { public static HTMLElement parent = null; public static HTMLCanvasElement canvas = null; public static WebGL2RenderingContext webgl = null; - + static WebGLFramebuffer mainFramebuffer = null; public static void create() { win = Window.current(); doc = win.getDocument(); DebugConsoleWindow.initialize(win); - + logger.info("Creating main game canvas"); - + parent = doc.getElementById(ClientMain.configRootElementId); - if(parent == null) { - throw new RuntimeInitializationFailureException("Root element \"" + ClientMain.configRootElementId + "\" was not found in this document!"); + if (parent == null) { + throw new RuntimeInitializationFailureException( + "Root element \"" + ClientMain.configRootElementId + "\" was not found in this document!"); } CSSStyleDeclaration style = parent.getStyle(); style.setProperty("overflowX", "hidden"); style.setProperty("overflowY", "hidden"); - + canvas = (HTMLCanvasElement) doc.createElement("canvas"); - + style = canvas.getStyle(); style.setProperty("width", "100%"); style.setProperty("height", "100%"); style.setProperty("image-rendering", "pixelated"); - + double r = win.getDevicePixelRatio(); - int iw = (int)(parent.getClientWidth()); - int ih = (int)(parent.getClientHeight()); - int sw = (int)(r * iw); - int sh = (int)(r * ih); + int iw = (int) (parent.getClientWidth()); + int ih = (int) (parent.getClientHeight()); + int sw = (int) (r * iw); + int sh = (int) (r * ih); canvas.setWidth(sw); canvas.setHeight(sh); - + parent.appendChild(canvas); - + try { PlatformInput.initHooks(win, canvas); - }catch(Throwable t) { + } catch (Throwable t) { throw new RuntimeInitializationFailureException("Exception while registering window event handlers", t); } - + try { doc.exitPointerLock(); - }catch(Throwable t) { + } catch (Throwable t) { throw new PlatformIncompatibleException("Mouse cursor lock is not available on this device!"); } logger.info("Creating WebGL context"); - + JSObject webgl_ = canvas.getContext("webgl2", youEagler()); - if(webgl_ == null) { + if (webgl_ == null) { throw new PlatformIncompatibleException("WebGL 2.0 is not supported on this device!"); } - + webgl = (WebGL2RenderingContext) webgl_; PlatformOpenGL.setCurrentContext(webgl); - + mainFramebuffer = webgl.createFramebuffer(); PlatformInput.initFramebuffer(webgl, mainFramebuffer, sw, sh); - + EarlyLoadScreen.paintScreen(); - + EPKFileEntry[] epkFiles = ClientMain.configEPKFiles; - - for(int i = 0; i < epkFiles.length; ++i) { + + for (int i = 0; i < epkFiles.length; ++i) { String url = epkFiles[i].url; String logURL = url.startsWith("data:") ? "" : url; - + logger.info("Downloading: {}", logURL); - + ArrayBuffer epkFileData = downloadRemoteURI(url); - - if(epkFileData == null) { + + if (epkFileData == null) { throw new RuntimeInitializationFailureException("Could not download EPK file \"" + url + "\""); } - + logger.info("Decompressing: {}", logURL); - + try { EPKLoader.loadEPK(epkFileData, epkFiles[i].path, PlatformAssets.assets); - }catch(Throwable t) { + } catch (Throwable t) { throw new RuntimeInitializationFailureException("Could not extract EPK file \"" + url + "\"", t); } } @@ -178,14 +184,14 @@ public class PlatformRuntime { try { PlatformFilesystem.initialize(getClientConfigAdapter().getResourcePacksDB()); EaglerFolderResourcePack.setSupported(true); - }catch(FilesystemDatabaseLockedException t) { + } catch (FilesystemDatabaseLockedException t) { logger.error("Could not initialize filesystem, database is locked!"); - }catch(Throwable t) { + } catch (Throwable t) { logger.error("Could not initialize filesystem, encountered an exception!"); logger.error(t); } - if(!EaglerFolderResourcePack.isSupported()) { + if (!EaglerFolderResourcePack.isSupported()) { logger.error("Resource packs will be disabled for this session"); } @@ -195,7 +201,7 @@ public class PlatformRuntime { PlatformAudio.initialize(); - if(finalLoadScreen != null) { + if (finalLoadScreen != null) { EarlyLoadScreen.paintFinal(finalLoadScreen); } @@ -205,10 +211,10 @@ public class PlatformRuntime { FixWebMDurationJS.checkOldScriptStillLoaded(); } - - @JSBody(params = { }, script = "return {antialias: false, depth: false, powerPreference: \"high-performance\", desynchronized: true, preserveDrawingBuffer: false, premultipliedAlpha: false, alpha: false, stencil: false, failIfMajorPerformanceCaveat: false, xrCompatible: false, xrWebGLLayer: false};") + + @JSBody(params = {}, script = "return {antialias: false, depth: false, powerPreference: \"high-performance\", desynchronized: true, preserveDrawingBuffer: false, premultipliedAlpha: false, alpha: false, stencil: false, failIfMajorPerformanceCaveat: false, xrCompatible: false, xrWebGLLayer: false};") public static native JSObject youEagler(); - + public static class RuntimeInitializationFailureException extends IllegalStateException { public RuntimeInitializationFailureException(String message, Throwable cause) { @@ -218,15 +224,15 @@ public class PlatformRuntime { public RuntimeInitializationFailureException(String s) { super(s); } - + } - + public static class PlatformIncompatibleException extends IllegalStateException { public PlatformIncompatibleException(String s) { super(s); } - + } public static void destroy() { @@ -241,7 +247,7 @@ public class PlatformRuntime { return EnumPlatformAgent.getFromUA(getUserAgentString()); } - @JSBody(params = { }, script = "return window.navigator.userAgent;") + @JSBody(params = {}, script = "return window.navigator.userAgent;") public static native String getUserAgentString(); public static EnumPlatformOS getPlatformOS() { @@ -300,19 +306,19 @@ public class PlatformRuntime { } public static void freeByteBuffer(ByteBuffer byteBuffer) { - + } - + public static void freeIntBuffer(IntBuffer intBuffer) { - + } - + public static void freeFloatBuffer(FloatBuffer floatBuffer) { - + } public static void downloadRemoteURIByteArray(String assetPackageURI, final Consumer cb) { - downloadRemoteURI(assetPackageURI, arr -> cb.accept(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(arr)))); + downloadRemoteURI(assetPackageURI, arr -> cb.accept(TeaVMUtils.wrapByteArrayBuffer(arr))); } public static void downloadRemoteURI(String assetPackageURI, final Consumer cb) { @@ -333,7 +339,7 @@ public class PlatformRuntime { } }); } - + @Async public static native ArrayBuffer downloadRemoteURIOld(String assetPackageURI); @@ -341,34 +347,34 @@ public class PlatformRuntime { final XMLHttpRequest request = XMLHttpRequest.create(); request.setResponseType("arraybuffer"); request.open("GET", assetPackageURI, true); - + TeaVMUtils.addEventListener(request, "load", new EventListener() { @Override public void handleEvent(Event evt) { int stat = request.getStatus(); - if(stat == 0 || (stat >= 200 && stat < 400)) { - cb.complete((ArrayBuffer)request.getResponse()); - }else { + if (stat == 0 || (stat >= 200 && stat < 400)) { + cb.complete((ArrayBuffer) request.getResponse()); + } else { cb.complete(null); } } }); - + TeaVMUtils.addEventListener(request, "error", new EventListener() { @Override public void handleEvent(Event evt) { cb.complete(null); } }); - + request.send(); } - + @JSFunctor private static interface FetchHandler extends JSObject { void onFetch(ArrayBuffer data); } - + @JSBody(params = { "uri", "forceCache", "callback" }, script = "fetch(uri, { cache: forceCache, mode: \"cors\" })" + ".then(function(res) { return res.arrayBuffer(); }).then(function(arr) { callback(arr); })" + ".catch(function(err) { console.error(err); callback(null); });") @@ -381,14 +387,15 @@ public class PlatformRuntime { @Async public static native ArrayBuffer downloadRemoteURI(String assetPackageURI, boolean forceCache); - private static void downloadRemoteURI(String assetPackageURI, boolean useCache, final AsyncCallback cb) { + private static void downloadRemoteURI(String assetPackageURI, boolean useCache, + final AsyncCallback cb) { doFetchDownload(assetPackageURI, useCache ? "force-cache" : "no-store", cb::complete); } - + public static boolean isDebugRuntime() { return false; } - + public static void writeCrashReport(String crashDump) { ClientMain.showCrashScreen(crashDump); } @@ -396,22 +403,22 @@ public class PlatformRuntime { public static void removeEventHandlers() { try { PlatformInput.removeEventHandlers(); - }catch(Throwable t) { + } catch (Throwable t) { } } - + public static void getStackTrace(Throwable t, Consumer ret) { JSObject o = JSExceptions.getJSException(t); - if(o != null) { + if (o != null) { try { JSError err = o.cast(); String stack = err.getStack(); - if(stack != null) { + if (stack != null) { String[] stackElements = stack.split("[\\r\\n]+"); - if(stackElements.length > 0) { - for(int i = 0; i < stackElements.length; ++i) { + if (stackElements.length > 0) { + for (int i = 0; i < stackElements.length; ++i) { String str = stackElements[i].trim(); - if(str.startsWith("at ")) { + if (str.startsWith("at ")) { str = str.substring(3).trim(); } ret.accept(str); @@ -419,31 +426,31 @@ public class PlatformRuntime { return; } } - }catch(Throwable tt) { + } catch (Throwable tt) { ret.accept("[ error: " + t.toString() + " ]"); } } getFallbackStackTrace(t, ret); } - + private static void getFallbackStackTrace(Throwable t, Consumer ret) { StackTraceElement[] el = t.getStackTrace(); - if(el.length > 0) { - for(int i = 0; i < el.length; ++i) { + if (el.length > 0) { + for (int i = 0; i < el.length; ++i) { ret.accept(el[i].toString()); } - }else { + } else { ret.accept("[no stack trace]"); } } - + @JSBody(params = { "o" }, script = "console.error(o);") public static native void printNativeExceptionToConsoleTeaVM(JSObject o); - + public static boolean printJSExceptionIfBrowser(Throwable t) { - if(t != null) { + if (t != null) { JSObject o = JSExceptions.getJSException(t); - if(o != null) { + if (o != null) { printNativeExceptionToConsoleTeaVM(o); return true; } @@ -470,33 +477,33 @@ public class PlatformRuntime { public static long freeMemory() { return 1073741824l; } - + public static String getCallingClass(int backTrace) { return null; } - + public static OutputStream newDeflaterOutputStream(OutputStream os) throws IOException { return new DeflaterOutputStream(os); } - + public static OutputStream newGZIPOutputStream(OutputStream os) throws IOException { return new GZIPOutputStream(os); } - + public static InputStream newInflaterInputStream(InputStream is) throws IOException { return new InflaterInputStream(is); } - + public static InputStream newGZIPInputStream(InputStream is) throws IOException { return new GZIPInputStream(is); } - - @JSBody(params = { }, script = "return window.location.protocol && window.location.protocol.toLowerCase().startsWith(\"https\");") + + @JSBody(params = {}, script = "return window.location.protocol && window.location.protocol.toLowerCase().startsWith(\"https\");") public static native boolean requireSSL(); - - @JSBody(params = { }, script = "return window.location.protocol && window.location.protocol.toLowerCase().startsWith(\"file\");") + + @JSBody(params = {}, script = "return window.location.protocol && window.location.protocol.toLowerCase().startsWith(\"file\");") public static native boolean isOfflineDownloadURL(); - + public static IClientConfigAdapter getClientConfigAdapter() { return TeaVMClientConfigAdapter.instance; } @@ -513,16 +520,18 @@ public class PlatformRuntime { return recording && canRec; } - @JSBody(params = { "canvas", "audio" }, script = "const stream = canvas.captureStream(); stream.addTrack(audio.getTracks()[0]); return stream;") + @JSBody(params = { "canvas", + "audio" }, script = "const stream = canvas.captureStream(); stream.addTrack(audio.getTracks()[0]); return stream;") private static native MediaStream captureStreamAndAddAudio(HTMLCanvasElement canvas, MediaStream audio); - @JSBody(params = { "stream" }, script = "const rec = new MediaRecorder(stream, { mimeType: MediaRecorder.isTypeSupported(\"video/webm;codecs=vp9,opus\") ? \"video/webm;codecs=vp9,opus\" : \"video/webm\" }); rec.start(); return rec;") + @JSBody(params = { + "stream" }, script = "const rec = new MediaRecorder(stream, { mimeType: MediaRecorder.isTypeSupported(\"video/webm;codecs=vp9,opus\") ? \"video/webm;codecs=vp9,opus\" : \"video/webm\" }); rec.start(); return rec;") private static native JSObject createMediaRecorder(MediaStream stream); @JSBody(params = { "rec" }, script = "rec.stop();") private static native void stopRec(JSObject rec); - @JSBody(params = { }, script = "return \"MediaRecorder\" in window;") + @JSBody(params = {}, script = "return \"MediaRecorder\" in window;") private static native boolean canRec(); public static boolean recSupported() { @@ -553,7 +562,8 @@ public class PlatformRuntime { void onMedia(MediaStream stream); } - @JSBody(params = { "cb" }, script = "if (\"navigator\" in window && \"mediaDevices\" in window.navigator && \"getUserMedia\" in window.navigator.mediaDevices) { try { window.navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(function(stream) { cb(stream); }).catch(function(err) { console.error(err); cb(null); }); } catch(e) { console.error(\"getUserMedia Error!\"); cb(null); } } else { console.error(\"No getUserMedia!\"); cb(null); }") + @JSBody(params = { + "cb" }, script = "if (\"navigator\" in window && \"mediaDevices\" in window.navigator && \"getUserMedia\" in window.navigator.mediaDevices) { try { window.navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(function(stream) { cb(stream); }).catch(function(err) { console.error(err); cb(null); }); } catch(e) { console.error(\"getUserMedia Error!\"); cb(null); } } else { console.error(\"No getUserMedia!\"); cb(null); }") private static native void getMic0(MediaHandler cb); @Async @@ -610,7 +620,8 @@ public class PlatformRuntime { FixWebMDurationJS.getRecUrl(evt, (int) (System.currentTimeMillis() - startTime), url -> { HTMLAnchorElement a = (HTMLAnchorElement) doc.createElement("a"); dateInstance.setTime(startTime); - a.setDownload(EaglercraftVersion.mainMenuStringB + " - " + EaglerProfile.getName() + " - " + fmt.format(dateInstance) + ".webm"); + a.setDownload(EaglercraftVersion.mainMenuStringB + " - " + EaglerProfile.getName() + " - " + + fmt.format(dateInstance) + ".webm"); a.setHref(url); a.click(); TeaVMUtils.freeDataURL(url); @@ -624,7 +635,7 @@ public class PlatformRuntime { } public static long randomSeed() { - return (long)(Math.random() * 9007199254740991.0); + return (long) (Math.random() * 9007199254740991.0); } private static String currentThreadName = "main"; diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformUpdateSvc.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformUpdateSvc.java index 7a1dcc0..24e2621 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformUpdateSvc.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformUpdateSvc.java @@ -2,7 +2,6 @@ package net.lax1dude.eaglercraft.v1_8.internal; import org.teavm.jso.JSBody; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUpdateThread; @@ -15,14 +14,21 @@ import net.lax1dude.eaglercraft.v1_8.update.UpdateProgressStruct; /** * 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. * @@ -36,10 +42,10 @@ public class PlatformUpdateSvc { private static final UpdateProgressStruct progressStruct = new UpdateProgressStruct(); - @JSBody(params = { }, script = "if(typeof window.eaglercraftXClientSignature !== \"string\") return null; var ret = window.eaglercraftXClientSignature; window.eaglercraftXClientSignature = null; return ret;") + @JSBody(params = {}, script = "if(typeof window.eaglercraftXClientSignature !== \"string\") return null; var ret = window.eaglercraftXClientSignature; window.eaglercraftXClientSignature = null; return ret;") private static native String grabEaglercraftXClientSignature(); - @JSBody(params = { }, script = "if(typeof window.eaglercraftXClientBundle !== \"string\") return null; var ret = window.eaglercraftXClientBundle; window.eaglercraftXClientBundle = null; return ret;") + @JSBody(params = {}, script = "if(typeof window.eaglercraftXClientBundle !== \"string\") return null; var ret = window.eaglercraftXClientBundle; window.eaglercraftXClientBundle = null; return ret;") private static native String grabEaglercraftXClientBundle(); public static Thread updateThread = null; @@ -54,15 +60,15 @@ public class PlatformUpdateSvc { } private static byte[] loadClientData(String url) { - if(url == null) { + if (url == null) { return null; } ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(url); - if(buf == null) { + if (buf == null) { logger.error("Failed to download client bundle or signature URL!"); return null; } - return TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buf)); + return TeaVMUtils.wrapByteArrayBuffer(buf); } public static byte[] getClientSignatureData() { @@ -74,11 +80,11 @@ public class PlatformUpdateSvc { } public static void startClientUpdateFrom(UpdateCertificate clientUpdate) { - if(updateThread == null || !updateThread.isAlive()) { + if (updateThread == null || !updateThread.isAlive()) { updateThread = new Thread(new TeaVMUpdateThread(clientUpdate, progressStruct), "EaglerUpdateThread"); updateThread.setDaemon(true); updateThread.start(); - }else { + } else { logger.error("Tried to start a new download while the current download thread was still alive!"); } } diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebRTC.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebRTC.java index 234fc68..30f4443 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebRTC.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformWebRTC.java @@ -24,7 +24,6 @@ import org.teavm.jso.dom.events.Event; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.json.JSON; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import org.teavm.jso.websocket.WebSocket; import com.google.common.collect.LinkedListMultimap; @@ -37,14 +36,21 @@ import java.util.*; /** * Copyright (c) 2022-2024 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. * @@ -77,7 +83,8 @@ public class PlatformWebRTC { @JSBody(params = { "item" }, script = "return item.candidate.candidate;") static native String getCandidate(JSObject item); - @JSBody(params = { "iceServers" }, script = "return new RTCPeerConnection({ iceServers: JSON.parse(iceServers), optional: [ { DtlsSrtpKeyAgreement: true } ] });") + @JSBody(params = { + "iceServers" }, script = "return new RTCPeerConnection({ iceServers: JSON.parse(iceServers), optional: [ { DtlsSrtpKeyAgreement: true } ] });") static native JSObject createRTCPeerConnection(String iceServers); @JSBody(params = { "peerConnection", "name" }, script = "return peerConnection.createDataChannel(name);") @@ -95,19 +102,24 @@ public class PlatformWebRTC { @JSBody(params = { "peerConnection", "h1", "h2" }, script = "return peerConnection.createOffer(h1, h2);") static native void createOffer(JSObject peerConnection, DescHandler h1, ErrorHandler h2); - @JSBody(params = { "peerConnection", "desc", "h1", "h2" }, script = "return peerConnection.setLocalDescription(desc, h1, h2);") + @JSBody(params = { "peerConnection", "desc", "h1", + "h2" }, script = "return peerConnection.setLocalDescription(desc, h1, h2);") static native void setLocalDescription(JSObject peerConnection, JSObject desc, EmptyHandler h1, ErrorHandler h2); - @JSBody(params = { "peerConnection", "str" }, script = "return peerConnection.setRemoteDescription(JSON.parse(str));") + @JSBody(params = { "peerConnection", + "str" }, script = "return peerConnection.setRemoteDescription(JSON.parse(str));") static native void setRemoteDescription(JSObject peerConnection, String str); - @JSBody(params = { "peerConnection", "str" }, script = "const candidateList = JSON.parse(str); for (let i = 0; i < candidateList.length; ++i) { peerConnection.addIceCandidate(candidateList[i]); }; return null;") + @JSBody(params = { "peerConnection", + "str" }, script = "const candidateList = JSON.parse(str); for (let i = 0; i < candidateList.length; ++i) { peerConnection.addIceCandidate(candidateList[i]); }; return null;") static native void addIceCandidates(JSObject peerConnection, String str); - @JSBody(params = { "peerConnection", "str" }, script = "const candidateList = JSON.parse(str); for (let i = 0; i < candidateList.length; ++i) { peerConnection.addIceCandidate(new RTCIceCandidate(candidateList[i])); }; return null;") + @JSBody(params = { "peerConnection", + "str" }, script = "const candidateList = JSON.parse(str); for (let i = 0; i < candidateList.length; ++i) { peerConnection.addIceCandidate(new RTCIceCandidate(candidateList[i])); }; return null;") static native void addIceCandidates2(JSObject peerConnection, String str); - @JSBody(params = { "peerConnection", "str", "h1", "h2" }, script = "return peerConnection.setRemoteDescription(JSON.parse(str), h1, h2);") + @JSBody(params = { "peerConnection", "str", "h1", + "h2" }, script = "return peerConnection.setRemoteDescription(JSON.parse(str), h1, h2);") static native void setRemoteDescription2(JSObject peerConnection, String str, EmptyHandler h1, ErrorHandler h2); @JSBody(params = { "peerConnection", "h1", "h2" }, script = "return peerConnection.createAnswer(h1, h2);") @@ -169,7 +181,7 @@ public class PlatformWebRTC { } catch (Throwable e) { signalRemoteDisconnect(false); } - }else { + } else { signalRemoteDisconnect(false); } } @@ -200,18 +212,18 @@ public class PlatformWebRTC { final Object[] evtHandler = new Object[1]; evtHandler[0] = (EventListener) evt -> { if (!iceCandidates.isEmpty()) { - Window.setTimeout(() -> ((EventListener)evtHandler[0]).handleEvent(evt), 1); + Window.setTimeout(() -> ((EventListener) evtHandler[0]).handleEvent(evt), 1); return; } clientDataChannelClosed = false; clientDataChannelOpen = true; }; - TeaVMUtils.addEventListener(dataChannel, "open", (EventListener)evtHandler[0]); + TeaVMUtils.addEventListener(dataChannel, "open", (EventListener) evtHandler[0]); TeaVMUtils.addEventListener(dataChannel, "message", (EventListener) evt -> { - synchronized(clientLANPacketBuffer) { - clientLANPacketBuffer.add(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(getData(evt)))); + synchronized (clientLANPacketBuffer) { + clientLANPacketBuffer.add(TeaVMUtils.wrapByteArrayBuffer(getData(evt))); } }); @@ -270,7 +282,8 @@ public class PlatformWebRTC { if (peerConnection != null) { closeIt(peerConnection); } - if (!quiet) clientDataChannelClosed = true; + if (!quiet) + clientDataChannelClosed = true; readyState = READYSTATE_DISCONNECTED; } } @@ -296,8 +309,9 @@ public class PlatformWebRTC { if (iceCandidates.isEmpty()) { Window.setTimeout(() -> { if (peerConnection != null && !"disconnected".equals(getConnectionState(peerConnection))) { - LANPeerEvent.LANPeerICECandidateEvent e = new LANPeerEvent.LANPeerICECandidateEvent(peerId, JSONWriter.valueToString(iceCandidates)); - synchronized(serverLANEventBuffer) { + LANPeerEvent.LANPeerICECandidateEvent e = new LANPeerEvent.LANPeerICECandidateEvent( + peerId, JSONWriter.valueToString(iceCandidates)); + synchronized (serverLANEventBuffer) { serverLANEventBuffer.put(peerId, e); } iceCandidates.clear(); @@ -314,42 +328,46 @@ public class PlatformWebRTC { final Object[] evtHandler = new Object[1]; evtHandler[0] = (EventListener) evt -> { if (!iceCandidates.isEmpty()) { - Window.setTimeout(() -> ((EventListener)evtHandler[0]).handleEvent(evt), 1); + Window.setTimeout(() -> ((EventListener) evtHandler[0]).handleEvent(evt), 1); return; } - if (getChannel(evt) == null) return; + if (getChannel(evt) == null) + return; JSObject dataChannel = getChannel(evt); - synchronized(fuckTeaVM) { + synchronized (fuckTeaVM) { fuckTeaVM.put(peerId, dataChannel); } - synchronized(serverLANEventBuffer) { + synchronized (serverLANEventBuffer) { serverLANEventBuffer.put(peerId, new LANPeerEvent.LANPeerDataChannelEvent(peerId)); } TeaVMUtils.addEventListener(dataChannel, "message", (EventListener) evt2 -> { - LANPeerEvent.LANPeerPacketEvent e = new LANPeerEvent.LANPeerPacketEvent(peerId, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(getData(evt2)))); - synchronized(serverLANEventBuffer) { + LANPeerEvent.LANPeerPacketEvent e = new LANPeerEvent.LANPeerPacketEvent(peerId, + TeaVMUtils.wrapByteArrayBuffer(getData(evt2))); + synchronized (serverLANEventBuffer) { serverLANEventBuffer.put(peerId, e); } }); }; - - TeaVMUtils.addEventListener(peerConnection, "datachannel", (EventListener)evtHandler[0]); + + TeaVMUtils.addEventListener(peerConnection, "datachannel", (EventListener) evtHandler[0]); TeaVMUtils.addEventListener(peerConnection, "connectionstatechange", (EventListener) evt -> { String connectionState = getConnectionState(peerConnection); if ("disconnected".equals(connectionState)) { client.signalRemoteDisconnect(peerId); } else if ("connected".equals(connectionState)) { - if (client.peerState != PEERSTATE_SUCCESS) client.peerState = PEERSTATE_SUCCESS; + if (client.peerState != PEERSTATE_SUCCESS) + client.peerState = PEERSTATE_SUCCESS; } else if ("failed".equals(connectionState)) { - if (client.peerState == PEERSTATE_LOADING) client.peerState = PEERSTATE_FAILED; + if (client.peerState == PEERSTATE_LOADING) + client.peerState = PEERSTATE_FAILED; client.signalRemoteDisconnect(peerId); } }); } public void disconnect() { - synchronized(fuckTeaVM) { + synchronized (fuckTeaVM) { if (fuckTeaVM.get(peerId) != null) { closeIt(fuckTeaVM.get(peerId)); fuckTeaVM.remove(peerId); @@ -365,30 +383,37 @@ public class PlatformWebRTC { if (remoteDesc.has("type") && "offer".equals(remoteDesc.getString("type"))) { createAnswer(peerConnection, desc -> { setLocalDescription(peerConnection, desc, () -> { - LANPeerEvent.LANPeerDescriptionEvent e = new LANPeerEvent.LANPeerDescriptionEvent(peerId, JSON.stringify(desc)); - synchronized(serverLANEventBuffer) { + LANPeerEvent.LANPeerDescriptionEvent e = new LANPeerEvent.LANPeerDescriptionEvent( + peerId, JSON.stringify(desc)); + synchronized (serverLANEventBuffer) { serverLANEventBuffer.put(peerId, e); } - if (client.peerStateDesc != PEERSTATE_SUCCESS) client.peerStateDesc = PEERSTATE_SUCCESS; + if (client.peerStateDesc != PEERSTATE_SUCCESS) + client.peerStateDesc = PEERSTATE_SUCCESS; }, err -> { - logger.error("Failed to set local description for \"{}\"! {}", peerId, err.getMessage()); - if (client.peerStateDesc == PEERSTATE_LOADING) client.peerStateDesc = PEERSTATE_FAILED; + logger.error("Failed to set local description for \"{}\"! {}", peerId, + err.getMessage()); + if (client.peerStateDesc == PEERSTATE_LOADING) + client.peerStateDesc = PEERSTATE_FAILED; client.signalRemoteDisconnect(peerId); }); }, err -> { logger.error("Failed to create answer for \"{}\"! {}", peerId, err.getMessage()); - if (client.peerStateDesc == PEERSTATE_LOADING) client.peerStateDesc = PEERSTATE_FAILED; + if (client.peerStateDesc == PEERSTATE_LOADING) + client.peerStateDesc = PEERSTATE_FAILED; client.signalRemoteDisconnect(peerId); }); } }, err -> { logger.error("Failed to set remote description for \"{}\"! {}", peerId, err.getMessage()); - if (client.peerStateDesc == PEERSTATE_LOADING) client.peerStateDesc = PEERSTATE_FAILED; + if (client.peerStateDesc == PEERSTATE_LOADING) + client.peerStateDesc = PEERSTATE_FAILED; client.signalRemoteDisconnect(peerId); }); } catch (Throwable err) { logger.error("Failed to parse remote description for \"{}\"! {}", peerId, err.getMessage()); - if (client.peerStateDesc == PEERSTATE_LOADING) client.peerStateDesc = PEERSTATE_FAILED; + if (client.peerStateDesc == PEERSTATE_LOADING) + client.peerStateDesc = PEERSTATE_FAILED; client.signalRemoteDisconnect(peerId); } } @@ -396,10 +421,12 @@ public class PlatformWebRTC { public void addICECandidate(String candidates) { try { addIceCandidates2(peerConnection, candidates); - if (client.peerStateIce != PEERSTATE_SUCCESS) client.peerStateIce = PEERSTATE_SUCCESS; + if (client.peerStateIce != PEERSTATE_SUCCESS) + client.peerStateIce = PEERSTATE_SUCCESS; } catch (Throwable err) { logger.error("Failed to parse ice candidate for \"{}\"! {}", peerId, err.getMessage()); - if (client.peerStateIce == PEERSTATE_LOADING) client.peerStateIce = PEERSTATE_FAILED; + if (client.peerStateIce == PEERSTATE_LOADING) + client.peerStateIce = PEERSTATE_FAILED; client.signalRemoteDisconnect(peerId); } } @@ -436,8 +463,9 @@ public class PlatformWebRTC { LANPeer thePeer = this.peerList.get(peerId); if (thePeer != null) { boolean b = false; - synchronized(fuckTeaVM) { - if (fuckTeaVM.get(thePeer.peerId) != null && "open".equals(getReadyState(fuckTeaVM.get(thePeer.peerId)))) { + synchronized (fuckTeaVM) { + if (fuckTeaVM.get(thePeer.peerId) != null + && "open".equals(getReadyState(fuckTeaVM.get(thePeer.peerId)))) { try { sendIt(fuckTeaVM.get(thePeer.peerId), buffer); } catch (Throwable e) { @@ -447,7 +475,7 @@ public class PlatformWebRTC { b = true; } } - if(b) { + if (b) { signalRemoteDisconnect(peerId); } } @@ -462,9 +490,11 @@ public class PlatformWebRTC { JSObject peerConnection = createRTCPeerConnection(JSONWriter.valueToString(iceServers)); LANPeer peerInstance = new LANPeer(this, peerId, peerConnection); peerList.put(peerId, peerInstance); - if (peerStateConnect != PEERSTATE_SUCCESS) peerStateConnect = PEERSTATE_SUCCESS; + if (peerStateConnect != PEERSTATE_SUCCESS) + peerStateConnect = PEERSTATE_SUCCESS; } catch (Throwable e) { - if (peerStateConnect == PEERSTATE_LOADING) peerStateConnect = PEERSTATE_FAILED; + if (peerStateConnect == PEERSTATE_LOADING) + peerStateConnect = PEERSTATE_FAILED; } } @@ -488,28 +518,31 @@ public class PlatformWebRTC { if (thePeer != null) { try { thePeer.disconnect(); - } catch (Throwable ignored) {} - synchronized(serverLANEventBuffer) { - serverLANEventBuffer.put(thePeer.peerId, new LANPeerEvent.LANPeerDisconnectEvent(thePeer.peerId)); + } catch (Throwable ignored) { + } + synchronized (serverLANEventBuffer) { + serverLANEventBuffer.put(thePeer.peerId, + new LANPeerEvent.LANPeerDisconnectEvent(thePeer.peerId)); } } } peerList.clear(); - synchronized(fuckTeaVM) { + synchronized (fuckTeaVM) { fuckTeaVM.clear(); } return; } LANPeer thePeer = peerList.get(peerId); - if(thePeer != null) { + if (thePeer != null) { peerList.remove(peerId); try { thePeer.disconnect(); - } catch (Throwable ignored) {} - synchronized(fuckTeaVM) { + } catch (Throwable ignored) { + } + synchronized (fuckTeaVM) { fuckTeaVM.remove(peerId); } - synchronized(serverLANEventBuffer) { + synchronized (serverLANEventBuffer) { serverLANEventBuffer.put(thePeer.peerId, new LANPeerEvent.LANPeerDisconnectEvent(peerId)); } } @@ -538,12 +571,8 @@ public class PlatformWebRTC { @JSBody(params = { "obj" }, script = "return typeof obj === \"string\";") private static native boolean isString(JSObject obj); - private static ArrayBuffer convertToArrayBuffer(byte[] arr) { - return TeaVMUtils.unwrapUnsignedByteArray(arr).getBuffer(); - } - - private static final Map relayQueryLimited = new HashMap<>(); - private static final Map relayQueryBlocked = new HashMap<>(); + private static final Map relayQueryLimited = new HashMap<>(); + private static final Map relayQueryBlocked = new HashMap<>(); private static class RelayQueryImpl implements RelayQuery { @@ -576,7 +605,7 @@ public class PlatformWebRTC { s.setBinaryType("arraybuffer"); open = true; failed = false; - }catch(Throwable t) { + } catch (Throwable t) { connectionOpenedAt = 0l; sock = null; open = false; @@ -587,9 +616,8 @@ public class PlatformWebRTC { sock.onOpen(evt -> { try { connectionPingStart = System.currentTimeMillis(); - PlatformNetworking.nativeBinarySend(sock, convertToArrayBuffer( - IPacket.writePacket(new IPacket00Handshake(0x03, RelayManager.preferredRelayVersion, "")) - )); + PlatformNetworking.nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer( + IPacket.writePacket(new IPacket00Handshake(0x03, RelayManager.preferredRelayVersion, "")))); } catch (IOException e) { logger.error(e.toString()); sock.close(); @@ -597,33 +625,33 @@ public class PlatformWebRTC { } }); sock.onMessage(evt -> { - if(evt.getData() != null && !isString(evt.getData())) { + if (evt.getData() != null && !isString(evt.getData())) { hasRecievedAnyData = true; - byte[] arr = TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray())); - if(arr.length == 2 && arr[0] == (byte)0xFC) { + byte[] arr = TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray()); + if (arr.length == 2 && arr[0] == (byte) 0xFC) { long millis = System.currentTimeMillis(); - if(arr[1] == (byte)0x00 || arr[1] == (byte)0x01) { + if (arr[1] == (byte) 0x00 || arr[1] == (byte) 0x01) { rateLimitStatus = RateLimit.BLOCKED; relayQueryLimited.put(RelayQueryImpl.this.uri, millis); - }else if(arr[1] == (byte)0x02) { + } else if (arr[1] == (byte) 0x02) { rateLimitStatus = RateLimit.NOW_LOCKED; relayQueryLimited.put(RelayQueryImpl.this.uri, millis); relayQueryBlocked.put(RelayQueryImpl.this.uri, millis); - }else { + } else { rateLimitStatus = RateLimit.LOCKED; relayQueryBlocked.put(RelayQueryImpl.this.uri, millis); } failed = true; open = false; sock.close(); - }else { - if(open) { + } else { + if (open) { try { IPacket pkt = IPacket.readPacket(new DataInputStream(new EaglerInputStream(arr))); - if(pkt instanceof IPacket69Pong) { - IPacket69Pong ipkt = (IPacket69Pong)pkt; + if (pkt instanceof IPacket69Pong) { + IPacket69Pong ipkt = (IPacket69Pong) pkt; versError = VersionMismatch.COMPATIBLE; - if(connectionPingTimer == -1) { + if (connectionPingTimer == -1) { connectionPingTimer = System.currentTimeMillis() - connectionPingStart; } vers = ipkt.protcolVersion; @@ -632,21 +660,21 @@ public class PlatformWebRTC { open = false; failed = false; sock.close(); - }else if(pkt instanceof IPacket70SpecialUpdate) { - IPacket70SpecialUpdate ipkt = (IPacket70SpecialUpdate)pkt; - if(ipkt.operation == IPacket70SpecialUpdate.OPERATION_UPDATE_CERTIFICATE) { + } else if (pkt instanceof IPacket70SpecialUpdate) { + IPacket70SpecialUpdate ipkt = (IPacket70SpecialUpdate) pkt; + if (ipkt.operation == IPacket70SpecialUpdate.OPERATION_UPDATE_CERTIFICATE) { UpdateService.addCertificateToSet(ipkt.updatePacket); } - }else if(pkt instanceof IPacketFFErrorCode) { - IPacketFFErrorCode ipkt = (IPacketFFErrorCode)pkt; - if(ipkt.code == IPacketFFErrorCode.TYPE_PROTOCOL_VERSION) { + } else if (pkt instanceof IPacketFFErrorCode) { + IPacketFFErrorCode ipkt = (IPacketFFErrorCode) pkt; + if (ipkt.code == IPacketFFErrorCode.TYPE_PROTOCOL_VERSION) { String s1 = ipkt.desc.toLowerCase(); - if(s1.contains("outdated client") || s1.contains("client outdated")) { + if (s1.contains("outdated client") || s1.contains("client outdated")) { versError = VersionMismatch.CLIENT_OUTDATED; - }else if(s1.contains("outdated server") || s1.contains("server outdated") || + } else if (s1.contains("outdated server") || s1.contains("server outdated") || s1.contains("outdated relay") || s1.contains("server relay")) { versError = VersionMismatch.RELAY_OUTDATED; - }else { + } else { versError = VersionMismatch.UNKNOWN; } } @@ -654,7 +682,7 @@ public class PlatformWebRTC { open = false; failed = true; sock.close(); - }else { + } else { throw new IOException("Unexpected packet '" + pkt.getClass().getSimpleName() + "'"); } } catch (IOException e) { @@ -670,18 +698,18 @@ public class PlatformWebRTC { }); sock.onClose(evt -> { open = false; - if(!hasRecievedAnyData) { + if (!hasRecievedAnyData) { failed = true; Long l = relayQueryBlocked.get(uri); - if(l != null) { - if(System.currentTimeMillis() - l.longValue() < 400000l) { + if (l != null) { + if (System.currentTimeMillis() - l.longValue() < 400000l) { rateLimitStatus = RateLimit.LOCKED; return; } } l = relayQueryLimited.get(uri); - if(l != null) { - if(System.currentTimeMillis() - l.longValue() < 900000l) { + if (l != null) { + if (System.currentTimeMillis() - l.longValue() < 900000l) { rateLimitStatus = RateLimit.BLOCKED; return; } @@ -707,7 +735,7 @@ public class PlatformWebRTC { @Override public void close() { - if(sock != null && open) { + if (sock != null && open) { sock.close(); } open = false; @@ -798,12 +826,12 @@ public class PlatformWebRTC { long millis = System.currentTimeMillis(); Long l = relayQueryBlocked.get(addr); - if(l != null && millis - l.longValue() < 60000l) { + if (l != null && millis - l.longValue() < 60000l) { return new RelayQueryRatelimitDummy(RelayQuery.RateLimit.LOCKED); } l = relayQueryLimited.get(addr); - if(l != null && millis - l.longValue() < 10000l) { + if (l != null && millis - l.longValue() < 10000l) { return new RelayQueryRatelimitDummy(RelayQuery.RateLimit.BLOCKED); } @@ -833,7 +861,7 @@ public class PlatformWebRTC { s.setBinaryType("arraybuffer"); open = true; failed = false; - }catch(Throwable t) { + } catch (Throwable t) { sock = null; open = false; failed = true; @@ -842,9 +870,8 @@ public class PlatformWebRTC { sock = s; sock.onOpen(evt -> { try { - PlatformNetworking.nativeBinarySend(sock, convertToArrayBuffer( - IPacket.writePacket(new IPacket00Handshake(0x04, RelayManager.preferredRelayVersion, "")) - )); + PlatformNetworking.nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer( + IPacket.writePacket(new IPacket00Handshake(0x04, RelayManager.preferredRelayVersion, "")))); } catch (IOException e) { logger.error(e.toString()); sock.close(); @@ -853,49 +880,49 @@ public class PlatformWebRTC { } }); sock.onMessage(evt -> { - if(evt.getData() != null && !isString(evt.getData())) { + if (evt.getData() != null && !isString(evt.getData())) { hasRecievedAnyData = true; - byte[] arr = TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray())); - if(arr.length == 2 && arr[0] == (byte)0xFC) { + byte[] arr = TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray()); + if (arr.length == 2 && arr[0] == (byte) 0xFC) { long millis = System.currentTimeMillis(); - if(arr[1] == (byte)0x00 || arr[1] == (byte)0x01) { + if (arr[1] == (byte) 0x00 || arr[1] == (byte) 0x01) { rateLimitStatus = RelayQuery.RateLimit.BLOCKED; relayQueryLimited.put(RelayWorldsQueryImpl.this.uri, millis); - }else if(arr[1] == (byte)0x02) { + } else if (arr[1] == (byte) 0x02) { rateLimitStatus = RelayQuery.RateLimit.NOW_LOCKED; relayQueryLimited.put(RelayWorldsQueryImpl.this.uri, millis); relayQueryBlocked.put(RelayWorldsQueryImpl.this.uri, millis); - }else { + } else { rateLimitStatus = RelayQuery.RateLimit.LOCKED; relayQueryBlocked.put(RelayWorldsQueryImpl.this.uri, millis); } open = false; failed = true; sock.close(); - }else { - if(open) { + } else { + if (open) { try { IPacket pkt = IPacket.readPacket(new DataInputStream(new EaglerInputStream(arr))); - if(pkt instanceof IPacket07LocalWorlds) { - worlds = ((IPacket07LocalWorlds)pkt).worldsList; + if (pkt instanceof IPacket07LocalWorlds) { + worlds = ((IPacket07LocalWorlds) pkt).worldsList; sock.close(); open = false; failed = false; - }else if(pkt instanceof IPacket70SpecialUpdate) { - IPacket70SpecialUpdate ipkt = (IPacket70SpecialUpdate)pkt; - if(ipkt.operation == IPacket70SpecialUpdate.OPERATION_UPDATE_CERTIFICATE) { + } else if (pkt instanceof IPacket70SpecialUpdate) { + IPacket70SpecialUpdate ipkt = (IPacket70SpecialUpdate) pkt; + if (ipkt.operation == IPacket70SpecialUpdate.OPERATION_UPDATE_CERTIFICATE) { UpdateService.addCertificateToSet(ipkt.updatePacket); } - }else if(pkt instanceof IPacketFFErrorCode) { - IPacketFFErrorCode ipkt = (IPacketFFErrorCode)pkt; - if(ipkt.code == IPacketFFErrorCode.TYPE_PROTOCOL_VERSION) { + } else if (pkt instanceof IPacketFFErrorCode) { + IPacketFFErrorCode ipkt = (IPacketFFErrorCode) pkt; + if (ipkt.code == IPacketFFErrorCode.TYPE_PROTOCOL_VERSION) { String s1 = ipkt.desc.toLowerCase(); - if(s1.contains("outdated client") || s1.contains("client outdated")) { + if (s1.contains("outdated client") || s1.contains("client outdated")) { versError = RelayQuery.VersionMismatch.CLIENT_OUTDATED; - }else if(s1.contains("outdated server") || s1.contains("server outdated") || + } else if (s1.contains("outdated server") || s1.contains("server outdated") || s1.contains("outdated relay") || s1.contains("server relay")) { versError = RelayQuery.VersionMismatch.RELAY_OUTDATED; - }else { + } else { versError = RelayQuery.VersionMismatch.UNKNOWN; } } @@ -903,7 +930,7 @@ public class PlatformWebRTC { open = false; failed = true; sock.close(); - }else { + } else { throw new IOException("Unexpected packet '" + pkt.getClass().getSimpleName() + "'"); } } catch (IOException e) { @@ -919,18 +946,18 @@ public class PlatformWebRTC { }); sock.onClose(evt -> { open = false; - if(!hasRecievedAnyData) { + if (!hasRecievedAnyData) { failed = true; Long l = relayQueryBlocked.get(uri); - if(l != null) { - if(System.currentTimeMillis() - l.longValue() < 400000l) { + if (l != null) { + if (System.currentTimeMillis() - l.longValue() < 400000l) { rateLimitStatus = RelayQuery.RateLimit.LOCKED; return; } } l = relayQueryLimited.get(uri); - if(l != null) { - if(System.currentTimeMillis() - l.longValue() < 900000l) { + if (l != null) { + if (System.currentTimeMillis() - l.longValue() < 900000l) { rateLimitStatus = RelayQuery.RateLimit.BLOCKED; return; } @@ -956,7 +983,7 @@ public class PlatformWebRTC { @Override public void close() { - if(open && sock != null) { + if (open && sock != null) { sock.close(); } open = false; @@ -1016,12 +1043,12 @@ public class PlatformWebRTC { long millis = System.currentTimeMillis(); Long l = relayQueryBlocked.get(addr); - if(l != null && millis - l.longValue() < 60000l) { + if (l != null && millis - l.longValue() < 60000l) { return new RelayWorldsQueryRatelimitDummy(RelayQuery.RateLimit.LOCKED); } l = relayQueryLimited.get(addr); - if(l != null && millis - l.longValue() < 10000l) { + if (l != null && millis - l.longValue() < 10000l) { return new RelayWorldsQueryRatelimitDummy(RelayQuery.RateLimit.BLOCKED); } @@ -1051,7 +1078,7 @@ public class PlatformWebRTC { open = false; closed = false; failed = false; - }catch(Throwable t) { + } catch (Throwable t) { exceptions.add(t); sock = null; open = false; @@ -1062,16 +1089,17 @@ public class PlatformWebRTC { sock = s; sock.onOpen(evt -> open = true); sock.onMessage(evt -> { - if(evt.getData() != null && !isString(evt.getData())) { + if (evt.getData() != null && !isString(evt.getData())) { hasRecievedAnyData = true; try { - IPacket pkt = IPacket.readPacket(new DataInputStream(new EaglerInputStream(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray()))))); - if(pkt instanceof IPacket70SpecialUpdate) { - IPacket70SpecialUpdate ipkt = (IPacket70SpecialUpdate)pkt; - if(ipkt.operation == IPacket70SpecialUpdate.OPERATION_UPDATE_CERTIFICATE) { + IPacket pkt = IPacket.readPacket(new DataInputStream( + new EaglerInputStream(TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray())))); + if (pkt instanceof IPacket70SpecialUpdate) { + IPacket70SpecialUpdate ipkt = (IPacket70SpecialUpdate) pkt; + if (ipkt.operation == IPacket70SpecialUpdate.OPERATION_UPDATE_CERTIFICATE) { UpdateService.addCertificateToSet(ipkt.updatePacket); } - }else { + } else { packets.add(pkt); } } catch (IOException e) { @@ -1093,7 +1121,7 @@ public class PlatformWebRTC { closed = true; }); Window.setTimeout(() -> { - if(!open && !closed) { + if (!open && !closed) { closed = true; sock.close(); } @@ -1112,7 +1140,7 @@ public class PlatformWebRTC { @Override public void close() { - if(open && sock != null) { + if (open && sock != null) { sock.close(); } open = false; @@ -1126,9 +1154,9 @@ public class PlatformWebRTC { @Override public Throwable getException() { - if(!exceptions.isEmpty()) { + if (!exceptions.isEmpty()) { return exceptions.remove(0); - }else { + } else { return null; } } @@ -1136,7 +1164,7 @@ public class PlatformWebRTC { @Override public void writePacket(IPacket pkt) { try { - PlatformNetworking.nativeBinarySend(sock, convertToArrayBuffer(IPacket.writePacket(pkt))); + PlatformNetworking.nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer(IPacket.writePacket(pkt))); } catch (Throwable e) { logger.error("Relay connection error: {}", e.toString()); EagRuntime.debugPrintStackTrace(e); @@ -1150,28 +1178,28 @@ public class PlatformWebRTC { @Override public IPacket readPacket() { - if(!packets.isEmpty()) { + if (!packets.isEmpty()) { return packets.remove(0); - }else { + } else { return null; } } @Override public IPacket nextPacket() { - if(!packets.isEmpty()) { + if (!packets.isEmpty()) { return packets.get(0); - }else { + } else { return null; } } @Override public RelayQuery.RateLimit getRatelimitHistory() { - if(relayQueryBlocked.containsKey(uri)) { + if (relayQueryBlocked.containsKey(uri)) { return RelayQuery.RateLimit.LOCKED; } - if(relayQueryLimited.containsKey(uri)) { + if (relayQueryLimited.containsKey(uri)) { return RelayQuery.RateLimit.BLOCKED; } return RelayQuery.RateLimit.NONE; @@ -1246,12 +1274,12 @@ public class PlatformWebRTC { long millis = System.currentTimeMillis(); Long l = relayQueryBlocked.get(addr); - if(l != null && millis - l.longValue() < 60000l) { + if (l != null && millis - l.longValue() < 60000l) { return new RelayServerSocketRatelimitDummy(RelayQuery.RateLimit.LOCKED); } l = relayQueryLimited.get(addr); - if(l != null && millis - l.longValue() < 10000l) { + if (l != null && millis - l.longValue() < 10000l) { return new RelayServerSocketRatelimitDummy(RelayQuery.RateLimit.BLOCKED); } @@ -1283,22 +1311,22 @@ public class PlatformWebRTC { // todo: ArrayBuffer version public static void clientLANSendPacket(byte[] pkt) { - rtcLANClient.sendPacketToServer(convertToArrayBuffer(pkt)); + rtcLANClient.sendPacketToServer(TeaVMUtils.unwrapArrayBuffer(pkt)); } public static byte[] clientLANReadPacket() { - synchronized(clientLANPacketBuffer) { + synchronized (clientLANPacketBuffer) { return !clientLANPacketBuffer.isEmpty() ? clientLANPacketBuffer.remove(0) : null; } } public static List clientLANReadAllPacket() { - synchronized(clientLANPacketBuffer) { - if(!clientLANPacketBuffer.isEmpty()) { + synchronized (clientLANPacketBuffer) { + if (!clientLANPacketBuffer.isEmpty()) { List ret = new ArrayList(clientLANPacketBuffer); clientLANPacketBuffer.clear(); return ret; - }else { + } else { return null; } } @@ -1306,7 +1334,8 @@ public class PlatformWebRTC { public static void clientLANSetICEServersAndConnect(String[] servers) { rtcLANClient.setIceServers(servers); - if(clientLANReadyState() == LANClient.READYSTATE_CONNECTED || clientLANReadyState() == LANClient.READYSTATE_CONNECTING) { + if (clientLANReadyState() == LANClient.READYSTATE_CONNECTED + || clientLANReadyState() == LANClient.READYSTATE_CONNECTING) { rtcLANClient.signalRemoteDisconnect(true); } rtcLANClient.initialize(); @@ -1321,30 +1350,30 @@ public class PlatformWebRTC { } public static String clientLANAwaitICECandidate() { - if(clientICECandidate != null) { + if (clientICECandidate != null) { String ret = clientICECandidate; clientICECandidate = null; return ret; - }else { + } else { return null; } } public static String clientLANAwaitDescription() { - if(clientDescription != null) { + if (clientDescription != null) { String ret = clientDescription; clientDescription = null; return ret; - }else { + } else { return null; } } public static boolean clientLANAwaitChannel() { - if(clientDataChannelOpen) { + if (clientDataChannelOpen) { clientDataChannelOpen = false; return true; - }else { + } else { return false; } } @@ -1372,7 +1401,7 @@ public class PlatformWebRTC { private static final ListMultimap serverLANEventBuffer = LinkedListMultimap.create(); public static void serverLANInitializeServer(String[] servers) { - synchronized(serverLANEventBuffer) { + synchronized (serverLANEventBuffer) { serverLANEventBuffer.clear(); } rtcLANServer.resetPeerStates(); @@ -1384,10 +1413,10 @@ public class PlatformWebRTC { } public static LANPeerEvent serverLANGetEvent(String clientId) { - synchronized(serverLANEventBuffer) { - if(!serverLANEventBuffer.isEmpty()) { + synchronized (serverLANEventBuffer) { + if (!serverLANEventBuffer.isEmpty()) { List l = serverLANEventBuffer.get(clientId); - if(!l.isEmpty()) { + if (!l.isEmpty()) { return l.remove(0); } } @@ -1396,10 +1425,10 @@ public class PlatformWebRTC { } public static List serverLANGetAllEvent(String clientId) { - synchronized(serverLANEventBuffer) { - if(!serverLANEventBuffer.isEmpty()) { + synchronized (serverLANEventBuffer) { + if (!serverLANEventBuffer.isEmpty()) { List l = serverLANEventBuffer.removeAll(clientId); - if(l.isEmpty()) { + if (l.isEmpty()) { return null; } return l; @@ -1409,7 +1438,7 @@ public class PlatformWebRTC { } public static void serverLANWritePacket(String peer, byte[] data) { - rtcLANServer.sendPacketToRemoteClient(peer, TeaVMUtils.unwrapUnsignedByteArray(data).getBuffer()); + rtcLANServer.sendPacketToRemoteClient(peer, TeaVMUtils.unwrapArrayBuffer(data)); } public static void serverLANCreatePeer(String peer) { diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/RenderResolution.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/RenderResolution.java deleted file mode 100644 index cdb675c..0000000 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/RenderResolution.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.lax1dude.eaglercraft.v1_8.internal; - -import net.lax1dude.eaglercraft.v1_8.EagRuntime; -import net.lax1dude.eaglercraft.v1_8.EaglerInputStream; -import net.lax1dude.eaglercraft.v1_8.EaglerZLIB; -import net.minecraft.client.settings.KeyBinding; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; -import net.lax1dude.eaglercraft.v1_8.log4j.Logger; - -public class RenderResolution { - private static final Logger logger = LogManager.getLogger(); - private static float parseFloat(String parString1) { - return parString1.equals("true") ? 1.0F : (parString1.equals("false") ? 0.0F : Float.parseFloat(parString1)); - } - public static double renderScale = 1.0D; - public static void loadRenderScale() { - try { - byte[] options = EagRuntime.getStorage("g"); - if (options == null) { - return; - } - - BufferedReader bufferedreader = new BufferedReader( - new InputStreamReader(EaglerZLIB.newGZIPInputStream(new EaglerInputStream(options)))); - String s = ""; - - while ((s = bufferedreader.readLine()) != null) { - try { - String[] astring = s.split(":"); - if (astring[0].equals("renderScale")) { - renderScale = parseFloat(astring[1]); - } - } catch (Exception var8) { - logger.warn("Skipping bad option: " + s); - } - } - - KeyBinding.resetKeyBindingArrayAndHash(); - } catch (Exception exception) { - logger.error("Failed to load options", exception); - } - } - -} diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMClientConfigAdapter.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMClientConfigAdapter.java index ff47918..a2d014a 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMClientConfigAdapter.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMClientConfigAdapter.java @@ -67,6 +67,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter { private boolean allowFNAWSkins = true; private String localStorageNamespace = "_eaglercraftX"; private final TeaVMClientConfigAdapterHooks hooks = new TeaVMClientConfigAdapterHooks(); + private boolean enableMinceraft = true; public void loadNative(JSObject jsObject) { integratedServerOpts = new JSONObject(); @@ -91,6 +92,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter { allowVoiceClient = eaglercraftXOpts.getAllowVoiceClient(true); allowFNAWSkins = !demoMode && eaglercraftXOpts.getAllowFNAWSkins(true); localStorageNamespace = eaglercraftXOpts.getLocalStorageNamespace(EaglercraftVersion.localStorageNamespace); + enableMinceraft = eaglercraftXOpts.getEnableMinceraft(true); JSEaglercraftXOptsHooks hooksObj = eaglercraftXOpts.getHooks(); if (hooksObj != null) { hooks.loadHooks(hooksObj); @@ -191,6 +193,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter { allowFNAWSkins = eaglercraftOpts.optBoolean("allowFNAWSkins", true); localStorageNamespace = eaglercraftOpts.optString("localStorageNamespace", EaglercraftVersion.localStorageNamespace); + enableMinceraft = eaglercraftOpts.optBoolean("enableMinceraft", true); JSONArray serversArray = eaglercraftOpts.optJSONArray("servers"); if (serversArray != null) { for (int i = 0, l = serversArray.length(); i < l; ++i) { @@ -350,6 +353,11 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter { return localStorageNamespace; } + @Override + public boolean isEnableMinceraft() { + return enableMinceraft; + } + @Override public IClientConfigAdapterHooks getHooks() { return hooks; @@ -375,6 +383,7 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter { jsonObject.put("allowVoiceClient", allowVoiceClient); jsonObject.put("allowFNAWSkins", allowFNAWSkins); jsonObject.put("localStorageNamespace", localStorageNamespace); + jsonObject.put("enableMinceraft", enableMinceraft); JSONArray serversArr = new JSONArray(); for (int i = 0, l = defaultServers.size(); i < l; ++i) { DefaultServer srv = defaultServers.get(i); diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMServerQuery.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMServerQuery.java index adeb7ab..ef4e616 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMServerQuery.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMServerQuery.java @@ -10,7 +10,6 @@ import org.teavm.jso.dom.events.Event; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.dom.events.MessageEvent; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import org.teavm.jso.websocket.WebSocket; import net.lax1dude.eaglercraft.v1_8.internal.EnumServerRateLimit; @@ -22,14 +21,21 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger; /** * 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. * @@ -78,45 +84,45 @@ public class TeaVMServerQuery implements IServerQuery { @Override public void handleEvent(MessageEvent evt) { alive = true; - if(pingTimer == -1) { + if (pingTimer == -1) { pingTimer = System.currentTimeMillis() - pingStart; - if(pingTimer < 1) { + if (pingTimer < 1) { pingTimer = 1; } } - if(isString(evt.getData())) { + if (isString(evt.getData())) { String str = evt.getDataAsString(); - if(str.equalsIgnoreCase("BLOCKED")) { + if (str.equalsIgnoreCase("BLOCKED")) { logger.error("Reached full IP ratelimit for {}!", uri); rateLimit = EnumServerRateLimit.BLOCKED; return; } - if(str.equalsIgnoreCase("LOCKED")) { + if (str.equalsIgnoreCase("LOCKED")) { logger.error("Reached full IP ratelimit lockout for {}!", uri); rateLimit = EnumServerRateLimit.LOCKED_OUT; return; } try { JSONObject obj = new JSONObject(str); - if("blocked".equalsIgnoreCase(obj.optString("type", null))) { + if ("blocked".equalsIgnoreCase(obj.optString("type", null))) { logger.error("Reached query ratelimit for {}!", uri); rateLimit = EnumServerRateLimit.BLOCKED; - }else if("locked".equalsIgnoreCase(obj.optString("type", null))) { + } else if ("locked".equalsIgnoreCase(obj.optString("type", null))) { logger.error("Reached query ratelimit lockout for {}!", uri); rateLimit = EnumServerRateLimit.LOCKED_OUT; - }else { + } else { QueryResponse response = new QueryResponse(obj, pingTimer); - synchronized(queryResponses) { + synchronized (queryResponses) { queryResponses.add(response); } } - }catch(Throwable t) { + } catch (Throwable t) { logger.error("Exception thrown parsing websocket query response from \"" + uri + "\"!"); logger.error(t); } - }else { - synchronized(queryResponsesBytes) { - queryResponsesBytes.add(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray()))); + } else { + synchronized (queryResponsesBytes) { + queryResponsesBytes.add(TeaVMUtils.wrapByteArrayBuffer(evt.getDataAsArray())); } } } @@ -132,7 +138,7 @@ public class TeaVMServerQuery implements IServerQuery { @Override public void send(String str) { - if(open) { + if (open) { sock.send(str); } } @@ -142,24 +148,24 @@ public class TeaVMServerQuery implements IServerQuery { @Override public void send(byte[] bytes) { - if(open) { - nativeBinarySend(sock, TeaVMUtils.unwrapByteArray(bytes).getBuffer()); + if (open) { + nativeBinarySend(sock, TeaVMUtils.unwrapArrayBuffer(bytes)); } } @Override public int responsesAvailable() { - synchronized(queryResponses) { + synchronized (queryResponses) { return queryResponses.size(); } } @Override public QueryResponse getResponse() { - synchronized(queryResponses) { - if(queryResponses.size() > 0) { + synchronized (queryResponses) { + if (queryResponses.size() > 0) { return queryResponses.remove(0); - }else { + } else { return null; } } @@ -167,17 +173,17 @@ public class TeaVMServerQuery implements IServerQuery { @Override public int binaryResponsesAvailable() { - synchronized(queryResponsesBytes) { + synchronized (queryResponsesBytes) { return queryResponsesBytes.size(); } } @Override public byte[] getBinaryResponse() { - synchronized(queryResponsesBytes) { - if(queryResponsesBytes.size() > 0) { + synchronized (queryResponsesBytes) { + if (queryResponsesBytes.size() > 0) { return queryResponsesBytes.remove(0); - }else { + } else { return null; } } @@ -191,7 +197,7 @@ public class TeaVMServerQuery implements IServerQuery { @Override public void close() { - if(open) { + if (open) { open = false; sock.close(); } diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUpdateThread.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUpdateThread.java index 1d071a5..6f51e9b 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUpdateThread.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUpdateThread.java @@ -16,7 +16,6 @@ import org.teavm.jso.browser.Window; import org.teavm.jso.dom.events.Event; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import com.google.common.collect.ListMultimap; @@ -35,14 +34,21 @@ import net.lax1dude.eaglercraft.v1_8.update.UpdateService; /** * 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. * @@ -70,72 +76,72 @@ public class TeaVMUpdateThread implements Runnable { updateProg.statusString2 = "Please Wait"; List urlListA = new ArrayList(); - ListMultimap downloadSources = updateCert.getSourceMultimap(); + ListMultimap downloadSources = updateCert.getSourceMultimap(); List ls = downloadSources.get("list"); - for(int k = 0, l = ls.size(); k < l; ++k) { + for (int k = 0, l = ls.size(); k < l; ++k) { String str1 = ls.get(k); updateProg.statusString2 = "Fetch List (" + (k + 1) + "/" + l + ")"; byte[] b = downloadWithProgress(str1); - if(b == null) { + if (b == null) { logger.error("Failed to load additional url list: {}", str1); continue; } try { String[] str2 = EagUtils.linesArray(new String(b, StandardCharsets.UTF_8)); - for(int i = 0; i < str2.length; ++i) { - if(!StringUtils.isAllBlank(str2[i]) && (str2[i] = str2[i].trim()).charAt(0) != '#') { + for (int i = 0; i < str2.length; ++i) { + if (!StringUtils.isAllBlank(str2[i]) && (str2[i] = str2[i].trim()).charAt(0) != '#') { String[] strrr = str2[i].split(":", 2); downloadSources.put(strrr[0].trim(), strrr[1].trim()); } } - }catch(Throwable t) { + } catch (Throwable t) { logger.error("Failed to load/parse url list: {}", str1); logger.error(t); } } - + updateProg.statusString2 = "Please Wait"; - + urlListA.addAll(downloadSources.get("url")); - + List ls2 = downloadSources.get("use-gateway"); ls = downloadSources.get("ipfs"); - for(int k = 0, l = ls.size(); k < l; ++k) { + for (int k = 0, l = ls.size(); k < l; ++k) { String str1 = ls.get(k); String cid = str1; String path = ""; int pathSep = str1.indexOf('/'); - if(pathSep != -1) { + if (pathSep != -1) { path = cid.substring(pathSep + 1); cid = cid.substring(0, pathSep); } - for(int p = 0, q = ls2.size(); p < q; ++p) { + for (int p = 0, q = ls2.size(); p < q; ++p) { String str2 = ls2.get(p); urlListA.add(formatIPFSURL(cid, path, str2)); } } - + List urlListB = new ArrayList(); ls = downloadSources.get("use-proxy"); - for(int k = 0, l = ls.size(); k < l; ++k) { + for (int k = 0, l = ls.size(); k < l; ++k) { String str1 = ls.get(k); - for(int p = 0, q = urlListA.size(); p < q; ++p) { + for (int p = 0, q = urlListA.size(); p < q; ++p) { String str2 = urlListA.get(p); urlListB.add(formatProxyURL(str2, str1)); } } - + Collections.shuffle(urlListA); Collections.shuffle(urlListB); - + urlListA.addAll(urlListB); - - for(int i = 0, l = urlListA.size(); i < l; ++i) { + + for (int i = 0, l = urlListA.size(); i < l; ++i) { String url = urlListA.get(i); updateProg.statusString2 = "Attempt (" + (i + 1) + "/" + l + ")"; byte[] b = downloadWithProgress(url); - if(b == null) { + if (b == null) { updateProg.progressBar = 1.0f; updateProg.statusString3 = "FAILED!"; EagUtils.sleep(300l); @@ -146,7 +152,7 @@ public class TeaVMUpdateThread implements Runnable { updateProg.progressBar = 1.0f; updateProg.statusString2 = "Verifying"; logger.info("Verifying downloaded file..."); - if(updateCert.isBundleDataValid(b)) { + if (updateCert.isBundleDataValid(b)) { logger.info("Success! Signature is valid!"); downloadSignedOffline(updateCert, b); success = true; @@ -156,20 +162,22 @@ public class TeaVMUpdateThread implements Runnable { logger.error("File signature is invalid: {}", url); EagUtils.sleep(1000l); } - + updateProg.progressBar = -1.0f; updateProg.statusString3 = null; - - }catch(Throwable t) { + + } catch (Throwable t) { logger.error("Uncaught exception downloading updates!"); logger.error(t); - }finally { + } finally { PlatformUpdateSvc.updateThread = null; updateProg.isBusy = false; - if(!success) { - logger.error("Failed to download updates! No valid URL was found for {}", updateCert.bundleDisplayVersion); - Window.alert("ERROR: Failed to download updates!\n\nIf you are on a device with restricted internet access, try a different device or connect to a different WiFi network\n\nCheck the debug console for more info"); - }else { + if (!success) { + logger.error("Failed to download updates! No valid URL was found for {}", + updateCert.bundleDisplayVersion); + Window.alert( + "ERROR: Failed to download updates!\n\nIf you are on a device with restricted internet access, try a different device or connect to a different WiFi network\n\nCheck the debug console for more info"); + } else { UpdateService.dismiss(updateCert); } } @@ -181,11 +189,11 @@ public class TeaVMUpdateThread implements Runnable { updateProg.statusString3 = url; logger.info("Trying to download: {}", url); byte[] b = downloadWithProgress0(this, url); - if(b == null) { + if (b == null) { logger.error("Failed to download: {}", url); } return b; - }finally { + } finally { updateProg.statusString3 = null; } } @@ -196,7 +204,7 @@ public class TeaVMUpdateThread implements Runnable { private static void downloadWithProgress0(TeaVMUpdateThread self, String url, AsyncCallback cb) { try { self.downloadWithProgressImpl(url, cb); - }catch(Throwable t) { + } catch (Throwable t) { logger.error("Exception caught downloading file: {}", url); logger.error(t); cb.complete(null); @@ -210,23 +218,25 @@ public class TeaVMUpdateThread implements Runnable { TeaVMUtils.addEventListener(xhr, "progress", new EventListener() { @Override public void handleEvent(ProgressEvent evt) { - updateProg.progressBar = Math.min((float)evt.getLoaded() / (float)updateCert.bundleDataLength, 1.0f); + updateProg.progressBar = Math.min((float) evt.getLoaded() / (float) updateCert.bundleDataLength, 1.0f); } }); TeaVMUtils.addEventListener(xhr, "readystatechange", new EventListener() { @Override public void handleEvent(Event evt) { - if(xhr.getReadyState() == 4) { - if(xhr.getStatus() == 200) { - ArrayBuffer data = (ArrayBuffer)xhr.getResponse(); - if(data.getByteLength() == updateCert.bundleDataLength) { - cb.complete(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(data))); - }else { - logger.error("Unexpected response length {} (expect: {}) from URL: {}", xhr.getStatus(), xhr.getStatusText(), url); + if (xhr.getReadyState() == 4) { + if (xhr.getStatus() == 200) { + ArrayBuffer data = (ArrayBuffer) xhr.getResponse(); + if (data.getByteLength() == updateCert.bundleDataLength) { + cb.complete(TeaVMUtils.wrapByteArrayBuffer(data)); + } else { + logger.error("Unexpected response length {} (expect: {}) from URL: {}", xhr.getStatus(), + xhr.getStatusText(), url); cb.complete(null); } - }else { - logger.error("Got response code {} \"{}\" for url: {}", xhr.getStatus(), xhr.getStatusText(), url); + } else { + logger.error("Got response code {} \"{}\" for url: {}", xhr.getStatus(), xhr.getStatusText(), + url); cb.complete(null); } } @@ -236,7 +246,7 @@ public class TeaVMUpdateThread implements Runnable { @Override public void handleEvent(ProgressEvent evt) { logger.error("Exception caught downloading file: {}", url); - + } }); xhr.send(); @@ -251,16 +261,20 @@ public class TeaVMUpdateThread implements Runnable { } public static void downloadSignedOffline(UpdateCertificate cert, byte[] data) { - PlatformApplication.downloadFileWithName(cert.bundleDisplayName.replaceAll("[^a-zA-Z0-9\\-_\\.]", "_") + "_" + cert.bundleDisplayVersion.replaceAll("[^a-zA-Z0-9\\-_]", "_") + "_Offline_Signed.html", generateSignedOffline(cert, data)); + PlatformApplication.downloadFileWithName( + cert.bundleDisplayName.replaceAll("[^a-zA-Z0-9\\-_\\.]", "_") + "_" + + cert.bundleDisplayVersion.replaceAll("[^a-zA-Z0-9\\-_]", "_") + "_Offline_Signed.html", + generateSignedOffline(cert, data)); } public static byte[] generateSignedOffline(UpdateCertificate cert, byte[] data) { - return generateSignedOffline(cert.rawCertData, data, EagRuntime.fixDateFormat(new SimpleDateFormat("MM/dd/yyyy")).format(new Date(cert.sigTimestamp))); + return generateSignedOffline(cert.rawCertData, data, + EagRuntime.fixDateFormat(new SimpleDateFormat("MM/dd/yyyy")).format(new Date(cert.sigTimestamp))); } public static byte[] generateSignedOffline(byte[] cert, byte[] data, String date) { byte[] b = PlatformAssets.getResourceBytes("SignedClientTemplate.txt"); - if(b == null) { + if (b == null) { throw new RuntimeException("Could not load SignedClientTemplate.txt from assets.epk!"); } String templateHtml = new String(b, StandardCharsets.UTF_8); diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUtils.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUtils.java index e63e8eb..5922e2e 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUtils.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/TeaVMUtils.java @@ -19,14 +19,21 @@ import net.lax1dude.eaglercraft.v1_8.EagUtils; /** * 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. * @@ -35,105 +42,215 @@ public class TeaVMUtils { @JSBody(params = { "url" }, script = "URL.revokeObjectURL(url);") public static native void freeDataURL(String url); - + @JSBody(params = { "buf", "mime" }, script = "return URL.createObjectURL(new Blob([buf], {type: mime}));") public static native String getDataURL(ArrayBuffer buf, String mime); - + @JSBody(params = { "obj", "name", "handler" }, script = "obj.addEventListener(name, handler);") public static native void addEventListener(JSObject obj, String name, JSObject handler); - + @JSBody(params = {}, script = "return (new Error()).stack;") public static native String dumpJSStackTrace(); private static abstract class TeaVMArrayObject implements JSObject { @JSProperty - public abstract ArrayBufferView getData(); + public abstract ArrayBufferView getData(); } public static Int8Array unwrapByteArray(byte[] buf) { - return Int8Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer()); + if (buf == null) { + return null; + } + return Int8Array.create(((TeaVMArrayObject) (Object) buf).getData().getBuffer()); } public static ArrayBuffer unwrapArrayBuffer(byte[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData().getBuffer(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData().getBuffer(); } public static ArrayBufferView unwrapArrayBufferView(byte[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData(); } - @JSBody(params = { "buf" }, script = "return $rt_createByteArray(buf.buffer)") + @JSBody(params = { "buf" }, script = "return $rt_createByteArray(buf)") private static native JSObject wrapByteArray0(JSObject buf); public static byte[] wrapByteArray(Int8Array buf) { - return (byte[])(Object)wrapByteArray0(buf); + if (buf == null) { + return null; + } + return (byte[]) (Object) wrapByteArray0(buf.getBuffer()); + } + + public static byte[] wrapByteArrayBuffer(ArrayBuffer buf) { + if (buf == null) { + return null; + } + return (byte[]) (Object) wrapByteArray0(buf); + } + + public static byte[] wrapByteArrayBufferView(ArrayBufferView buf) { + if (buf == null) { + return null; + } + return (byte[]) (Object) wrapByteArray0(buf.getBuffer()); } public static Uint8Array unwrapUnsignedByteArray(byte[] buf) { - return Uint8Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer()); + if (buf == null) { + return null; + } + return Uint8Array.create(((TeaVMArrayObject) (Object) buf).getData().getBuffer()); } public static byte[] wrapUnsignedByteArray(Uint8Array buf) { - return (byte[])(Object)wrapByteArray0(buf); + if (buf == null) { + return null; + } + return (byte[]) (Object) wrapByteArray0(buf.getBuffer()); } public static Int32Array unwrapIntArray(int[] buf) { - return Int32Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer()); + if (buf == null) { + return null; + } + return Int32Array.create(((TeaVMArrayObject) (Object) buf).getData().getBuffer()); } public static ArrayBuffer unwrapArrayBuffer(int[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData().getBuffer(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData().getBuffer(); } public static ArrayBufferView unwrapArrayBufferView(int[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData(); } - @JSBody(params = { "buf" }, script = "return $rt_createIntArray(buf.buffer)") + @JSBody(params = { "buf" }, script = "return $rt_createIntArray(buf)") private static native JSObject wrapIntArray0(JSObject buf); public static int[] wrapIntArray(Int32Array buf) { - return (int[])(Object)wrapIntArray0(buf); + if (buf == null) { + return null; + } + return (int[]) (Object) wrapIntArray0(buf.getBuffer()); + } + + public static int[] wrapIntArrayBuffer(ArrayBuffer buf) { + if (buf == null) { + return null; + } + return (int[]) (Object) wrapIntArray0(buf); + } + + public static int[] wrapIntArrayBufferView(ArrayBufferView buf) { + if (buf == null) { + return null; + } + return (int[]) (Object) wrapIntArray0(buf.getBuffer()); } public static Float32Array unwrapFloatArray(float[] buf) { - return Float32Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer()); + if (buf == null) { + return null; + } + return Float32Array.create(((TeaVMArrayObject) (Object) buf).getData().getBuffer()); } public static ArrayBuffer unwrapArrayBuffer(float[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData().getBuffer(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData().getBuffer(); } public static ArrayBufferView unwrapArrayBufferView(float[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData(); } - @JSBody(params = { "buf" }, script = "return $rt_createFloatArray(buf.buffer)") + @JSBody(params = { "buf" }, script = "return $rt_createFloatArray(buf)") private static native JSObject wrapFloatArray0(JSObject buf); public static float[] wrapFloatArray(Float32Array buf) { - return (float[])(Object)wrapFloatArray0(buf); + if (buf == null) { + return null; + } + return (float[]) (Object) wrapFloatArray0(buf.getBuffer()); + } + + public static float[] wrapFloatArrayBuffer(ArrayBuffer buf) { + if (buf == null) { + return null; + } + return (float[]) (Object) wrapFloatArray0(buf); + } + + public static float[] wrapFloatArrayBufferView(ArrayBufferView buf) { + if (buf == null) { + return null; + } + return (float[]) (Object) wrapFloatArray0(buf.getBuffer()); } public static Int16Array unwrapShortArray(short[] buf) { - return Int16Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer()); + if (buf == null) { + return null; + } + return Int16Array.create(((TeaVMArrayObject) (Object) buf).getData().getBuffer()); } public static ArrayBuffer unwrapArrayBuffer(short[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData().getBuffer(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData().getBuffer(); } public static ArrayBufferView unwrapArrayBufferView(short[] buf) { - return ((TeaVMArrayObject)(Object)buf).getData(); + if (buf == null) { + return null; + } + return ((TeaVMArrayObject) (Object) buf).getData(); } - @JSBody(params = { "buf" }, script = "return $rt_createShortArray(buf.buffer)") + @JSBody(params = { "buf" }, script = "return $rt_createShortArray(buf)") private static native JSObject wrapShortArray0(JSObject buf); public static short[] wrapShortArray(Int16Array buf) { - return (short[])(Object)wrapShortArray0(buf); + if (buf == null) { + return null; + } + return (short[]) (Object) wrapShortArray0(buf.getBuffer()); } - + + public static short[] wrapShortArrayBuffer(ArrayBuffer buf) { + if (buf == null) { + return null; + } + return (short[]) (Object) wrapShortArray0(buf); + } + + public static short[] wrapShortArrayBuffer(ArrayBufferView buf) { + if (buf == null) { + return null; + } + return (short[]) (Object) wrapShortArray0(buf.getBuffer()); + } + @Async public static native void sleepSetTimeout(int millis); @@ -141,35 +258,27 @@ public class TeaVMUtils { Window.setTimeout(() -> cb.complete(null), millis); } - public static final byte[] arrayBufferToBytes(ArrayBuffer buf) { - if(buf == null) { - return null; - } - - return wrapUnsignedByteArray(Uint8Array.create(buf)); - } - public static String tryResolveClassesSource() { String str = dumpJSStackTrace(); String[] frames = EagUtils.splitPattern.split(str); - if("Error".equals(frames[0])) { + if ("Error".equals(frames[0])) { // V8 stack trace - if(frames.length > 1) { + if (frames.length > 1) { String framesTrim = frames[1].trim(); - if(framesTrim.startsWith("at")) { - //definitely V8 + if (framesTrim.startsWith("at")) { + // definitely V8 int i = framesTrim.indexOf('('); int j = framesTrim.indexOf(')'); - if(i != -1 && j != -1 && i < j) { + if (i != -1 && j != -1 && i < j) { return tryResolveClassesSourceFromFrame(framesTrim.substring(i + 1, j)); } } } - }else { + } else { // Mozilla/WebKit stack trace String framesTrim = frames[0].trim(); int i = framesTrim.indexOf('@'); - if(i != -1) { + if (i != -1) { return tryResolveClassesSourceFromFrame(framesTrim.substring(i + 1)); } } @@ -178,10 +287,10 @@ public class TeaVMUtils { private static String tryResolveClassesSourceFromFrame(String fileLineCol) { int i = fileLineCol.lastIndexOf(':'); - if(i > 0) { + if (i > 0) { i = fileLineCol.lastIndexOf(':', i - 1); } - if(i != -1) { + if (i != -1) { return fileLineCol.substring(0, i); } return null; diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/opts/JSEaglercraftXOptsRoot.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/opts/JSEaglercraftXOptsRoot.java index 56ee89e..a050fa5 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/opts/JSEaglercraftXOptsRoot.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/internal/teavm/opts/JSEaglercraftXOptsRoot.java @@ -113,4 +113,8 @@ public abstract class JSEaglercraftXOptsRoot implements JSObject { "def" }, script = "return (typeof this.localStorageNamespace === \"string\") ? this.localStorageNamespace : def;") public native String getLocalStorageNamespace(String defaultValue); + @JSBody(params = { + "def" }, script = "return (typeof this.enableMinceraft === \"boolean\") ? this.enableMinceraft : def;") + public native boolean getEnableMinceraft(boolean defaultValue); + } diff --git a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java index d05992b..7f7abc1 100644 --- a/src/teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java +++ b/src/teavm/java/net/lax1dude/eaglercraft/v1_8/sp/internal/ClientPlatformSingleplayer.java @@ -10,7 +10,6 @@ import org.teavm.jso.JSObject; import org.teavm.jso.dom.events.ErrorEvent; import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.typedarrays.ArrayBuffer; -import org.teavm.jso.typedarrays.Uint8Array; import org.teavm.jso.workers.Worker; import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData; @@ -23,14 +22,21 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger; /** * Copyright (c) 2023-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,7 +56,8 @@ public class ClientPlatformSingleplayer { @JSBody(params = {}, script = "try{throw new Error();}catch(ex){return ex.stack;}return null;") private static native String loadIntegratedServerSourceStack(); - @JSBody(params = { "csc" }, script = "if(typeof csc.src === \"string\" && csc.src.length > 0) return csc.src; else return null;") + @JSBody(params = { + "csc" }, script = "if(typeof csc.src === \"string\" && csc.src.length > 0) return csc.src; else return null;") private static native String loadIntegratedServerSourceURL(JSObject scriptTag); @JSBody(params = { "csc", "tail" }, script = "const cscText = csc.text;" @@ -79,86 +86,88 @@ public class ClientPlatformSingleplayer { private static native void sendWorkerStartPacket(Worker w, String workerArgs); private static class WorkerBinaryPacketHandlerImpl implements WorkerBinaryPacketHandler { - + public void onMessage(String channel, ArrayBuffer buf) { - if(channel == null) { + if (channel == null) { logger.error("Recieved IPC packet with null channel"); return; } - - if(buf == null) { + + if (buf == null) { logger.error("Recieved IPC packet with null buffer"); return; } - - synchronized(messageQueue) { - messageQueue.add(new IPCPacketData(channel, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buf)))); + + synchronized (messageQueue) { + messageQueue.add(new IPCPacketData(channel, TeaVMUtils.wrapByteArrayBuffer(buf))); } } - + } @JSBody(params = { "blobObj" }, script = "return URL.createObjectURL(blobObj);") private static native String createWorkerScriptURL(JSObject blobObj); - @JSBody(params = { "cscText", "tail" }, script = "return new Blob([cscText, tail], { type: \"text/javascript;charset=utf8\" });") + @JSBody(params = { "cscText", + "tail" }, script = "return new Blob([cscText, tail], { type: \"text/javascript;charset=utf8\" });") private static native JSObject createBlobObj(ArrayBuffer buf, String tail); private static final String workerBootstrapCode = "\n\nmain([\"_worker_process_\"]);"; private static JSObject loadIntegratedServerSource() { String str = loadIntegratedServerSourceOverrideURL(); - if(str != null) { + if (str != null) { ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(str); - if(buf != null) { + if (buf != null) { integratedServerSourceOriginalURL = str; logger.info("Using integrated server at: {}", str); return createBlobObj(buf, workerBootstrapCode); - }else { + } else { logger.error("Failed to load integrated server: {}", str); } } JSObject el = loadIntegratedServerSourceOverride(); - if(el != null) { + if (el != null) { String url = loadIntegratedServerSourceURL(el); - if(url == null) { + if (url == null) { el = loadIntegratedServerSourceInline(el, workerBootstrapCode); - if(el != null) { + if (el != null) { integratedServerSourceOriginalURL = "inline script tag"; logger.info("Loading integrated server from inline script tag"); return el; } - }else { + } else { ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(url); - if(buf != null) { + if (buf != null) { integratedServerSourceOriginalURL = url; logger.info("Using integrated server from script tag src: {}", url); return createBlobObj(buf, workerBootstrapCode); - }else { + } else { logger.error("Failed to load integrated server from script tag src: {}", url); } } } str = TeaVMUtils.tryResolveClassesSource(); - if(str != null) { + if (str != null) { ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(str); - if(buf != null) { + if (buf != null) { integratedServerSourceOriginalURL = str; logger.info("Using integrated server from script src: {}", str); return createBlobObj(buf, workerBootstrapCode); - }else { + } else { logger.error("Failed to load integrated server from script src: {}", str); } } logger.info("Could not resolve the location of client's classes.js!"); logger.info("Make sure client's classes.js is linked/embedded in a dedicated