This commit is contained in:
PeytonPlayz595 2024-05-31 15:48:07 -04:00
parent 86f35def00
commit 38e086fb0a
173 changed files with 7405 additions and 770 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -18,7 +18,7 @@ gui.all=All
eaglercraft.recording.unsupported=Recording Unsupported! eaglercraft.recording.unsupported=Recording Unsupported!
eaglercraft.recording.stop=Stop Recording eaglercraft.recording.stop=Stop Recording
eaglercraft.recording.start=Record Screen... 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.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! eaglercraft.resourcePack.prompt.text=Tip: Hold Shift to skip this screen when selecting a resource pack!
@ -44,6 +44,15 @@ eaglercraft.editProfile.playerSkin=Player Skin
eaglercraft.editProfile.addSkin=Add Skin eaglercraft.editProfile.addSkin=Add Skin
eaglercraft.editProfile.clearSkin=Clear List eaglercraft.editProfile.clearSkin=Clear List
eaglercraft.editProfile.capes=Capes
eaglercraft.editProfile.disableFNAW=(Note: go to 'Video Settings...' > 'Other...' to disable FNAW skins)
eaglercraft.editProfile.enableFNAW=(Note: go to 'Video Settings...' > 'Other...' 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 eaglercraft.editProfile.importExport=Import/Export
eaglercraft.settingsBackup.importExport.title=What do you wanna do? eaglercraft.settingsBackup.importExport.title=What do you wanna do?
@ -599,6 +608,60 @@ eaglercraft.updateList.refresh=Refresh
eaglercraft.updateList.note.0=Note: Updates are digitally signed, EaglercraftX will block any 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.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.title=Select Server
selectServer.empty=empty selectServer.empty=empty
selectServer.select=Join Server selectServer.select=Join Server
@ -799,6 +862,7 @@ options.chat.height.focused=Focused Height
options.chat.height.unfocused=Unfocused Height options.chat.height.unfocused=Unfocused Height
options.skinCustomisation=Skin Customization... options.skinCustomisation=Skin Customization...
options.skinCustomisation.title=Skin Customization options.skinCustomisation.title=Skin Customization
options.skinCustomisation.enableFNAWSkins=Show FNAW Skins
options.modelPart.cape=Cape options.modelPart.cape=Cape
options.modelPart.hat=Hat options.modelPart.hat=Hat
options.modelPart.jacket=Jacket options.modelPart.jacket=Jacket

View File

@ -60,6 +60,9 @@ public class PlatformAssets {
public static final ImageData loadImageFile(InputStream data) { public static final ImageData loadImageFile(InputStream data) {
try { try {
BufferedImage img = ImageIO.read(data); BufferedImage img = ImageIO.read(data);
if(img == null) {
throw new IOException("Data is not a supported image format!");
}
int w = img.getWidth(); int w = img.getWidth();
int h = img.getHeight(); int h = img.getHeight();
boolean a = img.getColorModel().hasAlpha(); boolean a = img.getColorModel().hasAlpha();

View File

@ -21,10 +21,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
public class PlatformBufferFunctions { public class PlatformBufferFunctions {
public static void put(ByteBuffer newBuffer, ByteBuffer flip) { public static void put(ByteBuffer newBuffer, ByteBuffer flip) {
int len = flip.remaining(); newBuffer.put(flip);
for(int i = 0; i < len; ++i) {
newBuffer.put(flip.get());
}
} }
public static void put(IntBuffer intBuffer, int index, int[] data) { public static void put(IntBuffer intBuffer, int index, int[] data) {

View File

@ -1,13 +1,11 @@
package net.lax1dude.eaglercraft.v1_8.internal; package net.lax1dude.eaglercraft.v1_8.internal;
import java.io.File; 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.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException; import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.DebugFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2.BreakLoop; 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.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; 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 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() { public static void initialize() {
if(!filesystemRoot.isDirectory() && !filesystemRoot.mkdirs()) { if(provider == null) {
throw new EaglerFileSystemException("Could not create directory for virtual filesystem: " + filesystemRoot.getAbsolutePath()); 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) { public static boolean eaglerDelete(String pathName) {
File f = getJREFile(pathName); if(provider == null) throwNotInitialized();
if(!f.exists()) { return provider.eaglerDelete(pathName);
logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
return false;
}
if(f.delete()) {
deleteParentIfEmpty(f);
return true;
}
return false;
} }
public static ByteBuffer eaglerRead(String pathName) { public static ByteBuffer eaglerRead(String pathName) {
File f = getJREFile(pathName); if(provider == null) throwNotInitialized();
if(f.isFile()) { return provider.eaglerRead(pathName);
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;
}
} }
public static void eaglerWrite(String pathName, ByteBuffer data) { public static void eaglerWrite(String pathName, ByteBuffer data) {
File f = getJREFile(pathName); if(provider == null) throwNotInitialized();
File p = f.getParentFile(); provider.eaglerWrite(pathName, data);
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);
}
} }
public static boolean eaglerExists(String pathName) { 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) { public static boolean eaglerMove(String pathNameOld, String pathNameNew) {
File f1 = getJREFile(pathNameOld); if(provider == null) throwNotInitialized();
File f2 = getJREFile(pathNameNew); return provider.eaglerMove(pathNameOld, 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;
} }
public static int eaglerCopy(String pathNameOld, String pathNameNew) { public static int eaglerCopy(String pathNameOld, String pathNameNew) {
File f1 = getJREFile(pathNameOld); if(provider == null) throwNotInitialized();
File f2 = getJREFile(pathNameNew); return provider.eaglerCopy(pathNameOld, 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;
} }
public static int eaglerSize(String pathName) { public static int eaglerSize(String pathName) {
File f = getJREFile(pathName); if(provider == null) throwNotInitialized();
if(f.isFile()) { return provider.eaglerSize(pathName);
long fileSize = f.length();
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
return (int)fileSize;
}else {
return -1;
}
} }
public static void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) { public static void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
try { if(provider == null) throwNotInitialized();
iterateFile(pathName, getJREFile(pathName), itr, recursive); provider.eaglerIterate(pathName, itr, recursive);
}catch(BreakLoop ex) {
}
} }
private static void iterateFile(String pathName, File f, VFSFilenameIterator itr, boolean recursive) { public static void platformShutdown() {
if(!f.exists()) { if(provider != null) {
return; if(provider instanceof JDBCFilesystem) {
((JDBCFilesystem)provider).shutdown();
} }
if(!f.isDirectory()) { provider = null;
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 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();
} }
} }
} }

View File

@ -58,6 +58,9 @@ public class PlatformInput {
private static final List<Character> keyboardCharList = new LinkedList(); private static final List<Character> keyboardCharList = new LinkedList();
private static boolean vsync = true;
private static boolean glfwVSyncState = false;
private static class KeyboardEvent { private static class KeyboardEvent {
protected final int key; protected final int key;
@ -214,8 +217,16 @@ public class PlatformInput {
return glfwWindowShouldClose(win); return glfwWindowShouldClose(win);
} }
public static void setVSync(boolean enable) {
vsync = enable;
}
public static void update() { public static void update() {
glfwPollEvents(); glfwPollEvents();
if(vsync != glfwVSyncState) {
glfwSwapInterval(vsync ? 1 : 0);
glfwVSyncState = vsync;
}
glfwSwapBuffers(win); glfwSwapBuffers(win);
} }

View File

@ -8,6 +8,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import static org.lwjgl.opengles.GLES30.*; import static org.lwjgl.opengles.GLES30.*;
import org.lwjgl.opengles.GLES31; import org.lwjgl.opengles.GLES31;
import org.lwjgl.opengles.GLESCapabilities;
/** /**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved. * Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
@ -26,6 +27,12 @@ import org.lwjgl.opengles.GLES31;
*/ */
public class PlatformOpenGL { 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) { public static final void _wglEnable(int glEnum) {
glEnable(glEnum); glEnable(glEnum);
} }
@ -271,6 +278,12 @@ public class PlatformOpenGL {
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data)); 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, public static final void _wglTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height,
int format, int type, ByteBuffer data) { int format, int type, ByteBuffer data) {
nglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, nglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
@ -533,4 +546,8 @@ public class PlatformOpenGL {
return GLES31.glGetTexLevelParameteri(glTexture2d, i, glTextureWidth); return GLES31.glGetTexLevelParameteri(glTexture2d, i, glTextureWidth);
} }
public static final boolean checkLinearHDR32FSupport() {
return hasLinearHDR32FSupport;
}
} }

View File

@ -171,7 +171,7 @@ public class PlatformRuntime {
EGL.createDisplayCapabilities(glfw_eglHandle, major[0], minor[0]); EGL.createDisplayCapabilities(glfw_eglHandle, major[0], minor[0]);
glfwMakeContextCurrent(windowHandle); glfwMakeContextCurrent(windowHandle);
GLES.createCapabilities(); PlatformOpenGL.setCurrentContext(GLES.createCapabilities());
logger.info("OpenGL Version: {}", (glVersion = GLES30.glGetString(GLES30.GL_VERSION))); logger.info("OpenGL Version: {}", (glVersion = GLES30.glGetString(GLES30.GL_VERSION)));
logger.info("OpenGL Renderer: {}", (glRenderer = GLES30.glGetString(GLES30.GL_RENDERER))); logger.info("OpenGL Renderer: {}", (glRenderer = GLES30.glGetString(GLES30.GL_RENDERER)));
@ -245,6 +245,7 @@ public class PlatformRuntime {
public static void destroy() { public static void destroy() {
PlatformAudio.platformShutdown(); PlatformAudio.platformShutdown();
PlatformFilesystem.platformShutdown();
GLES.destroy(); GLES.destroy();
EGL.destroy(); EGL.destroy();
glfwDestroyWindow(windowHandle); glfwDestroyWindow(windowHandle);
@ -340,15 +341,27 @@ public class PlatformRuntime {
public static class NativeNIO { public static class NativeNIO {
public static java.nio.ByteBuffer allocateByteBuffer(int length) { 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) { 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) { 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) { public static java.nio.IntBuffer getIntBuffer(java.nio.ByteBuffer byteBuffer) {

View File

@ -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;
}
}

View File

@ -3,7 +3,7 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import org.lwjgl.system.jemalloc.JEmalloc; 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 * 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 * 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) { 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) { 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) { 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) { 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) { public static void freeByteBuffer(ByteBuffer buffer) {

View File

@ -1,10 +1,12 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer; package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.jemalloc.JEmalloc; 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 * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -104,35 +106,33 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public byte get() { public byte get() {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
return MemoryUtil.memGetByte(address + position++); return UnsafeUtils.getMemByte(address + position++);
} }
@Override @Override
public ByteBuffer put(byte b) { public ByteBuffer put(byte b) {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutByte(address + position++, b); UnsafeUtils.setMemByte(address + position++, b);
return this; return this;
} }
@Override @Override
public byte get(int index) { public byte get(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetByte(address + index); return UnsafeUtils.getMemByte(address + index);
} }
@Override @Override
public ByteBuffer put(int index, byte b) { public ByteBuffer put(int index, byte b) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutByte(address + index, b); UnsafeUtils.setMemByte(address + index, b);
return this; return this;
} }
@Override @Override
public ByteBuffer get(byte[] dst, int offset, int length) { public ByteBuffer get(byte[] dst, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpy(dst, offset, address + position, length);
dst[offset + i] = MemoryUtil.memGetByte(address + position + i);
}
position += length; position += length;
return this; return this;
} }
@ -140,9 +140,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer get(byte[] dst) { public ByteBuffer get(byte[] dst) {
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1); if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
for(int i = 0; i < dst.length; ++i) { UnsafeMemcpy.memcpy(dst, 0, address + position, dst.length);
dst[position + i] = MemoryUtil.memGetByte(address + position + i);
}
position += dst.length; position += dst.length;
return this; return this;
} }
@ -153,14 +151,14 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
EaglerLWJGLByteBuffer c = (EaglerLWJGLByteBuffer)src; EaglerLWJGLByteBuffer c = (EaglerLWJGLByteBuffer)src;
int l = c.limit - c.position; int l = c.limit - c.position;
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); 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; position += l;
c.position += l; c.position += l;
}else { }else {
int l = src.remaining(); int l = src.remaining();
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
for(int i = 0; i < l; ++i) { for(int i = 0; i < l; ++i) {
MemoryUtil.memPutByte(address + position + l, src.get()); UnsafeUtils.setMemByte(address + position + l, src.get());
} }
position += l; position += l;
} }
@ -170,9 +168,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer put(byte[] src, int offset, int length) { public ByteBuffer put(byte[] src, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpy(address + position, src, offset, length);
MemoryUtil.memPutByte(address + position + i, src[offset + i]);
}
position += length; position += length;
return this; return this;
} }
@ -180,9 +176,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer put(byte[] src) { public ByteBuffer put(byte[] src) {
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1); if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
for(int i = 0; i < src.length; ++i) { UnsafeMemcpy.memcpy(address + position, src, 0, src.length);
MemoryUtil.memPutByte(address + position + i, src[i]);
}
position += src.length; position += src.length;
return this; return this;
} }
@ -203,7 +197,10 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
int newLen = limit - position; int newLen = limit - position;
long newAlloc = JEmalloc.nje_malloc(newLen); 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); return new EaglerLWJGLByteBuffer(newAlloc, newLen, true);
} }
@ -211,7 +208,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public char getChar() { public char getChar() {
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
char c = (char)MemoryUtil.memGetShort(address + position); char c = UnsafeUtils.getMemChar(address + position);
position += 2; position += 2;
return c; return c;
} }
@ -219,7 +216,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer putChar(char value) { public ByteBuffer putChar(char value) {
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutShort(address + position, (short)value); UnsafeUtils.setMemChar(address + position, value);
position += 2; position += 2;
return this; return this;
} }
@ -227,20 +224,20 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public char getChar(int index) { public char getChar(int index) {
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
return (char)MemoryUtil.memGetShort(address + index); return UnsafeUtils.getMemChar(address + index);
} }
@Override @Override
public ByteBuffer putChar(int index, char value) { public ByteBuffer putChar(int index, char value) {
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutShort(address + index, (short)value); UnsafeUtils.setMemChar(address + index, value);
return this; return this;
} }
@Override @Override
public short getShort() { public short getShort() {
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
short s = MemoryUtil.memGetShort(address + position); short s = UnsafeUtils.getMemShort(address + position);
position += 2; position += 2;
return s; return s;
} }
@ -248,7 +245,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer putShort(short value) { public ByteBuffer putShort(short value) {
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutShort(address + position, value); UnsafeUtils.setMemShort(address + position, value);
position += 2; position += 2;
return this; return this;
} }
@ -256,13 +253,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public short getShort(int index) { public short getShort(int index) {
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetShort(address + index); return UnsafeUtils.getMemShort(address + index);
} }
@Override @Override
public ByteBuffer putShort(int index, short value) { public ByteBuffer putShort(int index, short value) {
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutShort(address + index, value); UnsafeUtils.setMemShort(address + index, value);
return this; return this;
} }
@ -274,7 +271,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public int getInt() { public int getInt() {
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
int i = MemoryUtil.memGetInt(address + position); int i = UnsafeUtils.getMemInt(address + position);
position += 4; position += 4;
return i; return i;
} }
@ -282,7 +279,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer putInt(int value) { public ByteBuffer putInt(int value) {
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutInt(address + position, value); UnsafeUtils.setMemInt(address + position, value);
position += 4; position += 4;
return this; return this;
} }
@ -290,13 +287,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public int getInt(int index) { public int getInt(int index) {
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetInt(address + index); return UnsafeUtils.getMemInt(address + index);
} }
@Override @Override
public ByteBuffer putInt(int index, int value) { public ByteBuffer putInt(int index, int value) {
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutInt(address + index, value); UnsafeUtils.setMemInt(address + index, value);
return this; return this;
} }
@ -308,7 +305,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public long getLong() { public long getLong() {
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
long l = MemoryUtil.memGetLong(address + position); long l = UnsafeUtils.getMemLong(address + position);
position += 8; position += 8;
return l; return l;
} }
@ -316,7 +313,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer putLong(long value) { public ByteBuffer putLong(long value) {
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutLong(address + position, value); UnsafeUtils.setMemLong(address + position, value);
position += 8; position += 8;
return this; return this;
} }
@ -324,20 +321,20 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public long getLong(int index) { public long getLong(int index) {
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetLong(address + index); return UnsafeUtils.getMemLong(address + index);
} }
@Override @Override
public ByteBuffer putLong(int index, long value) { public ByteBuffer putLong(int index, long value) {
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutLong(address + index, value); UnsafeUtils.setMemLong(address + index, value);
return this; return this;
} }
@Override @Override
public float getFloat() { public float getFloat() {
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
float f = MemoryUtil.memGetFloat(address + position); float f = UnsafeUtils.getMemFloat(address + position);
position += 4; position += 4;
return f; return f;
} }
@ -345,7 +342,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public ByteBuffer putFloat(float value) { public ByteBuffer putFloat(float value) {
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position); if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutFloat(address + position, value); UnsafeUtils.setMemFloat(address + position, value);
position += 4; position += 4;
return this; return this;
} }
@ -353,13 +350,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
@Override @Override
public float getFloat(int index) { public float getFloat(int index) {
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetFloat(address + index); return UnsafeUtils.getMemFloat(address + index);
} }
@Override @Override
public ByteBuffer putFloat(int index, float value) { public ByteBuffer putFloat(int index, float value) {
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index); if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutFloat(address + index, value); UnsafeUtils.setMemFloat(address + index, value);
return this; return this;
} }

View File

@ -1,10 +1,12 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer; package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.jemalloc.JEmalloc; 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 * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -106,47 +108,45 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
@Override @Override
public float get() { public float get() {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
return MemoryUtil.memGetFloat(address + ((position++) << SHIFT)); return UnsafeUtils.getMemFloat(address + ((position++) << SHIFT));
} }
@Override @Override
public FloatBuffer put(float b) { public FloatBuffer put(float b) {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutFloat(address + ((position++) << SHIFT), b); UnsafeUtils.setMemFloat(address + ((position++) << SHIFT), b);
return this; return this;
} }
@Override @Override
public float get(int index) { public float get(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetFloat(address + (index << SHIFT)); return UnsafeUtils.getMemFloat(address + (index << SHIFT));
} }
@Override @Override
public FloatBuffer put(int index, float b) { public FloatBuffer put(int index, float b) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutFloat(address + (index << SHIFT), b); UnsafeUtils.setMemFloat(address + (index << SHIFT), b);
return this; return this;
} }
@Override @Override
public float getElement(int index) { public float getElement(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetFloat(address + (index << SHIFT)); return UnsafeUtils.getMemFloat(address + (index << SHIFT));
} }
@Override @Override
public void putElement(int index, float value) { public void putElement(int index, float value) {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutFloat(address + ((position++) << SHIFT), value); UnsafeUtils.setMemFloat(address + ((position++) << SHIFT), value);
} }
@Override @Override
public FloatBuffer get(float[] dst, int offset, int length) { public FloatBuffer get(float[] dst, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
dst[offset + i] = MemoryUtil.memGetFloat(address + ((position + i) << SHIFT));
}
position += length; position += length;
return this; return this;
} }
@ -154,9 +154,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
@Override @Override
public FloatBuffer get(float[] dst) { public FloatBuffer get(float[] dst) {
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1); if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
for(int i = 0; i < dst.length; ++i) { UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
dst[i] = MemoryUtil.memGetFloat(address + ((position + i) << SHIFT));
}
position += dst.length; position += dst.length;
return this; return this;
} }
@ -167,14 +165,14 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
EaglerLWJGLFloatBuffer c = (EaglerLWJGLFloatBuffer)src; EaglerLWJGLFloatBuffer c = (EaglerLWJGLFloatBuffer)src;
int l = c.limit - c.position; int l = c.limit - c.position;
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); 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; position += l;
c.position += l; c.position += l;
}else { }else {
int l = src.remaining(); int l = src.remaining();
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
for(int i = 0; i < l; ++i) { 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; position += l;
} }
@ -184,9 +182,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
@Override @Override
public FloatBuffer put(float[] src, int offset, int length) { public FloatBuffer put(float[] src, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
MemoryUtil.memPutFloat(address + ((position + i) << SHIFT), src[offset + i]);
}
position += length; position += length;
return this; return this;
} }
@ -194,9 +190,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
@Override @Override
public FloatBuffer put(float[] src) { public FloatBuffer put(float[] src) {
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1); if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
for(int i = 0; i < src.length; ++i) { UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
MemoryUtil.memPutFloat(address + ((position + i) << SHIFT), src[i]);
}
position += src.length; position += src.length;
return this; return this;
} }
@ -217,7 +211,10 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
int newLen = limit - position; int newLen = limit - position;
long newAlloc = JEmalloc.nje_malloc(newLen); 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); return new EaglerLWJGLFloatBuffer(newAlloc, newLen, true);
} }

