Update #22 - Singleplayer and shared worlds, shader fixes

This commit is contained in:
lax1dude
2023-12-12 01:22:54 -08:00
parent e3d6256493
commit 3f00d402fa
2350 changed files with 45241 additions and 7798 deletions

View File

@ -12,16 +12,18 @@ import net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGLQuery;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGLVertexArray;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class OpenGLObjects {

View File

@ -16,29 +16,37 @@ import org.teavm.jso.canvas.CanvasRenderingContext2D;
import org.teavm.jso.dom.events.Event;
import org.teavm.jso.dom.events.EventListener;
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.dom.xml.Document;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Int8Array;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.Base64;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.DebugConsoleWindow;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformApplication {
public static void openLink(String url) {
if(url.indexOf(':') == -1) {
url = "http://" + url;
}
Window.current().open(url, "_blank", "noopener,noreferrer");
}
@ -90,7 +98,11 @@ public class PlatformApplication {
try {
Storage s = Window.current().getLocalStorage();
if(s != null) {
s.setItem("_eaglercraftX." + name, Base64.encodeBase64String(data));
if(data != null) {
s.setItem("_eaglercraftX." + name, Base64.encodeBase64String(data));
}else {
s.removeItem("_eaglercraftX." + name);
}
}
}catch(Throwable t) {
}
@ -114,7 +126,7 @@ public class PlatformApplication {
}
}
private static final DateFormat dateFormatSS = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss");
private static final DateFormat dateFormatSS = EagRuntime.fixDateFormat(new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss"));
public static String saveScreenshot() {
String name = "screenshot_" + dateFormatSS.format(new Date()).toString() + ".png";
@ -156,12 +168,7 @@ public class PlatformApplication {
if(name == null) {
fileChooserResultObject = null;
}else {
Int8Array typedArray = Int8Array.create(buffer);
byte[] bytes = new byte[typedArray.getByteLength()];
for(int i = 0; i < bytes.length; ++i) {
bytes[i] = typedArray.get(i);
}
fileChooserResultObject = new FileChooserResult(name, bytes);
fileChooserResultObject = new FileChooserResult(name, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buffer)));
}
}
@ -213,8 +220,14 @@ public class PlatformApplication {
return res;
}
@JSBody(params = { "doc", "str" }, script = "doc.write(str);")
private static native void documentWrite(Document doc, String str);
private static final String faviconURLString = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAR/SURBVEhLtZXZK3ZRFMYPcqXc+gv413DHxVuGIpIhkciQWaRccCNjSCkligwXSOZ5nmfv9zvn2e8+58V753sudmuvvdZ61l5r7XOc8H+GS/D19aUNkPz5+aktQH5/f//4+LBKZKuRkpUtQjCUYG5gD2T38vLy/PwsDfL9/f3Dw8PT05M0b29vnKLhCKCBT4L4gvBLBIei4//4+Hh1dUVEQutUuLu7E83FxQUGnKLBWKfQaA3S+AREVxaEOD8/Pzk50XpzcyMDcH19zdZG3N3d3dzc3Nvb01aX5pQUpQGGQJxcQpfNysoKhUIdHR1o1tbWbInYAgxIPDMzMy8vLzc3FxqOdMoRqwJK8G8ALUYIhHMiSEhIwI6CyIb0qQzC4eGhsXCc1tZWnZIEKzdQJQSXgKxfX18RCM3Z5eWlcfVAxKOjo+Pj49PTU88lTOk2NjbMsePc3t6SAfcgFdszOyMuAdeBg0CQi2lhYUHOeOLDCisN8FzcPFZXV3t7ezHY3t5GQ+6it+2xMASsKhEEWKsmRLRBBUpPvpJ/TpFKFBwKYAiITmicsbYhdHfJAltqhUCVsCQhwslmeXmZxiBQT9c0Ar9E2O3v72sYSE0N1yQArkKy0kBMXLqlZqIZHR3t6empqqqSDcBdhXEJSJ/bUc3q6uq+vj629GB9fR1WsLW1NTs7u7S0RN2locMjIyOEm5ubQ7+4uJienk4/+vv77Y1hwhLBEKhwWHitdVFfX9/Y2Gg2HuLi4owUAysrK8yCG97rh0+ApP5Q2ZycHFlPTExUVFRIBvn5+WhKSkp2dnaMKhptbW2426GgQ/rwuAQCZ1hwFayLiork9hMFBQV1dXVmE0BLS4vqw3QFB8kn4IAxoGPkYpxi4FeDmpqas7Mz4pClAgqGwD48rjY2NmacYqC0tJQ1KSlJWyE5OZkpUKkBAxZVIntAoZh04+Q48fHxPNGBgYHExMT29naj9cBodnZ2mo3jlJWVMeW2OGQck4B1amqqoaGhqamJjx2lGxwcpL0mUgR8fJhsWqJtSkoKU2SbHHUDpkhPBujd8xuQG6PJRM/Pz09PT7O1NNnZ2Tw3fgZkXVhYKCUlUhBATP+hCVyKZGky17RV0g04laayslJ6hlVeFHB4eFhKaogGd0LxtmTgE+hbhKDnPjMzgw8E3qGL2tpaBWpubjYqj2BoaEj6rq4uNATRZ0ZwCbiL6gXEzINk5vCBQJ9rMD4+rkA8QNK036uDg4Py8vLu7m680KjIBNR3zBDoWQM1g98snyB+VSoRW8C/UwR81/SvhgNj9JOTkwwVERUdRBEI0BAdLRVERkhLS8vIyEDQlrsTPTU1lVFhKxARvZgUlFLbegCf4BvIsbi4mIg4E5EogIHhiKCMtU0WUFiVy06j5fAJIDdSBDQw+PegDfBRcbOPwH4F9LuFWIIQdQNKwWqzIE0aoFUaBsw+SQuFw0uNtC9A+F4i3QNrbg3IDn+SAsHh+wYiEpeyBEMLv/cAO6KzAijxxB+Y4wisBhssJUhjEbPJf4Nw+B+JXqLW3bw+wQAAAABJRU5ErkJggg==";
public static String faviconURLTeaVM() {
return faviconURLString.substring(0);
}
@JSBody(params = { "doc", "str" }, script = "doc.write(str);doc.close();")
private static native void documentWrite(HTMLDocument doc, String str);
public static void openCreditsPopup(String text) {
Window currentWin = Window.current();
@ -226,9 +239,43 @@ public class PlatformApplication {
int y = (currentWin.getScreen().getHeight() - h) / 2;
Window newWin = Window.current().open("", "_blank", "top=" + y + ",left=" + x + ",width=" + w + ",height=" + h + ",menubar=0,status=0,titlebar=0,toolbar=0");
if(newWin == null) {
Window.alert("ERROR: Popup blocked!\n\nPlease make sure you have popups enabled for this site!");
return;
}
newWin.focus();
documentWrite(newWin.getDocument(), "<html><head><title>EaglercraftX 1.8 Credits</title></head><body><pre>" + text + "</pre></body></html>");
documentWrite(newWin.getDocument(), "<!DOCTYPE html><html><head><meta charset=\"UTF-8\" />"
+ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /><title>EaglercraftX 1.8 Credits</title>"
+ "<link type=\"image/png\" rel=\"shortcut icon\" href=\"" + PlatformApplication.faviconURLTeaVM() + "\" />"
+ "</head><body><pre>" + text + "</pre></body></html>");
}
public static void clearFileChooserResult() {
fileChooserHasResult = false;
fileChooserResultObject = null;
}
@JSBody(params = { "name", "buf" }, script =
"var hr = window.URL.createObjectURL(new Blob([buf], {type: \"octet/stream\"}));" +
"var a = document.createElement(\"a\");" +
"a.href = hr; a.download = name; a.click();" +
"window.URL.revokeObjectURL(hr);")
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());
}
public static void showDebugConsole() {
DebugConsoleWindow.showDebugConsole();
}
public static void addLogMessage(String text, boolean err) {
DebugConsoleWindow.addLogMessage(text, err);
}
public static boolean isShowingDebugConsole() {
return DebugConsoleWindow.isShowingDebugConsole();
}
}

View File

