diff --git a/desktopRuntime/UnsafeMemcpy.dll b/desktopRuntime/UnsafeMemcpy.dll
new file mode 100755
index 0000000..067de85
Binary files /dev/null and b/desktopRuntime/UnsafeMemcpy.dll differ
diff --git a/desktopRuntime/UnsafeMemcpy.jar b/desktopRuntime/UnsafeMemcpy.jar
new file mode 100755
index 0000000..59fa359
Binary files /dev/null and b/desktopRuntime/UnsafeMemcpy.jar differ
diff --git a/desktopRuntime/eclipseProject/.classpath b/desktopRuntime/eclipseProject/.classpath
index 210b72d..7ed6dda 100755
--- a/desktopRuntime/eclipseProject/.classpath
+++ b/desktopRuntime/eclipseProject/.classpath
@@ -18,5 +18,6 @@
+
diff --git a/desktopRuntime/eclipseProject/deps_fix/UnsafeMemcpy.jar b/desktopRuntime/eclipseProject/deps_fix/UnsafeMemcpy.jar
new file mode 100755
index 0000000..59fa359
Binary files /dev/null and b/desktopRuntime/eclipseProject/deps_fix/UnsafeMemcpy.jar differ
diff --git a/desktopRuntime/libUnsafeMemcpy.so b/desktopRuntime/libUnsafeMemcpy.so
new file mode 100755
index 0000000..61ec556
Binary files /dev/null and b/desktopRuntime/libUnsafeMemcpy.so differ
diff --git a/desktopRuntime/resources/assets/eagler/CREDITS.txt b/desktopRuntime/resources/assets/eagler/CREDITS.txt
index 1c81c30..9f65537 100755
--- a/desktopRuntime/resources/assets/eagler/CREDITS.txt
+++ b/desktopRuntime/resources/assets/eagler/CREDITS.txt
@@ -11,13 +11,15 @@
- Made the integrated PBR resource pack
- Wrote all desktop emulation code
- Wrote EaglercraftXBungee
- - Wrote WebRTC Relay Server
+ - Wrote WebRTC relay server
+ - Wrote voice chat server
- Wrote the patch and build system
ayunami2000:
- Many bug fixes
- WebRTC LAN worlds
+ - WebRTC voice chat
- Added resource packs
- Added screen recording
- Added seamless fullscreen
diff --git a/desktopRuntime/resources/assets/eagler/capes/01.minecon_2011.png b/desktopRuntime/resources/assets/eagler/capes/01.minecon_2011.png
new file mode 100755
index 0000000..77e0ccc
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/01.minecon_2011.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/02.minecon_2012.png b/desktopRuntime/resources/assets/eagler/capes/02.minecon_2012.png
new file mode 100755
index 0000000..6390662
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/02.minecon_2012.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/03.minecon_2013.png b/desktopRuntime/resources/assets/eagler/capes/03.minecon_2013.png
new file mode 100755
index 0000000..1cd6a12
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/03.minecon_2013.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/04.minecon_2015.png b/desktopRuntime/resources/assets/eagler/capes/04.minecon_2015.png
new file mode 100755
index 0000000..a272284
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/04.minecon_2015.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/05.minecon_2016.png b/desktopRuntime/resources/assets/eagler/capes/05.minecon_2016.png
new file mode 100755
index 0000000..492eee1
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/05.minecon_2016.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/06.microsoft_account.png b/desktopRuntime/resources/assets/eagler/capes/06.microsoft_account.png
new file mode 100755
index 0000000..7fccd56
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/06.microsoft_account.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/07.mapmaker.png b/desktopRuntime/resources/assets/eagler/capes/07.mapmaker.png
new file mode 100755
index 0000000..58a217a
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/07.mapmaker.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/08.mojang_old.png b/desktopRuntime/resources/assets/eagler/capes/08.mojang_old.png
new file mode 100755
index 0000000..438edff
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/08.mojang_old.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/09.mojang_new.png b/desktopRuntime/resources/assets/eagler/capes/09.mojang_new.png
new file mode 100755
index 0000000..2eca0d3
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/09.mojang_new.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/10.jira_mod.png b/desktopRuntime/resources/assets/eagler/capes/10.jira_mod.png
new file mode 100755
index 0000000..f3d4fe8
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/10.jira_mod.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/11.mojang_very_old.png b/desktopRuntime/resources/assets/eagler/capes/11.mojang_very_old.png
new file mode 100755
index 0000000..375aea8
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/11.mojang_very_old.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/12.scrolls.png b/desktopRuntime/resources/assets/eagler/capes/12.scrolls.png
new file mode 100755
index 0000000..25e1447
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/12.scrolls.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/13.cobalt.png b/desktopRuntime/resources/assets/eagler/capes/13.cobalt.png
new file mode 100755
index 0000000..50d24b7
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/13.cobalt.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/14.translator.png b/desktopRuntime/resources/assets/eagler/capes/14.translator.png
new file mode 100755
index 0000000..b681c26
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/14.translator.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/15.millionth_account.png b/desktopRuntime/resources/assets/eagler/capes/15.millionth_account.png
new file mode 100755
index 0000000..c2f0a02
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/15.millionth_account.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/16.prismarine.png b/desktopRuntime/resources/assets/eagler/capes/16.prismarine.png
new file mode 100755
index 0000000..3ee69b2
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/16.prismarine.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/17.snowman.png b/desktopRuntime/resources/assets/eagler/capes/17.snowman.png
new file mode 100755
index 0000000..f4ad552
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/17.snowman.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/18.spade.png b/desktopRuntime/resources/assets/eagler/capes/18.spade.png
new file mode 100755
index 0000000..7cf8e8b
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/18.spade.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/19.birthday.png b/desktopRuntime/resources/assets/eagler/capes/19.birthday.png
new file mode 100755
index 0000000..048ef8e
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/19.birthday.png differ
diff --git a/desktopRuntime/resources/assets/eagler/capes/20.db.png b/desktopRuntime/resources/assets/eagler/capes/20.db.png
new file mode 100755
index 0000000..8110bd2
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/capes/20.db.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/charles.fallback.png b/desktopRuntime/resources/assets/eagler/mesh/charles.fallback.png
new file mode 100755
index 0000000..f1d90ca
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/charles.fallback.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/charles.png b/desktopRuntime/resources/assets/eagler/mesh/charles.png
new file mode 100755
index 0000000..a23587f
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/charles.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/charles0.mdl b/desktopRuntime/resources/assets/eagler/mesh/charles0.mdl
new file mode 100755
index 0000000..84138ca
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/charles0.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/charles1.mdl b/desktopRuntime/resources/assets/eagler/mesh/charles1.mdl
new file mode 100755
index 0000000..549898a
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/charles1.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/charles2.mdl b/desktopRuntime/resources/assets/eagler/mesh/charles2.mdl
new file mode 100755
index 0000000..614cada
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/charles2.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/laxativedude.fallback.png b/desktopRuntime/resources/assets/eagler/mesh/laxativedude.fallback.png
new file mode 100755
index 0000000..27b1f9c
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/laxativedude.fallback.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/laxativedude.png b/desktopRuntime/resources/assets/eagler/mesh/laxativedude.png
new file mode 100755
index 0000000..ece3e4a
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/laxativedude.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/laxativedude0.mdl b/desktopRuntime/resources/assets/eagler/mesh/laxativedude0.mdl
new file mode 100755
index 0000000..90da430
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/laxativedude0.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/laxativedude1.mdl b/desktopRuntime/resources/assets/eagler/mesh/laxativedude1.mdl
new file mode 100755
index 0000000..3f4d94f
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/laxativedude1.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/laxativedude2.mdl b/desktopRuntime/resources/assets/eagler/mesh/laxativedude2.mdl
new file mode 100755
index 0000000..1dffcbc
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/laxativedude2.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/laxativedude3.mdl b/desktopRuntime/resources/assets/eagler/mesh/laxativedude3.mdl
new file mode 100755
index 0000000..56dee1c
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/laxativedude3.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/longarms.fallback.png b/desktopRuntime/resources/assets/eagler/mesh/longarms.fallback.png
new file mode 100755
index 0000000..b506534
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/longarms.fallback.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/longarms.png b/desktopRuntime/resources/assets/eagler/mesh/longarms.png
new file mode 100755
index 0000000..c021684
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/longarms.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/longarms0.mdl b/desktopRuntime/resources/assets/eagler/mesh/longarms0.mdl
new file mode 100755
index 0000000..29895c1
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/longarms0.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/longarms1.mdl b/desktopRuntime/resources/assets/eagler/mesh/longarms1.mdl
new file mode 100755
index 0000000..a72acfa
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/longarms1.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/longarms2.mdl b/desktopRuntime/resources/assets/eagler/mesh/longarms2.mdl
new file mode 100755
index 0000000..57544d6
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/longarms2.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/weirdclimber.fallback.png b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber.fallback.png
new file mode 100755
index 0000000..da5d052
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber.fallback.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/weirdclimber.png b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber.png
new file mode 100755
index 0000000..792cac5
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/weirdclimber0.mdl b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber0.mdl
new file mode 100755
index 0000000..72efddb
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber0.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/weirdclimber1.mdl b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber1.mdl
new file mode 100755
index 0000000..933d3c8
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber1.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/weirdclimber2.mdl b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber2.mdl
new file mode 100755
index 0000000..728db6a
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/weirdclimber2.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/winston.fallback.png b/desktopRuntime/resources/assets/eagler/mesh/winston.fallback.png
new file mode 100755
index 0000000..b0da89c
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/winston.fallback.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/winston.png b/desktopRuntime/resources/assets/eagler/mesh/winston.png
new file mode 100755
index 0000000..fceadbb
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/winston.png differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/winston0.mdl b/desktopRuntime/resources/assets/eagler/mesh/winston0.mdl
new file mode 100755
index 0000000..f66da49
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/winston0.mdl differ
diff --git a/desktopRuntime/resources/assets/eagler/mesh/winston1.mdl b/desktopRuntime/resources/assets/eagler/mesh/winston1.mdl
new file mode 100755
index 0000000..c8cced5
Binary files /dev/null and b/desktopRuntime/resources/assets/eagler/mesh/winston1.mdl differ
diff --git a/desktopRuntime/resources/assets/minecraft/lang/en_US.lang b/desktopRuntime/resources/assets/minecraft/lang/en_US.lang
index a3e5723..e542e1d 100755
--- a/desktopRuntime/resources/assets/minecraft/lang/en_US.lang
+++ b/desktopRuntime/resources/assets/minecraft/lang/en_US.lang
@@ -18,7 +18,7 @@ gui.all=All
eaglercraft.recording.unsupported=Recording Unsupported!
eaglercraft.recording.stop=Stop Recording
eaglercraft.recording.start=Record Screen...
-eaglercraft.soundCategory.voice=Voice
+eaglercraft.soundCategory.voice=Recording Voice
eaglercraft.resourcePack.prompt.title=What do you want to do with '%s'?
eaglercraft.resourcePack.prompt.text=Tip: Hold Shift to skip this screen when selecting a resource pack!
@@ -43,6 +43,14 @@ eaglercraft.editProfile.username=Username
eaglercraft.editProfile.playerSkin=Player Skin
eaglercraft.editProfile.addSkin=Add Skin
eaglercraft.editProfile.clearSkin=Clear List
+eaglercraft.editProfile.capes=Capes
+eaglercraft.editProfile.disableFNAW=(Note: go to 'Options...' > 'Skin Customization' to disable FNAW skins)
+eaglercraft.editProfile.enableFNAW=(Note: go to 'Options...' > 'Skin Customization' to enable FNAW skins)
+
+eaglercraft.editCape.title=Edit Cape
+eaglercraft.editCape.playerCape=Player Cape
+eaglercraft.editCape.addCape=Add Cape
+eaglercraft.editCape.clearCape=Clear List
eaglercraft.editProfile.importExport=Import/Export
@@ -599,6 +607,60 @@ eaglercraft.updateList.refresh=Refresh
eaglercraft.updateList.note.0=Note: Updates are digitally signed, EaglercraftX will block any
eaglercraft.updateList.note.1=updates that were not created by lax1dude or ayunami2000
+eaglercraft.voice.title=Voice Channel
+eaglercraft.voice.titleNoVoice=Voice is disabled on this server
+eaglercraft.voice.titleVoiceUnavailable=Voice is unavailable
+eaglercraft.voice.titleVoiceBrowserError=(browser issue)
+eaglercraft.voice.ptt=Press '%s' to speak
+eaglercraft.voice.pttChangeDesc=(Press Any Key)
+eaglercraft.voice.changeKey=Change
+eaglercraft.voice.off=OFF
+eaglercraft.voice.radius=NEARBY
+eaglercraft.voice.global=GLOBAL
+eaglercraft.voice.volumeTitle=Change Volume
+eaglercraft.voice.volumeListen=Speakers Volume:
+eaglercraft.voice.volumeSpeak=Microphone Volume:
+eaglercraft.voice.radiusTitle=Change Listener Radius
+eaglercraft.voice.radiusLabel=Players Within:
+eaglercraft.voice.radiusChange=change
+eaglercraft.voice.notConnected=Not Connected
+eaglercraft.voice.connecting=Connecting...
+eaglercraft.voice.unavailable=Could not connect!
+eaglercraft.voice.connectedGlobal=Connected - Global
+eaglercraft.voice.connectedRadius=Connected - $f$Within $radius$m
+eaglercraft.voice.playersListening=Players Listening:
+eaglercraft.voice.muted=Players Muted:
+eaglercraft.voice.unmute=unmute
+eaglercraft.voice.mute=mute
+eaglercraft.voice.apply=Apply
+eaglercraft.voice.volumeSpeakerLabel=Speakers:
+eaglercraft.voice.volumeMicrophoneLabel=Microphone:
+
+eaglercraft.voice.unsupportedWarning1=Voice Warning
+eaglercraft.voice.unsupportedWarning2=Your network's firewall may not support
+eaglercraft.voice.unsupportedWarning3=eaglercraft's voice chat.
+eaglercraft.voice.unsupportedWarning4=If your game doesn't work it's your issue
+eaglercraft.voice.unsupportedWarning5=to solve, not ayunami2000's or lax1dude's.
+eaglercraft.voice.unsupportedWarning6=Don't ask them to 'fix' it for you because
+eaglercraft.voice.unsupportedWarning7=they won't help you fix a problem that only
+eaglercraft.voice.unsupportedWarning8=you or your network's administrator has the
+eaglercraft.voice.unsupportedWarning9=ability to correctly resolve.
+eaglercraft.voice.unsupportedWarning10=Continue
+eaglercraft.voice.unsupportedWarning11=Cancel
+
+eaglercraft.voice.ipGrabWarning1=IP Logger Warning
+eaglercraft.voice.ipGrabWarning2=Using Eaglercraft voice chat may allow your
+eaglercraft.voice.ipGrabWarning3=IP address to be logged by other players
+eaglercraft.voice.ipGrabWarning4=also using voice on the server.
+eaglercraft.voice.ipGrabWarning5=This issue will not be fixed, it is an
+eaglercraft.voice.ipGrabWarning6=internal browser issue, not a mistake in the
+eaglercraft.voice.ipGrabWarning7=game. Fortunately, this can only be done if
+eaglercraft.voice.ipGrabWarning8=the other player uses a hacked web browser
+eaglercraft.voice.ipGrabWarning9=or has Wireshark to capture the voice
+eaglercraft.voice.ipGrabWarning10=packets, as there exists no real javascript
+eaglercraft.voice.ipGrabWarning11=method to log IPs using a normal skidded
+eaglercraft.voice.ipGrabWarning12=eaglercraft hacked client.
+
selectServer.title=Select Server
selectServer.empty=empty
selectServer.select=Join Server
@@ -799,6 +861,7 @@ options.chat.height.focused=Focused Height
options.chat.height.unfocused=Unfocused Height
options.skinCustomisation=Skin Customization...
options.skinCustomisation.title=Skin Customization
+options.skinCustomisation.enableFNAWSkins=Show FNAW Skins
options.modelPart.cape=Cape
options.modelPart.hat=Hat
options.modelPart.jacket=Jacket
diff --git a/desktopRuntime/resources/plugin_download.zip b/desktopRuntime/resources/plugin_download.zip
index 1e05891..7b99d4b 100755
Binary files a/desktopRuntime/resources/plugin_download.zip and b/desktopRuntime/resources/plugin_download.zip differ
diff --git a/desktopRuntime/resources/plugin_version.json b/desktopRuntime/resources/plugin_version.json
index 5f9aed6..56a0adb 100755
--- a/desktopRuntime/resources/plugin_version.json
+++ b/desktopRuntime/resources/plugin_version.json
@@ -1 +1 @@
-{"pluginName":"EaglercraftXBungee","pluginVersion":"1.0.10","pluginButton":"Download \"EaglerXBungee-1.0.10.jar\"","pluginFilename":"EaglerXBungee.zip"}
\ No newline at end of file
+{"pluginName":"EaglercraftXBungee","pluginVersion":"1.1.0","pluginButton":"Download \"EaglerXBungee-1.1.0.jar\"","pluginFilename":"EaglerXBungee.zip"}
\ No newline at end of file
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java
index 0fd9966..e703e7f 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformAssets.java
@@ -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();
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformBufferFunctions.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformBufferFunctions.java
index 41c8194..b2b425c 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformBufferFunctions.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformBufferFunctions.java
@@ -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) {
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformFilesystem.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformFilesystem.java
index 19e1f5b..da004b4 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformFilesystem.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformFilesystem.java
@@ -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;
}
}
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java
index a9bdf1d..da4dd22 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformInput.java
@@ -57,7 +57,10 @@ public class PlatformInput {
public static boolean lockKeys = false;
private static final List 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);
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java
index 3f3759a..14b6e86 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformOpenGL.java
@@ -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;
+ }
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java
index 70e824a..7002d42 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformRuntime.java
@@ -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) {
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformVoiceClient.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformVoiceClient.java
new file mode 100755
index 0000000..4da3bff
--- /dev/null
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/PlatformVoiceClient.java
@@ -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;
+ }
+
+}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLAllocator.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLAllocator.java
index 2efe7e3..a84d0c7 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLAllocator.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLAllocator.java
@@ -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) {
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLByteBuffer.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLByteBuffer.java
index ad005c4..d6d47e9 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLByteBuffer.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLByteBuffer.java
@@ -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;
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLFloatBuffer.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLFloatBuffer.java
index 7fa804d..3b1be55 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLFloatBuffer.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLFloatBuffer.java
@@ -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);
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLIntBuffer.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLIntBuffer.java
index cd0b54f..d9391a3 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLIntBuffer.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLIntBuffer.java
@@ -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);
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLShortBuffer.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLShortBuffer.java
index eaf69b1..ce95806 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLShortBuffer.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/buffer/EaglerLWJGLShortBuffer.java
@@ -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);
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DebugFilesystem.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DebugFilesystem.java
new file mode 100755
index 0000000..feffec3
--- /dev/null
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DebugFilesystem.java
@@ -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();
+ }
+ }
+}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DesktopClientConfigAdapter.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DesktopClientConfigAdapter.java
index 26550fa..e0c69c5 100755
--- a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DesktopClientConfigAdapter.java
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/DesktopClientConfigAdapter.java
@@ -124,4 +124,9 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
return false;
}
+ @Override
+ public boolean isAllowVoiceClient() {
+ return false;
+ }
+
}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/FilesystemConvertingDialog.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/FilesystemConvertingDialog.java
new file mode 100755
index 0000000..935745e
--- /dev/null
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/FilesystemConvertingDialog.java
@@ -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);
+ }
+
+}
diff --git a/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/JDBCFilesystem.java b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/JDBCFilesystem.java
new file mode 100755
index 0000000..eeaaa5d
--- /dev/null
+++ b/src/lwjgl/java/net/lax1dude/eaglercraft/v1_8/internal/lwjgl/JDBCFilesystem.java
@@ -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 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 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