View File

@ -1,10 +1,12 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer; package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.jemalloc.JEmalloc; 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 * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -106,47 +108,45 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
@Override @Override
public int get() { public int get() {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
return MemoryUtil.memGetInt(address + ((position++) << SHIFT)); return UnsafeUtils.getMemInt(address + ((position++) << SHIFT));
} }
@Override @Override
public IntBuffer put(int b) { public IntBuffer put(int b) {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutInt(address + ((position++) << SHIFT), b); UnsafeUtils.setMemInt(address + ((position++) << SHIFT), b);
return this; return this;
} }
@Override @Override
public int get(int index) { public int get(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetInt(address + (index << SHIFT)); return UnsafeUtils.getMemInt(address + (index << SHIFT));
} }
@Override @Override
public IntBuffer put(int index, int b) { public IntBuffer put(int index, int b) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutInt(address + (index << SHIFT), b); UnsafeUtils.setMemInt(address + (index << SHIFT), b);
return this; return this;
} }
@Override @Override
public int getElement(int index) { public int getElement(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetInt(address + (index << SHIFT)); return UnsafeUtils.getMemInt(address + (index << SHIFT));
} }
@Override @Override
public void putElement(int index, int value) { public void putElement(int index, int value) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutInt(address + (index << SHIFT), value); UnsafeUtils.setMemInt(address + (index << SHIFT), value);
} }
@Override @Override
public IntBuffer get(int[] dst, int offset, int length) { public IntBuffer get(int[] dst, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
dst[offset + i] = MemoryUtil.memGetInt(address + ((position + i) << SHIFT));
}
position += length; position += length;
return this; return this;
} }
@ -154,9 +154,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
@Override @Override
public IntBuffer get(int[] dst) { public IntBuffer get(int[] dst) {
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1); if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
for(int i = 0; i < dst.length; ++i) { UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
dst[i] = MemoryUtil.memGetInt(address + ((position + i) << SHIFT));
}
position += dst.length; position += dst.length;
return this; return this;
} }
@ -167,14 +165,14 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
EaglerLWJGLIntBuffer c = (EaglerLWJGLIntBuffer)src; EaglerLWJGLIntBuffer c = (EaglerLWJGLIntBuffer)src;
int l = c.limit - c.position; int l = c.limit - c.position;
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); 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; position += l;
c.position += l; c.position += l;
}else { }else {
int l = src.remaining(); int l = src.remaining();
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
for(int i = 0; i < l; ++i) { 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; position += l;
} }
@ -184,9 +182,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
@Override @Override
public IntBuffer put(int[] src, int offset, int length) { public IntBuffer put(int[] src, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
MemoryUtil.memPutInt(address + ((position + i) << SHIFT), src[offset + i]);
}
position += length; position += length;
return this; return this;
} }
@ -194,9 +190,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
@Override @Override
public IntBuffer put(int[] src) { public IntBuffer put(int[] src) {
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1); if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
for(int i = 0; i < src.length; ++i) { UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
MemoryUtil.memPutInt(address + ((position + i) << SHIFT), src[i]);
}
position += src.length; position += src.length;
return this; return this;
} }
@ -217,7 +211,10 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
int newLen = limit - position; int newLen = limit - position;
long newAlloc = JEmalloc.nje_malloc(newLen); 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); return new EaglerLWJGLIntBuffer(newAlloc, newLen, true);
} }

View File

@ -1,10 +1,12 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer; package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.jemalloc.JEmalloc; 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 * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -106,47 +108,45 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
@Override @Override
public short get() { public short get() {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
return MemoryUtil.memGetShort(address + ((position++) << SHIFT)); return UnsafeUtils.getMemShort(address + ((position++) << SHIFT));
} }
@Override @Override
public ShortBuffer put(short b) { public ShortBuffer put(short b) {
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position); if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
MemoryUtil.memPutShort(address + ((position++) << SHIFT), b); UnsafeUtils.setMemShort(address + ((position++) << SHIFT), b);
return this; return this;
} }
@Override @Override
public short get(int index) { public short get(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetShort(address + (index << SHIFT)); return UnsafeUtils.getMemShort(address + (index << SHIFT));
} }
@Override @Override
public ShortBuffer put(int index, short b) { public ShortBuffer put(int index, short b) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutShort(address + (index << SHIFT), b); UnsafeUtils.setMemShort(address + (index << SHIFT), b);
return this; return this;
} }
@Override @Override
public short getElement(int index) { public short getElement(int index) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
return MemoryUtil.memGetShort(address + (index << SHIFT)); return UnsafeUtils.getMemShort(address + (index << SHIFT));
} }
@Override @Override
public void putElement(int index, short value) { public void putElement(int index, short value) {
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index); if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
MemoryUtil.memPutShort(address + (index << SHIFT), value); UnsafeUtils.setMemShort(address + (index << SHIFT), value);
} }
@Override @Override
public ShortBuffer get(short[] dst, int offset, int length) { public ShortBuffer get(short[] dst, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
dst[offset + i] = MemoryUtil.memGetShort(address + ((position + i) << SHIFT));
}
position += length; position += length;
return this; return this;
} }
@ -154,9 +154,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
@Override @Override
public ShortBuffer get(short[] dst) { public ShortBuffer get(short[] dst) {
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1); if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
for(int i = 0; i < dst.length; ++i) { UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
dst[i] = MemoryUtil.memGetShort(address + ((position + i) << SHIFT));
}
position += dst.length; position += dst.length;
return this; return this;
} }
@ -167,14 +165,14 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
EaglerLWJGLShortBuffer c = (EaglerLWJGLShortBuffer)src; EaglerLWJGLShortBuffer c = (EaglerLWJGLShortBuffer)src;
int l = c.limit - c.position; int l = c.limit - c.position;
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); 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; position += l;
c.position += l; c.position += l;
}else { }else {
int l = src.remaining(); int l = src.remaining();
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1); if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
for(int i = 0; i < l; ++i) { 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; position += l;
} }
@ -184,9 +182,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
@Override @Override
public ShortBuffer put(short[] src, int offset, int length) { public ShortBuffer put(short[] src, int offset, int length) {
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1); if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
for(int i = 0; i < length; ++i) { UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
MemoryUtil.memPutShort(address + ((position + i) << SHIFT), src[offset + i]);
}
position += length; position += length;
return this; return this;
} }
@ -194,9 +190,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
@Override @Override
public ShortBuffer put(short[] src) { public ShortBuffer put(short[] src) {
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1); if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
for(int i = 0; i < src.length; ++i) { UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
MemoryUtil.memPutShort(address + ((position + i) << SHIFT), src[i]);
}
position += src.length; position += src.length;
return this; return this;
} }
@ -217,7 +211,10 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
int newLen = limit - position; int newLen = limit - position;
long newAlloc = JEmalloc.nje_malloc(newLen); 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); return new EaglerLWJGLShortBuffer(newAlloc, newLen, true);
} }

View File

@ -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();
}
}
}

View File

@ -124,4 +124,9 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
return false; return false;
} }
@Override
public boolean isAllowVoiceClient() {
return false;
}
} }

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -6,6 +6,7 @@ import javax.swing.UnsupportedLookAndFeelException;
import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.EagUtils; import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformANGLE; 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.PlatformInput;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource; import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
@ -43,15 +44,9 @@ public class LWJGLEntryPoint {
boolean hideRenderDocDialog = false; boolean hideRenderDocDialog = false;
for(int i = 0; i < args.length; ++i) { for(int i = 0; i < args.length; ++i) {
if(args[i].equalsIgnoreCase("highp")) {
ShaderSource.setHighP(true);
}
if(args[i].equalsIgnoreCase("hide-renderdoc")) { if(args[i].equalsIgnoreCase("hide-renderdoc")) {
hideRenderDocDialog = true; hideRenderDocDialog = true;
} }
if(args[i].equalsIgnoreCase("fullscreen")) {
PlatformInput.setStartupFullscreen(true);
}
} }
if(!hideRenderDocDialog) { if(!hideRenderDocDialog) {
@ -66,7 +61,7 @@ public class LWJGLEntryPoint {
lr.dispose(); lr.dispose();
} }
getANGLEPlatformFromArgs(args); getPlatformOptionsFromArgs(args);
RelayManager.relayManager.load(EagRuntime.getStorage("r")); 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) { for(int i = 0; i < args.length; ++i) {
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]); EnumPlatformANGLE angle = EnumPlatformANGLE.fromId(args[i]);
if(angle != EnumPlatformANGLE.DEFAULT) { if(angle != EnumPlatformANGLE.DEFAULT) {
PlatformRuntime.requestANGLE(angle); PlatformRuntime.requestANGLE(angle);
break; }
} }
} }
} }

View File

@ -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();
}
}

View File

@ -11,7 +11,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/** /**
* Copyright (c) 2022-2023 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 * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -983,6 +983,30 @@ public class GlStateManager {
Matrix4f.mul(modeMatrix, paramMatrix, modeMatrix); Matrix4f.mul(modeMatrix, paramMatrix, modeMatrix);
} }
public static final void multMatrix(Matrix4f matrix) {
Matrix4f modeMatrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modeMatrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
modeMatrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
modeMatrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f.mul(modeMatrix, matrix, modeMatrix);
}
public static final void color(float colorRed, float colorGreen, float colorBlue, float colorAlpha) { public static final void color(float colorRed, float colorGreen, float colorBlue, float colorAlpha) {
stateColorR = colorRed; stateColorR = colorRed;
stateColorG = colorGreen; stateColorG = colorGreen;

View File

@ -39,6 +39,7 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack; import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFontRenderer; import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFontRenderer;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglerMeshLoader;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU; import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData; import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
@ -67,6 +68,8 @@ import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiScreenSingleplayerConnecting;
import net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer; import net.lax1dude.eaglercraft.v1_8.sp.internal.ClientPlatformSingleplayer;
import net.lax1dude.eaglercraft.v1_8.sp.lan.LANServerController; import net.lax1dude.eaglercraft.v1_8.sp.lan.LANServerController;
import net.lax1dude.eaglercraft.v1_8.update.RelayUpdateChecker; import net.lax1dude.eaglercraft.v1_8.update.RelayUpdateChecker;
import net.lax1dude.eaglercraft.v1_8.voice.GuiVoiceOverlay;
import net.lax1dude.eaglercraft.v1_8.voice.VoiceClientController;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.audio.MusicTicker; import net.minecraft.client.audio.MusicTicker;
@ -308,6 +311,8 @@ public class Minecraft implements IThreadListener {
public SkullCommand eagskullCommand; public SkullCommand eagskullCommand;
public GuiVoiceOverlay voiceOverlay;
public Minecraft(GameConfiguration gameConfig) { public Minecraft(GameConfiguration gameConfig) {
theMinecraft = this; theMinecraft = this;
StringTranslate.initClient(); StringTranslate.initClient();
@ -421,6 +426,7 @@ public class Minecraft implements IThreadListener {
this.mcResourceManager.registerReloadListener(new MetalsLUT()); this.mcResourceManager.registerReloadListener(new MetalsLUT());
this.mcResourceManager.registerReloadListener(new EmissiveItems()); this.mcResourceManager.registerReloadListener(new EmissiveItems());
this.mcResourceManager.registerReloadListener(new BlockVertexIDs()); this.mcResourceManager.registerReloadListener(new BlockVertexIDs());
this.mcResourceManager.registerReloadListener(new EaglerMeshLoader());
AchievementList.openInventory.setStatStringFormatter(new IStatStringFormat() { AchievementList.openInventory.setStatStringFormatter(new IStatStringFormat() {
public String formatString(String parString1) { public String formatString(String parString1) {
try { try {
@ -471,6 +477,9 @@ public class Minecraft implements IThreadListener {
this.checkGLError("Post startup"); this.checkGLError("Post startup");
this.ingameGUI = new GuiIngame(this); this.ingameGUI = new GuiIngame(this);
this.eagskullCommand = new SkullCommand(this); this.eagskullCommand = new SkullCommand(this);
this.voiceOverlay = new GuiVoiceOverlay(this);
ScaledResolution voiceRes = new ScaledResolution(this);
this.voiceOverlay.setResolution(voiceRes.getScaledWidth(), voiceRes.getScaledHeight());
ServerList.initServerList(this); ServerList.initServerList(this);
EaglerProfile.read(); EaglerProfile.read();
@ -868,6 +877,7 @@ public class Minecraft implements IThreadListener {
public void updateDisplay() { public void updateDisplay() {
this.mcProfiler.startSection("display_update"); this.mcProfiler.startSection("display_update");
Display.setVSync(this.gameSettings.enableVsync);
Display.update(); Display.update();
this.mcProfiler.endSection(); this.mcProfiler.endSection();
this.checkWindowResize(); this.checkWindowResize();
@ -1214,12 +1224,14 @@ public class Minecraft implements IThreadListener {
private void resize(int width, int height) { private void resize(int width, int height) {
this.displayWidth = Math.max(1, width); this.displayWidth = Math.max(1, width);
this.displayHeight = Math.max(1, height); this.displayHeight = Math.max(1, height);
if (this.currentScreen != null) {
ScaledResolution scaledresolution = new ScaledResolution(this); ScaledResolution scaledresolution = new ScaledResolution(this);
if (this.currentScreen != null) {
this.currentScreen.onResize(this, scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight()); this.currentScreen.onResize(this, scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight());
} }
this.loadingScreen = new LoadingScreenRenderer(this); this.loadingScreen = new LoadingScreenRenderer(this);
this.voiceOverlay.setResolution(scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight());
} }
public MusicTicker func_181535_r() { public MusicTicker func_181535_r() {
@ -1258,6 +1270,9 @@ public class Minecraft implements IThreadListener {
this.ingameGUI.updateTick(); this.ingameGUI.updateTick();
} }
this.mcProfiler.endStartSection("eaglerVoice");
VoiceClientController.tickVoiceClient(this);
this.mcProfiler.endSection(); this.mcProfiler.endSection();
this.entityRenderer.getMouseOver(1.0F); this.entityRenderer.getMouseOver(1.0F);
this.mcProfiler.startSection("gameMode"); this.mcProfiler.startSection("gameMode");
@ -1764,6 +1779,7 @@ public class Minecraft implements IThreadListener {
*/ */
public void launchIntegratedServer(String folderName, String worldName, WorldSettings worldSettingsIn) { public void launchIntegratedServer(String folderName, String worldName, WorldSettings worldSettingsIn) {
this.loadWorld((WorldClient) null); this.loadWorld((WorldClient) null);
Minecraft.getMinecraft().getRenderManager().setEnableFNAWSkins(this.gameSettings.enableFNAWSkins);
session.reset(); session.reset();
SingleplayerServerController.launchEaglercraftServer(folderName, gameSettings.difficulty.getDifficultyId(), SingleplayerServerController.launchEaglercraftServer(folderName, gameSettings.difficulty.getDifficultyId(),
Math.max(gameSettings.renderDistanceChunks, 2), worldSettingsIn); Math.max(gameSettings.renderDistanceChunks, 2), worldSettingsIn);
@ -2308,4 +2324,12 @@ public class Minecraft implements IThreadListener {
public void clearTitles() { public void clearTitles() {
ingameGUI.displayTitle(null, null, -1, -1, -1); ingameGUI.displayTitle(null, null, -1, -1, -1);
} }
public boolean getEnableFNAWSkins() {
boolean ret = this.gameSettings.enableFNAWSkins;
if (this.thePlayer != null) {
ret &= this.thePlayer.sendQueue.currentFNAWSkinAllowedState;
}
return ret;
}
} }

View File

@ -288,6 +288,10 @@ public class GuiIngame extends Gui {
this.renderScoreboard(scoreobjective1, scaledresolution); this.renderScoreboard(scoreobjective1, scaledresolution);
} }
if (this.mc.currentScreen == null) {
this.mc.voiceOverlay.drawOverlay();
}
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1, 0); GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, 1, 0);
GlStateManager.disableAlpha(); GlStateManager.disableAlpha();

View File