@ -16,26 +16,27 @@ import org.teavm.jso.dom.html.HTMLCanvasElement;
import org.teavm.jso.dom.html.HTMLImageElement;
import org.teavm.jso.dom.xml.Document;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.DataView;
import org.teavm.jso.typedarrays.Uint8Array;
import org.teavm.jso.typedarrays.Int32Array;
import org.teavm.jso.typedarrays.Uint8ClampedArray;
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.MainClass;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ClientMain;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformAssets {
@ -51,7 +52,7 @@ public class PlatformAssets {
byte[] data = assets.get(path);
if(data == null && path.startsWith("assets/minecraft/lang/") && !path.endsWith(".mcmeta")) {
ArrayBuffer file = PlatformRuntime.downloadRemoteURI(
MainClass.configLocalesFolder + "/" + path.substring(22));
ClientMain.configLocalesFolder + "/" + path.substring(22));
if(file != null && file.getByteLength() > 0) {
data = TeaVMUtils.arrayBufferToBytes(file);
assets.put(path, data);
@ -78,9 +79,7 @@ public class PlatformAssets {
private static CanvasRenderingContext2D imageLoadContext = null;
public static ImageData loadImageFile(byte[] data) {
Uint8Array buf = Uint8Array.create(data.length);
buf.set(data);
return loadImageFile(buf.getBuffer());
return loadImageFile(TeaVMUtils.unwrapUnsignedByteArray(data).getBuffer());
}
@JSBody(params = { }, script = "return { willReadFrequently: true };")
@ -117,12 +116,7 @@ public class PlatformAssets {
ret.complete(null);
return;
}
DataView view = DataView.create(pxls.getBuffer());
int[] pixels = new int[totalPixels];
for(int i = 0; i < pixels.length; ++i) {
pixels[i] = view.getUint32(i << 2, true);
}
ret.complete(new ImageData(pxlsDat.getWidth(), pxlsDat.getHeight(), pixels, true));
ret.complete(new ImageData(pxlsDat.getWidth(), pxlsDat.getHeight(), TeaVMUtils.wrapIntArray(Int32Array.create(pxls.getBuffer())), true));
}
});
toLoad.addEventListener("error", new EventListener<Event>() {

View File

@ -24,6 +24,7 @@ import org.teavm.jso.webaudio.MediaStream;
import org.teavm.jso.webaudio.MediaStreamAudioDestinationNode;
import org.teavm.jso.webaudio.PannerNode;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.util.MathHelper;
@ -211,9 +212,7 @@ public class PlatformAudio {
if(buffer == null) {
byte[] file = PlatformAssets.getResourceBytes(filename);
if(file == null) return null;
Uint8Array buf = Uint8Array.create(file.length);
buf.set(file);
buffer = new BrowserAudioResource(decodeAudioAsync(buf.getBuffer(), filename));
buffer = new BrowserAudioResource(decodeAudioAsync(TeaVMUtils.unwrapUnsignedByteArray(file).getBuffer(), filename));
if(holdInCache) {
synchronized(soundCache) {
soundCache.put(filename, buffer);

View File

@ -4,16 +4,18 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformBufferFunctions {

View File

@ -0,0 +1,354 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.indexeddb.EventHandler;
import org.teavm.jso.indexeddb.IDBCountRequest;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBCursorRequest;
import org.teavm.jso.indexeddb.IDBDatabase;
import org.teavm.jso.indexeddb.IDBFactory;
import org.teavm.jso.indexeddb.IDBGetRequest;
import org.teavm.jso.indexeddb.IDBObjectStoreParameters;
import org.teavm.jso.indexeddb.IDBOpenDBRequest;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.indexeddb.IDBTransaction;
import org.teavm.jso.indexeddb.IDBVersionChangeEvent;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.DataView;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.EaglerArrayBufferAllocator;
import net.lax1dude.eaglercraft.v1_8.internal.vfs.BooleanResult;
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2;
import net.lax1dude.eaglercraft.v1_8.sp.server.internal.ServerPlatformSingleplayer;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformFilesystem {
private static String filesystemDB = null;
private static IDBDatabase database = null;
public static void initialize() {
filesystemDB = "_net_lax1dude_eaglercraft_v1_8_internal_PlatformFilesystem_1_8_8_"
+ ServerPlatformSingleplayer.getClientConfigAdapter().getWorldsDB();
DatabaseOpen dbOpen = AsyncHandlers.openDB(filesystemDB);
if(dbOpen.failedLocked) {
throw new WorldsDatabaseLockedException(dbOpen.failedError);
}
if(dbOpen.failedInit) {
throw new WorldsDatabaseInitializationException(dbOpen.failedError);
}
if(dbOpen.database == null) {
throw new NullPointerException("IDBDatabase is null!");
}
database = dbOpen.database;
}
public static class WorldsDatabaseLockedException extends RuntimeException {
public WorldsDatabaseLockedException(String message) {
super(message);
}
}
public static class WorldsDatabaseInitializationException extends RuntimeException {
public WorldsDatabaseInitializationException(String message) {
super(message);
}
}
public static boolean eaglerDelete(String pathName) {
return AsyncHandlers.deleteFile(database, pathName).bool;
}
public static ByteBuffer eaglerRead(String pathName) {
ArrayBuffer ar = AsyncHandlers.readWholeFile(database, pathName);
if(ar == null) {
return null;
}
return EaglerArrayBufferAllocator.wrapByteBufferTeaVM(DataView.create(ar));
}
public static void eaglerWrite(String pathName, ByteBuffer data) {
if(!AsyncHandlers.writeWholeFile(database, pathName, EaglerArrayBufferAllocator.getDataViewStupid(data).getBuffer()).bool) {
throw new RuntimeException("Failed to write " + data.remaining() + " byte file to indexeddb table: " + pathName);
}
}
public static boolean eaglerExists(String pathName) {
return AsyncHandlers.fileExists(database, pathName).bool;
}
public static boolean eaglerMove(String pathNameOld, String pathNameNew) {
ArrayBuffer old = AsyncHandlers.readWholeFile(database, pathNameOld);
return old != null && AsyncHandlers.writeWholeFile(database, pathNameNew, old).bool && AsyncHandlers.deleteFile(database, pathNameOld).bool;
}
public static int eaglerCopy(String pathNameOld, String pathNameNew) {
ArrayBuffer old = AsyncHandlers.readWholeFile(database, pathNameOld);
if(old != null && AsyncHandlers.writeWholeFile(database, pathNameNew, old).bool) {
return old.getByteLength();
}else {
return -1;
}
}
public static int eaglerSize(String pathName) {
ArrayBuffer old = AsyncHandlers.readWholeFile(database, pathName);
return old == null ? -1 : old.getByteLength();
}
private static class VFSFilenameIteratorNonRecursive implements VFSFilenameIterator {
private final VFSFilenameIterator child;
private final int pathCount;
private VFSFilenameIteratorNonRecursive(VFSFilenameIterator child, int pathCount) {
this.child = child;
this.pathCount = pathCount;
}
@Override
public void next(String entry) {
if(countSlashes(entry) == pathCount) {
child.next(entry);
}
}
}
private static int countSlashes(String str) {
int j = 0;
for(int i = 0, l = str.length(); i < l; ++i) {
if(str.charAt(i) == '/') {
++j;
}
}
return j;
}
public static void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
if(recursive) {
AsyncHandlers.iterateFiles(database, pathName, false, itr);
}else {
AsyncHandlers.iterateFiles(database, pathName, false, new VFSFilenameIteratorNonRecursive(itr, countSlashes(pathName) + 1));
}
}
protected static class DatabaseOpen {
protected final boolean failedInit;
protected final boolean failedLocked;
protected final String failedError;
protected final IDBDatabase database;
protected DatabaseOpen(boolean init, boolean locked, String error, IDBDatabase db) {
failedInit = init;
failedLocked = locked;
failedError = error;
database = db;
}
}
@JSBody(script = "return ((typeof indexedDB) !== 'undefined') ? indexedDB : null;")
protected static native IDBFactory createIDBFactory();
protected static class AsyncHandlers {
@Async
protected static native DatabaseOpen openDB(String name);
private static void openDB(String name, final AsyncCallback<DatabaseOpen> cb) {
IDBFactory i = createIDBFactory();
if(i == null) {
cb.complete(new DatabaseOpen(false, false, "window.indexedDB was null or undefined", null));
return;
}
final IDBOpenDBRequest f = i.open(name, 1);
f.setOnBlocked(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, true, null, null));
}
});
f.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, false, null, f.getResult()));
}
});
f.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, false, "open error", null));
}
});
f.setOnUpgradeNeeded(new EventListener<IDBVersionChangeEvent>() {
@Override
public void handleEvent(IDBVersionChangeEvent evt) {
f.getResult().createObjectStore("filesystem", IDBObjectStoreParameters.create().keyPath("path"));
}
});
}
@Async
protected static native BooleanResult deleteFile(IDBDatabase db, String name);
private static void deleteFile(IDBDatabase db, String name, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBRequest r = tx.objectStore("filesystem").delete(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult.TRUE);
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult.FALSE);
}
});
}
@JSBody(params = { "obj" }, script = "return (typeof obj === \"undefined\") ? null : ((typeof obj.data === \"undefined\") ? null : obj.data);")
protected static native ArrayBuffer readRow(JSObject obj);
@JSBody(params = { "obj" }, script = "return [obj];")
private static native JSObject makeTheFuckingKeyWork(String k);
@Async
protected static native ArrayBuffer readWholeFile(IDBDatabase db, String name);
private static void readWholeFile(IDBDatabase db, String name, final AsyncCallback<ArrayBuffer> cb) {
IDBTransaction tx = db.transaction("filesystem", "readonly");
final IDBGetRequest r = tx.objectStore("filesystem").get(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(readRow(r.getResult()));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(null);
}
});
}
@JSBody(params = { "k" }, script = "return ((typeof k) === \"string\") ? k : (((typeof k) === \"undefined\") ? null : (((typeof k[0]) === \"string\") ? k[0] : null));")
private static native String readKey(JSObject k);
@JSBody(params = { "k" }, script = "return ((typeof k) === \"undefined\") ? null : (((typeof k.path) === \"undefined\") ? null : (((typeof k.path) === \"string\") ? k[0] : null));")
private static native String readRowKey(JSObject r);
@Async
protected static native Integer iterateFiles(IDBDatabase db, final String prefix, boolean rw, final VFSFilenameIterator itr);
private static void iterateFiles(IDBDatabase db, final String prefix, boolean rw, final VFSFilenameIterator itr, final AsyncCallback<Integer> cb) {
IDBTransaction tx = db.transaction("filesystem", rw ? "readwrite" : "readonly");
final IDBCursorRequest r = tx.objectStore("filesystem").openCursor();
final int[] res = new int[1];
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
IDBCursor c = r.getResult();
if(c == null || c.getKey() == null || c.getValue() == null) {
cb.complete(res[0]);
return;
}
String k = readKey(c.getKey());
if(k != null) {
if(k.startsWith(prefix)) {
int ci = res[0]++;
try {
itr.next(k);
}catch(VFSIterator2.BreakLoop ex) {
cb.complete(res[0]);
return;
}
}
}
c.doContinue();
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(res[0] > 0 ? res[0] : -1);
}
});
}
@Async
protected static native BooleanResult fileExists(IDBDatabase db, String name);
private static void fileExists(IDBDatabase db, String name, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readonly");
final IDBCountRequest r = tx.objectStore("filesystem").count(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(r.getResult() > 0));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult.FALSE);
}
});
}
@JSBody(params = { "pat", "dat" }, script = "return { path: pat, data: dat };")
protected static native JSObject writeRow(String name, ArrayBuffer data);
@Async
protected static native BooleanResult writeWholeFile(IDBDatabase db, String name, ArrayBuffer data);
private static void writeWholeFile(IDBDatabase db, String name, ArrayBuffer data, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBRequest r = tx.objectStore("filesystem").put(writeRow(name, data));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult.TRUE);
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult.FALSE);
}
});
}
}
}

View File

