update to u35
This commit is contained in:
parent
e13914a54f
commit
3409da13de
|
@ -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;
|
||||
|
|
|
@ -112,4 +112,5 @@ void main() {
|
|||
#endif
|
||||
|
||||
gl_Position = u_projectionMat4f * pos;
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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": [
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,4 +58,4 @@ void main() {
|
|||
|
||||
v_position4f = u_modelViewMatrix4f * vec4(pos3f, 1.0);
|
||||
gl_Position = u_projectionMatrix4f * v_position4f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,4 +77,4 @@ void main() {
|
|||
#endif
|
||||
|
||||
gl_Position = u_projectionMat4f * v_position4f;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 942 B After Width: | Height: | Size: 315 B |
|
@ -0,0 +1,2 @@
|
|||
# Change to 0 to disable blur
|
||||
enable_blur=1
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -81,5 +81,7 @@ public interface IClientConfigAdapter {
|
|||
|
||||
String getLocalStorageNamespace();
|
||||
|
||||
boolean isEnableMinceraft();
|
||||
|
||||
IClientConfigAdapterHooks getHooks();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<IResource> 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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<String, DynamicLightInstance> lightRenderers = new HashMap();
|
||||
private static List<DynamicLightInstance> lightInstancePool = new ArrayList();
|
||||
private static int instancePoolIndex = 0;
|
||||
private static int maxListLengthTracker = 0;
|
||||
static final List<DynamicLightInstance> 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<DynamicLightInstance> 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<DynamicLightInstance> 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<DynamicLightInstance> itr = lightRenderers.values().iterator();
|
||||
while (itr.hasNext()) {
|
||||
itr.next().destroy();
|
||||
}
|
||||
lightRenderers.clear();
|
||||
lightInstancePool = new ArrayList();
|
||||
}
|
||||
|
||||
public static String getF3String() {
|
||||
return "DynamicLightsTotal: " + lastTotal;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -613,6 +613,7 @@ public class Minecraft implements IThreadListener {
|
|||
}
|
||||
|
||||
ShaderSource.clearCache();
|
||||
GuiMainMenu.doResourceReloadHack();
|
||||
|
||||
this.mcLanguageManager.parseLanguageMetadata(arraylist);
|
||||
if (this.renderGlobal != null) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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<String,byte[]> assets = new HashMap();
|
||||
|
||||
|
||||
static final Map<String, byte[]> 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<ImageData> ret) {
|
||||
final Document doc = Window.current().getDocument();
|
||||
final HTMLImageElement toLoad = (HTMLImageElement) doc.createElement("img");
|
||||
toLoad.addEventListener("load", new EventListener<Event>() {
|
||||
@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<Event>() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:") ? "<data: " + url.length() + " chars>" : 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<byte[]> 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<ArrayBuffer> 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<Event>() {
|
||||
@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<Event>() {
|
||||
@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<ArrayBuffer> cb) {
|
||||
private static void downloadRemoteURI(String assetPackageURI, boolean useCache,
|
||||
final AsyncCallback<ArrayBuffer> 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<String> 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<String> 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";
|
||||
|
|
|
@ -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!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Event>) evt -> {
|
||||
if (!iceCandidates.isEmpty()) {
|
||||
Window.setTimeout(() -> ((EventListener<Event>)evtHandler[0]).handleEvent(evt), 1);
|
||||
Window.setTimeout(() -> ((EventListener<Event>) evtHandler[0]).handleEvent(evt), 1);
|
||||
return;
|
||||
}
|
||||
clientDataChannelClosed = false;
|
||||
clientDataChannelOpen = true;
|
||||
};
|
||||
|
||||
TeaVMUtils.addEventListener(dataChannel, "open", (EventListener<Event>)evtHandler[0]);
|
||||
TeaVMUtils.addEventListener(dataChannel, "open", (EventListener<Event>) evtHandler[0]);
|
||||
|
||||
TeaVMUtils.addEventListener(dataChannel, "message", (EventListener<Event>) 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<Event>) evt -> {
|
||||
if (!iceCandidates.isEmpty()) {
|
||||
Window.setTimeout(() -> ((EventListener<Event>)evtHandler[0]).handleEvent(evt), 1);
|
||||
Window.setTimeout(() -> ((EventListener<Event>) 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<Event>) 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<Event>)evtHandler[0]);
|
||||
|
||||
TeaVMUtils.addEventListener(peerConnection, "datachannel", (EventListener<Event>) evtHandler[0]);
|
||||
|
||||
TeaVMUtils.addEventListener(peerConnection, "connectionstatechange", (EventListener<Event>) 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<String,Long> relayQueryLimited = new HashMap<>();
|
||||
private static final Map<String,Long> relayQueryBlocked = new HashMap<>();
|
||||
private static final Map<String, Long> relayQueryLimited = new HashMap<>();
|
||||
private static final Map<String, Long> 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<byte[]> clientLANReadAllPacket() {
|
||||
synchronized(clientLANPacketBuffer) {
|
||||
if(!clientLANPacketBuffer.isEmpty()) {
|
||||
synchronized (clientLANPacketBuffer) {
|
||||
if (!clientLANPacketBuffer.isEmpty()) {
|
||||
List<byte[]> 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<String, LANPeerEvent> 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<LANPeerEvent> l = serverLANEventBuffer.get(clientId);
|
||||
if(!l.isEmpty()) {
|
||||
if (!l.isEmpty()) {
|
||||
return l.remove(0);
|
||||
}
|
||||
}
|
||||
|
@ -1396,10 +1425,10 @@ public class PlatformWebRTC {
|
|||
}
|
||||
|
||||
public static List<LANPeerEvent> serverLANGetAllEvent(String clientId) {
|
||||
synchronized(serverLANEventBuffer) {
|
||||
if(!serverLANEventBuffer.isEmpty()) {
|
||||
synchronized (serverLANEventBuffer) {
|
||||
if (!serverLANEventBuffer.isEmpty()) {
|
||||
List<LANPeerEvent> 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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<String> urlListA = new ArrayList();
|
||||
ListMultimap<String,String> downloadSources = updateCert.getSourceMultimap();
|
||||
ListMultimap<String, String> downloadSources = updateCert.getSourceMultimap();
|
||||
|
||||
List<String> 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<String> 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<String> 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<byte[]> 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<ProgressEvent>() {
|
||||
@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<Event>() {
|
||||
@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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <script> tag");
|
||||
logger.info("Define \"window.eaglercraftXClientScriptElement\" or \"window.eaglercraftXClientScriptURL\" to force");
|
||||
logger.info(
|
||||
"Define \"window.eaglercraftXClientScriptElement\" or \"window.eaglercraftXClientScriptURL\" to force");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String createIntegratedServerWorkerURL() {
|
||||
JSObject blobObj = loadIntegratedServerSource();
|
||||
if(blobObj == null) {
|
||||
if (blobObj == null) {
|
||||
return null;
|
||||
}
|
||||
return createWorkerScriptURL(blobObj);
|
||||
|
@ -173,15 +182,16 @@ public class ClientPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static void startIntegratedServer() {
|
||||
if(!serverSourceLoaded) {
|
||||
if (!serverSourceLoaded) {
|
||||
integratedServerSource = createIntegratedServerWorkerURL();
|
||||
serverSourceLoaded = true;
|
||||
}
|
||||
|
||||
if(integratedServerSource == null) {
|
||||
throw new RuntimeException("Could not resolve the location of client's classes.js! Make sure client's classes.js is linked/embedded in a dedicated <script> tag. Define \"window.eaglercraftXClientScriptElement\" or \"window.eaglercraftXClientScriptURL\" to force");
|
||||
|
||||
if (integratedServerSource == null) {
|
||||
throw new RuntimeException(
|
||||
"Could not resolve the location of client's classes.js! Make sure client's classes.js is linked/embedded in a dedicated <script> tag. Define \"window.eaglercraftXClientScriptElement\" or \"window.eaglercraftXClientScriptURL\" to force");
|
||||
}
|
||||
|
||||
|
||||
workerObj = Worker.create(integratedServerSource);
|
||||
workerObj.onError(new EventListener<ErrorEvent>() {
|
||||
@Override
|
||||
|
@ -192,27 +202,24 @@ public class ClientPlatformSingleplayer {
|
|||
});
|
||||
registerPacketHandler(workerObj, new WorkerBinaryPacketHandlerImpl());
|
||||
sendWorkerStartPacket(workerObj, PlatformRuntime.getClientConfigAdapter().getIntegratedServerOpts().toString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void sendPacket(IPCPacketData packet) {
|
||||
ArrayBuffer arb = ArrayBuffer.create(packet.contents.length);
|
||||
Uint8Array ar = Uint8Array.create(arb);
|
||||
ar.set(packet.contents);
|
||||
sendPacketTeaVM(packet.channel, TeaVMUtils.unwrapUnsignedByteArray(packet.contents).getBuffer());
|
||||
sendPacketTeaVM(packet.channel, TeaVMUtils.unwrapArrayBuffer(packet.contents));
|
||||
}
|
||||
|
||||
public static void sendPacketTeaVM(String channel, ArrayBuffer packet) {
|
||||
if(workerObj != null) {
|
||||
if (workerObj != null) {
|
||||
sendWorkerPacket(workerObj, channel, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<IPCPacketData> recieveAllPacket() {
|
||||
synchronized(messageQueue) {
|
||||
if(messageQueue.size() == 0) {
|
||||
synchronized (messageQueue) {
|
||||
if (messageQueue.size() == 0) {
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
List<IPCPacketData> ret = new ArrayList<>(messageQueue);
|
||||
messageQueue.clear();
|
||||
return ret;
|
||||
|
@ -225,7 +232,7 @@ public class ClientPlatformSingleplayer {
|
|||
}
|
||||
|
||||
public static void killWorker() {
|
||||
if(workerObj != null) {
|
||||
if (workerObj != null) {
|
||||
workerObj.terminate();
|
||||
workerObj = null;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import org.teavm.jso.JSBody;
|
|||
import org.teavm.jso.JSFunctor;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||
import org.teavm.jso.typedarrays.Uint8Array;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData;
|
||||
|
@ -21,14 +20,21 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
|||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -45,23 +51,23 @@ public class ServerPlatformSingleplayer {
|
|||
}
|
||||
|
||||
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 = { "wb" }, script = "onmessage = function(o) { wb(o.data.ch, o.data.dat); };")
|
||||
|
@ -79,17 +85,14 @@ public class ServerPlatformSingleplayer {
|
|||
public static native void sendPacketTeaVM(String channel, ArrayBuffer arr);
|
||||
|
||||
public static void sendPacket(IPCPacketData packet) {
|
||||
ArrayBuffer arb = ArrayBuffer.create(packet.contents.length);
|
||||
Uint8Array ar = Uint8Array.create(arb);
|
||||
ar.set(packet.contents);
|
||||
sendPacketTeaVM(packet.channel, arb);
|
||||
sendPacketTeaVM(packet.channel, TeaVMUtils.unwrapArrayBuffer(packet.contents));
|
||||
}
|
||||
|
||||
public static List<IPCPacketData> recieveAllPacket() {
|
||||
synchronized(messageQueue) {
|
||||
if(messageQueue.size() == 0) {
|
||||
synchronized (messageQueue) {
|
||||
if (messageQueue.size() == 0) {
|
||||
return null;
|
||||
}else {
|
||||
} else {
|
||||
List<IPCPacketData> ret = new ArrayList(messageQueue);
|
||||
messageQueue.clear();
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue