Update #37 - Touch support without userscript, many other feats

This commit is contained in:
lax1dude
2024-09-21 20:17:42 -07:00
parent 173727c8c4
commit ec1ab8ece3
683 changed files with 62074 additions and 8996 deletions

View File

@ -0,0 +1,227 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* 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 abstract class AbstractWebSocketClient implements IWebSocketClient {
protected volatile int availableStringFrames = 0;
protected volatile int availableBinaryFrames = 0;
protected final List<IWebSocketFrame> recievedPacketBuffer = new LinkedList<>();
protected String currentURI;
protected AbstractWebSocketClient(String currentURI) {
this.currentURI = currentURI;
}
protected void addRecievedFrame(IWebSocketFrame frame) {
boolean str = frame.isString();
synchronized(recievedPacketBuffer) {
recievedPacketBuffer.add(frame);
if(str) {
++availableStringFrames;
}else {
++availableBinaryFrames;
}
}
}
@Override
public int availableFrames() {
synchronized(recievedPacketBuffer) {
return availableStringFrames + availableBinaryFrames;
}
}
@Override
public IWebSocketFrame getNextFrame() {
synchronized(recievedPacketBuffer) {
if(!recievedPacketBuffer.isEmpty()) {
IWebSocketFrame frame = recievedPacketBuffer.remove(0);
if(frame.isString()) {
--availableStringFrames;
}else {
--availableBinaryFrames;
}
return frame;
}else {
return null;
}
}
}
@Override
public List<IWebSocketFrame> getNextFrames() {
synchronized(recievedPacketBuffer) {
if(!recievedPacketBuffer.isEmpty()) {
List<IWebSocketFrame> ret = new ArrayList<>(recievedPacketBuffer);
recievedPacketBuffer.clear();
availableStringFrames = 0;
availableBinaryFrames = 0;
return ret;
}else {
return null;
}
}
}
@Override
public void clearFrames() {
synchronized(recievedPacketBuffer) {
recievedPacketBuffer.clear();
}
}
@Override
public int availableStringFrames() {
synchronized(recievedPacketBuffer) {
return availableStringFrames;
}
}
@Override
public IWebSocketFrame getNextStringFrame() {
synchronized(recievedPacketBuffer) {
if(availableStringFrames > 0) {
Iterator<IWebSocketFrame> itr = recievedPacketBuffer.iterator();
while(itr.hasNext()) {
IWebSocketFrame r = itr.next();
if(r.isString()) {
itr.remove();
--availableStringFrames;
return r;
}
}
availableStringFrames = 0;
return null;
}else {
return null;
}
}
}
@Override
public List<IWebSocketFrame> getNextStringFrames() {
synchronized(recievedPacketBuffer) {
if(availableStringFrames > 0) {
List<IWebSocketFrame> ret = new ArrayList<>(availableStringFrames);
Iterator<IWebSocketFrame> itr = recievedPacketBuffer.iterator();
while(itr.hasNext()) {
IWebSocketFrame r = itr.next();
if(r.isString()) {
itr.remove();
ret.add(r);
}
}
availableStringFrames = 0;
return ret;
}else {
return null;
}
}
}
@Override
public void clearStringFrames() {
synchronized(recievedPacketBuffer) {
if(availableStringFrames > 0) {
Iterator<IWebSocketFrame> itr = recievedPacketBuffer.iterator();
while(itr.hasNext()) {
IWebSocketFrame r = itr.next();
if(r.isString()) {
itr.remove();
}
}
availableStringFrames = 0;
}
}
}
@Override
public int availableBinaryFrames() {
synchronized(recievedPacketBuffer) {
return availableBinaryFrames;
}
}
@Override
public IWebSocketFrame getNextBinaryFrame() {
synchronized(recievedPacketBuffer) {
if(availableBinaryFrames > 0) {
Iterator<IWebSocketFrame> itr = recievedPacketBuffer.iterator();
while(itr.hasNext()) {
IWebSocketFrame r = itr.next();
if(!r.isString()) {
itr.remove();
--availableBinaryFrames;
return r;
}
}
availableBinaryFrames = 0;
return null;
}else {
return null;
}
}
}
@Override
public List<IWebSocketFrame> getNextBinaryFrames() {
synchronized(recievedPacketBuffer) {
if(availableBinaryFrames > 0) {
List<IWebSocketFrame> ret = new ArrayList<>(availableBinaryFrames);
Iterator<IWebSocketFrame> itr = recievedPacketBuffer.iterator();
while(itr.hasNext()) {
IWebSocketFrame r = itr.next();
if(!r.isString()) {
itr.remove();
ret.add(r);
}
}
availableBinaryFrames = 0;
return ret;
}else {
return null;
}
}
}
@Override
public void clearBinaryFrames() {
synchronized(recievedPacketBuffer) {
if(availableBinaryFrames > 0) {
Iterator<IWebSocketFrame> itr = recievedPacketBuffer.iterator();
while(itr.hasNext()) {
IWebSocketFrame r = itr.next();
if(!r.isString()) {
itr.remove();
}
}
availableBinaryFrames = 0;
}
}
}
@Override
public String getCurrentURI() {
return currentURI;
}
}