@ -25,16 +25,18 @@ import net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGL2RenderingContext;
import static net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGL2RenderingContext.*;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformInput {
@ -104,7 +106,7 @@ public class PlatformInput {
static void initHooks(Window window, HTMLCanvasElement canvaz) {
win = window;
canvas = canvaz;
canvas.getStyle().setProperty("cursor", "default");
win.addEventListener("contextmenu", contextmenu = new EventListener<MouseEvent>() {
@Override
public void handleEvent(MouseEvent evt) {
@ -596,5 +598,20 @@ public class PlatformInput {
@JSBody(params = { "element" }, script = "element.requestFullscreen();")
private static native void requestFullscreen(HTMLElement element);
public static void showCursor(EnumCursorType cursor) {
switch(cursor) {
case DEFAULT:
default:
canvas.getStyle().setProperty("cursor", "default");
break;
case HAND:
canvas.getStyle().setProperty("cursor", "pointer");
break;
case TEXT:
canvas.getStyle().setProperty("cursor", "text");
break;
}
}
}

View File

@ -1,6 +1,8 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
@ -19,16 +21,18 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformNetworking {
@ -115,13 +119,8 @@ public class PlatformNetworking {
serverRateLimit = EnumServerRateLimit.LOCKED_OUT;
}
}else {
Uint8Array a = Uint8Array.create(evt.getDataAsArray());
byte[] b = new byte[a.getByteLength()];
for(int i = 0; i < b.length; ++i) {
b[i] = (byte) a.get(i);
}
synchronized(readPackets) {
readPackets.add(b);
readPackets.add(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray())));
}
}
}
@ -155,6 +154,18 @@ public class PlatformNetworking {
}
}
public static List<byte[]> readAllPacket() {
synchronized(readPackets) {
if(!readPackets.isEmpty()) {
List<byte[]> ret = new ArrayList<>(readPackets);
readPackets.clear();
return ret;
}else {
return null;
}
}
}
public static int countAvailableReadData() {
int total = 0;
synchronized(readPackets) {
@ -166,13 +177,11 @@ public class PlatformNetworking {
}
@JSBody(params = { "sock", "buffer" }, script = "sock.send(buffer);")
private static native void nativeBinarySend(WebSocket sock, ArrayBuffer buffer);
protected static native void nativeBinarySend(WebSocket sock, ArrayBuffer buffer);
public static void writePlayPacket(byte[] pkt) {
if(sock != null && !sockIsConnecting) {
Uint8Array arr = Uint8Array.create(pkt.length);
arr.set(pkt);
nativeBinarySend(sock, arr.getBuffer());
nativeBinarySend(sock, TeaVMUtils.unwrapUnsignedByteArray(pkt).getBuffer());
}
}

View File

@ -13,16 +13,18 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformOpenGL {
@ -405,7 +407,7 @@ public class PlatformOpenGL {
public static final int _wglGetUniformBlockIndex(IProgramGL obj, String name) {
int i = ctx.getUniformBlockIndex(((OpenGLObjects.ProgramGL)obj).ptr, name);
if(i == 0xFFFFFFFFl) {
if(i > 2147483647) {
i = -1;
}
return i;

View File

@ -7,6 +7,7 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.function.Consumer;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.EaglercraftVersion;
import net.lax1dude.eaglercraft.v1_8.profile.EaglerProfile;
import org.teavm.interop.Async;
@ -41,8 +42,10 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.EPKLoader;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.EarlyLoadScreen;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.MainClass;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.MainClass.EPKFileEntry;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.FixWebMDurationJS;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ClientMain;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ClientMain.EPKFileEntry;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.DebugConsoleWindow;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMClientConfigAdapter;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.WebGL2RenderingContext;
@ -51,16 +54,18 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformRuntime {
@ -78,12 +83,13 @@ public class PlatformRuntime {
public static void create() {
win = Window.current();
doc = win.getDocument();
DebugConsoleWindow.initialize(win);
logger.info("Creating main game canvas");
parent = doc.getElementById(MainClass.configRootElement);
parent = doc.getElementById(ClientMain.configRootElementId);
if(parent == null) {
throw new RuntimeInitializationFailureException("Root element \"" + MainClass.configRootElement + "\" was not found in this document!");
throw new RuntimeInitializationFailureException("Root element \"" + ClientMain.configRootElementId + "\" was not found in this document!");
}
CSSStyleDeclaration style = parent.getStyle();
@ -135,7 +141,7 @@ public class PlatformRuntime {
EarlyLoadScreen.paintScreen();
EPKFileEntry[] epkFiles = MainClass.configEPKFiles;
EPKFileEntry[] epkFiles = ClientMain.configEPKFiles;
for(int i = 0; i < epkFiles.length; ++i) {
String url = epkFiles[i].url;
@ -173,6 +179,8 @@ public class PlatformRuntime {
}
logger.info("Platform initialization complete");
FixWebMDurationJS.checkOldScriptStillLoaded();
}
@JSBody(params = { }, script = "return {antialias: false, depth: false, powerPreference: \"high-performance\", desynchronized: true, preserveDrawingBuffer: false, premultipliedAlpha: false, alpha: false};")
@ -257,7 +265,11 @@ public class PlatformRuntime {
}
public static void downloadRemoteURI(String assetPackageURI, final Consumer<ArrayBuffer> cb) {
downloadRemoteURI(assetPackageURI, new AsyncCallback<ArrayBuffer>() {
downloadRemoteURI(assetPackageURI, false, cb);
}
public static void downloadRemoteURI(String assetPackageURI, boolean useCache, final Consumer<ArrayBuffer> cb) {
downloadRemoteURI(assetPackageURI, useCache, new AsyncCallback<ArrayBuffer>() {
@Override
public void complete(ArrayBuffer result) {
cb.accept(result);
@ -265,16 +277,16 @@ public class PlatformRuntime {
@Override
public void error(Throwable e) {
e.printStackTrace();
EagRuntime.debugPrintStackTrace(e);
cb.accept(null);
}
});
}
@Async
public static native ArrayBuffer downloadRemoteURI(String assetPackageURI);
public static native ArrayBuffer downloadRemoteURIOld(String assetPackageURI);
private static void downloadRemoteURI(String assetPackageURI, final AsyncCallback<ArrayBuffer> cb) {
private static void downloadRemoteURIOld(String assetPackageURI, final AsyncCallback<ArrayBuffer> cb) {
final XMLHttpRequest request = XMLHttpRequest.create();
request.setResponseType("arraybuffer");
request.open("GET", assetPackageURI, true);
@ -301,12 +313,33 @@ public class PlatformRuntime {
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); });")
private static native void doFetchDownload(String uri, String forceCache, FetchHandler callback);
public static ArrayBuffer downloadRemoteURI(String assetPackageURI) {
return downloadRemoteURI(assetPackageURI, true);
}
@Async
public static native ArrayBuffer downloadRemoteURI(String assetPackageURI, boolean forceCache);
private static void downloadRemoteURI(String assetPackageURI, boolean useCache, final AsyncCallback<ArrayBuffer> cb) {
doFetchDownload(assetPackageURI, useCache ? "force-cache" : "no-store", (bb) -> cb.complete(bb));
}
public static boolean isDebugRuntime() {
return false;
}
public static void writeCrashReport(String crashDump) {
MainClass.showCrashScreen(crashDump);
ClientMain.showCrashScreen(crashDump);
}
public static void removeEventHandlers() {
@ -354,13 +387,13 @@ public class PlatformRuntime {
}
@JSBody(params = { "o" }, script = "console.error(o);")
private static native void printNativeExceptionToConsole(JSObject o);
public static native void printNativeExceptionToConsoleTeaVM(JSObject o);
public static boolean printJSExceptionIfBrowser(Throwable t) {
if(t != null) {
JSObject o = JSExceptions.getJSException(t);
if(o != null) {
printNativeExceptionToConsole(o);
printNativeExceptionToConsoleTeaVM(o);
return true;
}
}
@ -372,7 +405,7 @@ public class PlatformRuntime {
}
public static void setThreadName(String string) {
// no teavm support
currentThreadName = string;
}
public static long maxMemory() {
@ -410,6 +443,9 @@ public class PlatformRuntime {
@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\");")
public static native boolean isOfflineDownloadURL();
public static IClientConfigAdapter getClientConfigAdapter() {
return TeaVMClientConfigAdapter.instance;
}
@ -437,14 +473,6 @@ public class PlatformRuntime {
@JSBody(params = { }, script = "return \"MediaRecorder\" in window;")
private static native boolean canRec();
@JSFunctor
private static interface RecUrlHandler extends JSObject {
void onUrl(String url);
}
@JSBody(params = { "e", "duration", "cb" }, script = "if (\"ysFixWebmDuration\" in window) { ysFixWebmDuration(e.data, duration, function(b) { cb(URL.createObjectURL(b)); }); } else { cb(URL.createObjectURL(e.data)); }")
private static native void getRecUrl(Event e, int duration, RecUrlHandler cb);
public static boolean recSupported() {
return true;
}
@ -516,7 +544,7 @@ public class PlatformRuntime {
return null;
}
private static final SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss");
private static final SimpleDateFormat fmt = EagRuntime.fixDateFormat(new SimpleDateFormat("yyyy-MM-dd hh-mm-ss"));
private static final Date dateInstance = new Date();
public static void toggleRec() {
@ -542,12 +570,15 @@ public class PlatformRuntime {
TeaVMUtils.addEventListener(mediaRec, "dataavailable", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
getRecUrl(evt, (int) (System.currentTimeMillis() - startTime), url -> {
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.setHref(url);
a.click();
TeaVMUtils.freeDataURL(url);
}, (msg) -> {
logger.info(msg);
});
}
});
@ -557,4 +588,14 @@ public class PlatformRuntime {
mediaRec = null;
}
}
public static long randomSeed() {
return (long)(Math.random() * 9007199254740991.0);
}
private static String currentThreadName = "main";
public static String currentThreadName() {
return currentThreadName;
}
}

View File

@ -0,0 +1,97 @@
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;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.update.UpdateCertificate;
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
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformUpdateSvc {
private static final Logger logger = LogManager.getLogger("PlatformUpdateSvc");
private static byte[] eaglercraftXClientSignature = null;
private static byte[] eaglercraftXClientBundle = null;
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;")
private static native String grabEaglercraftXClientSignature();
@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;
public static boolean supported() {
return true;
}
public static void initialize() {
eaglercraftXClientSignature = loadClientData(grabEaglercraftXClientSignature());
eaglercraftXClientBundle = loadClientData(grabEaglercraftXClientBundle());
}
private static byte[] loadClientData(String url) {
if(url == null) {
return null;
}
ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(url);
if(buf == null) {
logger.error("Failed to download client bundle or signature URL!");
return null;
}
return TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buf));
}
public static byte[] getClientSignatureData() {
return eaglercraftXClientSignature;
}
public static byte[] getClientBundleData() {
return eaglercraftXClientBundle;
}
public static void startClientUpdateFrom(UpdateCertificate clientUpdate) {
if(updateThread == null || !updateThread.isAlive()) {
updateThread = new Thread(new TeaVMUpdateThread(clientUpdate, progressStruct), "EaglerUpdateThread");
updateThread.setDaemon(true);
updateThread.start();
}else {
logger.error("Tried to start a new download while the current download thread was still alive!");
}
}
public static UpdateProgressStruct getUpdatingStatus() {
return progressStruct;
}
public static void quine(String filename, byte[] cert, byte[] data, String date) {
EagRuntime.downloadFileWithName(filename, TeaVMUpdateThread.generateSignedOffline(cert, data, date));
}
public static void quine(UpdateCertificate clientUpdate, byte[] data) {
TeaVMUpdateThread.downloadSignedOffline(clientUpdate, data);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -7,16 +7,18 @@ import org.teavm.jso.typedarrays.Uint16Array;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerArrayBufferAllocator {
@ -31,13 +33,25 @@ public class EaglerArrayBufferAllocator {
return new EaglerArrayByteBuffer(DataView.create(ArrayBuffer.create(size)));
}
public static ByteBuffer wrapByteBufferTeaVM(DataView dv) {
return new EaglerArrayByteBuffer(dv);
}
public static IntBuffer allocateIntBuffer(int size) {
return new EaglerArrayIntBuffer(DataView.create(ArrayBuffer.create(size << 2)));
}
public static IntBuffer wrapIntBufferTeaVM(DataView dv) {
return new EaglerArrayIntBuffer(dv);
}
public static FloatBuffer allocateFloatBuffer(int size) {
return new EaglerArrayFloatBuffer(DataView.create(ArrayBuffer.create(size << 2)));
}
public static FloatBuffer wrapFloatBufferTeaVM(DataView dv) {
return new EaglerArrayFloatBuffer(dv);
}
public static DataView getDataView(ByteBuffer buffer) {
if(buffer instanceof EaglerArrayByteBuffer) {

View File

@ -5,16 +5,18 @@ import org.teavm.jso.typedarrays.DataView;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerArrayByteBuffer implements ByteBuffer {

View File

@ -5,16 +5,18 @@ import org.teavm.jso.typedarrays.DataView;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerArrayFloatBuffer implements FloatBuffer {

View File

@ -5,16 +5,18 @@ import org.teavm.jso.typedarrays.DataView;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerArrayIntBuffer implements IntBuffer {

View File

@ -5,16 +5,18 @@ import org.teavm.jso.typedarrays.DataView;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerArrayShortBuffer implements ShortBuffer {

View File

@ -1,24 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
@JSFunctor
public interface EventHandler extends JSObject {
void handleEvent();
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSProperty;
public interface IDBCountRequest extends IDBRequest {
@JSProperty
int getResult();
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSMethod;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public interface IDBCursor extends JSObject {
String DIRECTION_NEXT = "next";
String DIRECTION_NEXT_UNIQUE = "nextunique";
String DIRECTION_PREVIOUS = "prev";
String DIRECTION_PREVIOUS_UNIQUE = "prevunique";
@JSProperty
IDBCursorSource getSource();
@JSProperty
String getDirection();
@JSProperty
JSObject getKey();
@JSProperty
JSObject getValue();
@JSProperty
JSObject getPrimaryKey();
IDBRequest update(JSObject value);
void advance(int count);
@JSMethod("continue")
void doContinue();
IDBRequest delete();
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSProperty;
public interface IDBCursorRequest extends IDBRequest {
@JSProperty
IDBCursor getResult();
}

View File

@ -1,21 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSObject;
public interface IDBCursorSource extends JSObject {
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.EventTarget;
public interface IDBDatabase extends EventTarget {
String TRANSACTION_READONLY = "readonly";
String TRANSACTION_READWRITE = "readwrite";
String TRANSACTION_VERSIONCHANGE = "versionchange";
@JSProperty
String getName();
@JSProperty
int getVersion();
@JSProperty
String[] getObjectStoreNames();
IDBObjectStore createObjectStore(String name, IDBObjectStoreParameters optionalParameters);
IDBObjectStore createObjectStore(String name);
void deleteObjectStore(String name);
IDBTransaction transaction(String storeName, String transactionMode);
IDBTransaction transaction(String storeName);
IDBTransaction transaction(String[] storeNames, String transactionMode);
IDBTransaction transaction(String[] storeNames);
void close();
@JSProperty("onabort")
void setOnAbort(EventHandler handler);
@JSProperty("onerror")
void setOnError(EventHandler handler);
@JSProperty("onversionchange")
void setOnVersionChange(EventHandler handler);
}

View File

@ -1,24 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public abstract class IDBError implements JSObject {
@JSProperty
public abstract String getName();
}

View File

@ -1,46 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
public abstract class IDBFactory implements JSObject {
public static boolean isSupported() {
return !getInstanceImpl().isUndefined();
}
@JSBody(script = "return typeof this === 'undefined';")
private native boolean isUndefined();
public static IDBFactory getInstance() {
IDBFactory factory = getInstanceImpl();
if (!factory.isUndefined()) {
throw new IllegalStateException("IndexedDB is not supported in this browser");
}
return factory;
}
@JSBody(script = "return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || "
+ "window.msIndexedDB;")
static native IDBFactory getInstanceImpl();
public abstract IDBOpenDBRequest open(String name, int version);
public abstract IDBOpenDBRequest deleteDatabase(String name);
public abstract int cmp(JSObject a, JSObject b);
}

View File

@ -1,24 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public interface IDBGetRequest extends IDBRequest {
@JSProperty
JSObject getResult();
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.core.JSString;
public abstract class IDBIndex implements JSObject, IDBCursorSource {
@JSProperty
public abstract String getName();
@JSProperty("keyPath")
abstract JSObject getKeyPathImpl();
public final String[] getKeyPath() {
JSObject result = getKeyPathImpl();
if (JSString.isInstance(result)) {
return new String[] { result.<JSString>cast().stringValue() };
} else {
return unwrapStringArray(result);
}
}
@JSBody(params = { "obj" }, script = "return this;")
private native String[] unwrapStringArray(JSObject obj);
@JSProperty
public abstract boolean isMultiEntry();
@JSProperty
public abstract boolean isUnique();
public abstract IDBCursorRequest openCursor();
public abstract IDBCursorRequest openCursor(IDBKeyRange range);
public abstract IDBCursorRequest openKeyCursor();
public abstract IDBGetRequest get(JSObject key);
public abstract IDBGetRequest getKey(JSObject key);
public abstract IDBCountRequest count(JSObject key);
public abstract IDBCountRequest count();
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public abstract class IDBKeyRange implements JSObject {
@JSProperty
public abstract JSObject getLower();
@JSProperty
public abstract JSObject getUpper();
@JSProperty
public abstract boolean isLowerOpen();
@JSProperty
public abstract boolean isUpperOpen();
@JSBody(params = "value", script = "return IDBKeyRange.only(value);")
public static native IDBKeyRange only(JSObject value);
@JSBody(params = { "lower", "open" }, script = "return IDBKeyRange.lowerBound(lower, open);")
public static native IDBKeyRange lowerBound(JSObject lower, boolean open);
public static IDBKeyRange lowerBound(JSObject lower) {
return lowerBound(lower, false);
}
@JSBody(params = { "upper", "open" }, script = "return IDBKeyRange.upperBound(upper, open);")
public static native IDBKeyRange upperBound(JSObject upper, boolean open);
public static IDBKeyRange upperBound(JSObject upper) {
return upperBound(upper, false);
}
@JSBody(params = { "lower", "upper", "lowerOpen", "upperOpen" },
script = "return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);")
public static native IDBKeyRange bound(JSObject lower, JSObject upper, boolean lowerOpen, boolean upperOpen);
public static IDBKeyRange bound(JSObject lower, JSObject upper) {
return bound(lower, upper, false, false);
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.core.JSString;
public abstract class IDBObjectStore implements JSObject, IDBCursorSource {
@JSProperty
public abstract String getName();
@JSProperty("keyPath")
abstract JSObject getKeyPathImpl();
public final String[] getKeyPath() {
JSObject result = getKeyPathImpl();
if (JSString.isInstance(result)) {
return new String[] { result.<JSString>cast().stringValue() };
} else {
return unwrapStringArray(result);
}
}
@JSBody(params = { "obj" }, script = "return this;")
private native String[] unwrapStringArray(JSObject obj);
@JSProperty
public abstract String[] getIndexNames();
@JSProperty
public abstract boolean isAutoIncrement();
public abstract IDBRequest put(JSObject value, JSObject key);
public abstract IDBRequest put(JSObject value);
public abstract IDBRequest add(JSObject value, JSObject key);
public abstract IDBRequest add(JSObject value);
public abstract IDBRequest delete(JSObject key);
public abstract IDBGetRequest get(JSObject key);
public abstract IDBRequest clear();
public abstract IDBCursorRequest openCursor();
public abstract IDBCursorRequest openCursor(IDBKeyRange range);
public abstract IDBIndex createIndex(String name, String key);
public abstract IDBIndex createIndex(String name, String[] keys);
public abstract IDBIndex index(String name);
public abstract void deleteIndex(String name);
public abstract IDBCountRequest count();
public abstract IDBCountRequest count(JSObject key);
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public abstract class IDBObjectStoreParameters implements JSObject {
@JSBody(script = "return {};")
public static native IDBObjectStoreParameters create();
public final IDBObjectStoreParameters keyPath(String... keys) {
setKeyPath(keys);
return this;
}
public final IDBObjectStoreParameters autoIncrement(boolean autoIncrement) {
setAutoIncrement(autoIncrement);
return this;
}
@JSProperty
abstract void setKeyPath(String[] keys);
@JSProperty
abstract void setAutoIncrement(boolean autoIncrement);
}

View File

@ -1,30 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.EventListener;
public interface IDBOpenDBRequest extends IDBRequest {
@JSProperty
IDBDatabase getResult();
@JSProperty
void setOnBlocked(EventHandler handler);
@JSProperty("onupgradeneeded")
void setOnUpgradeNeeded(EventListener<IDBVersionChangeEvent> listener);
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.EventTarget;
public interface IDBRequest extends EventTarget {
String STATE_PENDING = "pending";
String STATE_DONE = "done";
@JSProperty
IDBError getError();
@JSProperty
IDBRequestSource getSource();
@JSProperty
IDBTransaction getTransaction();
@JSProperty
String getReadyState();
@JSProperty("onerror")
void setOnError(EventHandler handler);
@JSProperty("onsuccess")
void setOnSuccess(EventHandler handler);
}

View File

@ -1,21 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSObject;
public interface IDBRequestSource extends JSObject {
}

View File

@ -1,44 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.EventTarget;
public interface IDBTransaction extends JSObject, EventTarget {
@JSProperty
String getMode();
@JSProperty
IDBDatabase getDb();
@JSProperty
IDBError getError();
IDBObjectStore objectStore(String name);
void abort();
@JSProperty("onabort")
void setOnAbort(EventHandler handler);
@JSProperty("oncomplete")
void setOnComplete(EventHandler handler);
@JSProperty("onerror")
void setOnError(EventHandler handler);
}

View File

@ -1,27 +0,0 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8.internal.indexeddb;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.Event;
public interface IDBVersionChangeEvent extends Event {
@JSProperty
int getOldVersion();
@JSProperty
int getNewVersion();
}

View File

@ -6,16 +6,18 @@ import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ArrayBufferInputStream extends InputStream {

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,173 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import java.util.LinkedList;
import java.util.List;
import org.teavm.jso.JSBody;
import org.teavm.jso.browser.Window;
import org.teavm.jso.dom.events.Event;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.dom.html.HTMLBodyElement;
import org.teavm.jso.dom.html.HTMLCollection;
import org.teavm.jso.dom.html.HTMLDocument;
import org.teavm.jso.dom.html.HTMLElement;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DebugConsoleWindow {
private static class LogMessage {
private final boolean err;
private final String msg;
public LogMessage(boolean err, String msg) {
this.err = err;
this.msg = msg;
}
}
private static final int bufferSpoolSize = 256;
private static final int windowMaxMessages = 2048;
private static final List<LogMessage> messageBuffer = new LinkedList();
public static Window parent = null;
public static Window logger = null;
private static HTMLDocument loggerDoc = null;
private static HTMLBodyElement loggerBody = null;
private static HTMLElement loggerMessageContainer = null;
public static void initialize(Window parentWindow) {
parent = parentWindow;
parent.addEventListener("unload", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
destroyWindow();
}
});
if("true".equals(parent.getLocalStorage().getItem("_eaglercraftX.showDebugConsole"))) {
showDebugConsole0();
}
}
public static void showDebugConsole() {
parent.getLocalStorage().setItem("_eaglercraftX.showDebugConsole", "true");
showDebugConsole0();
}
@JSBody(params = { "doc", "str" }, script = "doc.write(str);doc.close();")
private static native void documentWrite(HTMLDocument doc, String str);
private static void showDebugConsole0() {
if(logger == null) {
int w = (int)(1000 * parent.getDevicePixelRatio());
int h = (int)(400 * parent.getDevicePixelRatio());
int x = (parent.getScreen().getWidth() - w) / 2;
int y = (parent.getScreen().getHeight() - h) / 2;
logger = parent.open("", "_blank", "top=" + y + ",left=" + x + ",width=" + w + ",height=" + h + ",menubar=0,status=0,titlebar=0,toolbar=0");
if(logger == null) {
LogManager.getLogger("DebugConsoleWindow").error("Logger popup was blocked!");
Window.alert("ERROR: Popup blocked!\n\nPlease make sure you have popups enabled for this site!");
return;
}
logger.focus();
documentWrite(logger.getDocument(), "<!DOCTYPE html><html><head><meta charset=\"UTF-8\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />"
+ "<title>Debug Console</title><link type=\"image/png\" rel=\"shortcut icon\" href=\"" + PlatformApplication.faviconURLTeaVM() + "\" />"
+ "</head><body style=\"overflow-x:hidden;overflow-y:scroll;padding:0px;\"><p id=\"loggerMessageContainer\" style=\"overflow-wrap:break-word;white-space:pre-wrap;font:14px monospace;padding:10px;\"></p></body></html>");
loggerDoc = logger.getDocument();
loggerBody = loggerDoc.getBody();
loggerMessageContainer = loggerDoc.getElementById("loggerMessageContainer");
synchronized(messageBuffer) {
for(LogMessage msg : messageBuffer) {
appendLogMessage(msg.msg + "\n", msg.err ? "#DD0000" : "#000000");
}
messageBuffer.clear();
}
scrollToEnd0(logger, loggerDoc);
EventListener<Event> unloadListener = new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
if(logger != null) {
logger = null;
parent.getLocalStorage().setItem("_eaglercraftX.showDebugConsole", "false");
}
}
};
logger.addEventListener("beforeunload", unloadListener);
logger.addEventListener("unload", unloadListener);
}else {
logger.focus();
}
}
public static void addLogMessage(String text, boolean isErr) {
if(logger == null) {
synchronized(messageBuffer) {
if(logger == null) {
messageBuffer.add(new LogMessage(isErr, text));
while(messageBuffer.size() > bufferSpoolSize) {
messageBuffer.remove(0);
}
return;
}
}
}
appendLogMessageAndScroll(text + "\n", isErr ? "#DD0000" : "#000000");
}
private static void appendLogMessageAndScroll(String text, String color) {
boolean b = isScrollToEnd(logger, loggerDoc);
appendLogMessage(text, color);
if(b) {
scrollToEnd0(logger, loggerDoc);
}
}
private static void appendLogMessage(String text, String color) {
HTMLElement el = loggerDoc.createElement("span");
el.setInnerText(text);
el.getStyle().setProperty("color", color);
loggerMessageContainer.appendChild(el);
HTMLCollection children = loggerMessageContainer.getChildren();
while(children.getLength() > windowMaxMessages) {
children.get(0).delete();
}
}
@JSBody(params = { "win", "doc" }, script = "return (win.innerHeight + win.pageYOffset) >= doc.body.offsetHeight;")
private static native boolean isScrollToEnd(Window win, HTMLDocument doc);
@JSBody(params = { "win", "doc" }, script = "setTimeout(function(){win.scrollTo(0, doc.body.scrollHeight || doc.body.clientHeight);}, 1);")
private static native void scrollToEnd0(Window win, HTMLDocument doc);
public static void destroyWindow() {
if(logger != null) {
Window w = logger;
logger = null;
w.close();
}
}
public static boolean isShowingDebugConsole() {
return logger != null;
}
}

View File

@ -12,16 +12,18 @@ import com.jcraft.jzlib.GZIPInputStream;
import com.jcraft.jzlib.InflaterInputStream;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EPKLoader {

View File

@ -20,16 +20,18 @@ import net.lax1dude.eaglercraft.v1_8.Base64;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EarlyLoadScreen {

View File

@ -0,0 +1,115 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.Event;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
/**
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FixWebMDurationJS {
private static final Logger logger = LogManager.getLogger("FixWebMDurationJS");
private static JSObject fixWebMDurationHandle = null;
@JSBody(params = {}, script = "return typeof window.ysFixWebmDuration !== \"undefined\"")
private static native boolean isOldScriptStillLoaded();
public static void checkOldScriptStillLoaded() {
if(isOldScriptStillLoaded()) {
logger.error("The \"fix-webm-duration.js\" script is no longer required for EaglercraftX 1.8 u20 and up, it can be safely removed from this page");
}
}
public static void getRecUrl(Event e, int duration, RecUrlHandler cb, LogMsgHandler logger) {
checkOldScriptStillLoaded();
if(fixWebMDurationHandle == null) {
fixWebMDurationHandle = register();
}
getRecUrlImpl(fixWebMDurationHandle, e, duration, cb, logger);
}
@JSFunctor
public static interface RecUrlHandler extends JSObject {
void onUrl(String url);
}
@JSFunctor
public static interface LogMsgHandler extends JSObject {
void onMsg(String url);
}
@JSBody(params = { "lib", "e", "duration", "cb", "lgg" }, script = "lib(e.data, duration, function(b) { cb(URL.createObjectURL(b)); }, { logger: lgg });")
private static native void getRecUrlImpl(JSObject lib, Event e, int duration, RecUrlHandler cb, LogMsgHandler logger);
/*
* The MIT license (for fix-webm-duration)
*
* Copyright (c) 2018 Yury Sitnikov
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
@JSBody(params = {}, script = "function m(a,b){a.prototype=Object.create(b.prototype);a.prototype.constructor=a}function e(a,b){this.name=a||\"Unknown\";this.type=b||\"Unknown\"}function l(a,b){e.call(this,a,b||\"Uint\")}function k(a,b){e.call(this,a,b||\"Float\")}function h(a,b){e.call(this,a,b||\"Container\")}function n(a){h.call(this,\"File\",\"File\");"
+ "this.setSource(a)}function p(a,b,c,d){\"object\"===typeof c&&(d=c,c=void 0);if(!c)return new Promise(function(g){p(a,b,g,d)});try{var f=new FileReader;f.onloadend=function(){try{var g=new n(new Uint8Array(f.result));g.fixDuration(b,d)&&(a=g.toBlob(a.type))}catch(q){}c(a)};f.readAsArrayBuffer(a)}catch(g){c(a)}}var r={172351395:{name:\"EBML\",type:\"Container\"},646:{name:\"EBMLVersion\",type:\"Uint\"},759:{name:\"EBMLReadVersion\",type:\"Uint\"},754:{name:\"EBMLMaxIDLength\",type:\"Uint\"},755:{name:\"EBMLMaxSizeLength\","
+ "type:\"Uint\"},642:{name:\"DocType\",type:\"String\"},647:{name:\"DocTypeVersion\",type:\"Uint\"},645:{name:\"DocTypeReadVersion\",type:\"Uint\"},108:{name:\"Void\",type:\"Binary\"},63:{name:\"CRC-32\",type:\"Binary\"},190023271:{name:\"SignatureSlot\",type:\"Container\"},16010:{name:\"SignatureAlgo\",type:\"Uint\"},16026:{name:\"SignatureHash\",type:\"Uint\"},16037:{name:\"SignaturePublicKey\",type:\"Binary\"},16053:{name:\"Signature\",type:\"Binary\"},15963:{name:\"SignatureElements\",type:\"Container\"},15995:{name:\"SignatureElementList\","
+ "type:\"Container\"},9522:{name:\"SignedElement\",type:\"Binary\"},139690087:{name:\"Segment\",type:\"Container\"},21863284:{name:\"SeekHead\",type:\"Container\"},3515:{name:\"Seek\",type:\"Container\"},5035:{name:\"SeekID\",type:\"Binary\"},5036:{name:\"SeekPosition\",type:\"Uint\"},88713574:{name:\"Info\",type:\"Container\"},13220:{name:\"SegmentUID\",type:\"Binary\"},13188:{name:\"SegmentFilename\",type:\"String\"},1882403:{name:\"PrevUID\",type:\"Binary\"},1868715:{name:\"PrevFilename\",type:\"String\"},2013475:{name:\"NextUID\",type:\"Binary\"},"
+ "1999803:{name:\"NextFilename\",type:\"String\"},1092:{name:\"SegmentFamily\",type:\"Binary\"},10532:{name:\"ChapterTranslate\",type:\"Container\"},10748:{name:\"ChapterTranslateEditionUID\",type:\"Uint\"},10687:{name:\"ChapterTranslateCodec\",type:\"Uint\"},10661:{name:\"ChapterTranslateID\",type:\"Binary\"},710577:{name:\"TimecodeScale\",type:\"Uint\"},1161:{name:\"Duration\",type:\"Float\"},1121:{name:\"DateUTC\",type:\"Date\"},15273:{name:\"Title\",type:\"String\"},3456:{name:\"MuxingApp\",type:\"String\"},5953:{name:\"WritingApp\",type:\"String\"},"
+ "103:{name:\"Timecode\",type:\"Uint\"},6228:{name:\"SilentTracks\",type:\"Container\"},6359:{name:\"SilentTrackNumber\",type:\"Uint\"},39:{name:\"Position\",type:\"Uint\"},43:{name:\"PrevSize\",type:\"Uint\"},35:{name:\"SimpleBlock\",type:\"Binary\"},32:{name:\"BlockGroup\",type:\"Container\"},33:{name:\"Block\",type:\"Binary\"},34:{name:\"BlockVirtual\",type:\"Binary\"},13729:{name:\"BlockAdditions\",type:\"Container\"},38:{name:\"BlockMore\",type:\"Container\"},110:{name:\"BlockAddID\",type:\"Uint\"},37:{name:\"BlockAdditional\",type:\"Binary\"},"
+ "27:{name:\"BlockDuration\",type:\"Uint\"},122:{name:\"ReferencePriority\",type:\"Uint\"},123:{name:\"ReferenceBlock\",type:\"Int\"},125:{name:\"ReferenceVirtual\",type:\"Int\"},36:{name:\"CodecState\",type:\"Binary\"},13730:{name:\"DiscardPadding\",type:\"Int\"},14:{name:\"Slices\",type:\"Container\"},104:{name:\"TimeSlice\",type:\"Container\"},76:{name:\"LaceNumber\",type:\"Uint\"},77:{name:\"FrameNumber\",type:\"Uint\"},75:{name:\"BlockAdditionID\",type:\"Uint\"},78:{name:\"Delay\",type:\"Uint\"},79:{name:\"SliceDuration\",type:\"Uint\"},72:{name:\"ReferenceFrame\","
+ "type:\"Container\"},73:{name:\"ReferenceOffset\",type:\"Uint\"},74:{name:\"ReferenceTimeCode\",type:\"Uint\"},47:{name:\"EncryptedBlock\",type:\"Binary\"},106212971:{name:\"Tracks\",type:\"Container\"},46:{name:\"TrackEntry\",type:\"Container\"},87:{name:\"TrackNumber\",type:\"Uint\"},13253:{name:\"TrackUID\",type:\"Uint\"},3:{name:\"TrackType\",type:\"Uint\"},57:{name:\"FlagEnabled\",type:\"Uint\"},8:{name:\"FlagDefault\",type:\"Uint\"},5546:{name:\"FlagForced\",type:\"Uint\"},28:{name:\"FlagLacing\",type:\"Uint\"},11751:{name:\"MinCache\",type:\"Uint\"},"
+ "11768:{name:\"MaxCache\",type:\"Uint\"},254851:{name:\"DefaultDuration\",type:\"Uint\"},216698:{name:\"DefaultDecodedFieldDuration\",type:\"Uint\"},209231:{name:\"TrackTimecodeScale\",type:\"Float\"},4991:{name:\"TrackOffset\",type:\"Int\"},5614:{name:\"MaxBlockAdditionID\",type:\"Uint\"},4974:{name:\"Name\",type:\"String\"},177564:{name:\"Language\",type:\"String\"},6:{name:\"CodecID\",type:\"String\"},9122:{name:\"CodecPrivate\",type:\"Binary\"},362120:{name:\"CodecName\",type:\"String\"},13382:{name:\"AttachmentLink\",type:\"Uint\"},1742487:{name:\"CodecSettings\","
+ "type:\"String\"},1785920:{name:\"CodecInfoURL\",type:\"String\"},438848:{name:\"CodecDownloadURL\",type:\"String\"},42:{name:\"CodecDecodeAll\",type:\"Uint\"},12203:{name:\"TrackOverlay\",type:\"Uint\"},5802:{name:\"CodecDelay\",type:\"Uint\"},5819:{name:\"SeekPreRoll\",type:\"Uint\"},9764:{name:\"TrackTranslate\",type:\"Container\"},9980:{name:\"TrackTranslateEditionUID\",type:\"Uint\"},9919:{name:\"TrackTranslateCodec\",type:\"Uint\"},9893:{name:\"TrackTranslateTrackID\",type:\"Binary\"},96:{name:\"Video\",type:\"Container\"},26:{name:\"FlagInterlaced\","
+ "type:\"Uint\"},5048:{name:\"StereoMode\",type:\"Uint\"},5056:{name:\"AlphaMode\",type:\"Uint\"},5049:{name:\"OldStereoMode\",type:\"Uint\"},48:{name:\"PixelWidth\",type:\"Uint\"},58:{name:\"PixelHeight\",type:\"Uint\"},5290:{name:\"PixelCropBottom\",type:\"Uint\"},5307:{name:\"PixelCropTop\",type:\"Uint\"},5324:{name:\"PixelCropLeft\",type:\"Uint\"},5341:{name:\"PixelCropRight\",type:\"Uint\"},5296:{name:\"DisplayWidth\",type:\"Uint\"},5306:{name:\"DisplayHeight\",type:\"Uint\"},5298:{name:\"DisplayUnit\",type:\"Uint\"},5299:{name:\"AspectRatioType\","
+ "type:\"Uint\"},963876:{name:\"ColourSpace\",type:\"Binary\"},1029411:{name:\"GammaValue\",type:\"Float\"},230371:{name:\"FrameRate\",type:\"Float\"},97:{name:\"Audio\",type:\"Container\"},53:{name:\"SamplingFrequency\",type:\"Float\"},14517:{name:\"OutputSamplingFrequency\",type:\"Float\"},31:{name:\"Channels\",type:\"Uint\"},15739:{name:\"ChannelPositions\",type:\"Binary\"},8804:{name:\"BitDepth\",type:\"Uint\"},98:{name:\"TrackOperation\",type:\"Container\"},99:{name:\"TrackCombinePlanes\",type:\"Container\"},100:{name:\"TrackPlane\",type:\"Container\"},"
+ "101:{name:\"TrackPlaneUID\",type:\"Uint\"},102:{name:\"TrackPlaneType\",type:\"Uint\"},105:{name:\"TrackJoinBlocks\",type:\"Container\"},109:{name:\"TrackJoinUID\",type:\"Uint\"},64:{name:\"TrickTrackUID\",type:\"Uint\"},65:{name:\"TrickTrackSegmentUID\",type:\"Binary\"},70:{name:\"TrickTrackFlag\",type:\"Uint\"},71:{name:\"TrickMasterTrackUID\",type:\"Uint\"},68:{name:\"TrickMasterTrackSegmentUID\",type:\"Binary\"},11648:{name:\"ContentEncodings\",type:\"Container\"},8768:{name:\"ContentEncoding\",type:\"Container\"},4145:{name:\"ContentEncodingOrder\","
+ "type:\"Uint\"},4146:{name:\"ContentEncodingScope\",type:\"Uint\"},4147:{name:\"ContentEncodingType\",type:\"Uint\"},4148:{name:\"ContentCompression\",type:\"Container\"},596:{name:\"ContentCompAlgo\",type:\"Uint\"},597:{name:\"ContentCompSettings\",type:\"Binary\"},4149:{name:\"ContentEncryption\",type:\"Container\"},2017:{name:\"ContentEncAlgo\",type:\"Uint\"},2018:{name:\"ContentEncKeyID\",type:\"Binary\"},2019:{name:\"ContentSignature\",type:\"Binary\"},2020:{name:\"ContentSigKeyID\",type:\"Binary\"},2021:{name:\"ContentSigAlgo\",type:\"Uint\"},"
+ "2022:{name:\"ContentSigHashAlgo\",type:\"Uint\"},206814059:{name:\"Cues\",type:\"Container\"},59:{name:\"CuePoint\",type:\"Container\"},51:{name:\"CueTime\",type:\"Uint\"},55:{name:\"CueTrackPositions\",type:\"Container\"},119:{name:\"CueTrack\",type:\"Uint\"},113:{name:\"CueClusterPosition\",type:\"Uint\"},112:{name:\"CueRelativePosition\",type:\"Uint\"},50:{name:\"CueDuration\",type:\"Uint\"},4984:{name:\"CueBlockNumber\",type:\"Uint\"},106:{name:\"CueCodecState\",type:\"Uint\"},91:{name:\"CueReference\",type:\"Container\"},22:{name:\"CueRefTime\","
+ "type:\"Uint\"},23:{name:\"CueRefCluster\",type:\"Uint\"},4959:{name:\"CueRefNumber\",type:\"Uint\"},107:{name:\"CueRefCodecState\",type:\"Uint\"},155296873:{name:\"Attachments\",type:\"Container\"},8615:{name:\"AttachedFile\",type:\"Container\"},1662:{name:\"FileDescription\",type:\"String\"},1646:{name:\"FileName\",type:\"String\"},1632:{name:\"FileMimeType\",type:\"String\"},1628:{name:\"FileData\",type:\"Binary\"},1710:{name:\"FileUID\",type:\"Uint\"},1653:{name:\"FileReferral\",type:\"Binary\"},1633:{name:\"FileUsedStartTime\",type:\"Uint\"},"
+ "1634:{name:\"FileUsedEndTime\",type:\"Uint\"},4433776:{name:\"Chapters\",type:\"Container\"},1465:{name:\"EditionEntry\",type:\"Container\"},1468:{name:\"EditionUID\",type:\"Uint\"},1469:{name:\"EditionFlagHidden\",type:\"Uint\"},1499:{name:\"EditionFlagDefault\",type:\"Uint\"},1501:{name:\"EditionFlagOrdered\",type:\"Uint\"},54:{name:\"ChapterAtom\",type:\"Container\"},13252:{name:\"ChapterUID\",type:\"Uint\"},5716:{name:\"ChapterStringUID\",type:\"String\"},17:{name:\"ChapterTimeStart\",type:\"Uint\"},18:{name:\"ChapterTimeEnd\",type:\"Uint\"},"
+ "24:{name:\"ChapterFlagHidden\",type:\"Uint\"},1432:{name:\"ChapterFlagEnabled\",type:\"Uint\"},11879:{name:\"ChapterSegmentUID\",type:\"Binary\"},11964:{name:\"ChapterSegmentEditionUID\",type:\"Uint\"},9155:{name:\"ChapterPhysicalEquiv\",type:\"Uint\"},15:{name:\"ChapterTrack\",type:\"Container\"},9:{name:\"ChapterTrackNumber\",type:\"Uint\"},0:{name:\"ChapterDisplay\",type:\"Container\"},5:{name:\"ChapString\",type:\"String\"},892:{name:\"ChapLanguage\",type:\"String\"},894:{name:\"ChapCountry\",type:\"String\"},10564:{name:\"ChapProcess\","
+ "type:\"Container\"},10581:{name:\"ChapProcessCodecID\",type:\"Uint\"},1293:{name:\"ChapProcessPrivate\",type:\"Binary\"},10513:{name:\"ChapProcessCommand\",type:\"Container\"},10530:{name:\"ChapProcessTime\",type:\"Uint\"},10547:{name:\"ChapProcessData\",type:\"Binary\"},39109479:{name:\"Tags\",type:\"Container\"},13171:{name:\"Tag\",type:\"Container\"},9152:{name:\"Targets\",type:\"Container\"},10442:{name:\"TargetTypeValue\",type:\"Uint\"},9162:{name:\"TargetType\",type:\"String\"},9157:{name:\"TagTrackUID\",type:\"Uint\"},9161:{name:\"TagEditionUID\","
+ "type:\"Uint\"},9156:{name:\"TagChapterUID\",type:\"Uint\"},9158:{name:\"TagAttachmentUID\",type:\"Uint\"},10184:{name:\"SimpleTag\",type:\"Container\"},1443:{name:\"TagName\",type:\"String\"},1146:{name:\"TagLanguage\",type:\"String\"},1156:{name:\"TagDefault\",type:\"Uint\"},1159:{name:\"TagString\",type:\"String\"},1157:{name:\"TagBinary\",type:\"Binary\"}};e.prototype.updateBySource=function(){};e.prototype.setSource=function(a){this.source=a;this.updateBySource()};e.prototype.updateByData=function(){};e.prototype.setData=function(a){this.data="
+ "a;this.updateByData()};m(l,e);l.prototype.updateBySource=function(){this.data=\"\";for(var a=0;a<this.source.length;a++){var b=this.source[a].toString(16);this.data+=1===b.length%2?\"0\"+b:b}};l.prototype.updateByData=function(){var a=this.data.length/2;this.source=new Uint8Array(a);for(var b=0;b<a;b++){var c=this.data.substr(2*b,2);this.source[b]=parseInt(c,16)}};l.prototype.getValue=function(){return parseInt(this.data,16)};l.prototype.setValue=function(a){var b=this.setData;a=a.toString(16);b.call(this,"
+ "1===a.length%2?\"0\"+a:a)};m(k,e);k.prototype.getFloatArrayType=function(){return this.source&&4===this.source.length?Float32Array:Float64Array};k.prototype.updateBySource=function(){var a=this.source.reverse();this.data=(new (this.getFloatArrayType())(a.buffer))[0]};k.prototype.updateByData=function(){var a=new (this.getFloatArrayType())([this.data]);this.source=(new Uint8Array(a.buffer)).reverse()};k.prototype.getValue=function(){return this.data};k.prototype.setValue=function(a){this.setData(a)};"
+ "m(h,e);h.prototype.readByte=function(){return this.source[this.offset++]};h.prototype.readUint=function(){var a=this.readByte(),b=8-a.toString(2).length;a-=1<<7-b;for(var c=0;c<b;c++)a*=256,a+=this.readByte();return a};h.prototype.updateBySource=function(){this.data=[];for(this.offset=0;this.offset<this.source.length;this.offset=b){var a=this.readUint();b=this.readUint();var b=Math.min(this.offset+b,this.source.length),c=this.source.slice(this.offset,b),d=r[a]||{name:\"Unknown\",type:\"Unknown\"},f=e;"
+ "switch(d.type){case \"Container\":f=h;break;case \"Uint\":f=l;break;case \"Float\":f=k}d=new f(d.name,d.type);d.setSource(c);this.data.push({id:a,idHex:a.toString(16),data:d})}};h.prototype.writeUint=function(a,b){for(var c=1,d=128;a>=d&&8>c;c++,d*=128);if(!b)for(a=d+a,b=c-1;0<=b;b--)d=a%256,this.source[this.offset+b]=d,a=(a-d)/256;this.offset+=c};h.prototype.writeSections=function(a){for(var b=this.offset=0;b<this.data.length;b++){var c=this.data[b],d=c.data.source,f=d.length;this.writeUint(c.id,a);this.writeUint(f,"
+ "a);a||this.source.set(d,this.offset);this.offset+=f}return this.offset};h.prototype.updateByData=function(){var a=this.writeSections(\"draft\");this.source=new Uint8Array(a);this.writeSections()};h.prototype.getSectionById=function(a){for(var b=0;b<this.data.length;b++){var c=this.data[b];if(c.id===a)return c.data}return null};m(n,h);n.prototype.fixDuration=function(a,b){b=b.logger;var c=this.getSectionById(139690087);if(!c)return b(\"[fix-webm-duration] Segment section is missing\"),"
+ "!1;var d=c.getSectionById(88713574);if(!d)return b(\"[fix-webm-duration] Info section is missing\"),!1;var f=d.getSectionById(710577);if(!f)return b(\"[fix-webm-duration] TimecodeScale section is missing\"),!1;var g=d.getSectionById(1161);if(g)if(0>=g.getValue())b(\"[fix-webm-duration] Duration section is present, but the value is empty\"),g.setValue(a);else return b(\"[fix-webm-duration] Duration section is present\"),!1;else b(\"[fix-webm-duration] Duration section is missing\"),g=new k(\"Duration\",\"Float\"),"
+ "g.setValue(a),d.data.push({id:1161,data:g});f.setValue(1E6);d.updateByData();c.updateByData();this.updateByData();return!0};n.prototype.toBlob=function(a){return new Blob([this.source.buffer],{type:a||\"video/webm\"})};return p.default=p;")
private static native JSObject register();
}

File diff suppressed because one or more lines are too long

View File

@ -1,24 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
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.sp.relay.RelayManager;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import org.json.JSONArray;
import org.json.JSONObject;
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter;
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
@ -26,13 +37,40 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
public static final IClientConfigAdapter instance = new TeaVMClientConfigAdapter();
private String defaultLocale = "en_US";
private boolean hideDownDefaultServers = false;
private List<DefaultServer> defaultServers = new ArrayList();
private List<RelayEntry> relays = new ArrayList();
private String serverToJoin = null;
private String worldsDB = "worlds";
private JSONObject originalEaglercraftOpts;
private boolean isCheckShaderGLErrors = false;
private boolean demoMode = EaglercraftVersion.forceDemoMode;
private boolean isAllowUpdateSvc = EaglercraftVersion.enableUpdateService;
private boolean isAllowUpdateDL = EaglercraftVersion.enableUpdateService;
private boolean isEnableDownloadOfflineButton = true;
private String downloadOfflineButtonLink = null;
private boolean useSpecialCursors = false;
private boolean logInvalidCerts = false;
private boolean checkRelaysForUpdates = false;
private boolean enableSignatureBadge = false;
private static final EaglercraftRandom random = new EaglercraftRandom();
void loadJSON(JSONObject eaglercraftOpts) {
public void loadJSON(JSONObject eaglercraftOpts) {
originalEaglercraftOpts = eaglercraftOpts;
defaultLocale = eaglercraftOpts.optString("lang", "en_US");
serverToJoin = eaglercraftOpts.optString("joinServer", null);
worldsDB = eaglercraftOpts.optString("worldsDB", "worlds");
isCheckShaderGLErrors = eaglercraftOpts.optBoolean("checkShaderGLErrors", false);
if(EaglercraftVersion.forceDemoMode) {
eaglercraftOpts.put("demoMode", true);
}
demoMode = EaglercraftVersion.forceDemoMode || eaglercraftOpts.optBoolean("demoMode", false);
isAllowUpdateSvc = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftOpts.optBoolean("allowUpdateSvc", true);
isAllowUpdateDL = EaglercraftVersion.enableUpdateService && !demoMode && eaglercraftOpts.optBoolean("allowUpdateDL", true);
isEnableDownloadOfflineButton = eaglercraftOpts.optBoolean("enableDownloadOfflineButton", true);
downloadOfflineButtonLink = eaglercraftOpts.optString("downloadOfflineButtonLink", null);
useSpecialCursors = eaglercraftOpts.optBoolean("html5CursorSupport", false);
logInvalidCerts = !demoMode && eaglercraftOpts.optBoolean("logInvalidCerts", false);
enableSignatureBadge = eaglercraftOpts.optBoolean("enableSignatureBadge", false);
JSONArray serversArray = eaglercraftOpts.optJSONArray("servers");
if(serversArray != null) {
for(int i = 0, l = serversArray.length(); i < l; ++i) {
@ -44,6 +82,64 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
}
}
}
JSONArray relaysArray = eaglercraftOpts.optJSONArray("relays");
if(relaysArray != null) {
boolean gotAPrimary = false;
for (int i = 0, l = relaysArray.length(); i < l; ++i) {
JSONObject relay = relaysArray.getJSONObject(i);
boolean p = relay.getBoolean("primary");
if(p) {
if(gotAPrimary) {
p = false;
}else {
gotAPrimary = true;
}
}
relays.add(new RelayEntry(relay.getString("addr"), relay.getString("comment"), p));
}
}
if (relays.size() <= 0) {
int choice = random.nextInt(3);
relays.add(new RelayEntry("wss://relay.deev.is/", "lax1dude relay #1", choice == 0));
relays.add(new RelayEntry("wss://relay.lax1dude.net/", "lax1dude relay #2", choice == 1));
relays.add(new RelayEntry("wss://relay.shhnowisnottheti.me/", "ayunami relay #1", choice == 2));
checkRelaysForUpdates = !demoMode && eaglercraftOpts.optBoolean("checkRelaysForUpdates", true);
}else {
boolean isOfficial = true;
for(int i = 0, l = relays.size(); i < l; ++i) {
String addr = relays.get(i).address;
if(!addr.contains("deev.is") && !addr.contains("lax1dude.net") && !addr.contains("shhnowisnottheti.me")) {
isOfficial = false;
break;
}
}
checkRelaysForUpdates = !demoMode && eaglercraftOpts.optBoolean("checkRelaysForUpdates", isOfficial);
}
try {
byte[] localStorage = EagRuntime.getStorage("r");
if (localStorage != null) {
NBTTagCompound nbttagcompound = CompressedStreamTools
.readCompressed(new EaglerInputStream(localStorage));
if (nbttagcompound == null) {
RelayManager.relayManager.load(null);
} else {
RelayManager.relayManager.load(nbttagcompound.getTagList("relays", 10));
}
} else {
RelayManager.relayManager.load(null);
}
} catch (IOException e) {
EagRuntime.debugPrintStackTrace(e);
}
if (RelayManager.relayManager.count() <= 0) {
RelayManager.relayManager.loadDefaults();
RelayManager.relayManager.save();
}
}
@Override
@ -61,4 +157,69 @@ public class TeaVMClientConfigAdapter implements IClientConfigAdapter {
return serverToJoin;
}
@Override
public String getWorldsDB() {
return worldsDB;
}
@Override
public JSONObject dumpConfig() {
return originalEaglercraftOpts;
}
@Override
public List<RelayEntry> getRelays() {
return relays;
}
@Override
public boolean checkShaderGLErrors() {
return isCheckShaderGLErrors;
}
@Override
public boolean isDemo() {
return demoMode;
}
@Override
public boolean allowUpdateSvc() {
return isAllowUpdateSvc;
}
@Override
public boolean allowUpdateDL() {
return isAllowUpdateDL;
}
@Override
public boolean isEnableDownloadOfflineButton() {
return isEnableDownloadOfflineButton;
}
@Override
public String getDownloadOfflineButtonLink() {
return downloadOfflineButtonLink;
}
@Override
public boolean useSpecialCursors() {
return useSpecialCursors;
}
@Override
public boolean isLogInvalidCerts() {
return logInvalidCerts;
}
@Override
public boolean isCheckRelaysForUpdates() {
return checkRelaysForUpdates;
}
@Override
public boolean isEnableSignatureBadge() {
return enableSignatureBadge;
}
}

View File

@ -10,7 +10,7 @@ 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.Int8Array;
import org.teavm.jso.typedarrays.Uint8Array;
import org.teavm.jso.websocket.WebSocket;
import net.lax1dude.eaglercraft.v1_8.internal.EnumServerRateLimit;
@ -20,16 +20,18 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class TeaVMServerQuery implements IServerQuery {
@ -114,12 +116,7 @@ public class TeaVMServerQuery implements IServerQuery {
}
}else {
synchronized(queryResponsesBytes) {
Int8Array packetBytes = Int8Array.create(evt.getDataAsArray());
byte[] data = new byte[packetBytes.getLength()];
for(int i = 0; i < data.length; ++i) {
data[i] = packetBytes.get(i);
}
queryResponsesBytes.add(data);
queryResponsesBytes.add(TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(evt.getDataAsArray())));
}
}
}
@ -146,9 +143,7 @@ public class TeaVMServerQuery implements IServerQuery {
@Override
public void send(byte[] bytes) {
if(open) {
Int8Array arr = Int8Array.create(bytes.length);
arr.set(bytes, 0);
nativeBinarySend(sock, arr.getBuffer());
nativeBinarySend(sock, TeaVMUtils.unwrapByteArray(bytes).getBuffer());
}
}

View File

@ -0,0 +1,272 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.ajax.ProgressEvent;
import org.teavm.jso.ajax.XMLHttpRequest;
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;
import net.lax1dude.eaglercraft.v1_8.Base64;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformAssets;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformUpdateSvc;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.update.UpdateCertificate;
import net.lax1dude.eaglercraft.v1_8.update.UpdateProgressStruct;
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
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class TeaVMUpdateThread implements Runnable {
private static final Logger logger = LogManager.getLogger("TeaVMUpdateThread");
public final UpdateCertificate updateCert;
public final UpdateProgressStruct updateProg;
public TeaVMUpdateThread(UpdateCertificate updateCert, UpdateProgressStruct updateProg) {
this.updateCert = updateCert;
this.updateProg = updateProg;
}
@Override
public void run() {
boolean success = false;
try {
logger.info("Starting update thread...");
updateProg.clear();
updateProg.isBusy = true;
updateProg.statusString1 = updateCert.bundleDisplayName + " - " + updateCert.bundleDisplayVersion;
updateProg.statusString2 = "Please Wait";
List<String> urlListA = new ArrayList();
ListMultimap<String,String> downloadSources = updateCert.getSourceMultimap();
List<String> ls = downloadSources.get("list");
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) {
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) != '#') {
String[] strrr = str2[i].split(":", 2);
downloadSources.put(strrr[0].trim(), strrr[1].trim());
}
}
}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) {
String str1 = ls.get(k);
String cid = str1;
String path = "";
int pathSep = str1.indexOf('/');
if(pathSep != -1) {
path = cid.substring(pathSep + 1);
cid = cid.substring(0, pathSep);
}
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) {
String str1 = ls.get(k);
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) {
String url = urlListA.get(i);
updateProg.statusString2 = "Attempt (" + (i + 1) + "/" + l + ")";
byte[] b = downloadWithProgress(url);
if(b == null) {
updateProg.progressBar = 1.0f;
updateProg.statusString3 = "FAILED!";
EagUtils.sleep(300l);
updateProg.progressBar = -1.0f;
updateProg.statusString3 = null;
continue;
}
updateProg.progressBar = 1.0f;
updateProg.statusString2 = "Verifying";
logger.info("Verifying downloaded file...");
if(updateCert.isBundleDataValid(b)) {
logger.info("Success! Signature is valid!");
downloadSignedOffline(updateCert, b);
success = true;
return;
}
updateProg.statusString2 = "Signature Invalid!";
logger.error("File signature is invalid: {}");
EagUtils.sleep(1000l);
}
updateProg.progressBar = -1.0f;
updateProg.statusString3 = null;
}catch(Throwable t) {
logger.error("Uncaught exception downloading updates!");
logger.error(t);
}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 {
UpdateService.dismiss(updateCert);
}
}
}
private byte[] downloadWithProgress(String url) {
updateProg.progressBar = 0.0f;
try {
updateProg.statusString3 = url;
logger.info("Trying to download: {}", url);
byte[] b = downloadWithProgress0(this, url);
if(b == null) {
logger.error("Failed to download: {}", url);
}
return b;
}finally {
updateProg.statusString3 = null;
}
}
@Async
private static native byte[] downloadWithProgress0(TeaVMUpdateThread self, String url);
private static void downloadWithProgress0(TeaVMUpdateThread self, String url, AsyncCallback<byte[]> cb) {
try {
self.downloadWithProgressImpl(url, cb);
}catch(Throwable t) {
logger.error("Exception caught downloading file: {}", url);
logger.error(t);
cb.complete(null);
}
}
private void downloadWithProgressImpl(String url, final AsyncCallback<byte[]> cb) {
final XMLHttpRequest xhr = XMLHttpRequest.create();
xhr.open("GET", url);
xhr.setResponseType("arraybuffer");
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);
}
});
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());
cb.complete(null);
}
}else {
logger.error("Got response code {} \"{}\" for url: {}", xhr.getStatus(), xhr.getStatusText());
cb.complete(null);
}
}
}
});
TeaVMUtils.addEventListener(xhr, "error", new EventListener<ProgressEvent>() {
@Override
public void handleEvent(ProgressEvent evt) {
logger.error("Exception caught downloading file: {}", url);
}
});
xhr.send();
}
private static String formatIPFSURL(String cid, String path, String pattern) {
return pattern.replace("$cid$", cid).replace("$path$", path);
}
private static String formatProxyURL(String path, String pattern) {
return pattern.replace("$url$", Window.encodeURIComponent(path));
}
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));
}
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)));
}
public static byte[] generateSignedOffline(byte[] cert, byte[] data, String date) {
byte[] b = PlatformAssets.getResourceBytes("SignedClientTemplate.txt");
if(b == null) {
throw new RuntimeException("Could not load SignedClientTemplate.txt from assets.epk!");
}
String templateHtml = new String(b, StandardCharsets.UTF_8);
templateHtml = templateHtml.replace("${client_signature}", Base64.encodeBase64String(cert));
templateHtml = templateHtml.replace("${client_bundle}", Base64.encodeBase64String(data));
templateHtml = templateHtml.replace("${date}", date);
return templateHtml.getBytes(StandardCharsets.UTF_8);
}
}

View File

@ -1,21 +1,33 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.browser.Window;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.ArrayBufferView;
import org.teavm.jso.typedarrays.Float32Array;
import org.teavm.jso.typedarrays.Int32Array;
import org.teavm.jso.typedarrays.Int8Array;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class TeaVMUtils {
@ -29,18 +41,105 @@ public class TeaVMUtils {
@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 static Int8Array unwrapByteArray(byte[] buf) {
return Int8Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer());
}
@JSBody(params = { "buf" }, script = "return $rt_createByteArray(buf.buffer)")
private static native JSObject wrapByteArray0(JSObject buf);
public static byte[] wrapByteArray(Int8Array buf) {
return (byte[])(Object)wrapByteArray0(buf);
}
public static Uint8Array unwrapUnsignedByteArray(byte[] buf) {
return Uint8Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer());
}
public static byte[] wrapUnsignedByteArray(Uint8Array buf) {
return (byte[])(Object)wrapByteArray0(buf);
}
public static Int32Array unwrapIntArray(int[] buf) {
return Int32Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer());
}
@JSBody(params = { "buf" }, script = "return $rt_createIntArray(buf.buffer)")
private static native JSObject wrapIntArray0(JSObject buf);
public static int[] wrapIntArray(Int32Array buf) {
return (int[])(Object)wrapIntArray0(buf);
}
public static Float32Array unwrapFloatArray(float[] buf) {
return Float32Array.create(((TeaVMArrayObject)(Object)buf).getData().getBuffer());
}
@JSBody(params = { "buf" }, script = "return $rt_createFloatArray(buf.buffer)")
private static native JSObject wrapFloatArray0(JSObject buf);
public static float[] wrapFloatArray(Float32Array buf) {
return (float[])(Object)wrapFloatArray0(buf);
}
@Async
public static native void sleepSetTimeout(int millis);
private static void sleepSetTimeout(int millis, AsyncCallback<Void> cb) {
Window.setTimeout(() -> cb.complete(null), millis);
}
public static final byte[] arrayBufferToBytes(ArrayBuffer buf) {
if(buf == null) {
return null;
}
Int8Array arr = Int8Array.create(buf);
byte[] ret = new byte[arr.getByteLength()];
for(int i = 0; i < ret.length; ++i) {
ret[i] = arr.get(i);
return wrapUnsignedByteArray(Uint8Array.create(buf));
}
public static String tryResolveClassesSource() {
String str = dumpJSStackTrace();
String[] frames = EagUtils.splitPattern.split(str);
if("Error".equals(frames[0])) {
// V8 stack trace
if(frames.length > 1) {
String framesTrim = frames[1].trim();
if(framesTrim.startsWith("at")) {
//definitely V8
int i = framesTrim.indexOf('(');
int j = framesTrim.indexOf(')');
if(i != -1 && j != -1 && i < j) {
return tryResolveClassesSourceFromFrame(framesTrim.substring(i + 1, j));
}
}
}
}else {
// Mozilla/WebKit stack trace
String framesTrim = frames[0].trim();
int i = framesTrim.indexOf('@');
if(i != -1) {
return tryResolveClassesSourceFromFrame(framesTrim.substring(i + 1));
}
}
return ret;
return null;
}
private static String tryResolveClassesSourceFromFrame(String fileLineCol) {
int i = fileLineCol.lastIndexOf(':');
if(i > 0) {
i = fileLineCol.lastIndexOf(':', i - 1);
}
if(i != -1) {
return fileLineCol.substring(0, i);
}
return null;
}
}

View File

@ -9,16 +9,18 @@ import org.teavm.jso.webgl.WebGLTexture;
import org.teavm.jso.webgl.WebGLUniformLocation;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface WebGL2RenderingContext extends WebGLRenderingContext {

View File

@ -3,16 +3,18 @@ package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import org.teavm.jso.JSObject;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface WebGLQuery extends JSObject {

View File

@ -3,16 +3,18 @@ package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import org.teavm.jso.JSObject;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface WebGLVertexArray extends JSObject {

View File

@ -1,19 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class BooleanResult {
public static final BooleanResult TRUE = new BooleanResult(true);

View File

@ -8,19 +8,20 @@ import java.util.List;
import java.util.Set;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FolderResourcePack extends AbstractResourcePack {
private final String prefix;

View File

@ -1,5 +1,6 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.crypto.SHA1Digest;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ArrayBufferInputStream;
@ -18,19 +19,20 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SYS {
public static final VirtualFilesystem VFS;
@ -111,7 +113,7 @@ public class SYS {
return false;
}
} catch (IOException e) {
e.printStackTrace();
EagRuntime.debugPrintStackTrace(e);
return false;
}
}
@ -154,7 +156,7 @@ public class SYS {
zis.close();
return true;
} catch (IOException e) {
e.printStackTrace();
EagRuntime.debugPrintStackTrace(e);
return false;
}
}

View File

@ -1,19 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface VFSIterator {
public static class BreakLoop extends RuntimeException {

View File

@ -7,19 +7,20 @@ import java.util.Arrays;
import java.util.List;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VFile {
public static final String pathSeperator = "/";

View File

@ -13,23 +13,27 @@ import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.Event;
import org.teavm.jso.dom.events.EventListener;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBCursor;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBRequest;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
@ -226,16 +230,8 @@ public class VIteratorFile extends VFile {
if(arr == null) {
return null;
}
Uint8Array a = Uint8Array.create(arr);
int ii = a.getByteLength();
byte[] array = new byte[ii];
for(int i = 0; i < ii; ++i) {
array[i] = (byte)a.get(i);
}
return array;
return TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(arr));
}
public String getAllChars() {

View File

@ -11,40 +11,43 @@ import java.util.Iterator;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.EventListener;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.EventHandler;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBCountRequest;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBCursor;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBCursorRequest;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBDatabase;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBFactory;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBGetRequest;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBObjectStoreParameters;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBOpenDBRequest;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBRequest;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBTransaction;
import net.lax1dude.eaglercraft.v1_8.internal.indexeddb.IDBVersionChangeEvent;
import org.teavm.jso.indexeddb.EventHandler;
import org.teavm.jso.indexeddb.IDBCountRequest;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBCursorRequest;
import org.teavm.jso.indexeddb.IDBDatabase;
import org.teavm.jso.indexeddb.IDBFactory;
import org.teavm.jso.indexeddb.IDBGetRequest;
import org.teavm.jso.indexeddb.IDBObjectStoreParameters;
import org.teavm.jso.indexeddb.IDBOpenDBRequest;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.indexeddb.IDBTransaction;
import org.teavm.jso.indexeddb.IDBVersionChangeEvent;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022-2023 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VirtualFilesystem {
protected static class VirtualOutputStream extends ByteArrayOutputStream {
@ -203,10 +206,7 @@ public class VirtualFilesystem {
}
Uint8Array a = Uint8Array.create(b);
this.fileSize = a.getByteLength();
byte[] array = new byte[fileSize];
for(int i = 0; i < a.getByteLength(); ++i) {
array[i] = (byte)a.get(i);
}
byte[] array = TeaVMUtils.wrapUnsignedByteArray(a);
if(cacheEnabled) {
if(copy) {
cache = new byte[fileSize];
@ -242,10 +242,7 @@ public class VirtualFilesystem {
cache = copz;
return sync();
}else {
ArrayBuffer a = ArrayBuffer.create(bytes.length);
Uint8Array ar = Uint8Array.create(a);
ar.set(bytes);
boolean s = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, a).bool;
boolean s = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, TeaVMUtils.unwrapUnsignedByteArray(bytes).getBuffer()).bool;
hasBeenAccessed = true;
exists = exists || s;
return s;
@ -255,10 +252,7 @@ public class VirtualFilesystem {
public boolean sync() {
if(cacheEnabled && cache != null && !hasBeenDeleted) {
cacheHit = System.currentTimeMillis();
ArrayBuffer a = ArrayBuffer.create(cache.length);
Uint8Array ar = Uint8Array.create(a);
ar.set(cache);
boolean tryWrite = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, a).bool;
boolean tryWrite = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, TeaVMUtils.unwrapUnsignedByteArray(cache).getBuffer()).bool;
hasBeenAccessed = true;
exists = exists || tryWrite;
return tryWrite;

View File

@ -0,0 +1,246 @@
package net.lax1dude.eaglercraft.v1_8.sp.internal;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
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;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ClientMain;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
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
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ClientPlatformSingleplayer {
private static final Logger logger = LogManager.getLogger("ClientPlatformSingleplayer");
private static final LinkedList<IPCPacketData> messageQueue = new LinkedList();
@JSBody(params = {}, script = "return (typeof window.eaglercraftXClientScriptElement !== \"undefined\") ? window.eaglercraftXClientScriptElement : null;")
private static native JSObject loadIntegratedServerSourceOverride();
@JSBody(params = {}, script = "return (typeof window.eaglercraftXClientScriptURL === \"string\") ? window.eaglercraftXClientScriptURL : null;")
private static native String loadIntegratedServerSourceOverrideURL();
@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;")
private static native String loadIntegratedServerSourceURL(JSObject scriptTag);
@JSBody(params = { "csc", "tail" }, script = "const cscText = csc.text;"
+ "if(typeof cscText === \"string\" && cscText.length > 0) return new Blob([cscText, tail], { type: \"text/javascript;charset=utf8\" });"
+ "else return null;")
private static native JSObject loadIntegratedServerSourceInline(JSObject scriptTag, String tail);
private static String integratedServerSource = null;
private static String integratedServerSourceOriginalURL = null;
private static boolean serverSourceLoaded = false;
private static Worker workerObj = null;
@JSFunctor
private static interface WorkerBinaryPacketHandler extends JSObject {
public void onMessage(String channel, ArrayBuffer buf);
}
@JSBody(params = { "w", "wb" }, script = "w.onmessage = function(o) { wb(o.data.ch, o.data.dat); };")
private static native void registerPacketHandler(Worker w, WorkerBinaryPacketHandler wb);
@JSBody(params = { "w", "ch", "dat" }, script = "w.postMessage({ ch: ch, dat : dat });")
private static native void sendWorkerPacket(Worker w, String channel, ArrayBuffer arr);
@JSBody(params = { "w", "workerArgs" }, script = "w.postMessage({ msg : workerArgs });")
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) {
logger.error("Recieved IPC packet with null channel");
return;
}
if(buf == null) {
logger.error("Recieved IPC packet with null buffer");
return;
}
synchronized(messageQueue) {
messageQueue.add(new IPCPacketData(channel, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(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\" });")
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) {
ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(str);
if(buf != null) {
integratedServerSourceOriginalURL = str;
logger.info("Using integrated server at: {}", str);
return createBlobObj(buf, workerBootstrapCode);
}else {
logger.error("Failed to load integrated server: {}", str);
}
}
JSObject el = loadIntegratedServerSourceOverride();
if(el != null) {
String url = loadIntegratedServerSourceURL(el);
if(url == null) {
el = loadIntegratedServerSourceInline(el, workerBootstrapCode);
if(el != null) {
integratedServerSourceOriginalURL = "inline script tag";
logger.info("Loading integrated server from inline script tag");
return el;
}
}else {
ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(url);
if(buf != null) {
integratedServerSourceOriginalURL = url;
logger.info("Using integrated server from script tag src: {}", url);
return createBlobObj(buf, workerBootstrapCode);
}else {
logger.error("Failed to load integrated server from script tag src: {}", url);
}
}
}
str = TeaVMUtils.tryResolveClassesSource();
if(str != null) {
ArrayBuffer buf = PlatformRuntime.downloadRemoteURI(str);
if(buf != null) {
integratedServerSourceOriginalURL = str;
logger.info("Using integrated server from script src: {}", str);
return createBlobObj(buf, workerBootstrapCode);
}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");
return null;
}
private static String createIntegratedServerWorkerURL() {
JSObject blobObj = loadIntegratedServerSource();
if(blobObj == null) {
return null;
}
return createWorkerScriptURL(blobObj);
}
public static String getLoadedWorkerURLTeaVM() {
return (serverSourceLoaded && workerObj != null) ? integratedServerSource : null;
}
public static String getLoadedWorkerSourceURLTeaVM() {
return (serverSourceLoaded && workerObj != null) ? integratedServerSourceOriginalURL : null;
}
public static void startIntegratedServer() {
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");
}
workerObj = Worker.create(integratedServerSource);
workerObj.onError(new EventListener<ErrorEvent>() {
@Override
public void handleEvent(ErrorEvent evt) {
logger.error("Worker Error: {}", evt.getError());
PlatformRuntime.printNativeExceptionToConsoleTeaVM(evt);
}
});
registerPacketHandler(workerObj, new WorkerBinaryPacketHandlerImpl());
sendWorkerStartPacket(workerObj, PlatformRuntime.getClientConfigAdapter().dumpConfig().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());
}
public static void sendPacketTeaVM(String channel, ArrayBuffer packet) {
if(workerObj != null) {
sendWorkerPacket(workerObj, channel, packet);
}
}
public static List<IPCPacketData> recieveAllPacket() {
synchronized(messageQueue) {
if(messageQueue.size() == 0) {
return null;
}else {
List<IPCPacketData> ret = new ArrayList<>(messageQueue);
messageQueue.clear();
return ret;
}
}
}
public static boolean canKillWorker() {
return true;
}
public static void killWorker() {
if(workerObj != null) {
workerObj.terminate();
workerObj = null;
}
}
public static boolean isRunningSingleThreadMode() {
return false;
}
public static void showCrashReportOverlay(String report, int x, int y, int w, int h) {
ClientMain.showIntegratedServerCrashReportOverlay(report, x, y, w, h);
}
public static void hideCrashReportOverlay() {
ClientMain.hideIntegratedServerCrashReportOverlay();
}
}

View File

@ -0,0 +1,106 @@
package net.lax1dude.eaglercraft.v1_8.sp.server.internal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.sp.server.classes.EaglerServerBootstrap;
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;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMClientConfigAdapter;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
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
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ServerPlatformSingleplayer {
private static final Logger logger = LogManager.getLogger("ServerPlatformSingleplayer");
private static final LinkedList<IPCPacketData> messageQueue = new LinkedList();
@JSFunctor
private static interface WorkerBinaryPacketHandler extends JSObject {
public void onMessage(String channel, ArrayBuffer buf);
}
private static class WorkerBinaryPacketHandlerImpl implements WorkerBinaryPacketHandler {
public void onMessage(String channel, ArrayBuffer buf) {
if(channel == null) {
logger.error("Recieved IPC packet with null channel");
return;
}
if(buf == null) {
logger.error("Recieved IPC packet with null buffer");
return;
}
synchronized(messageQueue) {
messageQueue.add(new IPCPacketData(channel, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buf))));
}
}
}
@JSBody(params = { "wb" }, script = "onmessage = function(o) { wb(o.data.ch, o.data.dat); };")
private static native void registerPacketHandler(WorkerBinaryPacketHandler wb);
public static void register() {
registerPacketHandler(new WorkerBinaryPacketHandlerImpl());
}
public static void initializeContext() {
PlatformFilesystem.initialize();
EaglerServerBootstrap.staticInit();
}
@JSBody(params = { "ch", "dat" }, script = "postMessage({ ch: ch, dat : dat });")
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);
}
public static List<IPCPacketData> recieveAllPacket() {
synchronized(messageQueue) {
if(messageQueue.size() == 0) {
return null;
}else {
List<IPCPacketData> ret = new ArrayList(messageQueue);
messageQueue.clear();
return ret;
}
}
}
public static IClientConfigAdapter getClientConfigAdapter() {
return TeaVMClientConfigAdapter.instance;
}
}

View File

@ -0,0 +1,98 @@
package net.lax1dude.eaglercraft.v1_8.sp.server.internal.teavm;
import java.io.PrintStream;
import org.json.JSONObject;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMClientConfigAdapter;
import net.lax1dude.eaglercraft.v1_8.sp.ipc.IPCPacket15Crashed;
import net.lax1dude.eaglercraft.v1_8.sp.ipc.IPCPacketFFProcessKeepAlive;
import net.lax1dude.eaglercraft.v1_8.sp.server.EaglerIntegratedServerWorker;
import net.lax1dude.eaglercraft.v1_8.sp.server.internal.ServerPlatformSingleplayer;
/**
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class WorkerMain {
public static void _main() {
PrintStream systemOut = System.out;
PrintStream systemErr = System.err;
try {
__println(systemOut, false, "WorkerMain: [INFO] eaglercraftx worker thread is starting...");
String startArgs = getStartArgs();
__println(systemOut, false, "WorkerMain: [INFO] reading configuration");
if(startArgs == null) {
throw new NullPointerException("startup arguments is null!");
}
((TeaVMClientConfigAdapter)TeaVMClientConfigAdapter.instance).loadJSON(new JSONObject(startArgs));
__println(systemOut, false, "WorkerMain: [INFO] initializing server runtime");
EaglerIntegratedServerWorker.enableLoggingRedirector(true);
ServerPlatformSingleplayer.initializeContext();
__println(systemOut, false, "WorkerMain: [INFO] starting worker thread");
PlatformRuntime.setThreadName("IntegratedServer");
EaglerIntegratedServerWorker.serverMain();
}catch(Throwable t) {
System.setOut(systemOut);
System.setErr(systemErr);
__println(systemErr, true, "WorkerMain: [ERROR] uncaught exception thrown!");
EaglerIntegratedServerWorker.sendLogMessagePacket(EagRuntime.getStackTrace(t), true);
EagRuntime.debugPrintStackTraceToSTDERR(t);
EaglerIntegratedServerWorker.sendIPCPacket(new IPCPacket15Crashed("UNCAUGHT EXCEPTION CAUGHT IN WORKER PROCESS!\n\n" + EagRuntime.getStackTrace(t)));
EaglerIntegratedServerWorker.sendIPCPacket(new IPCPacketFFProcessKeepAlive(IPCPacketFFProcessKeepAlive.EXITED));
}finally {
__println(systemErr, true, "WorkerMain: [ERROR] eaglercraftx worker thread has exited");
}
}
private static void __println(PrintStream stream, boolean err, String msg) {
stream.println(msg);
try {
EaglerIntegratedServerWorker.sendLogMessagePacket(msg, err);
}catch(Throwable t) {
}
}
@JSFunctor
private static interface WorkerArgumentsPacketHandler extends JSObject {
public void onMessage(String msg);
}
@JSBody(params = { "wb" }, script = "onmessage = function(o) { wb(o.data.msg); };")
private static native void setOnMessage(WorkerArgumentsPacketHandler cb);
@Async
private static native String getStartArgs();
private static void getStartArgs(final AsyncCallback<String> cb) {
setOnMessage(new WorkerArgumentsPacketHandler() {
@Override
public void onMessage(String msg) {
ServerPlatformSingleplayer.register();
cb.complete(msg);
}
});
}
}