@ -1,5 +1,6 @@
package net.minecraft.client.gui; package net.minecraft.client.gui;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.Mouse; import net.lax1dude.eaglercraft.v1_8.Mouse;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.sp.SingleplayerServerController; import net.lax1dude.eaglercraft.v1_8.sp.SingleplayerServerController;
@ -8,6 +9,8 @@ import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiScreenLANNotSupported;
import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiShareToLan; import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiShareToLan;
import net.lax1dude.eaglercraft.v1_8.sp.lan.LANServerController; import net.lax1dude.eaglercraft.v1_8.sp.lan.LANServerController;
import net.lax1dude.eaglercraft.v1_8.update.GuiUpdateCheckerOverlay; import net.lax1dude.eaglercraft.v1_8.update.GuiUpdateCheckerOverlay;
import net.lax1dude.eaglercraft.v1_8.voice.GuiVoiceMenu;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.achievement.GuiAchievements; import net.minecraft.client.gui.achievement.GuiAchievements;
import net.minecraft.client.gui.achievement.GuiStats; import net.minecraft.client.gui.achievement.GuiStats;
@ -44,9 +47,13 @@ public class GuiIngameMenu extends GuiScreen {
boolean hasSentAutoSave = !SingleplayerServerController.isWorldRunning(); boolean hasSentAutoSave = !SingleplayerServerController.isWorldRunning();
private GuiUpdateCheckerOverlay updateCheckerOverlay; private GuiUpdateCheckerOverlay updateCheckerOverlay;
private GuiVoiceMenu voiceMenu;
public GuiIngameMenu() { public GuiIngameMenu() {
updateCheckerOverlay = new GuiUpdateCheckerOverlay(true, this); updateCheckerOverlay = new GuiUpdateCheckerOverlay(true, this);
if (EagRuntime.getConfiguration().isAllowVoiceClient()) {
voiceMenu = new GuiVoiceMenu(this);
}
} }
/**+ /**+
@ -75,6 +82,10 @@ public class GuiIngameMenu extends GuiScreen {
I18n.format("gui.achievements", new Object[0]))); I18n.format("gui.achievements", new Object[0])));
this.buttonList.add(new GuiButton(6, this.width / 2 + 2, this.height / 4 + 48 + b0, 98, 20, this.buttonList.add(new GuiButton(6, this.width / 2 + 2, this.height / 4 + 48 + b0, 98, 20,
I18n.format("gui.stats", new Object[0]))); I18n.format("gui.stats", new Object[0])));
GuiButton mods;
this.buttonList.add(mods = new GuiButton(69420, this.width / 2 - 100, this.height / 4 + 73 + b0,
I18n.format("EaglerForge Mods", new Object[0])));
mods.enabled = false;
lanButton.enabled = SingleplayerServerController.isWorldRunning(); lanButton.enabled = SingleplayerServerController.isWorldRunning();
if (!hasSentAutoSave) { if (!hasSentAutoSave) {
hasSentAutoSave = true; hasSentAutoSave = true;
@ -139,6 +150,10 @@ public class GuiIngameMenu extends GuiScreen {
*/ */
public void updateScreen() { public void updateScreen() {
super.updateScreen(); super.updateScreen();
if (EagRuntime.getConfiguration().isAllowVoiceClient()
&& (!mc.isSingleplayer() || LANServerController.isHostingLAN())) {
voiceMenu.updateScreen();
}
if (Mouse.isActuallyGrabbed()) { if (Mouse.isActuallyGrabbed()) {
Mouse.setGrabbed(false); Mouse.setGrabbed(false);
} }
@ -156,38 +171,68 @@ public class GuiIngameMenu extends GuiScreen {
this.updateCheckerOverlay.drawScreen(i, j, f); this.updateCheckerOverlay.drawScreen(i, j, f);
if (LANServerController.isLANOpen()) { if (LANServerController.isLANOpen()) {
int offset = this.updateCheckerOverlay.getSharedWorldInfoYOffset();
String str = I18n.format("lanServer.pauseMenu0"); String str = I18n.format("lanServer.pauseMenu0");
drawString(fontRendererObj, str, 6, 32, 0xFFFF55); drawString(fontRendererObj, str, 6, 10 + offset, 0xFFFF55);
if (mc.gameSettings.hideJoinCode) { if (mc.gameSettings.hideJoinCode) {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(7.0f, 47.0f, 0.0f); GlStateManager.translate(7.0f, 25.0f + offset, 0.0f);
GlStateManager.scale(0.75f, 0.75f, 0.75f); GlStateManager.scale(0.75f, 0.75f, 0.75f);
str = I18n.format("lanServer.showCode"); str = I18n.format("lanServer.showCode");
int w = fontRendererObj.getStringWidth(str); int w = fontRendererObj.getStringWidth(str);
boolean hover = i > 6 && i < 8 + w * 3 / 4 && j > 46 && j < 47 + 8; boolean hover = i > 4 && i < 8 + w * 3 / 4 && j > 24 + offset && j < 25 + offset + 8;
drawString(fontRendererObj, EnumChatFormatting.UNDERLINE + str, 0, 0, hover ? 0xEEEEAA : 0xCCCC55); drawString(fontRendererObj, EnumChatFormatting.UNDERLINE + str, 0, 0, hover ? 0xEEEEAA : 0xCCCC55);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} else { } else {
int w = fontRendererObj.getStringWidth(str); int w = fontRendererObj.getStringWidth(str);
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(6 + w + 3, 33, 0.0f); GlStateManager.translate(6 + w + 3, 11 + offset, 0.0f);
GlStateManager.scale(0.75f, 0.75f, 0.75f); GlStateManager.scale(0.75f, 0.75f, 0.75f);
str = I18n.format("lanServer.hideCode"); str = I18n.format("lanServer.hideCode");
int w2 = fontRendererObj.getStringWidth(str); int w2 = fontRendererObj.getStringWidth(str);
boolean hover = i > 6 + w + 2 && i < 6 + w + 3 + w2 * 3 / 4 && j > 33 - 1 && j < 33 + 6; boolean hover = i > 6 + w + 2 && i < 6 + w + 3 + w2 * 3 / 4 && j > 11 + offset - 1
&& j < 11 + offset + 6;
drawString(fontRendererObj, EnumChatFormatting.UNDERLINE + str, 0, 0, hover ? 0xEEEEAA : 0xCCCC55); drawString(fontRendererObj, EnumChatFormatting.UNDERLINE + str, 0, 0, hover ? 0xEEEEAA : 0xCCCC55);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
drawString(fontRendererObj, EnumChatFormatting.GRAY + I18n.format("lanServer.pauseMenu1") + " " drawString(
+ EnumChatFormatting.RESET + LANServerController.getCurrentURI(), 6, 47, 0xFFFFFF); fontRendererObj, EnumChatFormatting.GRAY + I18n.format("lanServer.pauseMenu1") + " "
drawString(fontRendererObj, EnumChatFormatting.GRAY + I18n.format("lanServer.pauseMenu2") + " " + EnumChatFormatting.RESET + LANServerController.getCurrentURI(),
+ EnumChatFormatting.RESET + LANServerController.getCurrentCode(), 6, 57, 0xFFFFFF); 6, 25 + offset, 0xFFFFFF);
drawString(
fontRendererObj, EnumChatFormatting.GRAY + I18n.format("lanServer.pauseMenu2") + " "
+ EnumChatFormatting.RESET + LANServerController.getCurrentCode(),
6, 35 + offset, 0xFFFFFF);
} }
} }
try {
if (EagRuntime.getConfiguration().isAllowVoiceClient()
&& (!mc.isSingleplayer() || LANServerController.isHostingLAN())) {
if (voiceMenu.isBlockingInput()) {
super.drawScreen(0, 0, f);
} else {
super.drawScreen(i, j, f); super.drawScreen(i, j, f);
} }
voiceMenu.drawScreen(i, j, f);
} else {
super.drawScreen(i, j, f);
}
} catch (GuiVoiceMenu.AbortedException ex) {
}
}
protected void keyTyped(char par1, int par2) {
try {
if (EagRuntime.getConfiguration().isAllowVoiceClient()
&& (!mc.isSingleplayer() || LANServerController.isHostingLAN())) {
voiceMenu.keyTyped(par1, par2);
}
super.keyTyped(par1, par2);
} catch (GuiVoiceMenu.AbortedException ex) {
}
}
public void confirmClicked(boolean par1, int par2) { public void confirmClicked(boolean par1, int par2) {
mc.displayGuiScreen(this); mc.displayGuiScreen(this);
@ -201,11 +246,20 @@ public class GuiIngameMenu extends GuiScreen {
} }
protected void mouseClicked(int par1, int par2, int par3) { protected void mouseClicked(int par1, int par2, int par3) {
try {
if (EagRuntime.getConfiguration().isAllowVoiceClient()
&& (!mc.isSingleplayer() || LANServerController.isHostingLAN())) {
voiceMenu.mouseClicked(par1, par2, par3);
}
} catch (GuiVoiceMenu.AbortedException ex) {
return;
}
if (par3 == 0) { if (par3 == 0) {
int offset = this.updateCheckerOverlay.getSharedWorldInfoYOffset();
if (mc.gameSettings.hideJoinCode) { if (mc.gameSettings.hideJoinCode) {
String str = I18n.format("lanServer.showCode"); String str = I18n.format("lanServer.showCode");
int w = fontRendererObj.getStringWidth(str); int w = fontRendererObj.getStringWidth(str);
if (par1 > 6 && par1 < 8 + w * 3 / 4 && par2 > 46 && par2 < 47 + 8) { if (par1 > 4 && par1 < 8 + w * 3 / 4 && par2 > 24 + offset && par2 < 25 + offset + 8) {
mc.gameSettings.hideJoinCode = false; mc.gameSettings.hideJoinCode = false;
this.mc.getSoundHandler() this.mc.getSoundHandler()
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); .playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
@ -216,7 +270,8 @@ public class GuiIngameMenu extends GuiScreen {
int w = fontRendererObj.getStringWidth(str); int w = fontRendererObj.getStringWidth(str);
str = I18n.format("lanServer.hideCode"); str = I18n.format("lanServer.hideCode");
int w2 = fontRendererObj.getStringWidth(str); int w2 = fontRendererObj.getStringWidth(str);
if (par1 > 6 + w + 2 && par1 < 6 + w + 3 + w2 * 3 / 4 && par2 > 33 - 1 && par2 < 33 + 6) { if (par1 > 6 + w + 2 && par1 < 6 + w + 3 + w2 * 3 / 4 && par2 > 11 + offset - 1
&& par2 < 11 + offset + 6) {
mc.gameSettings.hideJoinCode = true; mc.gameSettings.hideJoinCode = true;
this.mc.getSoundHandler() this.mc.getSoundHandler()
.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); .playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
@ -228,4 +283,22 @@ public class GuiIngameMenu extends GuiScreen {
this.updateCheckerOverlay.mouseClicked(par1, par2, par3); this.updateCheckerOverlay.mouseClicked(par1, par2, par3);
super.mouseClicked(par1, par2, par3); super.mouseClicked(par1, par2, par3);
} }
public void setWorldAndResolution(Minecraft par1Minecraft, int par2, int par3) {
super.setWorldAndResolution(par1Minecraft, par2, par3);
if (EagRuntime.getConfiguration().isAllowVoiceClient()) {
voiceMenu.setResolution(par1Minecraft, par2, par3);
}
}
protected void mouseReleased(int par1, int par2, int par3) {
try {
if (EagRuntime.getConfiguration().isAllowVoiceClient()
&& (!mc.isSingleplayer() || LANServerController.isHostingLAN())) {
voiceMenu.mouseReleased(par1, par2, par3);
}
super.mouseReleased(par1, par2, par3);
} catch (GuiVoiceMenu.AbortedException ex) {
}
}
} }

View File

@ -673,4 +673,8 @@ public abstract class GuiScreen extends Gui implements GuiYesNoCallback {
public boolean shouldHangupIntegratedServer() { public boolean shouldHangupIntegratedServer() {
return true; return true;
} }
public boolean blockPTTKey() {
return false;
}
} }

View File

@ -13,12 +13,15 @@ import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import net.lax1dude.eaglercraft.v1_8.netty.Unpooled; import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
import net.lax1dude.eaglercraft.v1_8.profile.CapePackets;
import net.lax1dude.eaglercraft.v1_8.profile.ServerCapeCache;
import net.lax1dude.eaglercraft.v1_8.profile.ServerSkinCache; import net.lax1dude.eaglercraft.v1_8.profile.ServerSkinCache;
import net.lax1dude.eaglercraft.v1_8.profile.SkinPackets; import net.lax1dude.eaglercraft.v1_8.profile.SkinPackets;
import net.lax1dude.eaglercraft.v1_8.socket.EaglercraftNetworkManager; import net.lax1dude.eaglercraft.v1_8.socket.EaglercraftNetworkManager;
import net.lax1dude.eaglercraft.v1_8.sp.lan.LANClientNetworkManager; import net.lax1dude.eaglercraft.v1_8.sp.lan.LANClientNetworkManager;
import net.lax1dude.eaglercraft.v1_8.sp.socket.ClientIntegratedServerNetworkManager; import net.lax1dude.eaglercraft.v1_8.sp.socket.ClientIntegratedServerNetworkManager;
import net.lax1dude.eaglercraft.v1_8.update.UpdateService; import net.lax1dude.eaglercraft.v1_8.update.UpdateService;
import net.lax1dude.eaglercraft.v1_8.voice.VoiceClientController;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack; import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack;
@ -242,6 +245,8 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
*/ */
private final EaglercraftRandom avRandomizer = new EaglercraftRandom(); private final EaglercraftRandom avRandomizer = new EaglercraftRandom();
private final ServerSkinCache skinCache; private final ServerSkinCache skinCache;
private final ServerCapeCache capeCache;
public boolean currentFNAWSkinAllowedState = true;
public NetHandlerPlayClient(Minecraft mcIn, GuiScreen parGuiScreen, EaglercraftNetworkManager parNetworkManager, public NetHandlerPlayClient(Minecraft mcIn, GuiScreen parGuiScreen, EaglercraftNetworkManager parNetworkManager,
GameProfile parGameProfile) { GameProfile parGameProfile) {
@ -250,6 +255,7 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
this.netManager = parNetworkManager; this.netManager = parNetworkManager;
this.profile = parGameProfile; this.profile = parGameProfile;
this.skinCache = new ServerSkinCache(parNetworkManager, mcIn.getTextureManager()); this.skinCache = new ServerSkinCache(parNetworkManager, mcIn.getTextureManager());
this.capeCache = new ServerCapeCache(parNetworkManager, mcIn.getTextureManager());
this.isIntegratedServer = (parNetworkManager instanceof ClientIntegratedServerNetworkManager) this.isIntegratedServer = (parNetworkManager instanceof ClientIntegratedServerNetworkManager)
|| (parNetworkManager instanceof LANClientNetworkManager); || (parNetworkManager instanceof LANClientNetworkManager);
} }
@ -261,12 +267,17 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
public void cleanup() { public void cleanup() {
this.clientWorldController = null; this.clientWorldController = null;
this.skinCache.destroy(); this.skinCache.destroy();
this.capeCache.destroy();
} }
public ServerSkinCache getSkinCache() { public ServerSkinCache getSkinCache() {
return this.skinCache; return this.skinCache;
} }
public ServerCapeCache getCapeCache() {
return this.capeCache;
}
/**+ /**+
* Registers some server properties * Registers some server properties
* (gametype,hardcore-mode,terraintype,difficulty,player limit), * (gametype,hardcore-mode,terraintype,difficulty,player limit),
@ -290,6 +301,10 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
this.gameController.gameSettings.sendSettingsToServer(); this.gameController.gameSettings.sendSettingsToServer();
this.netManager.sendPacket(new C17PacketCustomPayload("MC|Brand", this.netManager.sendPacket(new C17PacketCustomPayload("MC|Brand",
(new PacketBuffer(Unpooled.buffer())).writeString(ClientBrandRetriever.getClientModName()))); (new PacketBuffer(Unpooled.buffer())).writeString(ClientBrandRetriever.getClientModName())));
if (VoiceClientController.isClientSupported()) {
VoiceClientController.initializeVoiceClient((pkt) -> this.netManager
.sendPacket(new C17PacketCustomPayload(VoiceClientController.SIGNAL_CHANNEL, pkt)));
}
} }
/**+ /**+
@ -712,6 +727,9 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
* describing the reason for termination * describing the reason for termination
*/ */
public void onDisconnect(IChatComponent ichatcomponent) { public void onDisconnect(IChatComponent ichatcomponent) {
VoiceClientController.handleServerDisconnect();
Minecraft.getMinecraft().getRenderManager()
.setEnableFNAWSkins(this.gameController.gameSettings.enableFNAWSkins);
if (this.gameController.theWorld != null) { if (this.gameController.theWorld != null) {
this.gameController.loadWorld((WorldClient) null); this.gameController.loadWorld((WorldClient) null);
} }
@ -1419,6 +1437,7 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
EaglercraftUUID uuid = s38packetplayerlistitem$addplayerdata.getProfile().getId(); EaglercraftUUID uuid = s38packetplayerlistitem$addplayerdata.getProfile().getId();
this.playerInfoMap.remove(uuid); this.playerInfoMap.remove(uuid);
this.skinCache.evictSkin(uuid); this.skinCache.evictSkin(uuid);
this.capeCache.evictCape(uuid);
} else { } else {
NetworkPlayerInfo networkplayerinfo = (NetworkPlayerInfo) this.playerInfoMap NetworkPlayerInfo networkplayerinfo = (NetworkPlayerInfo) this.playerInfoMap
.get(s38packetplayerlistitem$addplayerdata.getProfile().getId()); .get(s38packetplayerlistitem$addplayerdata.getProfile().getId());
@ -1600,6 +1619,13 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
logger.error("Couldn't read EAG|Skins-1.8 packet!"); logger.error("Couldn't read EAG|Skins-1.8 packet!");
logger.error(e); logger.error(e);
} }
} else if ("EAG|Capes-1.8".equals(packetIn.getChannelName())) {
try {
CapePackets.readPluginMessage(packetIn.getBufferData(), capeCache);
} catch (IOException e) {
logger.error("Couldn't read EAG|Capes-1.8 packet!");
logger.error(e);
}
} else if ("EAG|UpdateCert-1.8".equals(packetIn.getChannelName())) { } else if ("EAG|UpdateCert-1.8".equals(packetIn.getChannelName())) {
if (EagRuntime.getConfiguration().allowUpdateSvc()) { if (EagRuntime.getConfiguration().allowUpdateSvc()) {
try { try {
@ -1612,6 +1638,14 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient {
logger.error(e); logger.error(e);
} }
} }
} else if (VoiceClientController.SIGNAL_CHANNEL.equals(packetIn.getChannelName())) {
if (VoiceClientController.isClientSupported()) {
VoiceClientController.handleVoiceSignalPacket(packetIn.getBufferData());
}
} else if ("EAG|FNAWSEn-1.8".equals(packetIn.getChannelName())) {
this.currentFNAWSkinAllowedState = packetIn.getBufferData().readBoolean();
Minecraft.getMinecraft().getRenderManager().setEnableFNAWSkins(
this.currentFNAWSkinAllowedState && Minecraft.getMinecraft().gameSettings.enableFNAWSkins);
} }
} }

View File

@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayManager; import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayManager;
import net.lax1dude.eaglercraft.v1_8.voice.VoiceClientController;
import org.json.JSONArray; import org.json.JSONArray;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -33,6 +34,7 @@ import net.lax1dude.eaglercraft.v1_8.EaglerZLIB;
import net.lax1dude.eaglercraft.v1_8.HString; import net.lax1dude.eaglercraft.v1_8.HString;
import net.lax1dude.eaglercraft.v1_8.Keyboard; import net.lax1dude.eaglercraft.v1_8.Keyboard;
import net.lax1dude.eaglercraft.v1_8.Mouse; import net.lax1dude.eaglercraft.v1_8.Mouse;
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformType;
import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants; import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
@ -110,7 +112,7 @@ public class GameSettings {
public boolean chatLinksPrompt = true; public boolean chatLinksPrompt = true;
public float chatOpacity = 1.0F; public float chatOpacity = 1.0F;
public boolean snooperEnabled = true; public boolean snooperEnabled = true;
public boolean enableVsync = true; public boolean enableVsync = EagRuntime.getPlatformType() != EnumPlatformType.DESKTOP;
public boolean allowBlockAlternatives = true; public boolean allowBlockAlternatives = true;
public boolean reducedDebugInfo = false; public boolean reducedDebugInfo = false;
public boolean hideServerAddress; public boolean hideServerAddress;
@ -266,6 +268,12 @@ public class GameSettings {
public boolean ofCustomColors = true; public boolean ofCustomColors = true;
public boolean hidePassword = true; public boolean hidePassword = true;
public boolean enableFNAWSkins = true;
public int voiceListenRadius = 16;
public float voiceListenVolume = 0.5f;
public float voiceSpeakVolume = 0.5f;
public int voicePTTKey = 47; // V
public GameSettings(Minecraft mcIn) { public GameSettings(Minecraft mcIn) {
this.keyBindings = (KeyBinding[]) ArrayUtils.addAll(new KeyBinding[] { this.keyBindAttack, this.keyBindUseItem, this.keyBindings = (KeyBinding[]) ArrayUtils.addAll(new KeyBinding[] { this.keyBindAttack, this.keyBindUseItem,
this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump, this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump,
@ -897,6 +905,15 @@ public class GameSettings {
hidePassword =! hidePassword; hidePassword =! hidePassword;
} }
if (parOptions == GameSettings.Options.FNAW_SKINS) {
this.enableFNAWSkins = !this.enableFNAWSkins;
this.mc.getRenderManager().setEnableFNAWSkins(this.mc.getEnableFNAWSkins());
}
if (parOptions == GameSettings.Options.EAGLER_VSYNC) {
this.enableVsync = !this.enableVsync;
}
this.saveOptions(); this.saveOptions();
} }
@ -1019,6 +1036,10 @@ public class GameSettings {
return this.ofCustomColors; return this.ofCustomColors;
case HIDE_PASSWORD: case HIDE_PASSWORD:
return hidePassword; return hidePassword;
case FNAW_SKINS:
return this.enableFNAWSkins;
case EAGLER_VSYNC:
return this.enableVsync;
default: default:
return false; return false;
} }
@ -1474,7 +1495,7 @@ public class GameSettings {
this.snooperEnabled = astring[1].equals("true"); this.snooperEnabled = astring[1].equals("true");
} }
if (astring[0].equals("enableVsync")) { if (astring[0].equals("enableVsyncEag")) {
this.enableVsync = astring[1].equals("true"); this.enableVsync = astring[1].equals("true");
} }
@ -1869,7 +1890,21 @@ public class GameSettings {
hidePassword = Boolean.valueOf(astring[1]).booleanValue(); hidePassword = Boolean.valueOf(astring[1]).booleanValue();
} }
Keyboard.setFunctionKeyModifier(keyBindFunction.getKeyCode()); if (astring[0].equals("voiceListenRadius")) {
voiceListenRadius = Integer.parseInt(astring[1]);
}
if (astring[0].equals("voiceListenVolume")) {
voiceListenVolume = this.parseFloat(astring[1]);
}
if (astring[0].equals("voiceSpeakVolume")) {
voiceSpeakVolume = this.parseFloat(astring[1]);
}
if (astring[0].equals("voicePTTKey")) {
voicePTTKey = Integer.parseInt(astring[1]);
}
for (SoundCategory soundcategory : SoundCategory._VALUES) { for (SoundCategory soundcategory : SoundCategory._VALUES) {
if (astring[0].equals("soundCategory_" + soundcategory.getCategoryName())) { if (astring[0].equals("soundCategory_" + soundcategory.getCategoryName())) {
@ -1883,6 +1918,10 @@ public class GameSettings {
} }
} }
if (astring[0].equals("enableFNAWSkins")) {
this.enableFNAWSkins = astring[1].equals("true");
}
deferredShaderConf.readOption(astring[0], astring[1]); deferredShaderConf.readOption(astring[0], astring[1]);
} catch (Exception var8) { } catch (Exception var8) {
logger.warn("Skipping bad option: " + s); logger.warn("Skipping bad option: " + s);
@ -1890,8 +1929,16 @@ public class GameSettings {
} }
KeyBinding.resetKeyBindingArrayAndHash(); KeyBinding.resetKeyBindingArrayAndHash();
Keyboard.setFunctionKeyModifier(keyBindFunction.getKeyCode());
VoiceClientController.setVoiceListenVolume(voiceListenVolume);
VoiceClientController.setVoiceSpeakVolume(voiceSpeakVolume);
VoiceClientController.setVoiceProximity(voiceListenRadius);
if (this.mc.getRenderManager() != null)
this.mc.getRenderManager().setEnableFNAWSkins(this.enableFNAWSkins);
} catch (Exception exception) { } catch (Exception exception) {
logger.error("Failed to load options", exception); logger.error("Failed to load options");
logger.error(exception);
} }
} }
@ -1958,7 +2005,7 @@ public class GameSettings {
printwriter.println("chatLinksPrompt:" + this.chatLinksPrompt); printwriter.println("chatLinksPrompt:" + this.chatLinksPrompt);
printwriter.println("chatOpacity:" + this.chatOpacity); printwriter.println("chatOpacity:" + this.chatOpacity);
printwriter.println("snooperEnabled:" + this.snooperEnabled); printwriter.println("snooperEnabled:" + this.snooperEnabled);
printwriter.println("enableVsync:" + this.enableVsync); printwriter.println("enableVsyncEag:" + this.enableVsync);
printwriter.println("hideServerAddress:" + this.hideServerAddress); printwriter.println("hideServerAddress:" + this.hideServerAddress);
printwriter.println("advancedItemTooltips:" + this.advancedItemTooltips); printwriter.println("advancedItemTooltips:" + this.advancedItemTooltips);
printwriter.println("pauseOnLostFocus:" + this.pauseOnLostFocus); printwriter.println("pauseOnLostFocus:" + this.pauseOnLostFocus);
@ -2047,6 +2094,11 @@ public class GameSettings {
printwriter.println("ofSmoothBiomes:" + this.ofSmoothBiomes); printwriter.println("ofSmoothBiomes:" + this.ofSmoothBiomes);
printwriter.println("ofCustomColors:" + this.ofCustomColors); printwriter.println("ofCustomColors:" + this.ofCustomColors);
printwriter.println("hidePassword:" + hidePassword); printwriter.println("hidePassword:" + hidePassword);
printwriter.println("voiceListenRadius:" + this.voiceListenRadius);
printwriter.println("voiceListenVolume:" + this.voiceListenVolume);
printwriter.println("voiceSpeakVolume:" + this.voiceSpeakVolume);
printwriter.println("voicePTTKey:" + this.voicePTTKey);
printwriter.println("enableFNAWSkins:" + this.enableFNAWSkins);
for (KeyBinding keybinding : this.keyBindings) { for (KeyBinding keybinding : this.keyBindings) {
printwriter.println("key_" + keybinding.getKeyDescription() + ":" + keybinding.getKeyCode()); printwriter.println("key_" + keybinding.getKeyDescription() + ":" + keybinding.getKeyCode());
@ -2069,7 +2121,8 @@ public class GameSettings {
printwriter.close(); printwriter.close();
return bao.toByteArray(); return bao.toByteArray();
} catch (Exception exception) { } catch (Exception exception) {
logger.error("Failed to save options", exception); logger.error("Failed to save options");
logger.error(exception);
return null; return null;
} }
@ -2255,7 +2308,9 @@ public class GameSettings {
SWAMP_COLORS("Swamp Colors", false, false), SWAMP_COLORS("Swamp Colors", false, false),
SMOOTH_BIOMES("Smooth Biomes", false, false), SMOOTH_BIOMES("Smooth Biomes", false, false),
CUSTOM_COLORS("Custom Colors", false, false), CUSTOM_COLORS("Custom Colors", false, false),
HIDE_PASSWORD("Hide Password", false, false); HIDE_PASSWORD("Hide Password", false, false),
FNAW_SKINS("options.skinCustomisation.enableFNAWSkins", false, true),
EAGLER_VSYNC("options.vsync", false, true);
private final boolean enumFloat; private final boolean enumFloat;
private final boolean enumBoolean; private final boolean enumBoolean;

View File

@ -12,7 +12,7 @@ public class GuiOtherSettingsOF extends GuiScreen implements GuiYesNoCallback {
private GuiScreen prevScreen; private GuiScreen prevScreen;
protected String title; protected String title;
private GameSettings settings; private GameSettings settings;
private static GameSettings.Options[] enumOptions = new GameSettings.Options[] {GameSettings.Options.LAGOMETER, GameSettings.Options.PROFILER, GameSettings.Options.WEATHER, GameSettings.Options.TIME, GameSettings.Options.FULLSCREEN, GameSettings.Options.HUD_FPS, GameSettings.Options.AUTOSAVE_TICKS, GameSettings.Options.ANAGLYPH, GameSettings.Options.HUD_COORDS, GameSettings.Options.HUD_PLAYER, GameSettings.Options.HUD_STATS, GameSettings.Options.HUD_WORLD, GameSettings.Options.HUD_24H}; private static GameSettings.Options[] enumOptions = new GameSettings.Options[] {GameSettings.Options.LAGOMETER, GameSettings.Options.PROFILER, GameSettings.Options.WEATHER, GameSettings.Options.TIME, GameSettings.Options.FULLSCREEN, GameSettings.Options.FNAW_SKINS, GameSettings.Options.HUD_FPS, GameSettings.Options.AUTOSAVE_TICKS, GameSettings.Options.ANAGLYPH, GameSettings.Options.HUD_COORDS, GameSettings.Options.HUD_PLAYER, GameSettings.Options.HUD_STATS, GameSettings.Options.HUD_WORLD, GameSettings.Options.HUD_24H};
public GuiOtherSettingsOF(GuiScreen p_i51_1_, GameSettings p_i51_2_) { public GuiOtherSettingsOF(GuiScreen p_i51_1_, GameSettings p_i51_2_) {
this.prevScreen = p_i51_1_; this.prevScreen = p_i51_1_;

View File

@ -45,6 +45,10 @@ public class Display {
return PlatformInput.isCloseRequested(); return PlatformInput.isCloseRequested();
} }
public static void setVSync(boolean enable) {
PlatformInput.setVSync(enable);
}
public static void update() { public static void update() {
PlatformInput.update(); PlatformInput.update();
} }

View File

@ -35,7 +35,7 @@ public class EaglercraftVersion {
public static final boolean enableUpdateService = false; public static final boolean enableUpdateService = false;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client"; public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 27; public static final int updateBundlePackageVersionInt = 29;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName; public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;

View File

@ -67,4 +67,6 @@ public interface IClientConfigAdapter {
boolean isCheckRelaysForUpdates(); boolean isCheckRelaysForUpdates();
boolean isEnableSignatureBadge(); boolean isEnableSignatureBadge();
boolean isAllowVoiceClient();
} }

View File

@ -0,0 +1,172 @@
package net.lax1dude.eaglercraft.v1_8.opengl;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.util.ResourceLocation;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/**
* 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 EaglerMeshLoader implements IResourceManagerReloadListener {
private static final Logger logger = LogManager.getLogger("EaglerMeshLoader");
private static final Map<ResourceLocation, HighPolyMesh> meshCache = new HashMap();
public static HighPolyMesh getEaglerMesh(ResourceLocation meshLoc) {
if(meshLoc.cachedPointerType == ResourceLocation.CACHED_POINTER_EAGLER_MESH) {
return (HighPolyMesh)meshLoc.cachedPointer;
}
HighPolyMesh theMesh = meshCache.get(meshLoc);
if(theMesh == null) {
theMesh = new HighPolyMesh();
reloadMesh(meshLoc, theMesh, Minecraft.getMinecraft().getResourceManager());
}
meshLoc.cachedPointerType = ResourceLocation.CACHED_POINTER_EAGLER_MESH;
meshLoc.cachedPointer = theMesh;
return theMesh;
}
private static void reloadMesh(ResourceLocation meshLoc, HighPolyMesh meshStruct, IResourceManager resourceManager) {
IntBuffer up1 = null;
try {
int intsOfVertex, intsOfIndex, intsTotal, stride;
try(DataInputStream dis = new DataInputStream(resourceManager.getResource(meshLoc).getInputStream())) {
byte[] header = new byte[8];
dis.read(header);
if(!Arrays.equals(header, new byte[] { (byte) 33, (byte) 69, (byte) 65, (byte) 71, (byte) 36,
(byte) 109, (byte) 100, (byte) 108 })) {
throw new IOException("File is not an eaglercraft high-poly mesh!");
}
char CT = (char)dis.read();
if(CT == 'C') {
meshStruct.hasTexture = false;
}else if(CT == 'T') {
meshStruct.hasTexture = true;
}else {
throw new IOException("Unsupported mesh type '" + CT + "'!");
}
dis.skipBytes(dis.readUnsignedShort());
meshStruct.vertexCount = dis.readInt();
meshStruct.indexCount = dis.readInt();
int byteIndexCount = meshStruct.indexCount;
if(byteIndexCount % 2 != 0) { // must round up to int
byteIndexCount += 1;
}
stride = meshStruct.hasTexture ? 24 : 16;
intsOfVertex = meshStruct.vertexCount * stride / 4;
intsOfIndex = byteIndexCount / 2;
intsTotal = intsOfIndex + intsOfVertex;
up1 = EagRuntime.allocateIntBuffer(intsTotal);
for(int i = 0; i < intsTotal; ++i) {
int ch1 = dis.read();
int ch2 = dis.read();
int ch3 = dis.read();
int ch4 = dis.read();
if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); // rip
up1.put((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
}
}
if(meshStruct.vertexArray == null) {
meshStruct.vertexArray = _wglGenVertexArrays();
}
if(meshStruct.vertexBuffer == null) {
meshStruct.vertexBuffer = _wglGenBuffers();
}
if(meshStruct.indexBuffer == null) {
meshStruct.indexBuffer = _wglGenBuffers();
}
up1.position(0).limit(intsOfVertex);
EaglercraftGPU.bindGLArrayBuffer(meshStruct.vertexBuffer);
_wglBufferData(GL_ARRAY_BUFFER, up1, GL_STATIC_DRAW);
EaglercraftGPU.bindGLBufferArray(meshStruct.vertexArray);
up1.position(intsOfVertex).limit(intsTotal);
_wglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshStruct.indexBuffer);
_wglBufferData(GL_ELEMENT_ARRAY_BUFFER, up1, GL_STATIC_DRAW);
_wglEnableVertexAttribArray(0);
_wglVertexAttribPointer(0, 3, GL_FLOAT, false, stride, 0);
if(meshStruct.hasTexture) {
_wglEnableVertexAttribArray(1);
_wglVertexAttribPointer(1, 2, GL_FLOAT, false, stride, 16);
}
_wglEnableVertexAttribArray(meshStruct.hasTexture ? 2 : 1);
_wglVertexAttribPointer(meshStruct.hasTexture ? 2 : 1, 4, GL_BYTE, true, stride, 12);
}catch(Throwable ex) {
if(meshStruct.vertexArray != null) {
_wglDeleteVertexArrays(meshStruct.vertexArray);
meshStruct.vertexArray = null;
}
if(meshStruct.vertexBuffer != null) {
_wglDeleteBuffers(meshStruct.vertexBuffer);
meshStruct.vertexBuffer = null;
}
if(meshStruct.indexBuffer != null) {
_wglDeleteBuffers(meshStruct.indexBuffer);
meshStruct.indexBuffer = null;
}
meshStruct.vertexCount = 0;
meshStruct.indexCount = 0;
meshStruct.hasTexture = false;
logger.error("Failed to load eaglercraft high-poly mesh: \"{}\"", meshLoc);
logger.error(ex);
}finally {
if(up1 != null) {
EagRuntime.freeIntBuffer(up1);
}
}
}
@Override
public void onResourceManagerReload(IResourceManager var1) {
for(Entry<ResourceLocation, HighPolyMesh> meshEntry : meshCache.entrySet()) {
reloadMesh(meshEntry.getKey(), meshEntry.getValue(), var1);
}
}
}

View File

@ -23,7 +23,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*; import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
/** /**
* Copyright (c) 2022-2023 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 * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -152,7 +152,7 @@ public class EaglercraftGPU {
currentList = null; currentList = null;
} }
public static void glCallList(int displayList) { public static final void glCallList(int displayList) {
DisplayList dp = mapDisplayListsGL.get(displayList); DisplayList dp = mapDisplayListsGL.get(displayList);
if(dp == null) { if(dp == null) {
throw new NullPointerException("Tried to call a display list that does not exist: " + displayList); throw new NullPointerException("Tried to call a display list that does not exist: " + displayList);
@ -492,10 +492,20 @@ public class EaglercraftGPU {
return mapTexturesGL.get(tex); return mapTexturesGL.get(tex);
} }
public static final void drawHighPoly(HighPolyMesh mesh) {
if(mesh.vertexCount == 0 || mesh.indexCount == 0 || mesh.vertexArray == null) {
return;
}
FixedFunctionPipeline p = FixedFunctionPipeline.setupRenderDisplayList(mesh.getAttribBits()).update();
EaglercraftGPU.bindGLBufferArray(mesh.vertexArray);
p.drawElements(GL_TRIANGLES, mesh.indexCount, GL_UNSIGNED_SHORT, 0);
}
static boolean hasFramebufferHDR16FSupport = false; static boolean hasFramebufferHDR16FSupport = false;
static boolean hasFramebufferHDR32FSupport = false; static boolean hasFramebufferHDR32FSupport = false;
static boolean hasLinearHDR32FSupport = false;
public static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback) { public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback) {
createFramebufferHDR16FTexture(target, level, w, h, format, allow32bitFallback, null); createFramebufferHDR16FTexture(target, level, w, h, format, allow32bitFallback, null);
} }
@ -503,7 +513,7 @@ public class EaglercraftGPU {
createFramebufferHDR16FTexture(target, level, w, h, format, false, pixelData); createFramebufferHDR16FTexture(target, level, w, h, format, false, pixelData);
} }
private static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback, ByteBuffer pixelData) { private static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, boolean allow32bitFallback, ByteBuffer pixelData) {
if(hasFramebufferHDR16FSupport) { if(hasFramebufferHDR16FSupport) {
int internalFormat; int internalFormat;
switch(format) { switch(format) {
@ -534,15 +544,15 @@ public class EaglercraftGPU {
} }
} }
public static void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback) { public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback) {
createFramebufferHDR32FTexture(target, level, w, h, format, allow16bitFallback, null); createFramebufferHDR32FTexture(target, level, w, h, format, allow16bitFallback, null);
} }
public static void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) { public static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
createFramebufferHDR32FTexture(target, level, w, h, format, false, pixelData); createFramebufferHDR32FTexture(target, level, w, h, format, false, pixelData);
} }
private static void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback, ByteBuffer pixelData) { private static final void createFramebufferHDR32FTexture(int target, int level, int w, int h, int format, boolean allow16bitFallback, ByteBuffer pixelData) {
if(hasFramebufferHDR32FSupport) { if(hasFramebufferHDR32FSupport) {
int internalFormat; int internalFormat;
switch(format) { switch(format) {
@ -559,7 +569,7 @@ public class EaglercraftGPU {
default: default:
throw new UnsupportedOperationException("Unknown format: " + format); throw new UnsupportedOperationException("Unknown format: " + format);
} }
_wglTexImage2D(target, level, internalFormat, w, h, 0, format, GL_FLOAT, pixelData); _wglTexImage2Df32(target, level, internalFormat, w, h, 0, format, GL_FLOAT, pixelData);
}else { }else {
if(allow16bitFallback) { if(allow16bitFallback) {
if(hasFramebufferHDR16FSupport) { if(hasFramebufferHDR16FSupport) {
@ -589,7 +599,13 @@ public class EaglercraftGPU {
}else { }else {
logger.error("32-bit HDR render target support: false"); logger.error("32-bit HDR render target support: false");
} }
if(!checkHasHDRFramebufferSupport()) { hasLinearHDR32FSupport = PlatformOpenGL.checkLinearHDR32FSupport();
if(hasLinearHDR32FSupport) {
logger.info("32-bit HDR linear filter support: true");
}else {
logger.error("32-bit HDR linear filter support: false");
}
if(!checkHasHDRFramebufferSupportWithFilter()) {
logger.error("No HDR render target support was detected! Shaders will be disabled."); logger.error("No HDR render target support was detected! Shaders will be disabled.");
} }
DrawUtils.init(); DrawUtils.init();
@ -620,4 +636,12 @@ public class EaglercraftGPU {
public static int glGetTexLevelParameteri(int glTexture2d, int i, int glTextureWidth) { public static int glGetTexLevelParameteri(int glTexture2d, int i, int glTextureWidth) {
return PlatformOpenGL._wglGetTexLevelParameteri(glTexture2d, i, glTextureWidth); return PlatformOpenGL._wglGetTexLevelParameteri(glTexture2d, i, glTextureWidth);
} }
public static final boolean checkHasHDRFramebufferSupportWithFilter() {
return hasFramebufferHDR16FSupport || (hasFramebufferHDR32FSupport && hasLinearHDR32FSupport);
}
public static final boolean checkLinearHDR32FSupport() {
return hasLinearHDR32FSupport;
}
} }

View File

@ -0,0 +1,66 @@
package net.lax1dude.eaglercraft.v1_8.opengl;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferArrayGL;
import net.lax1dude.eaglercraft.v1_8.internal.IBufferGL;
import net.lax1dude.eaglercraft.v1_8.opengl.FixedFunctionShader.FixedFunctionState;
/**
* 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 HighPolyMesh {
IBufferArrayGL vertexArray;
IBufferGL vertexBuffer;
IBufferGL indexBuffer;
int vertexCount;
int indexCount;
boolean hasTexture;
public HighPolyMesh(IBufferArrayGL vertexArray, IBufferGL vertexBuffer, IBufferGL indexBuffer, int vertexCount,
int indexCount, boolean hasTexture) {
this.vertexArray = vertexArray;
this.vertexBuffer = vertexBuffer;
this.indexBuffer = indexBuffer;
this.vertexCount = vertexCount;
this.indexCount = indexCount;
this.hasTexture = hasTexture;
}
HighPolyMesh() {
}
public boolean isNull() {
return vertexArray == null;
}
public int getVertexCount() {
return vertexCount;
}
public int getIndexCount() {
return indexCount;
}
public boolean getHasTexture() {
return hasTexture;
}
public int getAttribBits() {
return hasTexture ? (FixedFunctionState.STATE_HAS_ATTRIB_TEXTURE | FixedFunctionState.STATE_HAS_ATTRIB_NORMAL) : FixedFunctionState.STATE_HAS_ATTRIB_NORMAL;
}
}

View File

@ -3984,11 +3984,11 @@ public class EaglerDeferredPipeline {
} }
public static final boolean isSupported() { public static final boolean isSupported() {
return EaglercraftGPU.checkHasHDRFramebufferSupport(); return EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter();
} }
public static final String getReasonUnsupported() { public static final String getReasonUnsupported() {
if(!EaglercraftGPU.checkHasHDRFramebufferSupport()) { if(!EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter()) {
return I18n.format("shaders.gui.unsupported.reason.hdrFramebuffer"); return I18n.format("shaders.gui.unsupported.reason.hdrFramebuffer");
}else { }else {
return null; return null;

View File

@ -0,0 +1,83 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
import net.minecraft.network.PacketBuffer;
/**
* 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 CapePackets {
public static final int PACKET_MY_CAPE_PRESET = 0x01;
public static final int PACKET_MY_CAPE_CUSTOM = 0x02;
public static final int PACKET_GET_OTHER_CAPE = 0x03;
public static final int PACKET_OTHER_CAPE_PRESET = 0x04;
public static final int PACKET_OTHER_CAPE_CUSTOM = 0x05;
public static void readPluginMessage(PacketBuffer buffer, ServerCapeCache capeCache) throws IOException {
try {
int type = (int)buffer.readByte() & 0xFF;
switch(type) {
case PACKET_OTHER_CAPE_PRESET: {
EaglercraftUUID responseUUID = buffer.readUuid();
int responsePreset = buffer.readInt();
if(buffer.isReadable()) {
throw new IOException("PACKET_OTHER_CAPE_PRESET had " + buffer.readableBytes() + " remaining bytes!");
}
capeCache.cacheCapePreset(responseUUID, responsePreset);
break;
}
case PACKET_OTHER_CAPE_CUSTOM: {
EaglercraftUUID responseUUID = buffer.readUuid();
byte[] readCape = new byte[1173];
buffer.readBytes(readCape);
if(buffer.isReadable()) {
throw new IOException("PACKET_OTHER_CAPE_CUSTOM had " + buffer.readableBytes() + " remaining bytes!");
}
capeCache.cacheCapeCustom(responseUUID, readCape);
break;
}
default:
throw new IOException("Unknown skin packet type: " + type);
}
}catch(IOException ex) {
throw ex;
}catch(Throwable t) {
throw new IOException("Failed to parse cape packet!", t);
}
}
public static byte[] writeMyCapePreset(int capeId) {
return new byte[] { (byte) PACKET_MY_CAPE_PRESET, (byte) (capeId >> 24), (byte) (capeId >> 16),
(byte) (capeId >> 8), (byte) (capeId & 0xFF) };
}
public static byte[] writeMyCapeCustom(CustomCape customCape) {
byte[] packet = new byte[1 + customCape.texture.length];
packet[0] = (byte) PACKET_MY_CAPE_CUSTOM;
System.arraycopy(customCape.texture, 0, packet, 1, customCape.texture.length);
return packet;
}
public static PacketBuffer writeGetOtherCape(EaglercraftUUID playerId) throws IOException {
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(17, 17));
ret.writeByte(PACKET_GET_OTHER_CAPE);
ret.writeUuid(playerId);
return ret;
}
}

View File

@ -0,0 +1,58 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
/**
* 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 CustomCape {
public final String name;
public final byte[] texture;
private EaglerSkinTexture textureInstance;
private ResourceLocation resourceLocation;
private static int texId = 0;
public CustomCape(String name, byte[] texture) {
this.name = name;
this.texture = texture;
byte[] texture2 = new byte[4096];
SkinConverter.convertCape23x17RGBto32x32RGBA(texture, texture2);
this.textureInstance = new EaglerSkinTexture(texture2, 32, 32);
this.resourceLocation = null;
}
public void load() {
if(resourceLocation == null) {
resourceLocation = new ResourceLocation("eagler:capes/custom/tex_" + texId++);
Minecraft.getMinecraft().getTextureManager().loadTexture(resourceLocation, textureInstance);
}
}
public ResourceLocation getResource() {
return resourceLocation;
}
public void delete() {
if(resourceLocation != null) {
Minecraft.getMinecraft().getTextureManager().deleteTexture(resourceLocation);
resourceLocation = null;
}
}
}

View File

@ -0,0 +1,75 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum DefaultCapes {
NO_CAPE(0, "No Cape", null),
MINECON_2011(1, "Minecon 2011", new ResourceLocation("eagler:capes/01.minecon_2011.png")),
MINECON_2012(2, "Minecon 2012", new ResourceLocation("eagler:capes/02.minecon_2012.png")),
MINECON_2013(3, "Minecon 2013", new ResourceLocation("eagler:capes/03.minecon_2013.png")),
MINECON_2015(4, "Minecon 2015", new ResourceLocation("eagler:capes/04.minecon_2015.png")),
MINECON_2016(5, "Minecon 2016", new ResourceLocation("eagler:capes/05.minecon_2016.png")),
MICROSOFT_ACCOUNT(6, "Microsoft Account", new ResourceLocation("eagler:capes/06.microsoft_account.png")),
MAPMAKER(7, "Realms Mapmaker", new ResourceLocation("eagler:capes/07.mapmaker.png")),
MOJANG_OLD(8, "Mojang Old", new ResourceLocation("eagler:capes/08.mojang_old.png")),
MOJANG_NEW(9, "Mojang New", new ResourceLocation("eagler:capes/09.mojang_new.png")),
JIRA_MOD(10, "Jira Moderator", new ResourceLocation("eagler:capes/10.jira_mod.png")),
MOJANG_VERY_OLD(11, "Mojang Very Old", new ResourceLocation("eagler:capes/11.mojang_very_old.png")),
SCROLLS(12, "Scrolls", new ResourceLocation("eagler:capes/12.scrolls.png")),
COBALT(13, "Cobalt", new ResourceLocation("eagler:capes/13.cobalt.png")),
TRANSLATOR(14, "Lang Translator", new ResourceLocation("eagler:capes/14.translator.png")),
MILLIONTH_ACCOUNT(15, "Millionth Player", new ResourceLocation("eagler:capes/15.millionth_account.png")),
PRISMARINE(16, "Prismarine", new ResourceLocation("eagler:capes/16.prismarine.png")),
SNOWMAN(17, "Snowman", new ResourceLocation("eagler:capes/17.snowman.png")),
SPADE(18, "Spade", new ResourceLocation("eagler:capes/18.spade.png")),
BIRTHDAY(19, "Birthday", new ResourceLocation("eagler:capes/19.birthday.png")),
DB(20, "dB", new ResourceLocation("eagler:capes/20.db.png"));
public static final DefaultCapes[] defaultCapesMap = new DefaultCapes[21];
public final int id;
public final String name;
public final ResourceLocation location;
private DefaultCapes(int id, String name, ResourceLocation location) {
this.id = id;
this.name = name;
this.location = location;
}
public static DefaultCapes getCapeFromId(int id) {
DefaultCapes e = null;
if(id >= 0 && id < defaultCapesMap.length) {
e = defaultCapesMap[id];
}
if(e != null) {
return e;
}else {
return NO_CAPE;
}
}
static {
DefaultCapes[] capes = values();
for(int i = 0; i < capes.length; ++i) {
defaultCapesMap[capes[i].id] = capes[i];
}
}
}

View File

@ -42,9 +42,14 @@ public enum DefaultSkins {
CREEPER(20, "Creeper", new ResourceLocation("eagler:skins/21.creeper.png"), SkinModel.STEVE), CREEPER(20, "Creeper", new ResourceLocation("eagler:skins/21.creeper.png"), SkinModel.STEVE),
ZOMBIE(21, "Zombie", new ResourceLocation("eagler:skins/22.zombie.png"), SkinModel.ZOMBIE), ZOMBIE(21, "Zombie", new ResourceLocation("eagler:skins/22.zombie.png"), SkinModel.ZOMBIE),
PIG(22, "Pig", new ResourceLocation("eagler:skins/23.pig.png"), SkinModel.STEVE), PIG(22, "Pig", new ResourceLocation("eagler:skins/23.pig.png"), SkinModel.STEVE),
MOOSHROOM(23, "Mooshroom", new ResourceLocation("eagler:skins/24.mooshroom.png"), SkinModel.STEVE); MOOSHROOM(23, "Mooshroom", new ResourceLocation("eagler:skins/24.mooshroom.png"), SkinModel.STEVE),
LONG_ARMS(24, "Long Arms", new ResourceLocation("eagler:mesh/longarms.fallback.png"), SkinModel.LONG_ARMS),
WEIRD_CLIMBER_DUDE(25, "Weird Climber Dude", new ResourceLocation("eagler:mesh/weirdclimber.fallback.png"), SkinModel.WEIRD_CLIMBER_DUDE),
LAXATIVE_DUDE(26, "Laxative Dude", new ResourceLocation("eagler:mesh/laxativedude.fallback.png"), SkinModel.LAXATIVE_DUDE),
BABY_CHARLES(27, "Baby Charles", new ResourceLocation("eagler:mesh/charles.fallback.png"), SkinModel.BABY_CHARLES),
BABY_WINSTON(28, "Baby Winston", new ResourceLocation("eagler:mesh/winston.fallback.png"), SkinModel.BABY_WINSTON);
public static final DefaultSkins[] defaultSkinsMap = new DefaultSkins[24]; public static final DefaultSkins[] defaultSkinsMap = new DefaultSkins[29];
public final int id; public final int id;
public final String name; public final String name;

View File

@ -16,7 +16,7 @@ import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
/** /**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved. * Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -37,7 +37,11 @@ public class EaglerProfile {
public static int presetSkinId; public static int presetSkinId;
public static int customSkinId; public static int customSkinId;
public static int presetCapeId;
public static int customCapeId;
public static final List<CustomSkin> customSkins = new ArrayList(); public static final List<CustomSkin> customSkins = new ArrayList();
public static final List<CustomCape> customCapes = new ArrayList();
public static final EaglercraftRandom rand; public static final EaglercraftRandom rand;
@ -79,6 +83,25 @@ public class EaglerProfile {
} }
} }
public static ResourceLocation getActiveCapeResourceLocation() {
if(presetCapeId == -1) {
if(customCapeId >= 0 && customCapeId < customCapes.size()) {
return customCapes.get(customCapeId).getResource();
}else {
customCapeId = -1;
presetCapeId = 0;
return DefaultCapes.defaultCapesMap[0].location;
}
}else {
if(presetCapeId >= 0 && presetCapeId < DefaultCapes.defaultCapesMap.length) {
return DefaultCapes.defaultCapesMap[presetCapeId].location;
}else {
presetCapeId = 0;
return DefaultCapes.defaultCapesMap[0].location;
}
}
}
public static EaglercraftUUID getPlayerUUID() { public static EaglercraftUUID getPlayerUUID() {
return Minecraft.getMinecraft().getSession().getProfile().getId(); return Minecraft.getMinecraft().getSession().getProfile().getId();
} }
@ -114,6 +137,25 @@ public class EaglerProfile {
} }
} }
public static byte[] getCapePacket() {
if(presetCapeId == -1) {
if(customCapeId >= 0 && customCapeId < customCapes.size()) {
return CapePackets.writeMyCapeCustom(customCapes.get(customCapeId));
}else {
customCapeId = -1;
presetCapeId = 0;
return CapePackets.writeMyCapePreset(0);
}
}else {
if(presetCapeId >= 0 && presetCapeId < DefaultCapes.defaultCapesMap.length) {
return CapePackets.writeMyCapePreset(presetCapeId);
}else {
presetCapeId = 0;
return CapePackets.writeMyCapePreset(0);
}
}
}
private static boolean doesSkinExist(String name) { private static boolean doesSkinExist(String name) {
for(int i = 0, l = customSkins.size(); i < l; ++i) { for(int i = 0, l = customSkins.size(); i < l; ++i) {
if(customSkins.get(i).name.equalsIgnoreCase(name)) { if(customSkins.get(i).name.equalsIgnoreCase(name)) {
@ -123,6 +165,15 @@ public class EaglerProfile {
return false; return false;
} }
private static boolean doesCapeExist(String name) {
for(int i = 0, l = customCapes.size(); i < l; ++i) {
if(customCapes.get(i).name.equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
public static int addCustomSkin(String fileName, byte[] rawSkin) { public static int addCustomSkin(String fileName, byte[] rawSkin) {
if(doesSkinExist(fileName)) { if(doesSkinExist(fileName)) {
String newName; String newName;
@ -139,6 +190,22 @@ public class EaglerProfile {
return r; return r;
} }
public static int addCustomCape(String fileName, byte[] rawCape23x17RGB) {
if(doesCapeExist(fileName)) {
String newName;
int i = 2;
while(doesCapeExist(newName = fileName + " (" + i + ")")) {
++i;
}
fileName = newName;
}
CustomCape newCape = new CustomCape(fileName, rawCape23x17RGB);
newCape.load();
int r = customCapes.size();
customCapes.add(newCape);
return r;
}
public static void clearCustomSkins() { public static void clearCustomSkins() {
for(int i = 0, l = customSkins.size(); i < l; ++i) { for(int i = 0, l = customSkins.size(); i < l; ++i) {
customSkins.get(i).delete(); customSkins.get(i).delete();
@ -146,6 +213,13 @@ public class EaglerProfile {
customSkins.clear(); customSkins.clear();
} }
public static void clearCustomCapes() {
for(int i = 0, l = customCapes.size(); i < l; ++i) {
customCapes.get(i).delete();
}
customCapes.clear();
}
public static void read() { public static void read() {
read(EagRuntime.getStorage("p")); read(EagRuntime.getStorage("p"));
} }
@ -169,6 +243,9 @@ public class EaglerProfile {
presetSkinId = profile.getInteger("presetSkin"); presetSkinId = profile.getInteger("presetSkin");
customSkinId = profile.getInteger("customSkin"); customSkinId = profile.getInteger("customSkin");
if(profile.hasKey("presetCape", 99)) presetCapeId = profile.getInteger("presetCape");
if(profile.hasKey("customCape", 99)) customCapeId = profile.getInteger("customCape");
String loadUsername = profile.getString("username").trim(); String loadUsername = profile.getString("username").trim();
if(!loadUsername.isEmpty()) { if(!loadUsername.isEmpty()) {
@ -194,6 +271,20 @@ public class EaglerProfile {
customSkins.add(newSkin); customSkins.add(newSkin);
} }
if(profile.hasKey("capes", 9)) {
clearCustomCapes();
NBTTagList capesList = profile.getTagList("capes", 10);
for(int i = 0, l = capesList.tagCount(); i < l; ++i) {
NBTTagCompound cape = capesList.getCompoundTagAt(i);
String capeName = cape.getString("name");
byte[] capeData = cape.getByteArray("data");
if(capeData.length != 1173) continue;
CustomCape newCape = new CustomCape(capeName, capeData);
newCape.load();
customCapes.add(newCape);
}
}
if(presetSkinId == -1) { if(presetSkinId == -1) {
if(customSkinId < 0 || customSkinId >= customSkins.size()) { if(customSkinId < 0 || customSkinId >= customSkins.size()) {
presetSkinId = 0; presetSkinId = 0;
@ -206,12 +297,26 @@ public class EaglerProfile {
} }
} }
if(presetCapeId == -1) {
if(customCapeId < 0 || customCapeId >= customCapes.size()) {
presetCapeId = 0;
customCapeId = -1;
}
}else {
customCapeId = -1;
if(presetCapeId < 0 || presetCapeId >= DefaultCapes.defaultCapesMap.length) {
presetCapeId = 0;
}
}
} }
public static byte[] write() { public static byte[] write() {
NBTTagCompound profile = new NBTTagCompound(); NBTTagCompound profile = new NBTTagCompound();
profile.setInteger("presetSkin", presetSkinId); profile.setInteger("presetSkin", presetSkinId);
profile.setInteger("customSkin", customSkinId); profile.setInteger("customSkin", customSkinId);
profile.setInteger("presetCape", presetCapeId);
profile.setInteger("customCape", customCapeId);
profile.setString("username", username); profile.setString("username", username);
NBTTagList skinsList = new NBTTagList(); NBTTagList skinsList = new NBTTagList();
for(int i = 0, l = customSkins.size(); i < l; ++i) { for(int i = 0, l = customSkins.size(); i < l; ++i) {
@ -223,6 +328,15 @@ public class EaglerProfile {
skinsList.appendTag(skin); skinsList.appendTag(skin);
} }
profile.setTag("skins", skinsList); profile.setTag("skins", skinsList);
NBTTagList capesList = new NBTTagList();
for(int i = 0, l = customCapes.size(); i < l; ++i) {
CustomCape cp = customCapes.get(i);
NBTTagCompound cape = new NBTTagCompound();
cape.setString("name", cp.name);
cape.setByteArray("data", cp.texture);
capesList.appendTag(cape);
}
profile.setTag("capes", capesList);
EaglerOutputStream bao = new EaglerOutputStream(); EaglerOutputStream bao = new EaglerOutputStream();
try { try {
CompressedStreamTools.writeCompressed(profile, bao); CompressedStreamTools.writeCompressed(profile, bao);
@ -253,9 +367,14 @@ public class EaglerProfile {
setName(username); setName(username);
do {
presetSkinId = rand.nextInt(DefaultSkins.defaultSkinsMap.length); presetSkinId = rand.nextInt(DefaultSkins.defaultSkinsMap.length);
}while(DefaultSkins.defaultSkinsMap[presetSkinId].model.highPoly != null);
customSkinId = -1; customSkinId = -1;
presetCapeId = 0;
customCapeId = -1;
} }
} }

View File

@ -0,0 +1,359 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.Keyboard;
import net.lax1dude.eaglercraft.v1_8.Mouse;
import net.lax1dude.eaglercraft.v1_8.internal.EnumCursorType;
import net.lax1dude.eaglercraft.v1_8.internal.FileChooserResult;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import java.io.IOException;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class GuiScreenEditCape extends GuiScreen {
private final GuiScreenEditProfile parent;
private boolean dropDownOpen = false;
private String[] dropDownOptions;
private int slotsVisible = 0;
protected int selectedSlot = 0;
private int scrollPos = -1;
private int skinsHeight = 0;
private boolean dragging = false;
private int mousex = 0;
private int mousey = 0;
private static final ResourceLocation eaglerGui = new ResourceLocation("eagler:gui/eagler_gui.png");
protected String screenTitle = "Edit Cape";
public GuiScreenEditCape(GuiScreenEditProfile parent) {
this.parent = parent;
updateOptions();
}
public void initGui() {
Keyboard.enableRepeatEvents(true);
screenTitle = I18n.format("editCape.title");
selectedSlot = EaglerProfile.presetCapeId == -1 ? EaglerProfile.customCapeId : (EaglerProfile.presetCapeId + EaglerProfile.customCapes.size());
buttonList.add(new GuiButton(0, width / 2 - 100, height / 6 + 168, I18n.format("gui.done")));
buttonList.add(new GuiButton(1, width / 2 - 21, height / 6 + 80, 71, 20, I18n.format("editCape.addCape")));
buttonList.add(new GuiButton(2, width / 2 - 21 + 71, height / 6 + 80, 72, 20, I18n.format("editCape.clearCape")));
}
private void updateOptions() {
int numCustom = EaglerProfile.customCapes.size();
String[] n = new String[numCustom + DefaultCapes.defaultCapesMap.length];
for(int i = 0; i < numCustom; ++i) {
n[i] = EaglerProfile.customCapes.get(i).name;
}
int numDefault = DefaultCapes.defaultCapesMap.length;
for(int j = 0; j < numDefault; ++j) {
n[numCustom + j] = DefaultCapes.defaultCapesMap[j].name;
}
dropDownOptions = n;
}
public void drawScreen(int mx, int my, float partialTicks) {
drawDefaultBackground();
drawCenteredString(fontRendererObj, screenTitle, width / 2, 15, 16777215);
drawString(fontRendererObj, I18n.format("editCape.playerCape"), width / 2 - 20, height / 6 + 36, 10526880);
mousex = mx;
mousey = my;
int skinX = width / 2 - 120;
int skinY = height / 6 + 8;
int skinWidth = 80;
int skinHeight = 130;
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xFFA0A0A0);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xFF000015);
int skid = selectedSlot - EaglerProfile.customCapes.size();
if(skid < 0) {
skid = 0;
}
if(dropDownOpen) {
super.drawScreen(0, 0, partialTicks);
}else {
super.drawScreen(mx, my, partialTicks);
}
int numberOfCustomSkins = EaglerProfile.customSkins.size();
int numberOfCustomCapes = EaglerProfile.customCapes.size();
ResourceLocation skinTexture;
SkinModel model;
if(parent.selectedSlot < numberOfCustomSkins) {
CustomSkin customSkin = EaglerProfile.customSkins.get(parent.selectedSlot);
skinTexture = customSkin.getResource();
model = customSkin.model;
}else {
DefaultSkins defaultSkin = DefaultSkins.getSkinFromId(parent.selectedSlot - numberOfCustomSkins);
skinTexture = defaultSkin.location;
model = defaultSkin.model;
}
if(model.highPoly != null) {
drawCenteredString(fontRendererObj, I18n.format(this.mc.gameSettings.enableFNAWSkins ? "editProfile.disableFNAW" : "editProfile.enableFNAW"), width / 2, height / 6 + 150, 10526880);
}
skinX = width / 2 - 20;
skinY = height / 6 + 52;
skinWidth = 140;
skinHeight = 22;
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 21, skinY + skinHeight - 1, -16777216);
drawRect(skinX + skinWidth - 20, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
mc.getTextureManager().bindTexture(eaglerGui);
drawTexturedModalRect(skinX + skinWidth - 18, skinY + 3, 0, 0, 16, 16);
drawString(fontRendererObj, dropDownOptions[selectedSlot], skinX + 5, skinY + 7, 14737632);
skinX = width / 2 - 20;
skinY = height / 6 + 73;
skinWidth = 140;
skinHeight = (height - skinY - 10);
slotsVisible = (skinHeight / 10);
if(slotsVisible > dropDownOptions.length) slotsVisible = dropDownOptions.length;
skinHeight = slotsVisible * 10 + 7;
skinsHeight = skinHeight;
if(scrollPos == -1) {
scrollPos = selectedSlot - 2;
}
if(scrollPos > (dropDownOptions.length - slotsVisible)) {
scrollPos = (dropDownOptions.length - slotsVisible);
}
if(scrollPos < 0) {
scrollPos = 0;
}
if(dropDownOpen) {
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216);
for(int i = 0; i < slotsVisible; i++) {
if(i + scrollPos < dropDownOptions.length) {
if(selectedSlot == i + scrollPos) {
drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x77ffffff);
}else if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i*10 + 5) && my < (skinY + i*10 + 15)) {
drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x55ffffff);
}
drawString(fontRendererObj, dropDownOptions[i + scrollPos], skinX + 5, skinY + 5 + i*10, 14737632);
}
}
int scrollerSize = skinHeight * slotsVisible / dropDownOptions.length;
int scrollerPos = skinHeight * scrollPos / dropDownOptions.length;
drawRect(skinX + skinWidth - 4, skinY + scrollerPos + 1, skinX + skinWidth - 1, skinY + scrollerPos + scrollerSize, 0xff888888);
}
if(!EagRuntime.getConfiguration().isDemo()) {
GlStateManager.pushMatrix();
GlStateManager.scale(0.75f, 0.75f, 0.75f);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
String text = I18n.format("editProfile.importExport");
int w = mc.fontRendererObj.getStringWidth(text);
boolean hover = mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12;
if(hover) {
Mouse.showCursor(EnumCursorType.HAND);
}
drawString(mc.fontRendererObj, EnumChatFormatting.UNDERLINE + text, 5, 5, hover ? 0xFFEEEE22 : 0xFFCCCCCC);
GlStateManager.popMatrix();
}
int xx = width / 2 - 80;
int yy = height / 6 + 130;
skinX = this.width / 2 - 120;
skinY = this.height / 6 + 8;
skinWidth = 80;
skinHeight = 130;
ResourceLocation capeTexture;
if(selectedSlot < numberOfCustomCapes) {
capeTexture = EaglerProfile.customCapes.get(selectedSlot).getResource();
}else {
capeTexture = DefaultCapes.getCapeFromId(selectedSlot - numberOfCustomCapes).location;
}
SkinPreviewRenderer.renderPreview(xx, yy, mx, my, true, model, skinTexture, capeTexture);
}
public void handleMouseInput() throws IOException {
super.handleMouseInput();
if(dropDownOpen) {
int var1 = Mouse.getEventDWheel();
if(var1 < 0) {
scrollPos += 3;
}
if(var1 > 0) {
scrollPos -= 3;
if(scrollPos < 0) {
scrollPos = 0;
}
}
}
}
protected void actionPerformed(GuiButton par1GuiButton) {
if(!dropDownOpen) {
if(par1GuiButton.id == 0) {
safeProfile();
this.mc.displayGuiScreen((GuiScreen) parent);
}else if(par1GuiButton.id == 1) {
EagRuntime.displayFileChooser("image/png", "png");
}else if(par1GuiButton.id == 2) {
EaglerProfile.clearCustomCapes();
safeProfile();
updateOptions();
selectedSlot = 0;
}
}
}
public void updateScreen() {
if(EagRuntime.fileChooserHasResult()) {
FileChooserResult result = EagRuntime.getFileChooserResult();
if(result != null) {
ImageData loadedCape = ImageData.loadImageFile(result.fileData);
if(loadedCape != null) {
if((loadedCape.width == 32 || loadedCape.width == 64) && loadedCape.height == 32) {
byte[] resized = new byte[1173];
SkinConverter.convertCape32x32RGBAto23x17RGB(loadedCape, resized);
int k;
if((k = EaglerProfile.addCustomCape(result.fileName, resized)) != -1) {
selectedSlot = k;
updateOptions();
safeProfile();
}
}else {
EagRuntime.showPopup("The selected image '" + result.fileName + "' is not the right size!\nEaglercraft only supports 32x32 or 64x32 capes");
}
}else {
EagRuntime.showPopup("The selected file '" + result.fileName + "' is not a PNG file!");
}
}
}
if(dropDownOpen) {
if(Mouse.isButtonDown(0)) {
int skinX = width / 2 - 20;
int skinY = height / 6 + 73;
int skinWidth = 140;
if(mousex >= (skinX + skinWidth - 10) && mousex < (skinX + skinWidth) && mousey >= skinY && mousey < (skinY + skinsHeight)) {
dragging = true;
}
if(dragging) {
int scrollerSize = skinsHeight * slotsVisible / dropDownOptions.length;
scrollPos = (mousey - skinY - (scrollerSize / 2)) * dropDownOptions.length / skinsHeight;
}
}else {
dragging = false;
}
}else {
dragging = false;
}
}
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
}
protected void keyTyped(char c, int k) {
if(k == 200 && selectedSlot > 0) {
--selectedSlot;
scrollPos = selectedSlot - 2;
}
if(k == 208 && selectedSlot < (dropDownOptions.length - 1)) {
++selectedSlot;
scrollPos = selectedSlot - 2;
}
}
protected void mouseClicked(int mx, int my, int button) {
if (button == 0) {
if(!EagRuntime.getConfiguration().isDemo()) {
int w = mc.fontRendererObj.getStringWidth(I18n.format("editProfile.importExport"));
if(mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12) {
safeProfile();
mc.displayGuiScreen(new GuiScreenImportExportProfile(parent));
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
return;
}
}
int skinX = width / 2 + 140 - 40;
int skinY = height / 6 + 52;
if(mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) {
dropDownOpen = !dropDownOpen;
return;
}
skinX = width / 2 - 20;
skinY = height / 6 + 52;
int skinWidth = 140;
int skinHeight = skinsHeight;
if(!(mx >= skinX && mx < (skinX + skinWidth) && my >= skinY && my < (skinY + skinHeight + 22))) {
dragging = false;
if(dropDownOpen) {
dropDownOpen = false;
return;
}
}else if(dropDownOpen && !dragging) {
skinY += 21;
for(int i = 0; i < slotsVisible; i++) {
if(i + scrollPos < dropDownOptions.length) {
if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5) && my < (skinY + i * 10 + 15) && selectedSlot != i + scrollPos) {
selectedSlot = i + scrollPos;
dropDownOpen = false;
dragging = false;
return;
}
}
}
}
}
super.mouseClicked(mx, my, button);
}
protected void safeProfile() {
int customLen = EaglerProfile.customCapes.size();
if(selectedSlot < customLen) {
EaglerProfile.presetCapeId = -1;
EaglerProfile.customCapeId = selectedSlot;
}else {
EaglerProfile.presetCapeId = selectedSlot - customLen;
EaglerProfile.customCapeId = -1;
}
}
}

View File

@ -20,7 +20,7 @@ import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.io.IOException; import java.io.IOException;
/** /**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved. * Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -42,7 +42,7 @@ public class GuiScreenEditProfile extends GuiScreen {
private boolean dropDownOpen = false; private boolean dropDownOpen = false;
private String[] dropDownOptions; private String[] dropDownOptions;
private int slotsVisible = 0; private int slotsVisible = 0;
private int selectedSlot = 0; protected int selectedSlot = 0;
private int scrollPos = -1; private int scrollPos = -1;
private int skinsHeight = 0; private int skinsHeight = 0;
private boolean dragging = false; private boolean dragging = false;
@ -102,10 +102,24 @@ public class GuiScreenEditProfile extends GuiScreen {
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xFFA0A0A0); drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xFFA0A0A0);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xFF000015); drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xFF000015);
int skid = selectedSlot - EaglerProfile.customSkins.size(); GlStateManager.pushMatrix();
if(skid < 0) { GlStateManager.translate(skinX + 2, skinY - 9, 0.0f);
skid = 0; GlStateManager.scale(0.75f, 0.75f, 0.75f);
int numberOfCustomSkins = EaglerProfile.customSkins.size();
int skid = selectedSlot - numberOfCustomSkins;
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model : DefaultSkins.getSkinFromId(skid).model;
if(selectedSkinModel == SkinModel.STEVE || selectedSkinModel == SkinModel.ALEX || (selectedSkinModel.highPoly != null && !this.mc.gameSettings.enableFNAWSkins)) {
String capesText = I18n.format("editProfile.capes");
int color = 10526880;
if(mx > skinX - 10 && my > skinY - 16 && mx < skinX + (fontRendererObj.getStringWidth(capesText) * 0.75f) + 10 && my < skinY + 7) {
color = 0xFFCCCC44;
Mouse.showCursor(EnumCursorType.HAND);
} }
this.drawString(this.fontRendererObj, EnumChatFormatting.UNDERLINE + capesText, 0, 0, color);
}
GlStateManager.popMatrix();
usernameField.drawTextBox(); usernameField.drawTextBox();
if(dropDownOpen || newSkinWaitSteveOrAlex) { if(dropDownOpen || newSkinWaitSteveOrAlex) {
@ -114,6 +128,10 @@ public class GuiScreenEditProfile extends GuiScreen {
super.drawScreen(mx, my, partialTicks); super.drawScreen(mx, my, partialTicks);
} }
if(selectedSkinModel.highPoly != null) {
drawCenteredString(fontRendererObj, I18n.format(this.mc.gameSettings.enableFNAWSkins ? "editProfile.disableFNAW" : "editProfile.enableFNAW"), width / 2, height / 6 + 150, 10526880);
}
skinX = width / 2 - 20; skinX = width / 2 - 20;
skinY = height / 6 + 82; skinY = height / 6 + 82;
skinWidth = 140; skinWidth = 140;
@ -184,7 +202,6 @@ public class GuiScreenEditProfile extends GuiScreen {
int xx = width / 2 - 80; int xx = width / 2 - 80;
int yy = height / 6 + 130; int yy = height / 6 + 130;
int numberOfCustomSkins = EaglerProfile.customSkins.size();
if(newSkinWaitSteveOrAlex && selectedSlot < numberOfCustomSkins) { if(newSkinWaitSteveOrAlex && selectedSlot < numberOfCustomSkins) {
skinWidth = 70; skinWidth = 70;
@ -217,8 +234,8 @@ public class GuiScreenEditProfile extends GuiScreen {
drawCenteredString(fontRendererObj, "Steve", skinX + skinWidth / 2, skinY + skinHeight + 6, cc); drawCenteredString(fontRendererObj, "Steve", skinX + skinWidth / 2, skinY + skinHeight + 6, cc);
} }
mc.getTextureManager().bindTexture(newSkin.getResource()); SkinPreviewRenderer.renderPreview(xx, yy, mx, my, false, SkinModel.STEVE, newSkin.getResource(),
SkinPreviewRenderer.renderBiped(xx, yy, mx, my, SkinModel.STEVE); EaglerProfile.getActiveCapeResourceLocation());
skinX = width / 2 + 20; skinX = width / 2 + 20;
skinY = height / 4; skinY = height / 4;
@ -242,8 +259,8 @@ public class GuiScreenEditProfile extends GuiScreen {
drawCenteredString(fontRendererObj, "Alex", skinX + skinWidth / 2, skinY + skinHeight + 8, cc); drawCenteredString(fontRendererObj, "Alex", skinX + skinWidth / 2, skinY + skinHeight + 8, cc);
} }
mc.getTextureManager().bindTexture(newSkin.getResource()); SkinPreviewRenderer.renderPreview(xx, yy, mx, my, false, SkinModel.ALEX, newSkin.getResource(),
SkinPreviewRenderer.renderBiped(xx, yy, mx, my, SkinModel.ALEX); EaglerProfile.getActiveCapeResourceLocation());
}else { }else {
skinX = this.width / 2 - 120; skinX = this.width / 2 - 120;
skinY = this.height / 6 + 8; skinY = this.height / 6 + 8;
@ -251,19 +268,15 @@ public class GuiScreenEditProfile extends GuiScreen {
skinHeight = 130; skinHeight = 130;
ResourceLocation texture; ResourceLocation texture;
SkinModel model; if(skid < 0) {
if(selectedSlot < numberOfCustomSkins) { texture = EaglerProfile.customSkins.get(selectedSlot).getResource();
CustomSkin customSkin = EaglerProfile.customSkins.get(selectedSlot);
texture = customSkin.getResource();
model = customSkin.model;
}else { }else {
DefaultSkins defaultSkin = DefaultSkins.defaultSkinsMap[selectedSlot - numberOfCustomSkins]; texture = DefaultSkins.getSkinFromId(skid).location;
texture = defaultSkin.location;
model = defaultSkin.model;
} }
mc.getTextureManager().bindTexture(texture); SkinPreviewRenderer.renderPreview(xx, yy, newSkinWaitSteveOrAlex ? width / 2 : mx,
SkinPreviewRenderer.renderBiped(xx, yy, newSkinWaitSteveOrAlex ? width / 2 : mx, newSkinWaitSteveOrAlex ? height / 2 : my, model); newSkinWaitSteveOrAlex ? height / 2 : my, false, selectedSkinModel, texture,
EaglerProfile.getActiveCapeResourceLocation());
} }
} }
@ -293,6 +306,7 @@ public class GuiScreenEditProfile extends GuiScreen {
}else if(par1GuiButton.id == 2) { }else if(par1GuiButton.id == 2) {
EaglerProfile.clearCustomSkins(); EaglerProfile.clearCustomSkins();
safeProfile(); safeProfile();
EaglerProfile.save();
updateOptions(); updateOptions();
selectedSlot = 0; selectedSlot = 0;
} }
@ -335,6 +349,7 @@ public class GuiScreenEditProfile extends GuiScreen {
newSkinWaitSteveOrAlex = true; newSkinWaitSteveOrAlex = true;
updateOptions(); updateOptions();
safeProfile(); safeProfile();
EaglerProfile.save();
} }
}else { }else {
EagRuntime.showPopup("The selected image '" + result.fileName + "' is not the right size!\nEaglercraft only supports 64x32 or 64x64 skins"); EagRuntime.showPopup("The selected image '" + result.fileName + "' is not the right size!\nEaglercraft only supports 64x32 or 64x64 skins");
@ -387,21 +402,37 @@ public class GuiScreenEditProfile extends GuiScreen {
} }
protected void mouseClicked(int mx, int my, int button) { protected void mouseClicked(int mx, int my, int button) {
super.mouseClicked(mx, my, button);
usernameField.mouseClicked(mx, my, button); usernameField.mouseClicked(mx, my, button);
if (button == 0) { if (button == 0) {
if(!EagRuntime.getConfiguration().isDemo()) { if(!EagRuntime.getConfiguration().isDemo()) {
int w = mc.fontRendererObj.getStringWidth(I18n.format("editProfile.importExport")); int w = mc.fontRendererObj.getStringWidth(I18n.format("editProfile.importExport"));
if(mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12) { if(mx > 1 && my > 1 && mx < (w * 3 / 4) + 7 && my < 12) {
safeProfile();
EaglerProfile.save();
mc.displayGuiScreen(new GuiScreenImportExportProfile(this)); mc.displayGuiScreen(new GuiScreenImportExportProfile(this));
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
return; return;
} }
} }
int skinX, skinY;
int skid = selectedSlot - EaglerProfile.customSkins.size();
SkinModel selectedSkinModel = skid < 0 ? EaglerProfile.customSkins.get(selectedSlot).model : DefaultSkins.getSkinFromId(skid).model;
if(selectedSkinModel == SkinModel.STEVE || selectedSkinModel == SkinModel.ALEX || (selectedSkinModel.highPoly != null && !this.mc.gameSettings.enableFNAWSkins)) {
skinX = this.width / 2 - 120;
skinY = this.height / 6 + 8;
String capesText = I18n.format("editProfile.capes");
if(mx > skinX - 10 && my > skinY - 16 && mx < skinX + (fontRendererObj.getStringWidth(capesText) * 0.75f) + 10 && my < skinY + 7) {
safeProfile();
this.mc.displayGuiScreen(new GuiScreenEditCape(this));
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
return;
}
}
if(newSkinWaitSteveOrAlex) { if(newSkinWaitSteveOrAlex) {
int skinX = width / 2 - 90; skinX = width / 2 - 90;
int skinY = height / 4; skinY = height / 4;
int skinWidth = 70; int skinWidth = 70;
int skinHeight = 120; int skinHeight = 120;
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) { if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
@ -423,8 +454,8 @@ public class GuiScreenEditProfile extends GuiScreen {
} }
return; return;
}else if(selectedSlot < EaglerProfile.customSkins.size()) { }else if(selectedSlot < EaglerProfile.customSkins.size()) {
int skinX = width / 2 - 120; skinX = width / 2 - 120;
int skinY = height / 6 + 18; skinY = height / 6 + 18;
int skinWidth = 80; int skinWidth = 80;
int skinHeight = 120; int skinHeight = 120;
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) { if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
@ -434,8 +465,8 @@ public class GuiScreenEditProfile extends GuiScreen {
} }
} }
} }
int skinX = width / 2 + 140 - 40; skinX = width / 2 + 140 - 40;
int skinY = height / 6 + 82; skinY = height / 6 + 82;
if(mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) { if(mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) {
dropDownOpen = !dropDownOpen; dropDownOpen = !dropDownOpen;
@ -448,27 +479,26 @@ public class GuiScreenEditProfile extends GuiScreen {
int skinHeight = skinsHeight; int skinHeight = skinsHeight;
if(!(mx >= skinX && mx < (skinX + skinWidth) && my >= skinY && my < (skinY + skinHeight + 22))) { if(!(mx >= skinX && mx < (skinX + skinWidth) && my >= skinY && my < (skinY + skinHeight + 22))) {
dragging = false;
if(dropDownOpen) {
dropDownOpen = false;
return;
}
}else if(dropDownOpen && !dragging) {
skinY += 21;
for(int i = 0; i < slotsVisible; i++) {
if(i + scrollPos < dropDownOptions.length) {
if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5) && my < (skinY + i * 10 + 15)) {
selectedSlot = i + scrollPos;
dropDownOpen = false; dropDownOpen = false;
dragging = false; dragging = false;
return; return;
} }
skinY += 21;
if(dropDownOpen && !dragging) {
for(int i = 0; i < slotsVisible; i++) {
if(i + scrollPos < dropDownOptions.length) {
if(selectedSlot != i + scrollPos) {
if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5) && my < (skinY + i * 10 + 15) && selectedSlot != i + scrollPos) {
selectedSlot = i + scrollPos;
dropDownOpen = false;
dragging = false;
}
}
} }
} }
} }
} }
super.mouseClicked(mx, my, button);
} }
protected void safeProfile() { protected void safeProfile() {

View File

@ -0,0 +1,113 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum HighPolySkin {
LONG_ARMS(
new ResourceLocation("eagler:mesh/longarms.png"),
new ResourceLocation("eagler:mesh/longarms0.mdl"),
null,
new ResourceLocation("eagler:mesh/longarms2.mdl"),
new ResourceLocation[] {
new ResourceLocation("eagler:mesh/longarms1.mdl")
},
new float[] {
1.325f
},
0.0f,
new ResourceLocation("eagler:mesh/longarms.fallback.png")
),
WEIRD_CLIMBER_DUDE(
new ResourceLocation("eagler:mesh/weirdclimber.png"),
new ResourceLocation("eagler:mesh/weirdclimber0.mdl"),
null,
new ResourceLocation("eagler:mesh/weirdclimber2.mdl"),
new ResourceLocation[] {
new ResourceLocation("eagler:mesh/weirdclimber1.mdl")
},
new float[] {
2.62f
},
-90.0f,
new ResourceLocation("eagler:mesh/weirdclimber.fallback.png")
),
LAXATIVE_DUDE(
new ResourceLocation("eagler:mesh/laxativedude.png"),
new ResourceLocation("eagler:mesh/laxativedude0.mdl"),
null,
new ResourceLocation("eagler:mesh/laxativedude3.mdl"),
new ResourceLocation[] {
new ResourceLocation("eagler:mesh/laxativedude1.mdl"),
new ResourceLocation("eagler:mesh/laxativedude2.mdl")
},
new float[] {
2.04f
},
0.0f,
new ResourceLocation("eagler:mesh/laxativedude.fallback.png")
),
BABY_CHARLES(
new ResourceLocation("eagler:mesh/charles.png"),
new ResourceLocation("eagler:mesh/charles0.mdl"),
new ResourceLocation("eagler:mesh/charles1.mdl"),
new ResourceLocation("eagler:mesh/charles2.mdl"),
new ResourceLocation[] {},
new float[] {},
0.0f,
new ResourceLocation("eagler:mesh/charles.fallback.png")
),
BABY_WINSTON(
new ResourceLocation("eagler:mesh/winston.png"),
new ResourceLocation("eagler:mesh/winston0.mdl"),
null,
new ResourceLocation("eagler:mesh/winston1.mdl"),
new ResourceLocation[] {},
new float[] {},
0.0f,
new ResourceLocation("eagler:mesh/winston.fallback.png")
);
public static float highPolyScale = 0.5f;
public final ResourceLocation texture;
public final ResourceLocation bodyModel;
public final ResourceLocation headModel;
public final ResourceLocation eyesModel;
public final ResourceLocation[] limbsModel;
public final float[] limbsOffset;
public final float limbsInitialRotation;
public final ResourceLocation fallbackTexture;
HighPolySkin(ResourceLocation texture, ResourceLocation bodyModel, ResourceLocation headModel, ResourceLocation eyesModel,
ResourceLocation[] limbsModel, float[] limbsOffset, float limbsInitialRotation, ResourceLocation fallbackTexture) {
this.texture = texture;
this.bodyModel = bodyModel;
this.headModel = headModel;
this.eyesModel = eyesModel;
this.limbsModel = limbsModel;
this.limbsOffset = limbsOffset;
this.limbsInitialRotation = limbsInitialRotation;
this.fallbackTexture = fallbackTexture;
}
}

View File

@ -0,0 +1,471 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglerMeshLoader;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.OpenGlHelper;
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DeferredStateManager;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class RenderHighPoly extends RenderPlayer {
private static final Logger logger = LogManager.getLogger("RenderHighPoly");
public RenderHighPoly(RenderManager renderManager, ModelBase fallbackModel, float fallbackScale) {
super(renderManager, fallbackModel, fallbackScale);
}
private static final Matrix4f tmpMatrix = new Matrix4f();
public void doRender(AbstractClientPlayer abstractclientplayer, double d0, double d1, double d2, float f,
float f1) {
if (!abstractclientplayer.isUser() || this.renderManager.livingPlayer == abstractclientplayer) {
double nameY = d1;
HighPolySkin highPolySkin = abstractclientplayer.getEaglerSkinModel().highPoly;
if(highPolySkin == null) {
super.doRender(abstractclientplayer, d0, d1, d2, f, f1);
return;
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
nameY += 0.1;
}else if(highPolySkin == HighPolySkin.BABY_WINSTON) {
nameY -= 1.0;
}
GlStateManager.pushMatrix();
GlStateManager.disableCull();
try {
Minecraft mc = Minecraft.getMinecraft();
float f2 = this.interpolateRotation(abstractclientplayer.prevRenderYawOffset, abstractclientplayer.renderYawOffset,
f1);
float f3 = this.interpolateRotation(abstractclientplayer.prevRotationYawHead, abstractclientplayer.rotationYawHead,
f1);
float f4 = f3 - f2;
if (abstractclientplayer.isRiding() && abstractclientplayer.ridingEntity instanceof EntityLivingBase) {
EntityLivingBase entitylivingbase1 = (EntityLivingBase) abstractclientplayer.ridingEntity;
f2 = this.interpolateRotation(entitylivingbase1.prevRenderYawOffset, entitylivingbase1.renderYawOffset,
f1);
f4 = f3 - f2;
float f5 = MathHelper.wrapAngleTo180_float(f4);
if (f5 < -85.0F) {
f5 = -85.0F;
}
if (f5 >= 85.0F) {
f5 = 85.0F;
}
f2 = f3 - f5;
if (f5 * f5 > 2500.0F) {
f2 += f5 * 0.2F;
}
}
this.renderLivingAt(abstractclientplayer, d0, d1, d2);
float f10 = this.handleRotationFloat(abstractclientplayer, f1);
this.rotateCorpse(abstractclientplayer, f10, f2, f1);
GlStateManager.enableRescaleNormal();
this.preRenderCallback(abstractclientplayer, f1);
float f6 = 0.0625F;
GlStateManager.scale(HighPolySkin.highPolyScale, HighPolySkin.highPolyScale, HighPolySkin.highPolyScale);
mc.getTextureManager().bindTexture(highPolySkin.texture);
if(abstractclientplayer.isPlayerSleeping()) {
if(highPolySkin == HighPolySkin.LAXATIVE_DUDE || highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
GlStateManager.translate(0.0f, -3.7f, 0.0f);
}else if(highPolySkin == HighPolySkin.BABY_WINSTON) {
GlStateManager.translate(0.0f, -2.4f, 0.0f);
}else {
GlStateManager.translate(0.0f, -3.0f, 0.0f);
}
}
float var15 = abstractclientplayer.prevLimbSwingAmount + (abstractclientplayer.limbSwingAmount - abstractclientplayer.prevLimbSwingAmount) * f1;
float var16 = abstractclientplayer.limbSwing - abstractclientplayer.limbSwingAmount * (1.0F - f1);
if(highPolySkin == HighPolySkin.LONG_ARMS) {
GlStateManager.rotate(MathHelper.sin(var16) * 20f * var15, 0.0f, 1.0f, 0.0f);
GlStateManager.rotate(MathHelper.cos(var16) * 7f * var15, 0.0f, 0.0f, 1.0f);
}else if(highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
GlStateManager.rotate(MathHelper.sin(var16) * 7f * var15, 0.0f, 1.0f, 0.0f);
GlStateManager.rotate(MathHelper.cos(var16) * 3f * var15, 0.0f, 0.0f, 1.0f);
GlStateManager.rotate(-f3, 0.0f, 1.0f, 0.0f);
float xd = (float)(abstractclientplayer.posX - abstractclientplayer.prevPosX);
GlStateManager.rotate(xd * 70.0f * var15, 0.0f, 0.0f, 1.0f);
float zd = (float)(abstractclientplayer.posZ - abstractclientplayer.prevPosZ);
GlStateManager.rotate(zd * 70.0f * var15, 1.0f, 0.0f, 0.0f);
GlStateManager.rotate(f3, 0.0f, 1.0f, 0.0f);
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
GlStateManager.rotate(-f3, 0.0f, 1.0f, 0.0f);
float xd = (float)(abstractclientplayer.posX - abstractclientplayer.prevPosX);
GlStateManager.rotate(-xd * 40.0f * var15, 0.0f, 0.0f, 1.0f);
float zd = (float)(abstractclientplayer.posZ - abstractclientplayer.prevPosZ);
GlStateManager.rotate(-zd * 40.0f * var15, 1.0f, 0.0f, 0.0f);
GlStateManager.rotate(f3, 0.0f, 1.0f, 0.0f);
}else if(highPolySkin == HighPolySkin.BABY_WINSTON) {
GlStateManager.translate(0.0f, (MathHelper.cos(f10 % 100000.0f) + 1.0f) * var15 * 0.2f, 0.0f);
GlStateManager.rotate(MathHelper.sin(var16) * 5f * var15, 0.0f, 1.0f, 0.0f);
GlStateManager.rotate(MathHelper.cos(var16) * 5f * var15, 0.0f, 0.0f, 1.0f);
}
if (abstractclientplayer.hurtTime > 0 || abstractclientplayer.deathTime > 0) {
GlStateManager.color(1.2f, 0.8F, 0.8F, 1.0F);
}
if(DeferredStateManager.isInDeferredPass()) {
DeferredStateManager.setDefaultMaterialConstants();
DeferredStateManager.setRoughnessConstant(0.5f);
DeferredStateManager.setMetalnessConstant(0.05f);
}
if(highPolySkin.bodyModel != null) {
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.bodyModel));
}
float jumpFactor = 0.0f;
if(highPolySkin.headModel != null) {
if(highPolySkin == HighPolySkin.BABY_CHARLES) {
long millis = System.currentTimeMillis();
float partialTicks = (float) ((millis - abstractclientplayer.eaglerHighPolyAnimationTick) * 0.02);
//long l50 = millis / 50l * 50l;
//boolean runTick = par1EntityPlayer.eaglerHighPolyAnimationTick < l50 && millis >= l50;
abstractclientplayer.eaglerHighPolyAnimationTick = millis;
if(partialTicks < 0.0f) {
partialTicks = 0.0f;
}
if(partialTicks > 1.0f) {
partialTicks = 1.0f;
}
float jumpFac = (float)(abstractclientplayer.posY - abstractclientplayer.prevPosY);
if(jumpFac < 0.0f && !abstractclientplayer.isCollidedVertically) {
jumpFac = -jumpFac;
jumpFac *= 0.1f;
}
jumpFac -= 0.05f;
if(jumpFac > 0.1f && !abstractclientplayer.isCollidedVertically) {
jumpFac = 0.1f;
}else if(jumpFac < 0.0f) {
jumpFac = 0.0f;
}else if(jumpFac > 0.1f && abstractclientplayer.isCollidedVertically) {
jumpFac = 0.1f;
}else if(jumpFac > 0.4f) {
jumpFac = 0.4f;
}
jumpFac *= 10.0f;
abstractclientplayer.eaglerHighPolyAnimationFloat3 += (jumpFac / (jumpFac + 1.0f)) * 6.0f * partialTicks;
if(Float.isInfinite(abstractclientplayer.eaglerHighPolyAnimationFloat3)) {
abstractclientplayer.eaglerHighPolyAnimationFloat3 = 1.0f;
}else if(abstractclientplayer.eaglerHighPolyAnimationFloat3 > 1.0f) {
abstractclientplayer.eaglerHighPolyAnimationFloat3 = 1.0f;
}else if(abstractclientplayer.eaglerHighPolyAnimationFloat3 < -1.0f) {
abstractclientplayer.eaglerHighPolyAnimationFloat3 = -1.0f;
}
abstractclientplayer.eaglerHighPolyAnimationFloat2 += abstractclientplayer.eaglerHighPolyAnimationFloat3 * partialTicks;
abstractclientplayer.eaglerHighPolyAnimationFloat5 += partialTicks;
while(abstractclientplayer.eaglerHighPolyAnimationFloat5 > 0.05f) {
abstractclientplayer.eaglerHighPolyAnimationFloat5 -= 0.05f;
abstractclientplayer.eaglerHighPolyAnimationFloat3 *= 0.99f;
abstractclientplayer.eaglerHighPolyAnimationFloat2 *= 0.9f;
}
jumpFactor = abstractclientplayer.eaglerHighPolyAnimationFloat2; //(abstractclientplayer.eaglerHighPolyAnimationFloat1 - abstractclientplayer.eaglerHighPolyAnimationFloat2) * partialTicks + abstractclientplayer.eaglerHighPolyAnimationFloat2;
jumpFactor -= 0.12f;
if(jumpFactor < 0.0f) {
jumpFactor = 0.0f;
}
jumpFactor = jumpFactor / (jumpFactor + 2.0f);
if(jumpFactor > 1.0f) {
jumpFactor = 1.0f;
}
}
if(jumpFactor > 0.0f) {
GlStateManager.pushMatrix();
GlStateManager.translate(0.0f, jumpFactor * 3.0f, 0.0f);
}
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.headModel));
if(jumpFactor > 0.0f) {
GlStateManager.popMatrix();
}
}
if(highPolySkin.limbsModel != null && highPolySkin.limbsModel.length > 0) {
for(int i = 0; i < highPolySkin.limbsModel.length; ++i) {
DeferredStateManager.setRoughnessConstant(0.023f);
DeferredStateManager.setMetalnessConstant(0.902f);
float offset = 0.0f;
if(highPolySkin.limbsOffset != null) {
if(highPolySkin.limbsOffset.length == 1) {
offset = highPolySkin.limbsOffset[0];
}else {
offset = highPolySkin.limbsOffset[i];
}
}
GlStateManager.pushMatrix();
if(offset != 0.0f || highPolySkin.limbsInitialRotation != 0.0f) {
if(offset != 0.0f) {
GlStateManager.translate(0.0f, offset, 0.0f);
}
if(highPolySkin.limbsInitialRotation != 0.0f) {
GlStateManager.rotate(highPolySkin.limbsInitialRotation, 1.0f, 0.0f, 0.0f);
}
}
if(highPolySkin == HighPolySkin.LONG_ARMS) {
if(abstractclientplayer.isSwingInProgress) {
float var17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
var17 *= var17;
GlStateManager.rotate(-var17 * 20.0f, 1.0f, 0.0f, 0.0f);
}
}else if(highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
if(abstractclientplayer.isSwingInProgress) {
float var17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
var17 *= var17;
GlStateManager.rotate(var17 * 60.0f, 1.0f, 0.0f, 0.0f);
}
GlStateManager.rotate(40.0f * var15, 1.0f, 0.0f, 0.0f);
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
float fff = (i == 0) ? 1.0f : -1.0f;
float swing = (MathHelper.cos(f10 % 100000.0f) * fff + 0.2f) * var15;
float swing2 = (MathHelper.cos(f10 % 100000.0f) * fff * 0.5f + 0.0f) * var15;
GlStateManager.rotate(swing * 25.0f, 1.0f, 0.0f, 0.0f);
if(abstractclientplayer.isSwingInProgress) {
float var17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
var17 *= var17;
GlStateManager.rotate(-var17 * 25.0f, 1.0f, 0.0f, 0.0f);
}
// shear matrix
tmpMatrix.setIdentity();
tmpMatrix.m21 = swing2;
tmpMatrix.m23 = swing2 * -0.2f;
GlStateManager.multMatrix(tmpMatrix);
}
if(i != 0) {
mc.getTextureManager().bindTexture(highPolySkin.texture);
if (abstractclientplayer.hurtTime > 0 || abstractclientplayer.deathTime > 0) {
GlStateManager.color(1.2f, 0.8F, 0.8F, 1.0F);
}else {
GlStateManager.color(1.0f, 1.0F, 1.0F, 1.0F);
}
}
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.limbsModel[i]));
if(i == 0) {
GlStateManager.pushMatrix();
GlStateManager.translate(-0.287f, 0.05f, 0.0f);
if(highPolySkin == HighPolySkin.LONG_ARMS) {
GlStateManager.translate(1.72f, 2.05f, -0.24f);
ItemStack stk = abstractclientplayer.getHeldItem();
if(stk != null) {
Item itm = stk.getItem();
if(itm != null) {
if(itm == Items.bow) {
GlStateManager.translate(-0.22f, 0.8f, 0.6f);
GlStateManager.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
}else if(itm instanceof ItemBlock && !((ItemBlock)itm).getBlock().isNormalCube()) {
GlStateManager.translate(0.0f, -0.1f, 0.13f);
}else if(!itm.isFull3D()) {
GlStateManager.translate(-0.08f, -0.1f, 0.16f);
}
}
}
}else if(highPolySkin == HighPolySkin.WEIRD_CLIMBER_DUDE) {
GlStateManager.translate(-0.029f, 1.2f, -3f);
GlStateManager.rotate(-5.0f, 0.0f, 1.0f, 0.0f);
float var17 = -1.2f * var15;
if(abstractclientplayer.isSwingInProgress) {
float vvar17 = MathHelper.cos(-abstractclientplayer.getSwingProgress(f1) * (float)Math.PI * 2.0f - 1.2f) - 0.362f;
var17 = vvar17 < var17 ? vvar17 : var17;
}
GlStateManager.translate(-0.02f * var17, 0.42f * var17, var17 * 0.35f);
GlStateManager.rotate(var17 * 30.0f, 1.0f, 0.0f, 0.0f);
GlStateManager.rotate(110.0f, 1.0f, 0.0f, 0.0f);
ItemStack stk = abstractclientplayer.getHeldItem();
if(stk != null) {
Item itm = stk.getItem();
if(itm != null) {
if(itm == Items.bow) {
GlStateManager.translate(-0.18f, 1.0f, 0.4f);
GlStateManager.rotate(-95.0f, 1.0f, 0.0f, 0.0f);
}else if(itm instanceof ItemBlock && !((ItemBlock)itm).getBlock().isNormalCube()) {
GlStateManager.translate(0.0f, -0.1f, 0.13f);
}else if(!itm.isFull3D()) {
GlStateManager.translate(-0.08f, -0.1f, 0.16f);
}
}
}
}else if(highPolySkin == HighPolySkin.LAXATIVE_DUDE) {
GlStateManager.translate(1.291f, 2.44f, -2.18f);
GlStateManager.rotate(95.0f, 1.0f, 0.0f, 0.0f);
ItemStack stk = abstractclientplayer.getHeldItem();
if(stk != null) {
Item itm = stk.getItem();
if(itm != null) {
if(itm == Items.bow) {
GlStateManager.translate(-0.65f, 1.3f, -0.1f);
GlStateManager.rotate(180.0f, 0.0f, 0.0f, 1.0f);
GlStateManager.rotate(20.0f, 1.0f, 0.0f, 0.0f);
}else if(itm instanceof ItemBlock && !((ItemBlock)itm).getBlock().isNormalCube()) {
GlStateManager.translate(0.0f, -0.35f, 0.4f);
}else if(!itm.isFull3D()) {
GlStateManager.translate(-0.1f, -0.1f, 0.16f);
}
}
}
}
DeferredStateManager.setDefaultMaterialConstants();
renderHeldItem(abstractclientplayer, f1);
GlStateManager.popMatrix();
}
GlStateManager.popMatrix();
}
}
if(highPolySkin.eyesModel != null && !DeferredStateManager.isEnableShadowRender()) {
float ff = 0.00416f;
int brightness = abstractclientplayer.getBrightnessForRender(0.0f);
float blockLight = (brightness % 65536) * ff;
float skyLight = (brightness / 65536) * ff;
float sunCurve = (float)((abstractclientplayer.worldObj.getWorldTime() + 4000l) % 24000) / 24000.0f;
sunCurve = MathHelper.clamp_float(9.8f - MathHelper.abs(sunCurve * 5.0f + sunCurve * sunCurve * 45.0f - 14.3f) * 0.7f, 0.0f, 1.0f);
skyLight = skyLight * (sunCurve * 0.85f + 0.15f);
blockLight = blockLight * (sunCurve * 0.3f + 0.7f);
float eyeBrightness = blockLight;
if(skyLight > eyeBrightness) {
eyeBrightness = skyLight;
}
eyeBrightness += blockLight * 0.2f;
eyeBrightness = 1.0f - eyeBrightness;
eyeBrightness = MathHelper.clamp_float(eyeBrightness * 1.9f - 1.0f, 0.0f, 1.0f);
if(eyeBrightness > 0.1f) {
if(DeferredStateManager.isInDeferredPass()) {
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
DeferredStateManager.setDefaultMaterialConstants();
DeferredStateManager.setEmissionConstant(eyeBrightness);
}else {
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL_ONE, GL_ONE);
GlStateManager.color(eyeBrightness * 7.0f, eyeBrightness * 7.0f, eyeBrightness * 7.0f, 1.0f);
if(jumpFactor > 0.0f) {
GlStateManager.pushMatrix();
GlStateManager.translate(0.0f, jumpFactor * 3.0f, 0.0f);
}
}
GlStateManager.disableTexture2D();
GlStateManager.disableLighting();
GlStateManager.enableCull();
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(highPolySkin.eyesModel));
GlStateManager.enableTexture2D();
GlStateManager.enableLighting();
GlStateManager.disableCull();
if(jumpFactor > 0.0f) {
GlStateManager.popMatrix();
}
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
if(!DeferredStateManager.isInDeferredPass()) {
GlStateManager.disableBlend();
}
}
}
}catch(Throwable t) {
logger.error("Couldn\'t render entity");
logger.error(t);
}
GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit);
GlStateManager.enableTexture2D();
GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
GlStateManager.enableCull();
GlStateManager.popMatrix();
if (!this.renderOutlines) {
this.renderName(abstractclientplayer, d0, nameY, d2);
}
}
}
public void renderRightArm(AbstractClientPlayer clientPlayer) {
}
public void renderLeftArm(AbstractClientPlayer clientPlayer) {
}
protected void renderHeldItem(AbstractClientPlayer clientPlayer, float partialTicks) {
ItemStack itemstack = clientPlayer.getHeldItem();
if (itemstack != null) {
GlStateManager.pushMatrix();
GlStateManager.translate(-0.11F, 0.475F, 0.25F);
if (clientPlayer.fishEntity != null) {
itemstack = new ItemStack(Items.fishing_rod, 0);
}
Item item = itemstack.getItem();
Minecraft minecraft = Minecraft.getMinecraft();
if (item instanceof ItemBlock && Block.getBlockFromItem(item).getRenderType() == 2) {
GlStateManager.translate(0.0F, 0.1875F, -0.3125F);
GlStateManager.rotate(20.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(45.0F, 0.0F, 1.0F, 0.0F);
float f1 = 0.375F;
GlStateManager.scale(-f1, -f1, f1);
}
if (clientPlayer.isSneaking()) {
GlStateManager.translate(0.0F, 0.203125F, 0.0F);
}
minecraft.getItemRenderer().renderItem(clientPlayer, itemstack,
ItemCameraTransforms.TransformType.THIRD_PERSON);
GlStateManager.popMatrix();
}
}
}

View File

@ -0,0 +1,242 @@
package net.lax1dude.eaglercraft.v1_8.profile;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.socket.EaglercraftNetworkManager;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.client.C17PacketCustomPayload;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ServerCapeCache {
private static final Logger logger = LogManager.getLogger("ServerCapeCache");
public class CapeCacheEntry {
protected final boolean isPresetCape;
protected final int presetCapeId;
protected final CacheCustomCape customCape;
protected long lastCacheHit = System.currentTimeMillis();
protected CapeCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation) {
this.isPresetCape = false;
this.presetCapeId = -1;
this.customCape = new CacheCustomCape(textureInstance, resourceLocation);
ServerCapeCache.this.textureManager.loadTexture(resourceLocation, textureInstance);
}
/**
* Use only for the constant for the client player
*/
protected CapeCacheEntry(ResourceLocation resourceLocation) {
this.isPresetCape = false;
this.presetCapeId = -1;
this.customCape = new CacheCustomCape(null, resourceLocation);
}
protected CapeCacheEntry(int presetSkinId) {
this.isPresetCape = true;
this.presetCapeId = presetSkinId;
this.customCape = null;
}
public ResourceLocation getResourceLocation() {
if(isPresetCape) {
return DefaultCapes.getCapeFromId(presetCapeId).location;
}else {
if(customCape != null) {
return customCape.resourceLocation;
}else {
return null;
}
}
}
protected void free() {
if(!isPresetCape && customCape.resourceLocation != null) {
ServerCapeCache.this.textureManager.deleteTexture(customCape.resourceLocation);
}
}
}
protected static class CacheCustomCape {
protected final EaglerSkinTexture textureInstance;
protected final ResourceLocation resourceLocation;
protected CacheCustomCape(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation) {
this.textureInstance = textureInstance;
this.resourceLocation = resourceLocation;
}
}
private final CapeCacheEntry defaultCacheEntry = new CapeCacheEntry(0);
private final Map<EaglercraftUUID, CapeCacheEntry> capesCache = new HashMap();
private final Map<EaglercraftUUID, Long> waitingCapes = new HashMap();
private final Map<EaglercraftUUID, Long> evictedCapes = new HashMap();
private final EaglercraftNetworkManager networkManager;
protected final TextureManager textureManager;
private final EaglercraftUUID clientPlayerId;
private final CapeCacheEntry clientPlayerCacheEntry;
private long lastFlush = System.currentTimeMillis();
private long lastFlushReq = System.currentTimeMillis();
private long lastFlushEvict = System.currentTimeMillis();
private static int texId = 0;
public ServerCapeCache(EaglercraftNetworkManager networkManager, TextureManager textureManager) {
this.networkManager = networkManager;
this.textureManager = textureManager;
this.clientPlayerId = EaglerProfile.getPlayerUUID();
this.clientPlayerCacheEntry = new CapeCacheEntry(EaglerProfile.getActiveCapeResourceLocation());
}
public CapeCacheEntry getClientPlayerCape() {
return clientPlayerCacheEntry;
}
public CapeCacheEntry getCape(EaglercraftUUID player) {
if(player.equals(clientPlayerId)) {
return clientPlayerCacheEntry;
}
CapeCacheEntry etr = capesCache.get(player);
if(etr == null) {
if(!waitingCapes.containsKey(player) && !evictedCapes.containsKey(player)) {
waitingCapes.put(player, System.currentTimeMillis());
PacketBuffer buffer;
try {
buffer = CapePackets.writeGetOtherCape(player);
}catch(IOException ex) {
logger.error("Could not write cape request packet!");
logger.error(ex);
return defaultCacheEntry;
}
networkManager.sendPacket(new C17PacketCustomPayload("EAG|Capes-1.8", buffer));
}
return defaultCacheEntry;
}else {
etr.lastCacheHit = System.currentTimeMillis();
return etr;
}
}
public void cacheCapePreset(EaglercraftUUID player, int presetId) {
if(waitingCapes.remove(player) != null) {
CapeCacheEntry etr = capesCache.remove(player);
if(etr != null) {
etr.free();
}
capesCache.put(player, new CapeCacheEntry(presetId));
}else {
logger.error("Unsolicited cape response recieved for \"{}\"! (preset {})", player, presetId);
}
}
public void cacheCapeCustom(EaglercraftUUID player, byte[] pixels) {
if(waitingCapes.remove(player) != null) {
CapeCacheEntry etr = capesCache.remove(player);
if(etr != null) {
etr.free();
}
byte[] pixels32x32 = new byte[4096];
SkinConverter.convertCape23x17RGBto32x32RGBA(pixels, pixels32x32);
try {
etr = new CapeCacheEntry(new EaglerSkinTexture(pixels32x32, 32, 32),
new ResourceLocation("eagler:capes/multiplayer/tex_" + texId++));
}catch(Throwable t) {
etr = new CapeCacheEntry(0);
logger.error("Could not process custom skin packet for \"{}\"!", player);
logger.error(t);
}
capesCache.put(player, etr);
}else {
logger.error("Unsolicited skin response recieved for \"{}\"!", player);
}
}
public void flush() {
long millis = System.currentTimeMillis();
if(millis - lastFlushReq > 5000l) {
lastFlushReq = millis;
if(!waitingCapes.isEmpty()) {
Iterator<Long> waitingItr = waitingCapes.values().iterator();
while(waitingItr.hasNext()) {
if(millis - waitingItr.next().longValue() > 30000l) {
waitingItr.remove();
}
}
}
}
if(millis - lastFlushEvict > 1000l) {
lastFlushEvict = millis;
if(!evictedCapes.isEmpty()) {
Iterator<Long> evictItr = evictedCapes.values().iterator();
while(evictItr.hasNext()) {
if(millis - evictItr.next().longValue() > 3000l) {
evictItr.remove();
}
}
}
}
if(millis - lastFlush > 60000l) {
lastFlush = millis;
if(!capesCache.isEmpty()) {
Iterator<CapeCacheEntry> entryItr = capesCache.values().iterator();
while(entryItr.hasNext()) {
CapeCacheEntry etr = entryItr.next();
if(millis - etr.lastCacheHit > 900000l) { // 15 minutes
entryItr.remove();
etr.free();
}
}
}
}
}
public void destroy() {
Iterator<CapeCacheEntry> entryItr = capesCache.values().iterator();
while(entryItr.hasNext()) {
entryItr.next().free();
}
capesCache.clear();
waitingCapes.clear();
evictedCapes.clear();
}
public void evictCape(EaglercraftUUID uuid) {
evictedCapes.put(uuid, Long.valueOf(System.currentTimeMillis()));
CapeCacheEntry etr = capesCache.remove(uuid);
if(etr != null) {
etr.free();
}
}
}

View File

@ -321,6 +321,7 @@ public class ServerSkinCache {
} }
skinsCache.clear(); skinsCache.clear();
waitingSkins.clear(); waitingSkins.clear();
evictedSkins.clear();
} }
public void evictSkin(EaglercraftUUID uuid) { public void evictSkin(EaglercraftUUID uuid) {

View File

@ -3,7 +3,7 @@ package net.lax1dude.eaglercraft.v1_8.profile;
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData; import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
/** /**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved. * Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -35,6 +35,56 @@ public class SkinConverter {
copyRawPixels(skinIn.pixels, skinOut.pixels, 48, 52, 44, 64, 52, 20, 56, 32, 64, 64); copyRawPixels(skinIn.pixels, skinOut.pixels, 48, 52, 44, 64, 52, 20, 56, 32, 64, 64);
} }
public static void convertCape32x32RGBAto23x17RGB(ImageData skinIn, byte[] skinOut) {
int i, j;
for(int y = 0; y < 17; ++y) {
for(int x = 0; x < 22; ++x) {
i = (y * 23 + x) * 3;
j = skinIn.pixels[y * skinIn.width + x];
if((j & 0xFF000000) != 0) {
skinOut[i] = (byte)(j >> 16);
skinOut[i + 1] = (byte)(j >> 8);
skinOut[i + 2] = (byte)(j & 0xFF);
}else {
skinOut[i] = skinOut[i + 1] = skinOut[i + 2] = 0;
}
}
}
for(int y = 0; y < 11; ++y) {
i = ((y + 6) * 23 + 22) * 3;
j = skinIn.pixels[(y + 11) * skinIn.width + 22];
if((j & 0xFF000000) != 0) {
skinOut[i] = (byte)(j >> 16);
skinOut[i + 1] = (byte)(j >> 8);
skinOut[i + 2] = (byte)(j & 0xFF);
}else {
skinOut[i] = skinOut[i + 1] = skinOut[i + 2] = 0;
}
}
}
public static void convertCape23x17RGBto32x32RGBA(byte[] skinIn, byte[] skinOut) {
int i, j;
for(int y = 0; y < 17; ++y) {
for(int x = 0; x < 22; ++x) {
i = (y * 32 + x) << 2;
j = (y * 23 + x) * 3;
skinOut[i] = (byte)0xFF;
skinOut[i + 1] = skinIn[j];
skinOut[i + 2] = skinIn[j + 1];
skinOut[i + 3] = skinIn[j + 2];
}
}
for(int y = 0; y < 11; ++y) {
i = ((y + 11) * 32 + 22) << 2;
j = ((y + 6) * 23 + 22) * 3;
skinOut[i] = (byte)0xFF;
skinOut[i + 1] = skinIn[j];
skinOut[i + 2] = skinIn[j + 1];
skinOut[i + 3] = skinIn[j + 2];
}
}
private static void copyRawPixels(int[] imageIn, int[] imageOut, int dx1, int dy1, int dx2, int dy2, int sx1, private static void copyRawPixels(int[] imageIn, int[] imageOut, int dx1, int dy1, int dx2, int dy2, int sx1,
int sy1, int sx2, int sy2, int imgSrcWidth, int imgDstWidth) { int sy1, int sx2, int sy2, int imgSrcWidth, int imgDstWidth) {
if(dx1 > dx2) { if(dx1 > dx2) {

View File

@ -19,15 +19,19 @@ import java.util.Map;
* *
*/ */
public enum SkinModel { public enum SkinModel {
STEVE(0, 64, 64, "default", false), ALEX(1, 64, 64, "slim", false), ZOMBIE(2, 64, 64, "zombie", true); STEVE(0, 64, 64, "default", false), ALEX(1, 64, 64, "slim", false), ZOMBIE(2, 64, 64, "zombie", true),
LONG_ARMS(3, HighPolySkin.LONG_ARMS), WEIRD_CLIMBER_DUDE(4, HighPolySkin.WEIRD_CLIMBER_DUDE),
LAXATIVE_DUDE(5, HighPolySkin.LAXATIVE_DUDE), BABY_CHARLES(6, HighPolySkin.BABY_CHARLES),
BABY_WINSTON(7, HighPolySkin.BABY_WINSTON);
public final int id; public final int id;
public final int width; public final int width;
public final int height; public final int height;
public final String profileSkinType; public final String profileSkinType;
public final boolean sanitize; public final boolean sanitize;
public final HighPolySkin highPoly;
public static final SkinModel[] skinModels = new SkinModel[3]; public static final SkinModel[] skinModels = new SkinModel[8];
private static final Map<String, SkinModel> skinModelsByName = new HashMap(); private static final Map<String, SkinModel> skinModelsByName = new HashMap();
private SkinModel(int id, int w, int h, String profileSkinType, boolean sanitize) { private SkinModel(int id, int w, int h, String profileSkinType, boolean sanitize) {
@ -36,6 +40,16 @@ public enum SkinModel {
this.height = h; this.height = h;
this.profileSkinType = profileSkinType; this.profileSkinType = profileSkinType;
this.sanitize = sanitize; this.sanitize = sanitize;
this.highPoly = null;
}
private SkinModel(int id, HighPolySkin highPoly) {
this.id = id;
this.width = 256;
this.height = 128;
this.profileSkinType = "eagler";
this.sanitize = true;
this.highPoly = highPoly;
} }
public static SkinModel getModelFromId(String str) { public static SkinModel getModelFromId(String str) {

View File

@ -58,6 +58,9 @@ public class SkinPackets {
modelId = SkinModel.STEVE; modelId = SkinModel.STEVE;
} }
} }
if(modelId.highPoly != null) {
modelId = SkinModel.STEVE;
}
int bytesToRead = modelId.width * modelId.height * 4; int bytesToRead = modelId.width * modelId.height * 4;
byte[] readSkin = new byte[bytesToRead]; byte[] readSkin = new byte[bytesToRead];
buffer.readBytes(readSkin); buffer.readBytes(readSkin);

View File

@ -1,10 +1,14 @@
package net.lax1dude.eaglercraft.v1_8.profile; package net.lax1dude.eaglercraft.v1_8.profile;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglerMeshLoader;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelPlayer; import net.minecraft.client.model.ModelPlayer;
import net.minecraft.client.model.ModelZombie; import net.minecraft.client.model.ModelZombie;
import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.util.ResourceLocation;
/** /**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved. * Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
@ -36,7 +40,11 @@ public class SkinPreviewRenderer {
playerModelZombie.isChild = false; playerModelZombie.isChild = false;
} }
public static void renderBiped(int x, int y, int mx, int my, SkinModel skinModel) { public static void renderPreview(int x, int y, int mx, int my, SkinModel skinModel) {
renderPreview(x, y, mx, my, false, skinModel, null, null);
}
public static void renderPreview(int x, int y, int mx, int my, boolean capeMode, SkinModel skinModel, ResourceLocation skinTexture, ResourceLocation capeTexture) {
ModelBiped model; ModelBiped model;
switch(skinModel) { switch(skinModel) {
case STEVE: case STEVE:
@ -49,6 +57,17 @@ public class SkinPreviewRenderer {
case ZOMBIE: case ZOMBIE:
model = playerModelZombie; model = playerModelZombie;
break; break;
case LONG_ARMS:
case WEIRD_CLIMBER_DUDE:
case LAXATIVE_DUDE:
case BABY_CHARLES:
case BABY_WINSTON:
if(skinModel.highPoly != null && Minecraft.getMinecraft().gameSettings.enableFNAWSkins) {
renderHighPoly(x, y, mx, my, skinModel.highPoly);
return;
}
model = playerModelSteve;
break;
} }
GlStateManager.enableTexture2D(); GlStateManager.enableTexture2D();
@ -65,12 +84,95 @@ public class SkinPreviewRenderer {
RenderHelper.enableGUIStandardItemLighting(); RenderHelper.enableGUIStandardItemLighting();
GlStateManager.translate(0.0f, 1.0f, 0.0f); GlStateManager.translate(0.0f, 1.0f, 0.0f);
if(capeMode) {
GlStateManager.rotate(140.0f, 0.0f, 1.0f, 0.0f);
mx = x - (x - mx) - 20;
GlStateManager.rotate(((y - my) * -0.02f), 1.0f, 0.0f, 0.0f);
}else {
GlStateManager.rotate(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f); GlStateManager.rotate(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f);
}
GlStateManager.rotate(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f); GlStateManager.rotate(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f);
GlStateManager.translate(0.0f, -1.0f, 0.0f); GlStateManager.translate(0.0f, -1.0f, 0.0f);
if(skinTexture != null) {
Minecraft.getMinecraft().getTextureManager().bindTexture(skinTexture);
}
model.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625f); model.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625f);
if(capeTexture != null && model instanceof ModelPlayer) {
Minecraft.getMinecraft().getTextureManager().bindTexture(capeTexture);
GlStateManager.pushMatrix();
GlStateManager.translate(0.0F, 0.0F, 0.125F);
GlStateManager.rotate(6.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F);
((ModelPlayer)model).renderCape(0.0625f);
GlStateManager.popMatrix();
}
GlStateManager.popMatrix();
GlStateManager.disableLighting();
}
private static void renderHighPoly(int x, int y, int mx, int my, HighPolySkin msh) {
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
GlStateManager.disableCull();
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
GlStateManager.pushMatrix();
GlStateManager.translate(x, y - 80.0f, 100.0f);
GlStateManager.scale(50.0f, 50.0f, 50.0f);
GlStateManager.rotate(180.0f, 1.0f, 0.0f, 0.0f);
GlStateManager.scale(1.0f, -1.0f, 1.0f);
RenderHelper.enableGUIStandardItemLighting();
GlStateManager.translate(0.0f, 1.0f, 0.0f);
GlStateManager.rotate(((y - my) * -0.06f), 1.0f, 0.0f, 0.0f);
GlStateManager.rotate(((x - mx) * 0.06f), 0.0f, 1.0f, 0.0f);
GlStateManager.rotate(180.0f, 0.0f, 0.0f, 1.0f);
GlStateManager.translate(0.0f, -0.6f, 0.0f);
GlStateManager.scale(HighPolySkin.highPolyScale, HighPolySkin.highPolyScale, HighPolySkin.highPolyScale);
Minecraft.getMinecraft().getTextureManager().bindTexture(msh.texture);
if(msh.bodyModel != null) {
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(msh.bodyModel));
}
if(msh.headModel != null) {
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(msh.headModel));
}
if(msh.limbsModel != null && msh.limbsModel.length > 0) {
for(int i = 0; i < msh.limbsModel.length; ++i) {
float offset = 0.0f;
if(msh.limbsOffset != null) {
if(msh.limbsOffset.length == 1) {
offset = msh.limbsOffset[0];
}else {
offset = msh.limbsOffset[i];
}
}
if(offset != 0.0f || msh.limbsInitialRotation != 0.0f) {
GlStateManager.pushMatrix();
if(offset != 0.0f) {
GlStateManager.translate(0.0f, offset, 0.0f);
}
if(msh.limbsInitialRotation != 0.0f) {
GlStateManager.rotate(msh.limbsInitialRotation, 1.0f, 0.0f, 0.0f);
}
}
EaglercraftGPU.drawHighPoly(EaglerMeshLoader.getEaglerMesh(msh.limbsModel[i]));
if(offset != 0.0f || msh.limbsInitialRotation != 0.0f) {
GlStateManager.popMatrix();
}
}
}
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.disableLighting(); GlStateManager.disableLighting();
} }

View File

@ -293,6 +293,19 @@ public class ConnectionHandshake {
d.write(packetSkin); d.write(packetSkin);
PlatformNetworking.writePlayPacket(bao.toByteArray()); PlatformNetworking.writePlayPacket(bao.toByteArray());
bao.reset();
d.writeByte(HandshakePacketTypes.PROTOCOL_CLIENT_PROFILE_DATA);
profileDataType = "cape_v1";
d.writeByte(profileDataType.length());
d.writeBytes(profileDataType);
byte[] packetCape = EaglerProfile.getCapePacket();
if(packetCape.length > 0xFFFF) {
throw new IOException("Cape packet is too long: " + packetCape.length);
}
d.writeShort(packetCape.length);
d.write(packetCape);
PlatformNetworking.writePlayPacket(bao.toByteArray());
byte[] packetSignatureData = UpdateService.getClientSignatureData(); byte[] packetSignatureData = UpdateService.getClientSignatureData();
if(packetSignatureData != null) { if(packetSignatureData != null) {
bao.reset(); bao.reset();

Some files were not shown because too many files have changed in this diff Show More