mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 10:58:15 -05:00
Update #28 - Added capes, voice chat, FNAW skins, and fixes
This commit is contained in:
@ -60,6 +60,9 @@ public class PlatformAssets {
|
||||
public static final ImageData loadImageFile(InputStream data) {
|
||||
try {
|
||||
BufferedImage img = ImageIO.read(data);
|
||||
if(img == null) {
|
||||
throw new IOException("Data is not a supported image format!");
|
||||
}
|
||||
int w = img.getWidth();
|
||||
int h = img.getHeight();
|
||||
boolean a = img.getColorModel().hasAlpha();
|
||||
|
@ -21,10 +21,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
||||
public class PlatformBufferFunctions {
|
||||
|
||||
public static void put(ByteBuffer newBuffer, ByteBuffer flip) {
|
||||
int len = flip.remaining();
|
||||
for(int i = 0; i < len; ++i) {
|
||||
newBuffer.put(flip.get());
|
||||
}
|
||||
newBuffer.put(flip);
|
||||
}
|
||||
|
||||
public static void put(IntBuffer intBuffer, int index, int[] data) {
|
||||
|
@ -1,13 +1,11 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2.BreakLoop;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.DebugFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.JDBCFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.JDBCFilesystemConverter;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
@ -30,183 +28,104 @@ public class PlatformFilesystem {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("PlatformFilesystem");
|
||||
|
||||
public static final File filesystemRoot = (new File("filesystem/sp")).getAbsoluteFile();
|
||||
public static final File debugFilesystemRoot = (new File("filesystem/sp")).getAbsoluteFile();
|
||||
|
||||
private static IFilesystemProvider provider = null;
|
||||
|
||||
public static String jdbcUri = null;
|
||||
public static String jdbcDriver = null;
|
||||
|
||||
public static void initialize() {
|
||||
if(!filesystemRoot.isDirectory() && !filesystemRoot.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create directory for virtual filesystem: " + filesystemRoot.getAbsolutePath());
|
||||
if(provider == null) {
|
||||
if(jdbcUri != null && jdbcDriver != null) {
|
||||
provider = JDBCFilesystem.initialize(jdbcUri, jdbcDriver);
|
||||
if(((JDBCFilesystem)provider).isNewFilesystem() && debugFilesystemRoot.isDirectory() && debugFilesystemRoot.list().length > 0) {
|
||||
JDBCFilesystemConverter.convertFilesystem("Converting filesystem, please wait...", debugFilesystemRoot, provider, true);
|
||||
}
|
||||
}else {
|
||||
provider = DebugFilesystem.initialize(debugFilesystemRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setUseJDBC(String uri) {
|
||||
jdbcUri = uri;
|
||||
}
|
||||
|
||||
public static void setJDBCDriverClass(String driver) {
|
||||
jdbcDriver = driver;
|
||||
}
|
||||
|
||||
public static interface IFilesystemProvider {
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
private static void throwNotInitialized() {
|
||||
throw new UnsupportedOperationException("Filesystem has not been initialized!");
|
||||
}
|
||||
|
||||
public static boolean eaglerDelete(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(!f.exists()) {
|
||||
logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
|
||||
return false;
|
||||
}
|
||||
if(f.delete()) {
|
||||
deleteParentIfEmpty(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerDelete(pathName);
|
||||
}
|
||||
|
||||
public static ByteBuffer eaglerRead(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
ByteBuffer buf = PlatformRuntime.allocateByteBuffer((int)fileSize);
|
||||
try(FileInputStream is = new FileInputStream(f)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
buf.put(copyBuffer, 0, i);
|
||||
}
|
||||
if(buf.remaining() > 0) {
|
||||
throw new EaglerFileSystemException("ERROR: " + buf.remaining() + " bytes are remaining after reading: " + f.getAbsolutePath());
|
||||
}
|
||||
buf.flip();
|
||||
ByteBuffer tmp = buf;
|
||||
buf = null;
|
||||
return tmp;
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to read: " + f.getAbsolutePath(), e);
|
||||
}catch(ArrayIndexOutOfBoundsException ex) {
|
||||
throw new EaglerFileSystemException("ERROR: Expected " + fileSize + " bytes, buffer overflow reading: " + f.getAbsolutePath(), ex);
|
||||
}finally {
|
||||
if(buf != null) {
|
||||
PlatformRuntime.freeByteBuffer(buf);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
logger.warn("Tried to read file that doesn't exist: \"{}\"", f.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerRead(pathName);
|
||||
}
|
||||
|
||||
public static void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
File f = getJREFile(pathName);
|
||||
File p = f.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
try(FileOutputStream fos = new FileOutputStream(f)) {
|
||||
byte[] copyBuffer = new byte[Math.min(4096, data.remaining())];
|
||||
int i;
|
||||
while((i = data.remaining()) > 0) {
|
||||
if(i > copyBuffer.length) {
|
||||
i = copyBuffer.length;
|
||||
}
|
||||
data.get(copyBuffer, 0, i);
|
||||
fos.write(copyBuffer, 0, i);
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to write: " + f.getAbsolutePath(), e);
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
provider.eaglerWrite(pathName, data);
|
||||
}
|
||||
|
||||
public static boolean eaglerExists(String pathName) {
|
||||
return getJREFile(pathName).isFile();
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerExists(pathName);
|
||||
}
|
||||
|
||||
public static boolean eaglerMove(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(f2.exists()) {
|
||||
logger.warn("Tried to rename file \"{}\" to \"{}\" which already exists! File will be replaced");
|
||||
if(!f2.delete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(f1.renameTo(f2)) {
|
||||
deleteParentIfEmpty(f1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerMove(pathNameOld, pathNameNew);
|
||||
}
|
||||
|
||||
public static int eaglerCopy(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(!f1.isFile()) {
|
||||
return -1;
|
||||
}
|
||||
if(f2.isDirectory()) {
|
||||
throw new EaglerFileSystemException("Destination file is a directory: " + f2.getAbsolutePath());
|
||||
}
|
||||
File p = f2.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
int sz = 0;
|
||||
try(FileInputStream is = new FileInputStream(f1)) {
|
||||
try(FileOutputStream os = new FileOutputStream(f2)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
os.write(copyBuffer, 0, i);
|
||||
sz += i;
|
||||
}
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to copy \"" + f1.getAbsolutePath() + "\" to file \"" + f2.getAbsolutePath() + "\"", e);
|
||||
}
|
||||
return sz;
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerCopy(pathNameOld, pathNameNew);
|
||||
}
|
||||
|
||||
public static int eaglerSize(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
return (int)fileSize;
|
||||
}else {
|
||||
return -1;
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerSize(pathName);
|
||||
}
|
||||
|
||||
public static void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
|
||||
try {
|
||||
iterateFile(pathName, getJREFile(pathName), itr, recursive);
|
||||
}catch(BreakLoop ex) {
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
provider.eaglerIterate(pathName, itr, recursive);
|
||||
}
|
||||
|
||||
private static void iterateFile(String pathName, File f, VFSFilenameIterator itr, boolean recursive) {
|
||||
if(!f.exists()) {
|
||||
return;
|
||||
}
|
||||
if(!f.isDirectory()) {
|
||||
itr.next(pathName);
|
||||
return;
|
||||
}
|
||||
File[] fa = f.listFiles();
|
||||
for(int i = 0; i < fa.length; ++i) {
|
||||
File ff = fa[i];
|
||||
String fn = pathName + "/" + ff.getName();
|
||||
if(ff.isDirectory()) {
|
||||
if(recursive) {
|
||||
iterateFile(fn, ff, itr, true);
|
||||
}
|
||||
}else {
|
||||
itr.next(fn);
|
||||
public static void platformShutdown() {
|
||||
if(provider != null) {
|
||||
if(provider instanceof JDBCFilesystem) {
|
||||
((JDBCFilesystem)provider).shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static File getJREFile(String path) {
|
||||
return new File(filesystemRoot, path);
|
||||
}
|
||||
|
||||
private static void deleteParentIfEmpty(File f) {
|
||||
String[] s;
|
||||
while((f = f.getParentFile()) != null && (s = f.list()) != null && s.length == 0) {
|
||||
f.delete();
|
||||
provider = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,10 @@ public class PlatformInput {
|
||||
public static boolean lockKeys = false;
|
||||
|
||||
private static final List<Character> keyboardCharList = new LinkedList();
|
||||
|
||||
|
||||
private static boolean vsync = true;
|
||||
private static boolean glfwVSyncState = false;
|
||||
|
||||
private static class KeyboardEvent {
|
||||
|
||||
protected final int key;
|
||||
@ -214,8 +217,16 @@ public class PlatformInput {
|
||||
return glfwWindowShouldClose(win);
|
||||
}
|
||||
|
||||
public static void setVSync(boolean enable) {
|
||||
vsync = enable;
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
glfwPollEvents();
|
||||
if(vsync != glfwVSyncState) {
|
||||
glfwSwapInterval(vsync ? 1 : 0);
|
||||
glfwVSyncState = vsync;
|
||||
}
|
||||
glfwSwapBuffers(win);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
||||
|
||||
import static org.lwjgl.opengles.GLES30.*;
|
||||
|
||||
import org.lwjgl.opengles.GLESCapabilities;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
@ -24,6 +26,12 @@ import static org.lwjgl.opengles.GLES30.*;
|
||||
*/
|
||||
public class PlatformOpenGL {
|
||||
|
||||
private static boolean hasLinearHDR32FSupport = false;
|
||||
|
||||
static void setCurrentContext(GLESCapabilities caps) {
|
||||
hasLinearHDR32FSupport = caps.GL_OES_texture_float_linear;
|
||||
}
|
||||
|
||||
public static final void _wglEnable(int glEnum) {
|
||||
glEnable(glEnum);
|
||||
}
|
||||
@ -269,6 +277,12 @@ public class PlatformOpenGL {
|
||||
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data));
|
||||
}
|
||||
|
||||
public static final void _wglTexImage2Df32(int target, int level, int internalFormat, int width, int height,
|
||||
int border, int format, int type, ByteBuffer data) {
|
||||
nglTexImage2D(target, level, internalFormat, width, height, border, format, type,
|
||||
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data));
|
||||
}
|
||||
|
||||
public static final void _wglTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height,
|
||||
int format, int type, ByteBuffer data) {
|
||||
nglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
|
||||
@ -523,4 +537,7 @@ public class PlatformOpenGL {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final boolean checkLinearHDR32FSupport() {
|
||||
return hasLinearHDR32FSupport;
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ public class PlatformRuntime {
|
||||
|
||||
EGL.createDisplayCapabilities(glfw_eglHandle, major[0], minor[0]);
|
||||
glfwMakeContextCurrent(windowHandle);
|
||||
GLES.createCapabilities();
|
||||
PlatformOpenGL.setCurrentContext(GLES.createCapabilities());
|
||||
|
||||
logger.info("OpenGL Version: {}", (glVersion = GLES30.glGetString(GLES30.GL_VERSION)));
|
||||
logger.info("OpenGL Renderer: {}", (glRenderer = GLES30.glGetString(GLES30.GL_RENDERER)));
|
||||
@ -245,6 +245,7 @@ public class PlatformRuntime {
|
||||
|
||||
public static void destroy() {
|
||||
PlatformAudio.platformShutdown();
|
||||
PlatformFilesystem.platformShutdown();
|
||||
GLES.destroy();
|
||||
EGL.destroy();
|
||||
glfwDestroyWindow(windowHandle);
|
||||
@ -340,15 +341,27 @@ public class PlatformRuntime {
|
||||
public static class NativeNIO {
|
||||
|
||||
public static java.nio.ByteBuffer allocateByteBuffer(int length) {
|
||||
return MemoryUtil.memByteBuffer(JEmalloc.nje_malloc(length), length);
|
||||
long ret = JEmalloc.nje_malloc(length);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memByteBuffer(ret, length);
|
||||
}
|
||||
|
||||
public static java.nio.IntBuffer allocateIntBuffer(int length) {
|
||||
return MemoryUtil.memIntBuffer(JEmalloc.nje_malloc(length << 2), length);
|
||||
long ret = JEmalloc.nje_malloc(length << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memIntBuffer(ret, length);
|
||||
}
|
||||
|
||||
public static java.nio.FloatBuffer allocateFloatBuffer(int length) {
|
||||
return MemoryUtil.memFloatBuffer(JEmalloc.nje_malloc(length << 2), length);
|
||||
long ret = JEmalloc.nje_malloc(length << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memFloatBuffer(ret, length);
|
||||
}
|
||||
|
||||
public static java.nio.IntBuffer getIntBuffer(java.nio.ByteBuffer byteBuffer) {
|
||||
|
@ -0,0 +1,116 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.voice.EnumVoiceChannelPeerState;
|
||||
import net.lax1dude.eaglercraft.v1_8.voice.EnumVoiceChannelReadyState;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 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 PlatformVoiceClient {
|
||||
|
||||
public static void initialize() {
|
||||
|
||||
}
|
||||
|
||||
public static void initializeDevices() {
|
||||
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setVoiceListenVolume(float f) {
|
||||
|
||||
}
|
||||
|
||||
public static void setVoiceSpeakVolume(float f) {
|
||||
|
||||
}
|
||||
|
||||
public static void activateVoice(boolean talk) {
|
||||
|
||||
}
|
||||
|
||||
public static void setICEServers(String[] servs) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalConnect(EaglercraftUUID user, boolean offer) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalDisconnect(EaglercraftUUID user, boolean b) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalICECandidate(EaglercraftUUID user, String ice) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalDescription(EaglercraftUUID user, String desc) {
|
||||
|
||||
}
|
||||
|
||||
public static void tickVoiceClient() {
|
||||
|
||||
}
|
||||
|
||||
public static void updateVoicePosition(EaglercraftUUID uuid, double x, double y, double z) {
|
||||
|
||||
}
|
||||
|
||||
public static void resetPeerStates() {
|
||||
|
||||
}
|
||||
|
||||
public static void setVoiceProximity(int prox) {
|
||||
|
||||
}
|
||||
|
||||
public static void setMicVolume(float f) {
|
||||
|
||||
}
|
||||
|
||||
public static void mutePeer(EaglercraftUUID uuid, boolean mute) {
|
||||
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerState() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelReadyState getReadyState() {
|
||||
return EnumVoiceChannelReadyState.NONE;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateConnect() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateInitial() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateDesc() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateIce() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* 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
|
||||
@ -26,19 +26,35 @@ public class EaglerLWJGLAllocator {
|
||||
}
|
||||
|
||||
public static ByteBuffer allocByteBuffer(int len) {
|
||||
return new EaglerLWJGLByteBuffer(JEmalloc.nje_malloc(len), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLByteBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static ShortBuffer allocShortBuffer(int len) {
|
||||
return new EaglerLWJGLShortBuffer(JEmalloc.nje_malloc(len << 1), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len << 1);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLShortBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static IntBuffer allocIntBuffer(int len) {
|
||||
return new EaglerLWJGLIntBuffer(JEmalloc.nje_malloc(len << 2), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLIntBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static FloatBuffer allocFloatBuffer(int len) {
|
||||
return new EaglerLWJGLFloatBuffer(JEmalloc.nje_malloc(len << 2), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLFloatBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static void freeByteBuffer(ByteBuffer buffer) {
|
||||
|
@ -1,10 +1,12 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* 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
|
||||
@ -104,35 +106,33 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public byte get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetByte(address + position++);
|
||||
return UnsafeUtils.getMemByte(address + position++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(byte b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutByte(address + position++, b);
|
||||
UnsafeUtils.setMemByte(address + position++, b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetByte(address + index);
|
||||
return UnsafeUtils.getMemByte(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(int index, byte b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutByte(address + index, b);
|
||||
UnsafeUtils.setMemByte(address + index, b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer get(byte[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetByte(address + position + i);
|
||||
}
|
||||
UnsafeMemcpy.memcpy(dst, offset, address + position, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -140,9 +140,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer get(byte[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[position + i] = MemoryUtil.memGetByte(address + position + i);
|
||||
}
|
||||
UnsafeMemcpy.memcpy(dst, 0, address + position, dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
@ -153,14 +151,14 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
EaglerLWJGLByteBuffer c = (EaglerLWJGLByteBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + c.position, address + position, l);
|
||||
UnsafeMemcpy.memcpy(address + position, c.address + c.position, l);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutByte(address + position + l, src.get());
|
||||
UnsafeUtils.setMemByte(address + position + l, src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
@ -170,9 +168,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer put(byte[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutByte(address + position + i, src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpy(address + position, src, offset, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -180,9 +176,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer put(byte[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutByte(address + position + i, src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpy(address + position, src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
@ -203,7 +197,10 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + position, newAlloc, newLen);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + position, newLen);
|
||||
|
||||
return new EaglerLWJGLByteBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
@ -211,7 +208,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public char getChar() {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
char c = (char)MemoryUtil.memGetShort(address + position);
|
||||
char c = UnsafeUtils.getMemChar(address + position);
|
||||
position += 2;
|
||||
return c;
|
||||
}
|
||||
@ -219,7 +216,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer putChar(char value) {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutShort(address + position, (short)value);
|
||||
UnsafeUtils.setMemChar(address + position, value);
|
||||
position += 2;
|
||||
return this;
|
||||
}
|
||||
@ -227,20 +224,20 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public char getChar(int index) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return (char)MemoryUtil.memGetShort(address + index);
|
||||
return UnsafeUtils.getMemChar(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putChar(int index, char value) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + index, (short)value);
|
||||
UnsafeUtils.setMemChar(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort() {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
short s = MemoryUtil.memGetShort(address + position);
|
||||
short s = UnsafeUtils.getMemShort(address + position);
|
||||
position += 2;
|
||||
return s;
|
||||
}
|
||||
@ -248,7 +245,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer putShort(short value) {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutShort(address + position, value);
|
||||
UnsafeUtils.setMemShort(address + position, value);
|
||||
position += 2;
|
||||
return this;
|
||||
}
|
||||
@ -256,13 +253,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public short getShort(int index) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetShort(address + index);
|
||||
return UnsafeUtils.getMemShort(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putShort(int index, short value) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + index, value);
|
||||
UnsafeUtils.setMemShort(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -274,7 +271,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public int getInt() {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
int i = MemoryUtil.memGetInt(address + position);
|
||||
int i = UnsafeUtils.getMemInt(address + position);
|
||||
position += 4;
|
||||
return i;
|
||||
}
|
||||
@ -282,7 +279,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer putInt(int value) {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutInt(address + position, value);
|
||||
UnsafeUtils.setMemInt(address + position, value);
|
||||
position += 4;
|
||||
return this;
|
||||
}
|
||||
@ -290,13 +287,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public int getInt(int index) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetInt(address + index);
|
||||
return UnsafeUtils.getMemInt(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putInt(int index, int value) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutInt(address + index, value);
|
||||
UnsafeUtils.setMemInt(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -308,7 +305,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public long getLong() {
|
||||
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
long l = MemoryUtil.memGetLong(address + position);
|
||||
long l = UnsafeUtils.getMemLong(address + position);
|
||||
position += 8;
|
||||
return l;
|
||||
}
|
||||
@ -316,7 +313,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer putLong(long value) {
|
||||
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutLong(address + position, value);
|
||||
UnsafeUtils.setMemLong(address + position, value);
|
||||
position += 8;
|
||||
return this;
|
||||
}
|
||||
@ -324,20 +321,20 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public long getLong(int index) {
|
||||
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetLong(address + index);
|
||||
return UnsafeUtils.getMemLong(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putLong(int index, long value) {
|
||||
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutLong(address + index, value);
|
||||
UnsafeUtils.setMemLong(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat() {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
float f = MemoryUtil.memGetFloat(address + position);
|
||||
float f = UnsafeUtils.getMemFloat(address + position);
|
||||
position += 4;
|
||||
return f;
|
||||
}
|
||||
@ -345,7 +342,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public ByteBuffer putFloat(float value) {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutFloat(address + position, value);
|
||||
UnsafeUtils.setMemFloat(address + position, value);
|
||||
position += 4;
|
||||
return this;
|
||||
}
|
||||
@ -353,13 +350,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
@Override
|
||||
public float getFloat(int index) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetFloat(address + index);
|
||||
return UnsafeUtils.getMemFloat(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putFloat(int index, float value) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutFloat(address + index, value);
|
||||
UnsafeUtils.setMemFloat(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* 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
|
||||
@ -106,47 +108,45 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
@Override
|
||||
public float get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetFloat(address + ((position++) << SHIFT));
|
||||
return UnsafeUtils.getMemFloat(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(float b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutFloat(address + ((position++) << SHIFT), b);
|
||||
UnsafeUtils.setMemFloat(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetFloat(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemFloat(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(int index, float b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutFloat(address + (index << SHIFT), b);
|
||||
UnsafeUtils.setMemFloat(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetFloat(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemFloat(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, float value) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutFloat(address + ((position++) << SHIFT), value);
|
||||
UnsafeUtils.setMemFloat(address + ((position++) << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer get(float[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetFloat(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -154,9 +154,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
@Override
|
||||
public FloatBuffer get(float[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[i] = MemoryUtil.memGetFloat(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
@ -167,14 +165,14 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
EaglerLWJGLFloatBuffer c = (EaglerLWJGLFloatBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + (c.position << SHIFT), address + (position << SHIFT), l << SHIFT);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutFloat(address + ((position + l) << SHIFT), src.get());
|
||||
UnsafeUtils.setMemFloat(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
@ -184,9 +182,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
@Override
|
||||
public FloatBuffer put(float[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutFloat(address + ((position + i) << SHIFT), src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -194,9 +190,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
@Override
|
||||
public FloatBuffer put(float[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutFloat(address + ((position + i) << SHIFT), src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
@ -217,7 +211,10 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + (position << SHIFT), newAlloc, newLen << SHIFT);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLFloatBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* 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
|
||||
@ -106,47 +108,45 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
@Override
|
||||
public int get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetInt(address + ((position++) << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer put(int b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutInt(address + ((position++) << SHIFT), b);
|
||||
UnsafeUtils.setMemInt(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetInt(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer put(int index, int b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutInt(address + (index << SHIFT), b);
|
||||
UnsafeUtils.setMemInt(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetInt(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, int value) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutInt(address + (index << SHIFT), value);
|
||||
UnsafeUtils.setMemInt(address + (index << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer get(int[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetInt(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -154,9 +154,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
@Override
|
||||
public IntBuffer get(int[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[i] = MemoryUtil.memGetInt(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
@ -167,14 +165,14 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
EaglerLWJGLIntBuffer c = (EaglerLWJGLIntBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + (c.position << SHIFT), address + (position << SHIFT), l << SHIFT);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutInt(address + ((position + l) << SHIFT), src.get());
|
||||
UnsafeUtils.setMemInt(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
@ -184,9 +182,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
@Override
|
||||
public IntBuffer put(int[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutInt(address + ((position + i) << SHIFT), src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -194,9 +190,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
@Override
|
||||
public IntBuffer put(int[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutInt(address + ((position + i) << SHIFT), src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
@ -217,7 +211,10 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + (position << SHIFT), newAlloc, newLen << SHIFT);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLIntBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* 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
|
||||
@ -106,47 +108,45 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
||||
@Override
|
||||
public short get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetShort(address + ((position++) << SHIFT));
|
||||
return UnsafeUtils.getMemShort(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer put(short b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutShort(address + ((position++) << SHIFT), b);
|
||||
UnsafeUtils.setMemShort(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetShort(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemShort(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer put(int index, short b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + (index << SHIFT), b);
|
||||
UnsafeUtils.setMemShort(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetShort(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemShort(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, short value) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + (index << SHIFT), value);
|
||||
UnsafeUtils.setMemShort(address + (index << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer get(short[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetShort(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -154,9 +154,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
||||
@Override
|
||||
public ShortBuffer get(short[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[i] = MemoryUtil.memGetShort(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
@ -167,14 +165,14 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
||||
EaglerLWJGLShortBuffer c = (EaglerLWJGLShortBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + (c.position << SHIFT), address + (position << SHIFT), l << SHIFT);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutShort(address + ((position + l) << SHIFT), src.get());
|
||||
UnsafeUtils.setMemInt(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
@ -184,9 +182,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
||||
@Override
|
||||
public ShortBuffer put(short[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutShort(address + ((position + i) << SHIFT), src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
@ -194,9 +190,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
||||
@Override
|
||||
public ShortBuffer put(short[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutShort(address + ((position + i) << SHIFT), src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
@ -217,7 +211,10 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
||||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + (position << SHIFT), newAlloc, newLen << SHIFT);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLShortBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
@ -0,0 +1,224 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2.BreakLoop;
|
||||
|
||||
/**
|
||||
* 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 DebugFilesystem implements PlatformFilesystem.IFilesystemProvider {
|
||||
|
||||
public static DebugFilesystem initialize(File filesystemRoot) {
|
||||
if(!filesystemRoot.isDirectory() && !filesystemRoot.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create directory for virtual filesystem: " + filesystemRoot.getAbsolutePath());
|
||||
}
|
||||
return new DebugFilesystem(filesystemRoot);
|
||||
}
|
||||
|
||||
private final File filesystemRoot;
|
||||
|
||||
private DebugFilesystem(File root) {
|
||||
this.filesystemRoot = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerDelete(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(!f.exists()) {
|
||||
PlatformFilesystem.logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
|
||||
return false;
|
||||
}
|
||||
if(f.delete()) {
|
||||
deleteParentIfEmpty(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer eaglerRead(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
ByteBuffer buf = PlatformRuntime.allocateByteBuffer((int)fileSize);
|
||||
try(FileInputStream is = new FileInputStream(f)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
buf.put(copyBuffer, 0, i);
|
||||
}
|
||||
if(buf.remaining() > 0) {
|
||||
throw new EaglerFileSystemException("ERROR: " + buf.remaining() + " bytes are remaining after reading: " + f.getAbsolutePath());
|
||||
}
|
||||
buf.flip();
|
||||
ByteBuffer tmp = buf;
|
||||
buf = null;
|
||||
return tmp;
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to read: " + f.getAbsolutePath(), e);
|
||||
}catch(ArrayIndexOutOfBoundsException ex) {
|
||||
throw new EaglerFileSystemException("ERROR: Expected " + fileSize + " bytes, buffer overflow reading: " + f.getAbsolutePath(), ex);
|
||||
}finally {
|
||||
if(buf != null) {
|
||||
PlatformRuntime.freeByteBuffer(buf);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
PlatformFilesystem.logger.warn("Tried to read file that doesn't exist: \"{}\"", f.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
File f = getJREFile(pathName);
|
||||
File p = f.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
try(FileOutputStream fos = new FileOutputStream(f)) {
|
||||
byte[] copyBuffer = new byte[Math.min(4096, data.remaining())];
|
||||
int i;
|
||||
while((i = data.remaining()) > 0) {
|
||||
if(i > copyBuffer.length) {
|
||||
i = copyBuffer.length;
|
||||
}
|
||||
data.get(copyBuffer, 0, i);
|
||||
fos.write(copyBuffer, 0, i);
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to write: " + f.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerExists(String pathName) {
|
||||
return getJREFile(pathName).isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerMove(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(f2.exists()) {
|
||||
PlatformFilesystem.logger.warn("Tried to rename file \"{}\" to \"{}\" which already exists! File will be replaced");
|
||||
if(!f2.delete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(f1.renameTo(f2)) {
|
||||
deleteParentIfEmpty(f1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerCopy(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(!f1.isFile()) {
|
||||
return -1;
|
||||
}
|
||||
if(f2.isDirectory()) {
|
||||
throw new EaglerFileSystemException("Destination file is a directory: " + f2.getAbsolutePath());
|
||||
}
|
||||
File p = f2.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
int sz = 0;
|
||||
try(FileInputStream is = new FileInputStream(f1)) {
|
||||
try(FileOutputStream os = new FileOutputStream(f2)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
os.write(copyBuffer, 0, i);
|
||||
sz += i;
|
||||
}
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to copy \"" + f1.getAbsolutePath() + "\" to file \"" + f2.getAbsolutePath() + "\"", e);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerSize(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
return (int)fileSize;
|
||||
}else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
|
||||
try {
|
||||
iterateFile(pathName, getJREFile(pathName), itr, recursive);
|
||||
}catch(BreakLoop ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private void iterateFile(String pathName, File f, VFSFilenameIterator itr, boolean recursive) {
|
||||
if(!f.exists()) {
|
||||
return;
|
||||
}
|
||||
if(!f.isDirectory()) {
|
||||
itr.next(pathName);
|
||||
return;
|
||||
}
|
||||
File[] fa = f.listFiles();
|
||||
for(int i = 0; i < fa.length; ++i) {
|
||||
File ff = fa[i];
|
||||
String fn = pathName + "/" + ff.getName();
|
||||
if(ff.isDirectory()) {
|
||||
if(recursive) {
|
||||
iterateFile(fn, ff, itr, true);
|
||||
}
|
||||
}else {
|
||||
itr.next(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File getJREFile(String path) {
|
||||
return new File(filesystemRoot, path);
|
||||
}
|
||||
|
||||
private void deleteParentIfEmpty(File f) {
|
||||
String[] s;
|
||||
while((f = f.getParentFile()) != null && (s = f.list()) != null && s.length == 0) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
@ -124,4 +124,9 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowVoiceClient() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.Color;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JProgressBar;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* 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 FilesystemConvertingDialog extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private JPanel contentPane;
|
||||
private JProgressBar progressBar;
|
||||
|
||||
public FilesystemConvertingDialog(String title) {
|
||||
setIconImage(Toolkit.getDefaultToolkit().getImage("icon32.png"));
|
||||
setResizable(false);
|
||||
setAlwaysOnTop(true);
|
||||
setTitle("EaglercraftX 1.8");
|
||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
setBounds(100, 100, 420, 100);
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBackground(new Color(255, 255, 255));
|
||||
contentPane.setBorder(null);
|
||||
|
||||
setContentPane(contentPane);
|
||||
contentPane.setLayout(new BorderLayout(0, 0));
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
panel.setBackground(new Color(255, 255, 255));
|
||||
contentPane.add(panel, BorderLayout.SOUTH);
|
||||
panel.setLayout(new BorderLayout(0, 0));
|
||||
|
||||
progressBar = new JProgressBar();
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setPreferredSize(new Dimension(146, 20));
|
||||
progressBar.setMinimum(0);
|
||||
progressBar.setMaximum(512);
|
||||
panel.add(progressBar, BorderLayout.CENTER);
|
||||
|
||||
JLabel lblNewLabel = new JLabel(title);
|
||||
lblNewLabel.setFont(UIManager.getFont("PopupMenu.font"));
|
||||
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
contentPane.add(lblNewLabel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setProgressIndeterminate(boolean itr) {
|
||||
progressBar.setIndeterminate(itr);
|
||||
}
|
||||
|
||||
public void setProgressValue(int val) {
|
||||
progressBar.setValue(val);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,441 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem.IFilesystemProvider;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* 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 JDBCFilesystem implements IFilesystemProvider {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("JDBCFilesystem");
|
||||
|
||||
private boolean newFilesystem = true;
|
||||
|
||||
private static volatile boolean cleanupThreadStarted = false;
|
||||
private static final Collection<JDBCFilesystem> jdbcFilesystems = new LinkedList();
|
||||
|
||||
private final String jdbcUri;
|
||||
private final String jdbcDriver;
|
||||
|
||||
private final Connection conn;
|
||||
private final PreparedStatement createStatement;
|
||||
private final PreparedStatement updateStatement;
|
||||
private final PreparedStatement readStatement;
|
||||
private final PreparedStatement existsStatement;
|
||||
private final PreparedStatement sizeStatement;
|
||||
private final PreparedStatement deleteStatement;
|
||||
private final PreparedStatement renameStatement;
|
||||
private final PreparedStatement iterateNonRecursive;
|
||||
private final PreparedStatement iterateRecursive;
|
||||
private boolean hasClosed = false;
|
||||
|
||||
private final Object mutex = new Object();
|
||||
|
||||
public static IFilesystemProvider initialize(String jdbcUri, String jdbcDriver) {
|
||||
Class driver;
|
||||
try {
|
||||
driver = Class.forName(jdbcDriver);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new EaglerFileSystemException("JDBC driver class not found in JRE: " + jdbcDriver, e);
|
||||
}
|
||||
Driver driverObj = null;
|
||||
Enumeration<Driver> registeredDriversItr = DriverManager.getDrivers();
|
||||
while(registeredDriversItr.hasMoreElements()) {
|
||||
Driver drv = registeredDriversItr.nextElement();
|
||||
if(drv.getClass().equals(driver)) {
|
||||
driverObj = drv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(driverObj == null) {
|
||||
logger.warn("The class \"{}\" is not a registered JDBC driver, eaglercraft will try all registered drivers...", jdbcDriver);
|
||||
}
|
||||
Properties props = new Properties();
|
||||
for(Entry<Object, Object> etr : System.getProperties().entrySet()) {
|
||||
if(etr.getKey() instanceof String) {
|
||||
String str = (String)etr.getKey();
|
||||
if(str.startsWith("eagler.jdbc.opts.")) {
|
||||
props.put(str.substring(17), etr.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("Connecting to database: \"{}\"", jdbcUri);
|
||||
Connection conn;
|
||||
try {
|
||||
if(driverObj != null) {
|
||||
conn = driverObj.connect(jdbcUri, props);
|
||||
}else {
|
||||
conn = DriverManager.getConnection(jdbcUri, props);
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("Failed to connect to database: \"" + jdbcUri + "\"", ex);
|
||||
}
|
||||
try {
|
||||
return new JDBCFilesystem(conn, jdbcUri, jdbcDriver);
|
||||
} catch (SQLException ex) {
|
||||
try {
|
||||
conn.close();
|
||||
}catch(SQLException ex2) {
|
||||
}
|
||||
throw new EaglerFileSystemException("Failed to initialize database: \"" + jdbcUri + "\"", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private JDBCFilesystem(Connection conn, String jdbcUri, String jdbcDriver) throws SQLException {
|
||||
this.conn = conn;
|
||||
this.jdbcUri = jdbcUri;
|
||||
this.jdbcDriver = jdbcDriver;
|
||||
try(Statement stmt = conn.createStatement()) {
|
||||
stmt.execute("CREATE TABLE IF NOT EXISTS "
|
||||
+ "\"eaglercraft_desktop_runtime_filesystem\" ("
|
||||
+ "\"FileName\" VARCHAR(1024) NOT NULL,"
|
||||
+ "\"FileSize\" INT NOT NULL,"
|
||||
+ "\"FileData\" BLOB NOT NULL,"
|
||||
+ "PRIMARY KEY(\"FileName\"))");
|
||||
|
||||
int totalFiles = 0;
|
||||
try(ResultSet resultSet = stmt.executeQuery("SELECT COUNT(*) AS total_files FROM eaglercraft_desktop_runtime_filesystem")) {
|
||||
if(resultSet.next()) {
|
||||
totalFiles = resultSet.getInt(1);
|
||||
}
|
||||
}
|
||||
logger.info("Loaded JDBC filesystem with {} files: \"{}\"", totalFiles, jdbcUri);
|
||||
if(totalFiles > 0) {
|
||||
newFilesystem = false;
|
||||
}
|
||||
}
|
||||
this.createStatement = conn.prepareStatement("INSERT INTO eaglercraft_desktop_runtime_filesystem (FileName, FileSize, FileData) VALUES(?,?,?)");
|
||||
this.updateStatement = conn.prepareStatement("UPDATE eaglercraft_desktop_runtime_filesystem SET FileSize = ?, FileData = ? WHERE FileName = ?");
|
||||
this.readStatement = conn.prepareStatement("SELECT FileData FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ? LIMIT 1");
|
||||
this.existsStatement = conn.prepareStatement("SELECT COUNT(FileName) AS has_object FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ? LIMIT 1");
|
||||
this.sizeStatement = conn.prepareStatement("SELECT FileSize FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ? LIMIT 1");
|
||||
this.deleteStatement = conn.prepareStatement("DELETE FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ?");
|
||||
this.renameStatement = conn.prepareStatement("UPDATE eaglercraft_desktop_runtime_filesystem SET FileName = ? WHERE FileName = ?");
|
||||
this.iterateNonRecursive = conn.prepareStatement("SELECT FileName FROM eaglercraft_desktop_runtime_filesystem WHERE FileName LIKE ? AND NOT FileName LIKE ?");
|
||||
this.iterateRecursive = conn.prepareStatement("SELECT FileName FROM eaglercraft_desktop_runtime_filesystem WHERE FileName LIKE ?");
|
||||
startCleanupThread();
|
||||
synchronized(jdbcFilesystems) {
|
||||
jdbcFilesystems.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNewFilesystem() {
|
||||
return newFilesystem;
|
||||
}
|
||||
|
||||
private static void startCleanupThread() {
|
||||
if(!cleanupThreadStarted) {
|
||||
cleanupThreadStarted = true;
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
synchronized(jdbcFilesystems) {
|
||||
if(!jdbcFilesystems.isEmpty()) {
|
||||
for(JDBCFilesystem fs : jdbcFilesystems) {
|
||||
fs.shutdown0();
|
||||
}
|
||||
jdbcFilesystems.clear();
|
||||
}
|
||||
}
|
||||
}, "JDBCFilesystemCleanup"));
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
shutdown0();
|
||||
synchronized(jdbcFilesystems) {
|
||||
jdbcFilesystems.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdown0() {
|
||||
synchronized(mutex) {
|
||||
if(!hasClosed) {
|
||||
hasClosed = true;
|
||||
logger.info("Disconnecting from database: \"{}\"", jdbcUri);
|
||||
try {
|
||||
shutdown1();
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to disconnect from database: \"{}\"");
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdown1() throws SQLException {
|
||||
if(!conn.isClosed()) {
|
||||
quietClose(createStatement);
|
||||
quietClose(updateStatement);
|
||||
quietClose(readStatement);
|
||||
quietClose(existsStatement);
|
||||
quietClose(sizeStatement);
|
||||
quietClose(deleteStatement);
|
||||
quietClose(renameStatement);
|
||||
quietClose(iterateNonRecursive);
|
||||
quietClose(iterateRecursive);
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void quietClose(Statement stmt) {
|
||||
try {
|
||||
stmt.close();
|
||||
}catch(Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerDelete(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
deleteStatement.setString(1, pathName);
|
||||
int ret = deleteStatement.executeUpdate();
|
||||
if(ret == 0) {
|
||||
PlatformFilesystem.logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
|
||||
}
|
||||
return ret > 0;
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing delete!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer eaglerRead(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
readStatement.setString(1, pathName);
|
||||
byte[] has = null;
|
||||
try(ResultSet resultSet = readStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
has = resultSet.getBytes(1);
|
||||
}
|
||||
}
|
||||
if(has == null) {
|
||||
PlatformFilesystem.logger.warn("Tried to read file that doesn't exist: \"{}\"", pathName);
|
||||
return null;
|
||||
}
|
||||
ByteBuffer byteBuf = PlatformRuntime.allocateByteBuffer(has.length);
|
||||
byteBuf.put(has);
|
||||
byteBuf.flip();
|
||||
return byteBuf;
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing read!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
existsStatement.setString(1, pathName);
|
||||
boolean exists;
|
||||
try(ResultSet resultSet = existsStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
exists = resultSet.getInt(1) > 0;
|
||||
}else {
|
||||
exists = false;
|
||||
}
|
||||
}
|
||||
byte[] cp = new byte[data.remaining()];
|
||||
data.get(cp);
|
||||
if(exists) {
|
||||
updateStatement.setInt(1, cp.length);
|
||||
updateStatement.setBytes(2, cp);
|
||||
updateStatement.setString(3, pathName);
|
||||
if(updateStatement.executeUpdate() == 0) {
|
||||
throw new EaglerFileSystemException("SQL file update query did not update any rows!");
|
||||
}
|
||||
}else {
|
||||
createStatement.setString(1, pathName);
|
||||
createStatement.setInt(2, cp.length);
|
||||
createStatement.setBytes(3, cp);
|
||||
createStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing write!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerExists(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
existsStatement.setString(1, pathName);
|
||||
try(ResultSet resultSet = existsStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
return resultSet.getInt(1) > 0;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing exists!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerMove(String pathNameOld, String pathNameNew) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
renameStatement.setString(1, pathNameNew);
|
||||
renameStatement.setString(2, pathNameOld);
|
||||
return renameStatement.executeUpdate() > 0;
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing move!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerCopy(String pathNameOld, String pathNameNew) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
readStatement.setString(1, pathNameOld);
|
||||
try(ResultSet resultSet = readStatement.executeQuery()) {
|
||||
byte[] has = null;
|
||||
if(resultSet.next()) {
|
||||
has = resultSet.getBytes(1);
|
||||
}
|
||||
if(has == null) {
|
||||
return -1;
|
||||
}
|
||||
existsStatement.setString(1, pathNameNew);
|
||||
boolean exists;
|
||||
try(ResultSet resultSet2 = existsStatement.executeQuery()) {
|
||||
if(resultSet2.next()) {
|
||||
exists = resultSet2.getInt(1) > 0;
|
||||
}else {
|
||||
exists = false;
|
||||
}
|
||||
}
|
||||
if(exists) {
|
||||
updateStatement.setInt(1, has.length);
|
||||
updateStatement.setBytes(2, has);
|
||||
updateStatement.setString(3, pathNameNew);
|
||||
if(updateStatement.executeUpdate() == 0) {
|
||||
throw new EaglerFileSystemException("SQL file update query did not update any rows!");
|
||||
}
|
||||
}else {
|
||||
createStatement.setString(1, pathNameNew);
|
||||
createStatement.setInt(2, has.length);
|
||||
createStatement.setBytes(3, has);
|
||||
createStatement.executeUpdate();
|
||||
}
|
||||
return has.length;
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing copy!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerSize(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
sizeStatement.setString(1, pathName);
|
||||
try(ResultSet resultSet = sizeStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
return resultSet.getInt(1);
|
||||
}else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing size!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
PreparedStatement stmt;
|
||||
if(recursive) {
|
||||
stmt = iterateRecursive;
|
||||
stmt.setString(1, pathName + (!pathName.endsWith("/") ? "/%" : "%"));;
|
||||
}else {
|
||||
stmt = iterateNonRecursive;
|
||||
if(!pathName.endsWith("/")) {
|
||||
pathName += "/";
|
||||
}
|
||||
stmt.setString(1, pathName + "%");
|
||||
stmt.setString(2, pathName + "%/%");
|
||||
}
|
||||
try(ResultSet resultSet = stmt.executeQuery()) {
|
||||
while(resultSet.next()) {
|
||||
try {
|
||||
itr.next(resultSet.getString(1));
|
||||
}catch(VFSIterator2.BreakLoop exx) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing iterate!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem.IFilesystemProvider;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* 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 JDBCFilesystemConverter {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("JDBCFilesystemConverter");
|
||||
|
||||
public static void convertFilesystem(String title, File oldFS, IFilesystemProvider newFS, boolean deleteOld) {
|
||||
FilesystemConvertingDialog progressDialog = new FilesystemConvertingDialog(title);
|
||||
try {
|
||||
progressDialog.setProgressIndeterminate(true);
|
||||
progressDialog.setLocationRelativeTo(null);
|
||||
progressDialog.setVisible(true);
|
||||
|
||||
String slug = oldFS.getAbsolutePath();
|
||||
List<String> filesToCopy = new ArrayList();
|
||||
logger.info("Discovering files to convert...");
|
||||
iterateFolder(slug.length(), oldFS, filesToCopy);
|
||||
logger.info("Found {} files in the old directory", filesToCopy.size());
|
||||
|
||||
progressDialog.setProgressIndeterminate(false);
|
||||
progressDialog.setProgressValue(0);
|
||||
|
||||
int progCounter = 0;
|
||||
int lastProgUpdate = 0;
|
||||
byte[] copyArray = new byte[4096];
|
||||
|
||||
int l = filesToCopy.size();
|
||||
for(int i = 0; i < l; ++i) {
|
||||
String str = filesToCopy.get(i);
|
||||
File f = new File(oldFS, str);
|
||||
try(InputStream is = new FileInputStream(f)) {
|
||||
ByteBuffer copyBuffer = PlatformRuntime.allocateByteBuffer((int)f.length());
|
||||
try {
|
||||
int j;
|
||||
while(copyBuffer.hasRemaining() && (j = is.read(copyArray, 0, copyArray.length)) != -1) {
|
||||
copyBuffer.put(copyArray, 0, j);
|
||||
}
|
||||
copyBuffer.flip();
|
||||
progCounter += copyBuffer.remaining();
|
||||
newFS.eaglerWrite(str, copyBuffer);
|
||||
}finally {
|
||||
PlatformRuntime.freeByteBuffer(copyBuffer);
|
||||
}
|
||||
if(progCounter - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = progCounter;
|
||||
logger.info("Converted {}/{} files, {} bytes to JDBC format...", (i + 1), l, progCounter);
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
throw new EaglerFileSystemException("Failed to convert file: \"" + f.getAbsolutePath() + "\"", ex);
|
||||
}
|
||||
progressDialog.setProgressValue(i * 512 / (l - 1));
|
||||
}
|
||||
|
||||
logger.info("Converted {}/{} files successfully!", l, l);
|
||||
|
||||
if(deleteOld) {
|
||||
logger.info("Deleting old filesystem...");
|
||||
progressDialog.setProgressIndeterminate(true);
|
||||
deleteOldFolder(oldFS);
|
||||
logger.info("Delete complete!");
|
||||
}
|
||||
}finally {
|
||||
progressDialog.setVisible(false);
|
||||
progressDialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void iterateFolder(int slug, File file, List<String> ret) {
|
||||
File[] f = file.listFiles();
|
||||
if(f == null) {
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < f.length; ++i) {
|
||||
File ff = f[i];
|
||||
if(ff.isDirectory()) {
|
||||
iterateFolder(slug, ff, ret);
|
||||
}else {
|
||||
String str = ff.getAbsolutePath();
|
||||
if(str.length() > slug) {
|
||||
str = str.substring(slug).replace('\\', '/');
|
||||
if(str.startsWith("/")) {
|
||||
str = str.substring(1);
|
||||
}
|
||||
ret.add(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteOldFolder(File file) {
|
||||
File[] f = file.listFiles();
|
||||
for(int i = 0; i < f.length; ++i) {
|
||||
if(f[i].isDirectory()) {
|
||||
deleteOldFolder(f[i]);
|
||||
}else {
|
||||
f[i].delete();
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import javax.swing.UnsupportedLookAndFeelException;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformANGLE;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
|
||||
@ -43,15 +44,9 @@ public class LWJGLEntryPoint {
|
||||
|
||||
boolean hideRenderDocDialog = false;
|
||||
for(int i = 0; i < args.length; ++i) {
|
||||
if(args[i].equalsIgnoreCase("highp")) {
|
||||
ShaderSource.setHighP(true);
|
||||
}
|
||||
if(args[i].equalsIgnoreCase("hide-renderdoc")) {
|
||||
hideRenderDocDialog = true;
|
||||
}
|
||||
if(args[i].equalsIgnoreCase("fullscreen")) {
|
||||
PlatformInput.setStartupFullscreen(true);
|
||||
}
|
||||
}
|
||||
|
||||
if(!hideRenderDocDialog) {
|
||||
@ -66,7 +61,7 @@ public class LWJGLEntryPoint {
|
||||
lr.dispose();
|
||||
}
|
||||
|
||||
getANGLEPlatformFromArgs(args);
|
||||
getPlatformOptionsFromArgs(args);
|
||||
|
||||
RelayManager.relayManager.load(EagRuntime.getStorage("r"));
|
||||
|
||||
@ -81,12 +76,22 @@ public class LWJGLEntryPoint {
|
||||
|
||||
}
|
||||
|
||||
private static void getANGLEPlatformFromArgs(String[] args) {
|
||||
private static void getPlatformOptionsFromArgs(String[] args) {
|
||||
for(int i = 0; i < args.length; ++i) {
|
||||
EnumPlatformANGLE angle = EnumPlatformANGLE.fromId(args[i]);
|
||||
if(angle != EnumPlatformANGLE.DEFAULT) {
|
||||
PlatformRuntime.requestANGLE(angle);
|
||||
break;
|
||||
if(args[i].equalsIgnoreCase("fullscreen")) {
|
||||
PlatformInput.setStartupFullscreen(true);
|
||||
}else if(args[i].equalsIgnoreCase("highp")) {
|
||||
ShaderSource.setHighP(true);
|
||||
}else if(args[i].startsWith("jdbc:")) {
|
||||
if(i < args.length - 1) {
|
||||
PlatformFilesystem.setUseJDBC(args[i]);
|
||||
PlatformFilesystem.setJDBCDriverClass(args[++i]);
|
||||
}
|
||||
}else {
|
||||
EnumPlatformANGLE angle = EnumPlatformANGLE.fromId(args[i]);
|
||||
if(angle != EnumPlatformANGLE.DEFAULT) {
|
||||
PlatformRuntime.requestANGLE(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.Display;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.Keyboard;
|
||||
import net.lax1dude.eaglercraft.v1_8.Mouse;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants;
|
||||
|
||||
public class TestProgram {
|
||||
|
||||
private static boolean grab = false;
|
||||
|
||||
public static void main_(String[] args) {
|
||||
|
||||
while(!Display.isCloseRequested()) {
|
||||
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
Display.update();
|
||||
|
||||
while(Keyboard.next()) {
|
||||
if(Keyboard.getEventKey() == KeyboardConstants.KEY_E && Keyboard.getEventKeyState()) {
|
||||
grab = !grab;
|
||||
Mouse.setGrabbed(grab);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("" + Mouse.getDX() + ", " + Mouse.getDY());
|
||||
|
||||
EagUtils.sleep(100l);
|
||||
}
|
||||
|
||||
EagRuntime.destroy();
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user