View File

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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 EaglerMissingResourceException extends RuntimeException {
public EaglerMissingResourceException() {
}
public EaglerMissingResourceException(String message, Throwable cause) {
super(message, cause);
}
public EaglerMissingResourceException(String message) {
super(message);
}
public EaglerMissingResourceException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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 enum EnumFireKeyboardEvent {
KEY_DOWN, KEY_UP, KEY_REPEAT;
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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 enum EnumFireMouseEvent {
MOUSE_DOWN, MOUSE_UP, MOUSE_MOVE, MOUSE_WHEEL;
}

View File

@ -18,6 +18,7 @@ package net.lax1dude.eaglercraft.v1_8.internal;
public enum EnumPlatformANGLE {
DEFAULT(225281 /* GLFW_ANGLE_PLATFORM_TYPE_NONE */, "default", "Default"),
D3D9(225284 /* GLFW_ANGLE_PLATFORM_TYPE_D3D9 */, "d3d9", "Direct3D9"),
D3D11(225285 /* GLFW_ANGLE_PLATFORM_TYPE_D3D11 */, "d3d11", "Direct3D11"),
OPENGL(225282 /* GLFW_ANGLE_PLATFORM_TYPE_OPENGL */, "opengl", "OpenGL"),
OPENGLES(225283 /* GLFW_ANGLE_PLATFORM_TYPE_OPENGLES */, "opengles", "OpenGL ES"),
@ -41,6 +42,8 @@ public enum EnumPlatformANGLE {
public static EnumPlatformANGLE fromId(String id) {
if(id.equals("d3d11") || id.equals("d3d") || id.equals("dx11")) {
return D3D11;
}else if(id.equals("d3d9") || id.equals("dx9")) {
return D3D9;
}else if(id.equals("opengl")) {
return OPENGL;
}else if(id.equals("opengles")) {
@ -58,6 +61,8 @@ public enum EnumPlatformANGLE {
str = str.toLowerCase();
if(str.contains("direct3d11") || str.contains("d3d11")) {
return D3D11;
}else if(str.contains("direct3d9") || str.contains("d3d9")) {
return D3D9;
}else if(str.contains("opengl es")) {
return OPENGLES;
}else if(str.contains("opengl")) {

View File

@ -35,12 +35,15 @@ public enum EnumPlatformAgent {
}
public static EnumPlatformAgent getFromUA(String ua) {
if(ua == null) {
return UNKNOWN;
}
ua = " " + ua.toLowerCase();
if(ua.contains(" edg/")) {
return EDGE;
}else if(ua.contains(" opr/")) {
return OPERA;
}else if(ua.contains(" chrome/")) {
}else if(ua.contains(" chrome/") || ua.contains(" chromium/")) {
return CHROME;
}else if(ua.contains(" firefox/")) {
return FIREFOX;

View File

@ -42,6 +42,9 @@ public enum EnumPlatformOS {
}
public static EnumPlatformOS getFromJVM(String osNameProperty) {
if(osNameProperty == null) {
return OTHER;
}
osNameProperty = osNameProperty.toLowerCase();
if(osNameProperty.contains("chrome")) {
return CHROMEBOOK_LINUX;
@ -57,6 +60,9 @@ public enum EnumPlatformOS {
}
public static EnumPlatformOS getFromUA(String ua) {
if(ua == null) {
return OTHER;
}
ua = " " + ua.toLowerCase();
if(ua.contains(" cros")) {
return CHROMEBOOK_LINUX;

View File

@ -0,0 +1,43 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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 enum EnumTouchEvent {
TOUCHSTART(0), TOUCHMOVE(1), TOUCHEND(2);
public final int id;
private EnumTouchEvent(int id) {
this.id = id;
}
public static EnumTouchEvent getById(int id) {
if(id >= 0 && id < lookup.length) {
return lookup[id];
}else {
return null;
}
}
private static final EnumTouchEvent[] lookup = new EnumTouchEvent[3];
static {
EnumTouchEvent[] v = values();
for(int i = 0; i < v.length; ++i) {
lookup[v[i].id] = v[i];
}
}
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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 enum EnumWebViewContentMode {
URL_BASED, BLOB_BASED;
}

View File

@ -71,4 +71,11 @@ public class GLObjectMap<T> {
values = new Object[size];
System.arraycopy(oldValues, 0, values, 0, oldSize);
}
public void clear() {
if(allocatedObjects == 0) return;
values = new Object[size];
insertIndex = 0;
allocatedObjects = 0;
}
}

View File

@ -0,0 +1,134 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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 GamepadConstants {
private static final String[] buttonNames = new String[24];
private static final String[] axisNames = new String[4];
private static final int[] eaglerButtonsToGLFW = new int[24];
private static final int[] glfwButtonsToEagler = new int[24];
public static final int GAMEPAD_NONE = -1;
public static final int GAMEPAD_A = 0;
public static final int GAMEPAD_B = 1;
public static final int GAMEPAD_X = 2;
public static final int GAMEPAD_Y = 3;
public static final int GAMEPAD_LEFT_BUTTON = 4;
public static final int GAMEPAD_RIGHT_BUTTON = 5;
public static final int GAMEPAD_LEFT_TRIGGER = 6;
public static final int GAMEPAD_RIGHT_TRIGGER = 7;
public static final int GAMEPAD_BACK = 8;
public static final int GAMEPAD_START = 9;
public static final int GAMEPAD_LEFT_STICK_BUTTON = 10;
public static final int GAMEPAD_RIGHT_STICK_BUTTON = 11;
public static final int GAMEPAD_DPAD_UP = 12;
public static final int GAMEPAD_DPAD_DOWN = 13;
public static final int GAMEPAD_DPAD_LEFT = 14;
public static final int GAMEPAD_DPAD_RIGHT = 15;
public static final int GAMEPAD_GUIDE = 16;
public static final int GAMEPAD_AXIS_NONE = -1;
public static final int GAMEPAD_AXIS_LEFT_STICK_X = 0;
public static final int GAMEPAD_AXIS_LEFT_STICK_Y = 1;
public static final int GAMEPAD_AXIS_RIGHT_STICK_X = 2;
public static final int GAMEPAD_AXIS_RIGHT_STICK_Y = 3;
private static final int GLFW_GAMEPAD_BUTTON_A = 0, GLFW_GAMEPAD_BUTTON_B = 1, GLFW_GAMEPAD_BUTTON_X = 2,
GLFW_GAMEPAD_BUTTON_Y = 3, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = 4, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = 5,
GLFW_GAMEPAD_BUTTON_BACK = 6, GLFW_GAMEPAD_BUTTON_START = 7, GLFW_GAMEPAD_BUTTON_GUIDE = 8,
GLFW_GAMEPAD_BUTTON_LEFT_THUMB = 9, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = 10, GLFW_GAMEPAD_BUTTON_DPAD_UP = 11,
GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = 12, GLFW_GAMEPAD_BUTTON_DPAD_DOWN = 13, GLFW_GAMEPAD_BUTTON_DPAD_LEFT = 14;
private static void registerBtn(int eaglerBtn, int glfwBtn, String name) {
if(eaglerButtonsToGLFW[eaglerBtn] != 0) throw new IllegalArgumentException("Duplicate eaglerButtonsToGLFW entry: " + eaglerBtn + " -> " + glfwBtn);
if(glfwBtn != -1 && glfwButtonsToEagler[glfwBtn] != 0) throw new IllegalArgumentException("Duplicate glfwButtonsToEAGLER entry: " + glfwBtn + " -> " + eaglerBtn);
eaglerButtonsToGLFW[eaglerBtn] = glfwBtn;
if(glfwBtn != -1) glfwButtonsToEagler[glfwBtn] = eaglerBtn;
if(buttonNames[eaglerBtn] != null) throw new IllegalArgumentException("Duplicate buttonNames entry: " + eaglerBtn);
buttonNames[eaglerBtn] = name;
}
private static void registerAxis(int eaglerAxis, String name) {
if(axisNames[eaglerAxis] != null) throw new IllegalArgumentException("Duplicate axisNames entry: " + eaglerAxis);
axisNames[eaglerAxis] = name;
}
static {
registerBtn(GAMEPAD_A, GLFW_GAMEPAD_BUTTON_A, "A");
registerBtn(GAMEPAD_B, GLFW_GAMEPAD_BUTTON_B, "B");
registerBtn(GAMEPAD_X, GLFW_GAMEPAD_BUTTON_X, "X");
registerBtn(GAMEPAD_Y, GLFW_GAMEPAD_BUTTON_Y, "Y");
registerBtn(GAMEPAD_LEFT_BUTTON, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, "Left Button");
registerBtn(GAMEPAD_LEFT_TRIGGER, -1, "Left Trigger");
registerBtn(GAMEPAD_RIGHT_BUTTON, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, "Right Button");
registerBtn(GAMEPAD_RIGHT_TRIGGER, -1, "Right Trigger");
registerBtn(GAMEPAD_BACK, GLFW_GAMEPAD_BUTTON_BACK, "Back");
registerBtn(GAMEPAD_START, GLFW_GAMEPAD_BUTTON_START, "Start");
registerBtn(GAMEPAD_LEFT_STICK_BUTTON, GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "L. Stick Button");
registerBtn(GAMEPAD_RIGHT_STICK_BUTTON, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "R. Stick Button");
registerBtn(GAMEPAD_DPAD_UP, GLFW_GAMEPAD_BUTTON_DPAD_UP, "D-Pad Up");
registerBtn(GAMEPAD_DPAD_DOWN, GLFW_GAMEPAD_BUTTON_DPAD_DOWN, "D-Pad Down");
registerBtn(GAMEPAD_DPAD_LEFT, GLFW_GAMEPAD_BUTTON_DPAD_LEFT, "D-Pad Left");
registerBtn(GAMEPAD_DPAD_RIGHT, GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, "D-Pad Right");
registerBtn(GAMEPAD_GUIDE, GLFW_GAMEPAD_BUTTON_GUIDE, "Guide");
registerAxis(GAMEPAD_AXIS_LEFT_STICK_X, "Left Stick X");
registerAxis(GAMEPAD_AXIS_LEFT_STICK_Y, "Left Stick Y");
registerAxis(GAMEPAD_AXIS_RIGHT_STICK_X, "Right Stick X");
registerAxis(GAMEPAD_AXIS_RIGHT_STICK_Y, "Right Stick Y");
}
public static int getEaglerButtonFromBrowser(int button) {
return button;
}
public static int getBrowserButtonFromEagler(int button) {
return button;
}
public static int getEaglerButtonFromGLFW(int button) {
if(button >= 0 && button < glfwButtonsToEagler.length) {
return glfwButtonsToEagler[button];
}else {
return -1;
}
}
public static int getGLFWButtonFromEagler(int button) {
if(button >= 0 && button < eaglerButtonsToGLFW.length) {
return eaglerButtonsToGLFW[button];
}else {
return -1;
}
}
public static String getButtonName(int button) {
if(button >= 0 && button < buttonNames.length) {
return buttonNames[button];
}else {
return "Button " + button;
}
}
public static String getAxisName(int button) {
if(button >= 0 && button < axisNames.length) {
return axisNames[button];
}else {
return "Axis " + button;
}
}
}

View File

@ -26,10 +26,12 @@ public interface IClientConfigAdapter {
public final String name;
public final String addr;
public final boolean hideAddress;
public DefaultServer(String name, String addr) {
public DefaultServer(String name, String addr, boolean hideAddress) {
this.name = name;
this.addr = addr;
this.hideAddress = hideAddress;
}
}
@ -76,6 +78,24 @@ public interface IClientConfigAdapter {
boolean isEnableMinceraft();
boolean isEnableServerCookies();
boolean isAllowServerRedirects();
boolean isOpenDebugConsoleOnLaunch();
boolean isForceWebViewSupport();
boolean isEnableWebViewCSP();
boolean isAllowBootMenu();
boolean isForceProfanityFilter();
boolean isEaglerNoDelay();
boolean isRamdiskMode();
IClientConfigAdapterHooks getHooks();
}

View File

@ -25,4 +25,6 @@ public interface IClientConfigAdapterHooks {
void callCrashReportHook(String crashReport, Consumer<String> customMessageCB);
void callScreenChangedHook(String screenName, int scaledWidth, int scaledHeight, int realWidth, int realHeight, int scaleFactor);
}

View File

@ -0,0 +1,46 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
/**
* 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 interface IEaglerFilesystem {
String getFilesystemName();
String getInternalDBName();
boolean isRamdisk();
boolean eaglerDelete(String pathName);
ByteBuffer eaglerRead(String pathName);
void eaglerWrite(String pathName, ByteBuffer data);
boolean eaglerExists(String pathName);
boolean eaglerMove(String pathNameOld, String pathNameNew);
int eaglerCopy(String pathNameOld, String pathNameNew);
int eaglerSize(String pathName);
void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive);
void closeHandle();
}

View File

@ -2,6 +2,8 @@ package net.lax1dude.eaglercraft.v1_8.internal;
import org.json.JSONObject;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
@ -42,6 +44,8 @@ public interface IServerQuery {
}
void update();
void send(String str);
default void send(JSONObject json) {
@ -73,8 +77,8 @@ public interface IServerQuery {
EnumServerRateLimit getRateLimit();
default boolean awaitResponseAvailable(long timeout) {
long start = System.currentTimeMillis();
while(isOpen() && responsesAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) {
long start = EagRuntime.steadyTimeMillis();
while(isOpen() && responsesAvailable() <= 0 && (timeout <= 0l || EagRuntime.steadyTimeMillis() - start < timeout)) {
try {
Thread.sleep(0l, 250000);
} catch (InterruptedException e) {
@ -88,8 +92,8 @@ public interface IServerQuery {
}
default boolean awaitResponseBinaryAvailable(long timeout) {
long start = System.currentTimeMillis();
while(isOpen() && binaryResponsesAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) {
long start = EagRuntime.steadyTimeMillis();
while(isOpen() && binaryResponsesAvailable() <= 0 && (timeout <= 0l || EagRuntime.steadyTimeMillis() - start < timeout)) {
try {
Thread.sleep(0l, 250000);
} catch (InterruptedException e) {

View File

@ -0,0 +1,62 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.List;
/**
* 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 interface IWebSocketClient {
EnumEaglerConnectionState getState();
boolean connectBlocking(int timeoutMS);
boolean isOpen();
boolean isClosed();
void close();
int availableFrames();
IWebSocketFrame getNextFrame();
List<IWebSocketFrame> getNextFrames();
void clearFrames();
int availableStringFrames();
IWebSocketFrame getNextStringFrame();
List<IWebSocketFrame> getNextStringFrames();
void clearStringFrames();
int availableBinaryFrames();
IWebSocketFrame getNextBinaryFrame();
List<IWebSocketFrame> getNextBinaryFrames();
void clearBinaryFrames();
void send(String str);
void send(byte[] bytes);
String getCurrentURI();
}

View File

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.io.InputStream;
/**
* 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 interface IWebSocketFrame {
boolean isString();
String getString();
byte[] getByteArray();
InputStream getInputStream();
int getLength();
long getTimestamp();
}

View File

@ -2,6 +2,8 @@ package net.lax1dude.eaglercraft.v1_8.internal;
import org.json.JSONObject;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
@ -37,7 +39,7 @@ public class QueryResponse {
this.serverBrand = obj.getString("brand");
this.serverName = obj.getString("name");
this.serverTime = obj.getLong("time");
this.clientTime = System.currentTimeMillis();
this.clientTime = EagRuntime.steadyTimeMillis();
this.serverCracked = obj.optBoolean("cracked", false);
}

View File

@ -0,0 +1,131 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.Map;
import java.util.TreeMap;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
/**
* 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 RamdiskFilesystemImpl implements IEaglerFilesystem {
protected final String filesystemName;
protected final Map<String,byte[]> filesystemMap = new TreeMap<>();
public RamdiskFilesystemImpl(String filesystemName) {
this.filesystemName = filesystemName;
}
@Override
public String getFilesystemName() {
return filesystemName;
}
@Override
public String getInternalDBName() {
return "ramdisk:" + filesystemName;
}
@Override
public boolean isRamdisk() {
return true;
}
@Override
public boolean eaglerDelete(String pathName) {
return filesystemMap.remove(pathName) != null;
}
@Override
public ByteBuffer eaglerRead(String pathName) {
byte[] data = filesystemMap.get(pathName);
if(data != null) {
ByteBuffer buf = PlatformRuntime.castPrimitiveByteArray(data);
if(buf == null) {
buf = PlatformRuntime.allocateByteBuffer(data.length);
buf.put(data);
buf.flip();
}
return buf;
}else {
return null;
}
}
@Override
public void eaglerWrite(String pathName, ByteBuffer data) {
byte[] arr = PlatformRuntime.castNativeByteBuffer(data);
if(arr == null) {
arr = new byte[data.remaining()];
int i = data.position();
data.get(arr);
data.position(i);
}
filesystemMap.put(pathName, arr);
}
@Override
public boolean eaglerExists(String pathName) {
return filesystemMap.containsKey(pathName);
}
@Override
public boolean eaglerMove(String pathNameOld, String pathNameNew) {
byte[] dat = filesystemMap.remove(pathNameOld);
if(dat != null) {
filesystemMap.put(pathNameNew, dat);
return true;
}
return false;
}
@Override
public int eaglerCopy(String pathNameOld, String pathNameNew) {
byte[] dat = filesystemMap.get(pathNameOld);
if(dat != null) {
filesystemMap.put(pathNameNew, dat);
return dat.length;
}
return -1;
}
@Override
public int eaglerSize(String pathName) {
byte[] dat = filesystemMap.get(pathName);
return dat != null ? dat.length : -1;
}
@Override
public void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
if(!recursive) {
eaglerIterate(pathName, new VFSFilenameIteratorNonRecursive(itr,
VFSFilenameIteratorNonRecursive.countSlashes(pathName) + 1), true);
}else {
boolean b = pathName.length() == 0;
for(String key : filesystemMap.keySet()) {
if(b || key.startsWith(pathName)) {
itr.next(key);
}
}
}
}
@Override
public void closeHandle() {
filesystemMap.clear();
}
}

View File

@ -0,0 +1,37 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import net.lax1dude.eaglercraft.v1_8.recording.EnumScreenRecordingCodec;
/**
* 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 ScreenRecordParameters {
public final EnumScreenRecordingCodec codec;
public final int resolutionDivisior;
public final int videoBitsPerSecond;
public final int audioBitsPerSecond;
public final int captureFrameRate;
public ScreenRecordParameters(EnumScreenRecordingCodec codec, int resolutionDivisior, int videoBitsPerSecond,
int audioBitsPerSecond, int captureFrameRate) {
this.codec = codec;
this.resolutionDivisior = resolutionDivisior;
this.videoBitsPerSecond = videoBitsPerSecond;
this.audioBitsPerSecond = audioBitsPerSecond;
this.captureFrameRate = captureFrameRate;
}
}

View File

@ -0,0 +1,47 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* 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 VFSFilenameIteratorNonRecursive implements VFSFilenameIterator {
private final VFSFilenameIterator child;
private final int pathCount;
public VFSFilenameIteratorNonRecursive(VFSFilenameIterator child, int pathCount) {
this.child = child;
this.pathCount = pathCount;
}
@Override
public void next(String entry) {
int i = countSlashes(entry);
if(i == pathCount) {
child.next(entry);
}
}
public static int countSlashes(String str) {
if(str.length() == 0) return -1;
int j = 0;
for(int i = 0, l = str.length(); i < l; ++i) {
if(str.charAt(i) == '/') {
++j;
}
}
return j;
}
}

View File

@ -0,0 +1,67 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
/**
* 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 WebViewOptions {
public EnumWebViewContentMode contentMode = EnumWebViewContentMode.BLOB_BASED;
public String fallbackTitle = "WebView";
public boolean scriptEnabled = false;
public boolean strictCSPEnable = true;
public boolean serverMessageAPIEnabled = false;
public URI url = null;
public byte[] blob = null;
public EaglercraftUUID permissionsOriginUUID = null;
public WebViewOptions() {
}
public WebViewOptions(boolean script, boolean serverMessageAPIEnabled, boolean strictCSPEnable, URI url) {
this.contentMode = EnumWebViewContentMode.URL_BASED;
this.scriptEnabled = script;
this.strictCSPEnable = strictCSPEnable;
this.serverMessageAPIEnabled = serverMessageAPIEnabled;
this.url = url;
this.permissionsOriginUUID = getURLOriginUUID(url);
}
public WebViewOptions(boolean script, boolean serverMessageAPIEnabled, boolean strictCSPEnable, byte[] data, EaglercraftUUID permissionsOriginUUID) {
this.contentMode = EnumWebViewContentMode.BLOB_BASED;
this.scriptEnabled = script;
this.strictCSPEnable = strictCSPEnable;
this.serverMessageAPIEnabled = serverMessageAPIEnabled;
this.blob = data;
this.permissionsOriginUUID = permissionsOriginUUID;
}
public static EaglercraftUUID getURLOriginUUID(URI url) {
return EaglercraftUUID.nameUUIDFromBytes(("URLOrigin:" + url.toString()).getBytes(StandardCharsets.UTF_8));
}
public static EaglercraftUUID getEmbedOriginUUID(byte[] sha256) {
byte[] vigg = "BlobOrigin:".getBytes(StandardCharsets.UTF_8);
byte[] eagler = new byte[sha256.length + vigg.length];
System.arraycopy(vigg, 0, eagler, 0, vigg.length);
System.arraycopy(sha256, 0, eagler, vigg.length, sha256.length);
return EaglercraftUUID.nameUUIDFromBytes(eagler);
}
}

View File

@ -41,14 +41,14 @@ public interface Buffer {
boolean hasRemaining();
boolean isReadOnly();
boolean hasArray();
Object array();
int arrayOffset();
boolean isDirect();
static IndexOutOfBoundsException makeIOOBE(int idx) {
return new IndexOutOfBoundsException("Index out of range: " + idx);
}
}

View File

@ -18,12 +18,8 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
*/
public interface ByteBuffer extends Buffer {
ByteBuffer slice();
ByteBuffer duplicate();
ByteBuffer asReadOnlyBuffer();
byte get();
ByteBuffer put(byte b);
@ -42,10 +38,6 @@ public interface ByteBuffer extends Buffer {
ByteBuffer put(byte[] src);
int arrayOffset();
ByteBuffer compact();
char getChar();
ByteBuffer putChar(char value);
@ -54,7 +46,7 @@ public interface ByteBuffer extends Buffer {
ByteBuffer putChar(int index, char value);
public abstract short getShort();
short getShort();
ByteBuffer putShort(short value);
@ -106,4 +98,6 @@ public interface ByteBuffer extends Buffer {
ByteBuffer position(int newPosition);
byte[] array();
}

View File

@ -3,7 +3,6 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import java.io.IOException;
import java.io.InputStream;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*

View File

@ -17,12 +17,8 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
*/
public interface FloatBuffer extends Buffer {
FloatBuffer slice();
FloatBuffer duplicate();
FloatBuffer asReadOnlyBuffer();
float get();
FloatBuffer put(float b);
@ -45,10 +41,6 @@ public interface FloatBuffer extends Buffer {
FloatBuffer put(float[] src);
int getArrayOffset();
FloatBuffer compact();
boolean isDirect();
FloatBuffer mark();
@ -64,6 +56,8 @@ public interface FloatBuffer extends Buffer {
FloatBuffer limit(int newLimit);
FloatBuffer position(int newPosition);
float[] array();
}

View File

@ -17,12 +17,8 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
*/
public interface IntBuffer extends Buffer {
IntBuffer slice();
IntBuffer duplicate();
IntBuffer asReadOnlyBuffer();
int get();
IntBuffer put(int b);
@ -45,10 +41,6 @@ public interface IntBuffer extends Buffer {
IntBuffer put(int[] src);
int getArrayOffset();
IntBuffer compact();
boolean isDirect();
IntBuffer mark();
@ -64,6 +56,8 @@ public interface IntBuffer extends Buffer {
IntBuffer limit(int newLimit);
IntBuffer position(int newPosition);
int[] array();
}

View File

@ -17,12 +17,8 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
*/
public interface ShortBuffer extends Buffer {
ShortBuffer slice();
ShortBuffer duplicate();
ShortBuffer asReadOnlyBuffer();
short get();
ShortBuffer put(short b);
@ -45,10 +41,6 @@ public interface ShortBuffer extends Buffer {
ShortBuffer put(short[] src);
int getArrayOffset();
ShortBuffer compact();
boolean isDirect();
ShortBuffer mark();
@ -64,5 +56,7 @@ public interface ShortBuffer extends Buffer {
ShortBuffer limit(int newLimit);
ShortBuffer position(int newPosition);
short[] array();
}

View File

@ -1,5 +1,6 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import net.lax1dude.eaglercraft.v1_8.internal.IEaglerFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
/**
@ -19,15 +20,17 @@ import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
*/
class VFSFilenameIteratorImpl implements VFSFilenameIterator {
protected IEaglerFilesystem fs;
protected VFSIterator2 itr;
VFSFilenameIteratorImpl(VFSIterator2 itr) {
VFSFilenameIteratorImpl(IEaglerFilesystem fs, VFSIterator2 itr) {
this.fs = fs;
this.itr = itr;
}
@Override
public void next(String entry) {
itr.next(new VFile2(entry));
itr.next(VFile2.create(fs, entry));
}
}

View File

@ -2,6 +2,7 @@ package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.internal.IEaglerFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
/**
@ -21,15 +22,17 @@ import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
*/
class VFSListFilesIteratorImpl implements VFSFilenameIterator {
protected IEaglerFilesystem fs;
protected List<VFile2> list;
VFSListFilesIteratorImpl(List<VFile2> list) {
VFSListFilesIteratorImpl(IEaglerFilesystem fs, List<VFile2> list) {
this.fs = fs;
this.list = list;
}
@Override
public void next(String entry) {
list.add(new VFile2(entry));
list.add(VFile2.create(fs, entry));
}
}

View File

@ -5,9 +5,10 @@ import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.IEaglerFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
@ -31,6 +32,12 @@ public class VFile2 {
public static final String pathSeperator = "/";
public static final String[] altPathSeperator = new String[] { "\\" };
static IEaglerFilesystem primaryFilesystem = null;
public static void setPrimaryFilesystem(IEaglerFilesystem fs) {
primaryFilesystem = fs;
}
public static String normalizePath(String p) {
for(int i = 0; i < altPathSeperator.length; ++i) {
p = p.replace(altPathSeperator[i], pathSeperator);
@ -53,9 +60,11 @@ public class VFile2 {
}
protected String path;
protected IEaglerFilesystem myFilesystem;
protected Supplier<IEaglerFilesystem> myFilesystemProvider;
public static String createPath(Object... p) {
ArrayList<String> r = new ArrayList();
ArrayList<String> r = new ArrayList<>();
for(int i = 0; i < p.length; ++i) {
if(p[i] == null) {
continue;
@ -94,13 +103,45 @@ public class VFile2 {
}
}
public VFile2(Object... p) {
this.path = createPath(p);
public static VFile2 create(IEaglerFilesystem fs, Object... path) {
return new VFile2(createPath(path), fs);
}
public static VFile2 create(Supplier<IEaglerFilesystem> fs, Object... path) {
return new VFile2(createPath(path), fs);
}
public VFile2(Object... path) {
this(createPath(path), primaryFilesystem);
}
private VFile2(String path, IEaglerFilesystem fs) {
this.path = path;
this.myFilesystem = fs;
}
private VFile2(String path, Supplier<IEaglerFilesystem> fs) {
this.path = path;
this.myFilesystemProvider = fs;
}
protected IEaglerFilesystem getFS() {
if(myFilesystem == null) {
if(myFilesystemProvider != null) {
myFilesystem = myFilesystemProvider.get();
}else {
myFilesystem = primaryFilesystem;
}
if(myFilesystem == null) {
throw new IllegalStateException("The filesystem has not been initialized yet!");
}
}
return myFilesystem;
}
public InputStream getInputStream() {
assertNotRelative();
return new VFileInputStream(PlatformFilesystem.eaglerRead(path));
return new VFileInputStream(getFS().eaglerRead(path));
}
public OutputStream getOutputStream() {
@ -121,7 +162,7 @@ public class VFile2 {
}
public boolean canRead() {
return !isRelative() && PlatformFilesystem.eaglerExists(path);
return !isRelative() && getFS().eaglerExists(path);
}
public String getPath() {
@ -160,15 +201,15 @@ public class VFile2 {
}
public boolean exists() {
return !isRelative() && PlatformFilesystem.eaglerExists(path);
return !isRelative() && getFS().eaglerExists(path);
}
public boolean delete() {
return !isRelative() && PlatformFilesystem.eaglerDelete(path);
return !isRelative() && getFS().eaglerDelete(path);
}
public boolean renameTo(String p) {
if(!isRelative() && PlatformFilesystem.eaglerMove(path, p)) {
if(!isRelative() && getFS().eaglerMove(path, p)) {
return true;
}
return false;
@ -179,7 +220,7 @@ public class VFile2 {
}
public int length() {
return isRelative() ? -1 : PlatformFilesystem.eaglerSize(path);
return isRelative() ? -1 : getFS().eaglerSize(path);
}
public byte[] getAllBytes() {
@ -187,7 +228,7 @@ public class VFile2 {
if(!exists()) {
return null;
}
ByteBuffer readBuffer = PlatformFilesystem.eaglerRead(path);
ByteBuffer readBuffer = getFS().eaglerRead(path);
byte[] copyBuffer = PlatformRuntime.castNativeByteBuffer(readBuffer);
if(copyBuffer != null) {
return copyBuffer;
@ -225,14 +266,14 @@ public class VFile2 {
assertNotRelative();
ByteBuffer copyBuffer = PlatformRuntime.castPrimitiveByteArray(bytes);
if(copyBuffer != null) {
PlatformFilesystem.eaglerWrite(path, copyBuffer);
getFS().eaglerWrite(path, copyBuffer);
return;
}
copyBuffer = PlatformRuntime.allocateByteBuffer(bytes.length);
try {
copyBuffer.put(bytes);
copyBuffer.flip();
PlatformFilesystem.eaglerWrite(path, copyBuffer);
getFS().eaglerWrite(path, copyBuffer);
}finally {
PlatformRuntime.freeByteBuffer(copyBuffer);
}
@ -240,24 +281,30 @@ public class VFile2 {
public void iterateFiles(VFSIterator2 itr, boolean recursive) {
assertNotRelative();
PlatformFilesystem.eaglerIterate(path, new VFSFilenameIteratorImpl(itr), recursive);
IEaglerFilesystem fs = getFS();
fs.eaglerIterate(path, new VFSFilenameIteratorImpl(fs, itr), recursive);
}
public List<String> listFilenames(boolean recursive) {
List<String> ret = new ArrayList();
PlatformFilesystem.eaglerIterate(path, new VFSListFilenamesIteratorImpl(ret), recursive);
List<String> ret = new ArrayList<>();
getFS().eaglerIterate(path, new VFSListFilenamesIteratorImpl(ret), recursive);
return ret;
}
public List<VFile2> listFiles(boolean recursive) {
List<VFile2> ret = new ArrayList();
PlatformFilesystem.eaglerIterate(path, new VFSListFilesIteratorImpl(ret), recursive);
List<VFile2> ret = new ArrayList<>();
IEaglerFilesystem fs = getFS();
fs.eaglerIterate(path, new VFSListFilesIteratorImpl(fs, ret), recursive);
return ret;
}
public static int copyFile(VFile2 src, VFile2 dst) {
src.assertNotRelative();
dst.assertNotRelative();
return PlatformFilesystem.eaglerCopy(src.path, dst.path);
IEaglerFilesystem sfs = src.getFS();
if(sfs != dst.getFS()) {
throw new UnsupportedOperationException("Cannot copy file between filesystems!");
}
return sfs.eaglerCopy(src.path, dst.path);
}
}

View File

@ -3,7 +3,6 @@ package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.EaglerOutputStream;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
@ -41,7 +40,7 @@ class VFileOutputStream extends EaglerOutputStream {
copyBuffer.put(buf, 0, count);
copyBuffer.flip();
try {
PlatformFilesystem.eaglerWrite(vfsFile.path, copyBuffer);
vfsFile.getFS().eaglerWrite(vfsFile.path, copyBuffer);
}catch(Throwable t) {
throw new IOException("Could not write stream contents to file!", t);
}