u29
|
@ -11,18 +11,26 @@
|
|||
- Made the integrated PBR resource pack
|
||||
- Wrote all desktop emulation code
|
||||
- Wrote EaglercraftXBungee
|
||||
- Wrote WebRTC Relay Server
|
||||
- Wrote WebRTC relay server
|
||||
- Wrote voice chat server
|
||||
- Wrote the patch and build system
|
||||
|
||||
ayunami2000:
|
||||
|
||||
- Many bug fixes
|
||||
- WebRTC LAN worlds
|
||||
- WebRTC voice chat
|
||||
- Added resource packs
|
||||
- Added screen recording
|
||||
- Added seamless fullscreen
|
||||
- Created the replit
|
||||
|
||||
hoosiertransfer:
|
||||
|
||||
- Many memory optimizations
|
||||
- Bug fixes
|
||||
- Faster lighting engine
|
||||
|
||||
|
||||
|
||||
Code used within EaglercraftX
|
||||
|
|
After Width: | Height: | Size: 343 B |
After Width: | Height: | Size: 347 B |
After Width: | Height: | Size: 408 B |
After Width: | Height: | Size: 384 B |
After Width: | Height: | Size: 346 B |
After Width: | Height: | Size: 411 B |
After Width: | Height: | Size: 580 B |
After Width: | Height: | Size: 555 B |
After Width: | Height: | Size: 332 B |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 694 B |
After Width: | Height: | Size: 737 B |
After Width: | Height: | Size: 917 B |
After Width: | Height: | Size: 774 B |
After Width: | Height: | Size: 859 B |
After Width: | Height: | Size: 1007 B |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 557 B |
After Width: | Height: | Size: 876 B |
After Width: | Height: | Size: 609 B |
|
@ -18,7 +18,7 @@ gui.all=All
|
|||
eaglercraft.recording.unsupported=Recording Unsupported!
|
||||
eaglercraft.recording.stop=Stop Recording
|
||||
eaglercraft.recording.start=Record Screen...
|
||||
eaglercraft.soundCategory.voice=Voice
|
||||
eaglercraft.soundCategory.voice=Recording Voice
|
||||
|
||||
eaglercraft.resourcePack.prompt.title=What do you want to do with '%s'?
|
||||
eaglercraft.resourcePack.prompt.text=Tip: Hold Shift to skip this screen when selecting a resource pack!
|
||||
|
@ -43,6 +43,14 @@ eaglercraft.editProfile.username=Username
|
|||
eaglercraft.editProfile.playerSkin=Player Skin
|
||||
eaglercraft.editProfile.addSkin=Add Skin
|
||||
eaglercraft.editProfile.clearSkin=Clear List
|
||||
eaglercraft.editProfile.capes=Capes
|
||||
eaglercraft.editProfile.disableFNAW=(Note: go to 'Options...' > 'Skin Customization' to disable FNAW skins)
|
||||
eaglercraft.editProfile.enableFNAW=(Note: go to 'Options...' > 'Skin Customization' to enable FNAW skins)
|
||||
|
||||
eaglercraft.editCape.title=Edit Cape
|
||||
eaglercraft.editCape.playerCape=Player Cape
|
||||
eaglercraft.editCape.addCape=Add Cape
|
||||
eaglercraft.editCape.clearCape=Clear List
|
||||
|
||||
eaglercraft.editProfile.importExport=Import/Export
|
||||
|
||||
|
@ -599,6 +607,60 @@ eaglercraft.updateList.refresh=Refresh
|
|||
eaglercraft.updateList.note.0=Note: Updates are digitally signed, EaglercraftX will block any
|
||||
eaglercraft.updateList.note.1=updates that were not created by lax1dude or ayunami2000
|
||||
|
||||
eaglercraft.voice.title=Voice Channel
|
||||
eaglercraft.voice.titleNoVoice=Voice is disabled on this server
|
||||
eaglercraft.voice.titleVoiceUnavailable=Voice is unavailable
|
||||
eaglercraft.voice.titleVoiceBrowserError=(browser issue)
|
||||
eaglercraft.voice.ptt=Press '%s' to speak
|
||||
eaglercraft.voice.pttChangeDesc=(Press Any Key)
|
||||
eaglercraft.voice.changeKey=Change
|
||||
eaglercraft.voice.off=OFF
|
||||
eaglercraft.voice.radius=NEARBY
|
||||
eaglercraft.voice.global=GLOBAL
|
||||
eaglercraft.voice.volumeTitle=Change Volume
|
||||
eaglercraft.voice.volumeListen=Speakers Volume:
|
||||
eaglercraft.voice.volumeSpeak=Microphone Volume:
|
||||
eaglercraft.voice.radiusTitle=Change Listener Radius
|
||||
eaglercraft.voice.radiusLabel=Players Within:
|
||||
eaglercraft.voice.radiusChange=change
|
||||
eaglercraft.voice.notConnected=Not Connected
|
||||
eaglercraft.voice.connecting=Connecting...
|
||||
eaglercraft.voice.unavailable=Could not connect!
|
||||
eaglercraft.voice.connectedGlobal=Connected - Global
|
||||
eaglercraft.voice.connectedRadius=Connected - $f$Within $radius$m
|
||||
eaglercraft.voice.playersListening=Players Listening:
|
||||
eaglercraft.voice.muted=Players Muted:
|
||||
eaglercraft.voice.unmute=unmute
|
||||
eaglercraft.voice.mute=mute
|
||||
eaglercraft.voice.apply=Apply
|
||||
eaglercraft.voice.volumeSpeakerLabel=Speakers:
|
||||
eaglercraft.voice.volumeMicrophoneLabel=Microphone:
|
||||
|
||||
eaglercraft.voice.unsupportedWarning1=Voice Warning
|
||||
eaglercraft.voice.unsupportedWarning2=Your network's firewall may not support
|
||||
eaglercraft.voice.unsupportedWarning3=eaglercraft's voice chat.
|
||||
eaglercraft.voice.unsupportedWarning4=If your game doesn't work it's your issue
|
||||
eaglercraft.voice.unsupportedWarning5=to solve, not ayunami2000's or lax1dude's.
|
||||
eaglercraft.voice.unsupportedWarning6=Don't ask them to 'fix' it for you because
|
||||
eaglercraft.voice.unsupportedWarning7=they won't help you fix a problem that only
|
||||
eaglercraft.voice.unsupportedWarning8=you or your network's administrator has the
|
||||
eaglercraft.voice.unsupportedWarning9=ability to correctly resolve.
|
||||
eaglercraft.voice.unsupportedWarning10=Continue
|
||||
eaglercraft.voice.unsupportedWarning11=Cancel
|
||||
|
||||
eaglercraft.voice.ipGrabWarning1=IP Logger Warning
|
||||
eaglercraft.voice.ipGrabWarning2=Using Eaglercraft voice chat may allow your
|
||||
eaglercraft.voice.ipGrabWarning3=IP address to be logged by other players
|
||||
eaglercraft.voice.ipGrabWarning4=also using voice on the server.
|
||||
eaglercraft.voice.ipGrabWarning5=This issue will not be fixed, it is an
|
||||
eaglercraft.voice.ipGrabWarning6=internal browser issue, not a mistake in the
|
||||
eaglercraft.voice.ipGrabWarning7=game. Fortunately, this can only be done if
|
||||
eaglercraft.voice.ipGrabWarning8=the other player uses a hacked web browser
|
||||
eaglercraft.voice.ipGrabWarning9=or has Wireshark to capture the voice
|
||||
eaglercraft.voice.ipGrabWarning10=packets, as there exists no real javascript
|
||||
eaglercraft.voice.ipGrabWarning11=method to log IPs using a normal skidded
|
||||
eaglercraft.voice.ipGrabWarning12=eaglercraft hacked client.
|
||||
|
||||
selectServer.title=Select Server
|
||||
selectServer.empty=empty
|
||||
selectServer.select=Join Server
|
||||
|
@ -799,6 +861,7 @@ options.chat.height.focused=Focused Height
|
|||
options.chat.height.unfocused=Unfocused Height
|
||||
options.skinCustomisation=Skin Customization...
|
||||
options.skinCustomisation.title=Skin Customization
|
||||
options.skinCustomisation.enableFNAWSkins=Show FNAW Skins
|
||||
options.modelPart.cape=Cape
|
||||
options.modelPart.hat=Hat
|
||||
options.modelPart.jacket=Jacket
|
||||
|
|
67993
javascript/classes.js
|
@ -60,6 +60,9 @@ public class PlatformAssets {
|
|||
public static final ImageData loadImageFile(InputStream data) {
|
||||
try {
|
||||
BufferedImage img = ImageIO.read(data);
|
||||
if(img == null) {
|
||||
throw new IOException("Data is not a supported image format!");
|
||||
}
|
||||
int w = img.getWidth();
|
||||
int h = img.getHeight();
|
||||
boolean a = img.getColorModel().hasAlpha();
|
||||
|
|
|
@ -21,10 +21,7 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
|||
public class PlatformBufferFunctions {
|
||||
|
||||
public static void put(ByteBuffer newBuffer, ByteBuffer flip) {
|
||||
int len = flip.remaining();
|
||||
for(int i = 0; i < len; ++i) {
|
||||
newBuffer.put(flip.get());
|
||||
}
|
||||
newBuffer.put(flip);
|
||||
}
|
||||
|
||||
public static void put(IntBuffer intBuffer, int index, int[] data) {
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2.BreakLoop;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.DebugFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.JDBCFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.lwjgl.JDBCFilesystemConverter;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
|
@ -30,183 +28,104 @@ public class PlatformFilesystem {
|
|||
|
||||
public static final Logger logger = LogManager.getLogger("PlatformFilesystem");
|
||||
|
||||
public static final File filesystemRoot = (new File("filesystem/sp")).getAbsoluteFile();
|
||||
public static final File debugFilesystemRoot = (new File("filesystem/sp")).getAbsoluteFile();
|
||||
|
||||
private static IFilesystemProvider provider = null;
|
||||
|
||||
public static String jdbcUri = null;
|
||||
public static String jdbcDriver = null;
|
||||
|
||||
public static void initialize() {
|
||||
if(!filesystemRoot.isDirectory() && !filesystemRoot.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create directory for virtual filesystem: " + filesystemRoot.getAbsolutePath());
|
||||
if(provider == null) {
|
||||
if(jdbcUri != null && jdbcDriver != null) {
|
||||
provider = JDBCFilesystem.initialize(jdbcUri, jdbcDriver);
|
||||
if(((JDBCFilesystem)provider).isNewFilesystem() && debugFilesystemRoot.isDirectory() && debugFilesystemRoot.list().length > 0) {
|
||||
JDBCFilesystemConverter.convertFilesystem("Converting filesystem, please wait...", debugFilesystemRoot, provider, true);
|
||||
}
|
||||
}else {
|
||||
provider = DebugFilesystem.initialize(debugFilesystemRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setUseJDBC(String uri) {
|
||||
jdbcUri = uri;
|
||||
}
|
||||
|
||||
public static void setJDBCDriverClass(String driver) {
|
||||
jdbcDriver = driver;
|
||||
}
|
||||
|
||||
public static interface IFilesystemProvider {
|
||||
|
||||
boolean eaglerDelete(String pathName);
|
||||
|
||||
ByteBuffer eaglerRead(String pathName);
|
||||
|
||||
void eaglerWrite(String pathName, ByteBuffer data);
|
||||
|
||||
boolean eaglerExists(String pathName);
|
||||
|
||||
boolean eaglerMove(String pathNameOld, String pathNameNew);
|
||||
|
||||
int eaglerCopy(String pathNameOld, String pathNameNew);
|
||||
|
||||
int eaglerSize(String pathName);
|
||||
|
||||
void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive);
|
||||
|
||||
}
|
||||
|
||||
private static void throwNotInitialized() {
|
||||
throw new UnsupportedOperationException("Filesystem has not been initialized!");
|
||||
}
|
||||
|
||||
public static boolean eaglerDelete(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(!f.exists()) {
|
||||
logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
|
||||
return false;
|
||||
}
|
||||
if(f.delete()) {
|
||||
deleteParentIfEmpty(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerDelete(pathName);
|
||||
}
|
||||
|
||||
public static ByteBuffer eaglerRead(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
ByteBuffer buf = PlatformRuntime.allocateByteBuffer((int)fileSize);
|
||||
try(FileInputStream is = new FileInputStream(f)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
buf.put(copyBuffer, 0, i);
|
||||
}
|
||||
if(buf.remaining() > 0) {
|
||||
throw new EaglerFileSystemException("ERROR: " + buf.remaining() + " bytes are remaining after reading: " + f.getAbsolutePath());
|
||||
}
|
||||
buf.flip();
|
||||
ByteBuffer tmp = buf;
|
||||
buf = null;
|
||||
return tmp;
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to read: " + f.getAbsolutePath(), e);
|
||||
}catch(ArrayIndexOutOfBoundsException ex) {
|
||||
throw new EaglerFileSystemException("ERROR: Expected " + fileSize + " bytes, buffer overflow reading: " + f.getAbsolutePath(), ex);
|
||||
}finally {
|
||||
if(buf != null) {
|
||||
PlatformRuntime.freeByteBuffer(buf);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
logger.warn("Tried to read file that doesn't exist: \"{}\"", f.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerRead(pathName);
|
||||
}
|
||||
|
||||
public static void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
File f = getJREFile(pathName);
|
||||
File p = f.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
try(FileOutputStream fos = new FileOutputStream(f)) {
|
||||
byte[] copyBuffer = new byte[Math.min(4096, data.remaining())];
|
||||
int i;
|
||||
while((i = data.remaining()) > 0) {
|
||||
if(i > copyBuffer.length) {
|
||||
i = copyBuffer.length;
|
||||
}
|
||||
data.get(copyBuffer, 0, i);
|
||||
fos.write(copyBuffer, 0, i);
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to write: " + f.getAbsolutePath(), e);
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
provider.eaglerWrite(pathName, data);
|
||||
}
|
||||
|
||||
public static boolean eaglerExists(String pathName) {
|
||||
return getJREFile(pathName).isFile();
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerExists(pathName);
|
||||
}
|
||||
|
||||
public static boolean eaglerMove(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(f2.exists()) {
|
||||
logger.warn("Tried to rename file \"{}\" to \"{}\" which already exists! File will be replaced");
|
||||
if(!f2.delete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(f1.renameTo(f2)) {
|
||||
deleteParentIfEmpty(f1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerMove(pathNameOld, pathNameNew);
|
||||
}
|
||||
|
||||
public static int eaglerCopy(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(!f1.isFile()) {
|
||||
return -1;
|
||||
}
|
||||
if(f2.isDirectory()) {
|
||||
throw new EaglerFileSystemException("Destination file is a directory: " + f2.getAbsolutePath());
|
||||
}
|
||||
File p = f2.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
int sz = 0;
|
||||
try(FileInputStream is = new FileInputStream(f1)) {
|
||||
try(FileOutputStream os = new FileOutputStream(f2)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
os.write(copyBuffer, 0, i);
|
||||
sz += i;
|
||||
}
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to copy \"" + f1.getAbsolutePath() + "\" to file \"" + f2.getAbsolutePath() + "\"", e);
|
||||
}
|
||||
return sz;
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerCopy(pathNameOld, pathNameNew);
|
||||
}
|
||||
|
||||
public static int eaglerSize(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
return (int)fileSize;
|
||||
}else {
|
||||
return -1;
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
return provider.eaglerSize(pathName);
|
||||
}
|
||||
|
||||
public static void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
|
||||
try {
|
||||
iterateFile(pathName, getJREFile(pathName), itr, recursive);
|
||||
}catch(BreakLoop ex) {
|
||||
}
|
||||
if(provider == null) throwNotInitialized();
|
||||
provider.eaglerIterate(pathName, itr, recursive);
|
||||
}
|
||||
|
||||
private static void iterateFile(String pathName, File f, VFSFilenameIterator itr, boolean recursive) {
|
||||
if(!f.exists()) {
|
||||
return;
|
||||
}
|
||||
if(!f.isDirectory()) {
|
||||
itr.next(pathName);
|
||||
return;
|
||||
}
|
||||
File[] fa = f.listFiles();
|
||||
for(int i = 0; i < fa.length; ++i) {
|
||||
File ff = fa[i];
|
||||
String fn = pathName + "/" + ff.getName();
|
||||
if(ff.isDirectory()) {
|
||||
if(recursive) {
|
||||
iterateFile(fn, ff, itr, true);
|
||||
}
|
||||
}else {
|
||||
itr.next(fn);
|
||||
public static void platformShutdown() {
|
||||
if(provider != null) {
|
||||
if(provider instanceof JDBCFilesystem) {
|
||||
((JDBCFilesystem)provider).shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static File getJREFile(String path) {
|
||||
return new File(filesystemRoot, path);
|
||||
}
|
||||
|
||||
private static void deleteParentIfEmpty(File f) {
|
||||
String[] s;
|
||||
while((f = f.getParentFile()) != null && (s = f.list()) != null && s.length == 0) {
|
||||
f.delete();
|
||||
provider = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,10 @@ public class PlatformInput {
|
|||
public static boolean lockKeys = false;
|
||||
|
||||
private static final List<Character> keyboardCharList = new LinkedList();
|
||||
|
||||
|
||||
private static boolean vsync = true;
|
||||
private static boolean glfwVSyncState = false;
|
||||
|
||||
private static class KeyboardEvent {
|
||||
|
||||
protected final int key;
|
||||
|
@ -214,8 +217,16 @@ public class PlatformInput {
|
|||
return glfwWindowShouldClose(win);
|
||||
}
|
||||
|
||||
public static void setVSync(boolean enable) {
|
||||
vsync = enable;
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
glfwPollEvents();
|
||||
if(vsync != glfwVSyncState) {
|
||||
glfwSwapInterval(vsync ? 1 : 0);
|
||||
glfwVSyncState = vsync;
|
||||
}
|
||||
glfwSwapBuffers(win);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
|
|||
|
||||
import static org.lwjgl.opengles.GLES30.*;
|
||||
|
||||
import org.lwjgl.opengles.GLESCapabilities;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
|
@ -24,6 +26,12 @@ import static org.lwjgl.opengles.GLES30.*;
|
|||
*/
|
||||
public class PlatformOpenGL {
|
||||
|
||||
private static boolean hasLinearHDR32FSupport = false;
|
||||
|
||||
static void setCurrentContext(GLESCapabilities caps) {
|
||||
hasLinearHDR32FSupport = caps.GL_OES_texture_float_linear;
|
||||
}
|
||||
|
||||
public static final void _wglEnable(int glEnum) {
|
||||
glEnable(glEnum);
|
||||
}
|
||||
|
@ -269,6 +277,12 @@ public class PlatformOpenGL {
|
|||
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data));
|
||||
}
|
||||
|
||||
public static final void _wglTexImage2Df32(int target, int level, int internalFormat, int width, int height,
|
||||
int border, int format, int type, ByteBuffer data) {
|
||||
nglTexImage2D(target, level, internalFormat, width, height, border, format, type,
|
||||
data == null ? 0l : EaglerLWJGLAllocator.getAddress(data));
|
||||
}
|
||||
|
||||
public static final void _wglTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height,
|
||||
int format, int type, ByteBuffer data) {
|
||||
nglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
|
||||
|
@ -523,4 +537,7 @@ public class PlatformOpenGL {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static final boolean checkLinearHDR32FSupport() {
|
||||
return hasLinearHDR32FSupport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ public class PlatformRuntime {
|
|||
|
||||
EGL.createDisplayCapabilities(glfw_eglHandle, major[0], minor[0]);
|
||||
glfwMakeContextCurrent(windowHandle);
|
||||
GLES.createCapabilities();
|
||||
PlatformOpenGL.setCurrentContext(GLES.createCapabilities());
|
||||
|
||||
logger.info("OpenGL Version: {}", (glVersion = GLES30.glGetString(GLES30.GL_VERSION)));
|
||||
logger.info("OpenGL Renderer: {}", (glRenderer = GLES30.glGetString(GLES30.GL_RENDERER)));
|
||||
|
@ -245,6 +245,7 @@ public class PlatformRuntime {
|
|||
|
||||
public static void destroy() {
|
||||
PlatformAudio.platformShutdown();
|
||||
PlatformFilesystem.platformShutdown();
|
||||
GLES.destroy();
|
||||
EGL.destroy();
|
||||
glfwDestroyWindow(windowHandle);
|
||||
|
@ -340,15 +341,27 @@ public class PlatformRuntime {
|
|||
public static class NativeNIO {
|
||||
|
||||
public static java.nio.ByteBuffer allocateByteBuffer(int length) {
|
||||
return MemoryUtil.memByteBuffer(JEmalloc.nje_malloc(length), length);
|
||||
long ret = JEmalloc.nje_malloc(length);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memByteBuffer(ret, length);
|
||||
}
|
||||
|
||||
public static java.nio.IntBuffer allocateIntBuffer(int length) {
|
||||
return MemoryUtil.memIntBuffer(JEmalloc.nje_malloc(length << 2), length);
|
||||
long ret = JEmalloc.nje_malloc(length << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memIntBuffer(ret, length);
|
||||
}
|
||||
|
||||
public static java.nio.FloatBuffer allocateFloatBuffer(int length) {
|
||||
return MemoryUtil.memFloatBuffer(JEmalloc.nje_malloc(length << 2), length);
|
||||
long ret = JEmalloc.nje_malloc(length << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return MemoryUtil.memFloatBuffer(ret, length);
|
||||
}
|
||||
|
||||
public static java.nio.IntBuffer getIntBuffer(java.nio.ByteBuffer byteBuffer) {
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.voice.EnumVoiceChannelPeerState;
|
||||
import net.lax1dude.eaglercraft.v1_8.voice.EnumVoiceChannelReadyState;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class PlatformVoiceClient {
|
||||
|
||||
public static void initialize() {
|
||||
|
||||
}
|
||||
|
||||
public static void initializeDevices() {
|
||||
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setVoiceListenVolume(float f) {
|
||||
|
||||
}
|
||||
|
||||
public static void setVoiceSpeakVolume(float f) {
|
||||
|
||||
}
|
||||
|
||||
public static void activateVoice(boolean talk) {
|
||||
|
||||
}
|
||||
|
||||
public static void setICEServers(String[] servs) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalConnect(EaglercraftUUID user, boolean offer) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalDisconnect(EaglercraftUUID user, boolean b) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalICECandidate(EaglercraftUUID user, String ice) {
|
||||
|
||||
}
|
||||
|
||||
public static void signalDescription(EaglercraftUUID user, String desc) {
|
||||
|
||||
}
|
||||
|
||||
public static void tickVoiceClient() {
|
||||
|
||||
}
|
||||
|
||||
public static void updateVoicePosition(EaglercraftUUID uuid, double x, double y, double z) {
|
||||
|
||||
}
|
||||
|
||||
public static void resetPeerStates() {
|
||||
|
||||
}
|
||||
|
||||
public static void setVoiceProximity(int prox) {
|
||||
|
||||
}
|
||||
|
||||
public static void setMicVolume(float f) {
|
||||
|
||||
}
|
||||
|
||||
public static void mutePeer(EaglercraftUUID uuid, boolean mute) {
|
||||
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerState() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelReadyState getReadyState() {
|
||||
return EnumVoiceChannelReadyState.NONE;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateConnect() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateInitial() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateDesc() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelPeerState getPeerStateIce() {
|
||||
return EnumVoiceChannelPeerState.LOADING;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@ package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
|||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
|
@ -26,19 +26,35 @@ public class EaglerLWJGLAllocator {
|
|||
}
|
||||
|
||||
public static ByteBuffer allocByteBuffer(int len) {
|
||||
return new EaglerLWJGLByteBuffer(JEmalloc.nje_malloc(len), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLByteBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static ShortBuffer allocShortBuffer(int len) {
|
||||
return new EaglerLWJGLShortBuffer(JEmalloc.nje_malloc(len << 1), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len << 1);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLShortBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static IntBuffer allocIntBuffer(int len) {
|
||||
return new EaglerLWJGLIntBuffer(JEmalloc.nje_malloc(len << 2), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLIntBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static FloatBuffer allocFloatBuffer(int len) {
|
||||
return new EaglerLWJGLFloatBuffer(JEmalloc.nje_malloc(len << 2), len, true);
|
||||
long ret = JEmalloc.nje_malloc(len << 2);
|
||||
if(ret == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
return new EaglerLWJGLFloatBuffer(ret, len, true);
|
||||
}
|
||||
|
||||
public static void freeByteBuffer(ByteBuffer buffer) {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
|
@ -18,7 +20,7 @@ import org.lwjgl.system.jemalloc.JEmalloc;
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
||||
public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
|
||||
final long address;
|
||||
final boolean original;
|
||||
|
@ -28,11 +30,13 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
private int limit;
|
||||
private int mark;
|
||||
|
||||
EaglerLWJGLByteBuffer(long address, int capacity, boolean original) {
|
||||
private static final int SHIFT = 2;
|
||||
|
||||
EaglerLWJGLFloatBuffer(long address, int capacity, boolean original) {
|
||||
this(address, capacity, 0, capacity, -1, original);
|
||||
}
|
||||
|
||||
EaglerLWJGLByteBuffer(long address, int capacity, int position, int limit, int mark, boolean original) {
|
||||
EaglerLWJGLFloatBuffer(long address, int capacity, int position, int limit, int mark, boolean original) {
|
||||
this.address = address;
|
||||
this.capacity = capacity;
|
||||
this.position = position;
|
||||
|
@ -40,7 +44,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
this.mark = mark;
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int capacity() {
|
||||
return capacity;
|
||||
|
@ -82,85 +86,93 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
return true;
|
||||
public int arrayOffset() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer slice() {
|
||||
return new EaglerLWJGLByteBuffer(address + position, limit - position, false);
|
||||
public FloatBuffer slice() {
|
||||
return new EaglerLWJGLFloatBuffer(address + (position << SHIFT), limit - position, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer duplicate() {
|
||||
return new EaglerLWJGLByteBuffer(address, capacity, position, limit, mark, false);
|
||||
public FloatBuffer duplicate() {
|
||||
return new EaglerLWJGLFloatBuffer(address, capacity, position, limit, mark, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer asReadOnlyBuffer() {
|
||||
return new EaglerLWJGLByteBuffer(address, capacity, position, limit, mark, false);
|
||||
public FloatBuffer asReadOnlyBuffer() {
|
||||
return new EaglerLWJGLFloatBuffer(address, capacity, position, limit, mark, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte get() {
|
||||
public float get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetByte(address + position++);
|
||||
return UnsafeUtils.getMemFloat(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(byte b) {
|
||||
public FloatBuffer put(float b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutByte(address + position++, b);
|
||||
UnsafeUtils.setMemFloat(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte get(int index) {
|
||||
public float get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetByte(address + index);
|
||||
return UnsafeUtils.getMemFloat(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(int index, byte b) {
|
||||
public FloatBuffer put(int index, float b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutByte(address + index, b);
|
||||
UnsafeUtils.setMemFloat(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer get(byte[] dst, int offset, int length) {
|
||||
public float getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return UnsafeUtils.getMemFloat(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, float value) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
UnsafeUtils.setMemFloat(address + ((position++) << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer get(float[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetByte(address + position + i);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer get(byte[] dst) {
|
||||
public FloatBuffer get(float[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[position + i] = MemoryUtil.memGetByte(address + position + i);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(ByteBuffer src) {
|
||||
if(src instanceof EaglerLWJGLByteBuffer) {
|
||||
EaglerLWJGLByteBuffer c = (EaglerLWJGLByteBuffer)src;
|
||||
public FloatBuffer put(FloatBuffer src) {
|
||||
if(src instanceof EaglerLWJGLFloatBuffer) {
|
||||
EaglerLWJGLFloatBuffer c = (EaglerLWJGLFloatBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + c.position, address + position, l);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutByte(address + position + l, src.get());
|
||||
UnsafeUtils.setMemFloat(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
|
@ -168,214 +180,58 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(byte[] src, int offset, int length) {
|
||||
public FloatBuffer put(float[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutByte(address + position + i, src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer put(byte[] src) {
|
||||
public FloatBuffer put(float[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutByte(address + position + i, src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int arrayOffset() {
|
||||
public int getArrayOffset() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer compact() {
|
||||
public FloatBuffer compact() {
|
||||
if(limit > capacity) throw new ArrayIndexOutOfBoundsException(limit);
|
||||
if(position > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
|
||||
if(position == limit) {
|
||||
return new EaglerLWJGLByteBuffer(0l, 0, false);
|
||||
return new EaglerLWJGLFloatBuffer(0l, 0, false);
|
||||
}
|
||||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + position, newAlloc, newLen);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLByteBuffer(newAlloc, newLen, true);
|
||||
return new EaglerLWJGLFloatBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getChar() {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
char c = (char)MemoryUtil.memGetShort(address + position);
|
||||
position += 2;
|
||||
return c;
|
||||
public boolean isDirect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putChar(char value) {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutShort(address + position, (short)value);
|
||||
position += 2;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getChar(int index) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return (char)MemoryUtil.memGetShort(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putChar(int index, char value) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + index, (short)value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort() {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
short s = MemoryUtil.memGetShort(address + position);
|
||||
position += 2;
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putShort(short value) {
|
||||
if(position + 2 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutShort(address + position, value);
|
||||
position += 2;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(int index) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetShort(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putShort(int index, short value) {
|
||||
if(index + 2 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer asShortBuffer() {
|
||||
return new EaglerLWJGLShortBuffer(address, capacity >> 1, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt() {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
int i = MemoryUtil.memGetInt(address + position);
|
||||
position += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putInt(int value) {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutInt(address + position, value);
|
||||
position += 4;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int index) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetInt(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putInt(int index, int value) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutInt(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer asIntBuffer() {
|
||||
return new EaglerLWJGLIntBuffer(address, capacity >> 2, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong() {
|
||||
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
long l = MemoryUtil.memGetLong(address + position);
|
||||
position += 8;
|
||||
return l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putLong(long value) {
|
||||
if(position + 8 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutLong(address + position, value);
|
||||
position += 8;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(int index) {
|
||||
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetLong(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putLong(int index, long value) {
|
||||
if(index + 8 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutLong(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat() {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
float f = MemoryUtil.memGetFloat(address + position);
|
||||
position += 4;
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putFloat(float value) {
|
||||
if(position + 4 > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutFloat(address + position, value);
|
||||
position += 4;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(int index) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetFloat(address + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer putFloat(int index, float value) {
|
||||
if(index + 4 > limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutFloat(address + index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer asFloatBuffer() {
|
||||
return new EaglerLWJGLFloatBuffer(address, capacity >> 2, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer mark() {
|
||||
public FloatBuffer mark() {
|
||||
mark = position;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer reset() {
|
||||
public FloatBuffer reset() {
|
||||
int m = mark;
|
||||
if(m < 0) throw new ArrayIndexOutOfBoundsException("Invalid mark: " + m);
|
||||
position = m;
|
||||
|
@ -383,7 +239,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer clear() {
|
||||
public FloatBuffer clear() {
|
||||
position = 0;
|
||||
limit = capacity;
|
||||
mark = -1;
|
||||
|
@ -391,7 +247,7 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer flip() {
|
||||
public FloatBuffer flip() {
|
||||
limit = position;
|
||||
position = 0;
|
||||
mark = -1;
|
||||
|
@ -399,21 +255,21 @@ public class EaglerLWJGLByteBuffer implements ByteBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer rewind() {
|
||||
public FloatBuffer rewind() {
|
||||
position = 0;
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer limit(int newLimit) {
|
||||
public FloatBuffer limit(int newLimit) {
|
||||
if(newLimit < 0 || newLimit > capacity) throw new ArrayIndexOutOfBoundsException(newLimit);
|
||||
limit = newLimit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer position(int newPosition) {
|
||||
public FloatBuffer position(int newPosition) {
|
||||
if(newPosition < 0 || newPosition > limit) throw new ArrayIndexOutOfBoundsException(newPosition);
|
||||
position = newPosition;
|
||||
return this;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
|
@ -18,8 +20,8 @@ import org.lwjgl.system.jemalloc.JEmalloc;
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
||||
|
||||
public class EaglerLWJGLIntBuffer implements IntBuffer {
|
||||
|
||||
final long address;
|
||||
final boolean original;
|
||||
|
||||
|
@ -30,11 +32,11 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
|
||||
private static final int SHIFT = 2;
|
||||
|
||||
EaglerLWJGLFloatBuffer(long address, int capacity, boolean original) {
|
||||
EaglerLWJGLIntBuffer(long address, int capacity, boolean original) {
|
||||
this(address, capacity, 0, capacity, -1, original);
|
||||
}
|
||||
|
||||
EaglerLWJGLFloatBuffer(long address, int capacity, int position, int limit, int mark, boolean original) {
|
||||
EaglerLWJGLIntBuffer(long address, int capacity, int position, int limit, int mark, boolean original) {
|
||||
this.address = address;
|
||||
this.capacity = capacity;
|
||||
this.position = position;
|
||||
|
@ -89,92 +91,88 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer slice() {
|
||||
return new EaglerLWJGLFloatBuffer(address + (position << SHIFT), limit - position, false);
|
||||
public IntBuffer slice() {
|
||||
return new EaglerLWJGLIntBuffer(address + (position << SHIFT), limit - position, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer duplicate() {
|
||||
return new EaglerLWJGLFloatBuffer(address, capacity, position, limit, mark, false);
|
||||
public IntBuffer duplicate() {
|
||||
return new EaglerLWJGLIntBuffer(address, capacity, position, limit, mark, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer asReadOnlyBuffer() {
|
||||
return new EaglerLWJGLFloatBuffer(address, capacity, position, limit, mark, false);
|
||||
public IntBuffer asReadOnlyBuffer() {
|
||||
return new EaglerLWJGLIntBuffer(address, capacity, position, limit, mark, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float get() {
|
||||
public int get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetFloat(address + ((position++) << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(float b) {
|
||||
public IntBuffer put(int b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutFloat(address + ((position++) << SHIFT), b);
|
||||
UnsafeUtils.setMemInt(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float get(int index) {
|
||||
public int get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetFloat(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(int index, float b) {
|
||||
public IntBuffer put(int index, int b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutFloat(address + (index << SHIFT), b);
|
||||
UnsafeUtils.setMemInt(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getElement(int index) {
|
||||
public int getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetFloat(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, float value) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutFloat(address + ((position++) << SHIFT), value);
|
||||
public void putElement(int index, int value) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
UnsafeUtils.setMemInt(address + (index << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer get(float[] dst, int offset, int length) {
|
||||
public IntBuffer get(int[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetFloat(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer get(float[] dst) {
|
||||
public IntBuffer get(int[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[i] = MemoryUtil.memGetFloat(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(FloatBuffer src) {
|
||||
if(src instanceof EaglerLWJGLFloatBuffer) {
|
||||
EaglerLWJGLFloatBuffer c = (EaglerLWJGLFloatBuffer)src;
|
||||
public IntBuffer put(IntBuffer src) {
|
||||
if(src instanceof EaglerLWJGLIntBuffer) {
|
||||
EaglerLWJGLIntBuffer c = (EaglerLWJGLIntBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + (c.position << SHIFT), address + (position << SHIFT), l << SHIFT);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutFloat(address + ((position + l) << SHIFT), src.get());
|
||||
UnsafeUtils.setMemInt(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
|
@ -182,21 +180,17 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(float[] src, int offset, int length) {
|
||||
public IntBuffer put(int[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutFloat(address + ((position + i) << SHIFT), src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer put(float[] src) {
|
||||
public IntBuffer put(int[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutFloat(address + ((position + i) << SHIFT), src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
|
@ -207,19 +201,22 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer compact() {
|
||||
public IntBuffer compact() {
|
||||
if(limit > capacity) throw new ArrayIndexOutOfBoundsException(limit);
|
||||
if(position > limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
|
||||
if(position == limit) {
|
||||
return new EaglerLWJGLFloatBuffer(0l, 0, false);
|
||||
return new EaglerLWJGLIntBuffer(0l, 0, false);
|
||||
}
|
||||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + (position << SHIFT), newAlloc, newLen << SHIFT);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLFloatBuffer(newAlloc, newLen, true);
|
||||
return new EaglerLWJGLIntBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -228,13 +225,13 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer mark() {
|
||||
public IntBuffer mark() {
|
||||
mark = position;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer reset() {
|
||||
public IntBuffer reset() {
|
||||
int m = mark;
|
||||
if(m < 0) throw new ArrayIndexOutOfBoundsException("Invalid mark: " + m);
|
||||
position = m;
|
||||
|
@ -242,7 +239,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer clear() {
|
||||
public IntBuffer clear() {
|
||||
position = 0;
|
||||
limit = capacity;
|
||||
mark = -1;
|
||||
|
@ -250,7 +247,7 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer flip() {
|
||||
public IntBuffer flip() {
|
||||
limit = position;
|
||||
position = 0;
|
||||
mark = -1;
|
||||
|
@ -258,21 +255,21 @@ public class EaglerLWJGLFloatBuffer implements FloatBuffer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer rewind() {
|
||||
public IntBuffer rewind() {
|
||||
position = 0;
|
||||
mark = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer limit(int newLimit) {
|
||||
public IntBuffer limit(int newLimit) {
|
||||
if(newLimit < 0 || newLimit > capacity) throw new ArrayIndexOutOfBoundsException(newLimit);
|
||||
limit = newLimit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatBuffer position(int newPosition) {
|
||||
public IntBuffer position(int newPosition) {
|
||||
if(newPosition < 0 || newPosition > limit) throw new ArrayIndexOutOfBoundsException(newPosition);
|
||||
position = newPosition;
|
||||
return this;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
|
@ -106,47 +108,45 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
|||
@Override
|
||||
public int get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetInt(address + ((position++) << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer put(int b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutInt(address + ((position++) << SHIFT), b);
|
||||
UnsafeUtils.setMemInt(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetInt(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer put(int index, int b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutInt(address + (index << SHIFT), b);
|
||||
UnsafeUtils.setMemInt(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetInt(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemInt(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, int value) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutInt(address + (index << SHIFT), value);
|
||||
UnsafeUtils.setMemInt(address + (index << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntBuffer get(int[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetInt(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
@ -154,9 +154,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
|||
@Override
|
||||
public IntBuffer get(int[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[i] = MemoryUtil.memGetInt(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
|
@ -167,14 +165,14 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
|||
EaglerLWJGLIntBuffer c = (EaglerLWJGLIntBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + (c.position << SHIFT), address + (position << SHIFT), l << SHIFT);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutInt(address + ((position + l) << SHIFT), src.get());
|
||||
UnsafeUtils.setMemInt(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
|
@ -184,9 +182,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
|||
@Override
|
||||
public IntBuffer put(int[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutInt(address + ((position + i) << SHIFT), src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
@ -194,9 +190,7 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
|||
@Override
|
||||
public IntBuffer put(int[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutInt(address + ((position + i) << SHIFT), src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
|
@ -217,7 +211,10 @@ public class EaglerLWJGLIntBuffer implements IntBuffer {
|
|||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + (position << SHIFT), newAlloc, newLen << SHIFT);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLIntBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.system.jemalloc.JEmalloc;
|
||||
|
||||
import net.lax1dude.unsafememcpy.UnsafeMemcpy;
|
||||
import net.lax1dude.unsafememcpy.UnsafeUtils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
|
@ -106,47 +108,45 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
|||
@Override
|
||||
public short get() {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
return MemoryUtil.memGetShort(address + ((position++) << SHIFT));
|
||||
return UnsafeUtils.getMemShort(address + ((position++) << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer put(short b) {
|
||||
if(position >= limit) throw new ArrayIndexOutOfBoundsException(position);
|
||||
MemoryUtil.memPutShort(address + ((position++) << SHIFT), b);
|
||||
UnsafeUtils.setMemShort(address + ((position++) << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short get(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetShort(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemShort(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer put(int index, short b) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + (index << SHIFT), b);
|
||||
UnsafeUtils.setMemShort(address + (index << SHIFT), b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getElement(int index) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
return MemoryUtil.memGetShort(address + (index << SHIFT));
|
||||
return UnsafeUtils.getMemShort(address + (index << SHIFT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putElement(int index, short value) {
|
||||
if(index >= limit) throw new ArrayIndexOutOfBoundsException(index);
|
||||
MemoryUtil.memPutShort(address + (index << SHIFT), value);
|
||||
UnsafeUtils.setMemShort(address + (index << SHIFT), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortBuffer get(short[] dst, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
dst[offset + i] = MemoryUtil.memGetShort(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, offset << SHIFT, address + (position << SHIFT), length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
@ -154,9 +154,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
|||
@Override
|
||||
public ShortBuffer get(short[] dst) {
|
||||
if(position + dst.length > limit) throw new ArrayIndexOutOfBoundsException(position + dst.length - 1);
|
||||
for(int i = 0; i < dst.length; ++i) {
|
||||
dst[i] = MemoryUtil.memGetShort(address + ((position + i) << SHIFT));
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignDst(dst, 0, address + (position << SHIFT), dst.length);
|
||||
position += dst.length;
|
||||
return this;
|
||||
}
|
||||
|
@ -167,14 +165,14 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
|||
EaglerLWJGLShortBuffer c = (EaglerLWJGLShortBuffer)src;
|
||||
int l = c.limit - c.position;
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
MemoryUtil.memCopy(c.address + (c.position << SHIFT), address + (position << SHIFT), l << SHIFT);
|
||||
UnsafeMemcpy.memcpy(address + (position << SHIFT), c.address + (c.position << SHIFT), l << SHIFT);
|
||||
position += l;
|
||||
c.position += l;
|
||||
}else {
|
||||
int l = src.remaining();
|
||||
if(position + l > limit) throw new ArrayIndexOutOfBoundsException(position + l - 1);
|
||||
for(int i = 0; i < l; ++i) {
|
||||
MemoryUtil.memPutShort(address + ((position + l) << SHIFT), src.get());
|
||||
UnsafeUtils.setMemInt(address + ((position + l) << SHIFT), src.get());
|
||||
}
|
||||
position += l;
|
||||
}
|
||||
|
@ -184,9 +182,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
|||
@Override
|
||||
public ShortBuffer put(short[] src, int offset, int length) {
|
||||
if(position + length > limit) throw new ArrayIndexOutOfBoundsException(position + length - 1);
|
||||
for(int i = 0; i < length; ++i) {
|
||||
MemoryUtil.memPutShort(address + ((position + i) << SHIFT), src[offset + i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, offset << SHIFT, length);
|
||||
position += length;
|
||||
return this;
|
||||
}
|
||||
|
@ -194,9 +190,7 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
|||
@Override
|
||||
public ShortBuffer put(short[] src) {
|
||||
if(position + src.length > limit) throw new ArrayIndexOutOfBoundsException(position + src.length - 1);
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
MemoryUtil.memPutShort(address + ((position + i) << SHIFT), src[i]);
|
||||
}
|
||||
UnsafeMemcpy.memcpyAlignSrc(address + (position << SHIFT), src, 0, src.length);
|
||||
position += src.length;
|
||||
return this;
|
||||
}
|
||||
|
@ -217,7 +211,10 @@ public class EaglerLWJGLShortBuffer implements ShortBuffer {
|
|||
|
||||
int newLen = limit - position;
|
||||
long newAlloc = JEmalloc.nje_malloc(newLen);
|
||||
MemoryUtil.memCopy(address + (position << SHIFT), newAlloc, newLen << SHIFT);
|
||||
if(newAlloc == 0l) {
|
||||
throw new OutOfMemoryError("Native je_malloc call returned null pointer!");
|
||||
}
|
||||
UnsafeMemcpy.memcpy(newAlloc, address + (position << SHIFT), newLen << SHIFT);
|
||||
|
||||
return new EaglerLWJGLShortBuffer(newAlloc, newLen, true);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2.BreakLoop;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class DebugFilesystem implements PlatformFilesystem.IFilesystemProvider {
|
||||
|
||||
public static DebugFilesystem initialize(File filesystemRoot) {
|
||||
if(!filesystemRoot.isDirectory() && !filesystemRoot.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create directory for virtual filesystem: " + filesystemRoot.getAbsolutePath());
|
||||
}
|
||||
return new DebugFilesystem(filesystemRoot);
|
||||
}
|
||||
|
||||
private final File filesystemRoot;
|
||||
|
||||
private DebugFilesystem(File root) {
|
||||
this.filesystemRoot = root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerDelete(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(!f.exists()) {
|
||||
PlatformFilesystem.logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
|
||||
return false;
|
||||
}
|
||||
if(f.delete()) {
|
||||
deleteParentIfEmpty(f);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer eaglerRead(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
ByteBuffer buf = PlatformRuntime.allocateByteBuffer((int)fileSize);
|
||||
try(FileInputStream is = new FileInputStream(f)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
buf.put(copyBuffer, 0, i);
|
||||
}
|
||||
if(buf.remaining() > 0) {
|
||||
throw new EaglerFileSystemException("ERROR: " + buf.remaining() + " bytes are remaining after reading: " + f.getAbsolutePath());
|
||||
}
|
||||
buf.flip();
|
||||
ByteBuffer tmp = buf;
|
||||
buf = null;
|
||||
return tmp;
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to read: " + f.getAbsolutePath(), e);
|
||||
}catch(ArrayIndexOutOfBoundsException ex) {
|
||||
throw new EaglerFileSystemException("ERROR: Expected " + fileSize + " bytes, buffer overflow reading: " + f.getAbsolutePath(), ex);
|
||||
}finally {
|
||||
if(buf != null) {
|
||||
PlatformRuntime.freeByteBuffer(buf);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
PlatformFilesystem.logger.warn("Tried to read file that doesn't exist: \"{}\"", f.getAbsolutePath());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
File f = getJREFile(pathName);
|
||||
File p = f.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
try(FileOutputStream fos = new FileOutputStream(f)) {
|
||||
byte[] copyBuffer = new byte[Math.min(4096, data.remaining())];
|
||||
int i;
|
||||
while((i = data.remaining()) > 0) {
|
||||
if(i > copyBuffer.length) {
|
||||
i = copyBuffer.length;
|
||||
}
|
||||
data.get(copyBuffer, 0, i);
|
||||
fos.write(copyBuffer, 0, i);
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to write: " + f.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerExists(String pathName) {
|
||||
return getJREFile(pathName).isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerMove(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(f2.exists()) {
|
||||
PlatformFilesystem.logger.warn("Tried to rename file \"{}\" to \"{}\" which already exists! File will be replaced");
|
||||
if(!f2.delete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(f1.renameTo(f2)) {
|
||||
deleteParentIfEmpty(f1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerCopy(String pathNameOld, String pathNameNew) {
|
||||
File f1 = getJREFile(pathNameOld);
|
||||
File f2 = getJREFile(pathNameNew);
|
||||
if(!f1.isFile()) {
|
||||
return -1;
|
||||
}
|
||||
if(f2.isDirectory()) {
|
||||
throw new EaglerFileSystemException("Destination file is a directory: " + f2.getAbsolutePath());
|
||||
}
|
||||
File p = f2.getParentFile();
|
||||
if(!p.isDirectory()) {
|
||||
if(!p.mkdirs()) {
|
||||
throw new EaglerFileSystemException("Could not create parent directory: " + p.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
int sz = 0;
|
||||
try(FileInputStream is = new FileInputStream(f1)) {
|
||||
try(FileOutputStream os = new FileOutputStream(f2)) {
|
||||
byte[] copyBuffer = new byte[4096];
|
||||
int i;
|
||||
while((i = is.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
os.write(copyBuffer, 0, i);
|
||||
sz += i;
|
||||
}
|
||||
}
|
||||
}catch (IOException e) {
|
||||
throw new EaglerFileSystemException("Failed to copy \"" + f1.getAbsolutePath() + "\" to file \"" + f2.getAbsolutePath() + "\"", e);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerSize(String pathName) {
|
||||
File f = getJREFile(pathName);
|
||||
if(f.isFile()) {
|
||||
long fileSize = f.length();
|
||||
if(fileSize > 2147483647L) throw new EaglerFileSystemException("Too large: " + fileSize + " @ " + f.getAbsolutePath());
|
||||
return (int)fileSize;
|
||||
}else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
|
||||
try {
|
||||
iterateFile(pathName, getJREFile(pathName), itr, recursive);
|
||||
}catch(BreakLoop ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private void iterateFile(String pathName, File f, VFSFilenameIterator itr, boolean recursive) {
|
||||
if(!f.exists()) {
|
||||
return;
|
||||
}
|
||||
if(!f.isDirectory()) {
|
||||
itr.next(pathName);
|
||||
return;
|
||||
}
|
||||
File[] fa = f.listFiles();
|
||||
for(int i = 0; i < fa.length; ++i) {
|
||||
File ff = fa[i];
|
||||
String fn = pathName + "/" + ff.getName();
|
||||
if(ff.isDirectory()) {
|
||||
if(recursive) {
|
||||
iterateFile(fn, ff, itr, true);
|
||||
}
|
||||
}else {
|
||||
itr.next(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File getJREFile(String path) {
|
||||
return new File(filesystemRoot, path);
|
||||
}
|
||||
|
||||
private void deleteParentIfEmpty(File f) {
|
||||
String[] s;
|
||||
while((f = f.getParentFile()) != null && (s = f.list()) != null && s.length == 0) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -124,4 +124,8 @@ public class DesktopClientConfigAdapter implements IClientConfigAdapter {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowVoiceClient() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.Color;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JProgressBar;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class FilesystemConvertingDialog extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private JPanel contentPane;
|
||||
private JProgressBar progressBar;
|
||||
|
||||
public FilesystemConvertingDialog(String title) {
|
||||
setIconImage(Toolkit.getDefaultToolkit().getImage("icon32.png"));
|
||||
setResizable(false);
|
||||
setAlwaysOnTop(true);
|
||||
setTitle("EaglercraftX 1.8");
|
||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
setBounds(100, 100, 420, 100);
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBackground(new Color(255, 255, 255));
|
||||
contentPane.setBorder(null);
|
||||
|
||||
setContentPane(contentPane);
|
||||
contentPane.setLayout(new BorderLayout(0, 0));
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
panel.setBackground(new Color(255, 255, 255));
|
||||
contentPane.add(panel, BorderLayout.SOUTH);
|
||||
panel.setLayout(new BorderLayout(0, 0));
|
||||
|
||||
progressBar = new JProgressBar();
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setPreferredSize(new Dimension(146, 20));
|
||||
progressBar.setMinimum(0);
|
||||
progressBar.setMaximum(512);
|
||||
panel.add(progressBar, BorderLayout.CENTER);
|
||||
|
||||
JLabel lblNewLabel = new JLabel(title);
|
||||
lblNewLabel.setFont(UIManager.getFont("PopupMenu.font"));
|
||||
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
contentPane.add(lblNewLabel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setProgressIndeterminate(boolean itr) {
|
||||
progressBar.setIndeterminate(itr);
|
||||
}
|
||||
|
||||
public void setProgressValue(int val) {
|
||||
progressBar.setValue(val);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,441 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem.IFilesystemProvider;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class JDBCFilesystem implements IFilesystemProvider {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("JDBCFilesystem");
|
||||
|
||||
private boolean newFilesystem = true;
|
||||
|
||||
private static volatile boolean cleanupThreadStarted = false;
|
||||
private static final Collection<JDBCFilesystem> jdbcFilesystems = new LinkedList();
|
||||
|
||||
private final String jdbcUri;
|
||||
private final String jdbcDriver;
|
||||
|
||||
private final Connection conn;
|
||||
private final PreparedStatement createStatement;
|
||||
private final PreparedStatement updateStatement;
|
||||
private final PreparedStatement readStatement;
|
||||
private final PreparedStatement existsStatement;
|
||||
private final PreparedStatement sizeStatement;
|
||||
private final PreparedStatement deleteStatement;
|
||||
private final PreparedStatement renameStatement;
|
||||
private final PreparedStatement iterateNonRecursive;
|
||||
private final PreparedStatement iterateRecursive;
|
||||
private boolean hasClosed = false;
|
||||
|
||||
private final Object mutex = new Object();
|
||||
|
||||
public static IFilesystemProvider initialize(String jdbcUri, String jdbcDriver) {
|
||||
Class driver;
|
||||
try {
|
||||
driver = Class.forName(jdbcDriver);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new EaglerFileSystemException("JDBC driver class not found in JRE: " + jdbcDriver, e);
|
||||
}
|
||||
Driver driverObj = null;
|
||||
Enumeration<Driver> registeredDriversItr = DriverManager.getDrivers();
|
||||
while(registeredDriversItr.hasMoreElements()) {
|
||||
Driver drv = registeredDriversItr.nextElement();
|
||||
if(drv.getClass().equals(driver)) {
|
||||
driverObj = drv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(driverObj == null) {
|
||||
logger.warn("The class \"{}\" is not a registered JDBC driver, eaglercraft will try all registered drivers...", jdbcDriver);
|
||||
}
|
||||
Properties props = new Properties();
|
||||
for(Entry<Object, Object> etr : System.getProperties().entrySet()) {
|
||||
if(etr.getKey() instanceof String) {
|
||||
String str = (String)etr.getKey();
|
||||
if(str.startsWith("eagler.jdbc.opts.")) {
|
||||
props.put(str.substring(17), etr.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("Connecting to database: \"{}\"", jdbcUri);
|
||||
Connection conn;
|
||||
try {
|
||||
if(driverObj != null) {
|
||||
conn = driverObj.connect(jdbcUri, props);
|
||||
}else {
|
||||
conn = DriverManager.getConnection(jdbcUri, props);
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("Failed to connect to database: \"" + jdbcUri + "\"", ex);
|
||||
}
|
||||
try {
|
||||
return new JDBCFilesystem(conn, jdbcUri, jdbcDriver);
|
||||
} catch (SQLException ex) {
|
||||
try {
|
||||
conn.close();
|
||||
}catch(SQLException ex2) {
|
||||
}
|
||||
throw new EaglerFileSystemException("Failed to initialize database: \"" + jdbcUri + "\"", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private JDBCFilesystem(Connection conn, String jdbcUri, String jdbcDriver) throws SQLException {
|
||||
this.conn = conn;
|
||||
this.jdbcUri = jdbcUri;
|
||||
this.jdbcDriver = jdbcDriver;
|
||||
try(Statement stmt = conn.createStatement()) {
|
||||
stmt.execute("CREATE TABLE IF NOT EXISTS "
|
||||
+ "\"eaglercraft_desktop_runtime_filesystem\" ("
|
||||
+ "\"FileName\" VARCHAR(1024) NOT NULL,"
|
||||
+ "\"FileSize\" INT NOT NULL,"
|
||||
+ "\"FileData\" BLOB NOT NULL,"
|
||||
+ "PRIMARY KEY(\"FileName\"))");
|
||||
|
||||
int totalFiles = 0;
|
||||
try(ResultSet resultSet = stmt.executeQuery("SELECT COUNT(*) AS total_files FROM eaglercraft_desktop_runtime_filesystem")) {
|
||||
if(resultSet.next()) {
|
||||
totalFiles = resultSet.getInt(1);
|
||||
}
|
||||
}
|
||||
logger.info("Loaded JDBC filesystem with {} files: \"{}\"", totalFiles, jdbcUri);
|
||||
if(totalFiles > 0) {
|
||||
newFilesystem = false;
|
||||
}
|
||||
}
|
||||
this.createStatement = conn.prepareStatement("INSERT INTO eaglercraft_desktop_runtime_filesystem (FileName, FileSize, FileData) VALUES(?,?,?)");
|
||||
this.updateStatement = conn.prepareStatement("UPDATE eaglercraft_desktop_runtime_filesystem SET FileSize = ?, FileData = ? WHERE FileName = ?");
|
||||
this.readStatement = conn.prepareStatement("SELECT FileData FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ? LIMIT 1");
|
||||
this.existsStatement = conn.prepareStatement("SELECT COUNT(FileName) AS has_object FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ? LIMIT 1");
|
||||
this.sizeStatement = conn.prepareStatement("SELECT FileSize FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ? LIMIT 1");
|
||||
this.deleteStatement = conn.prepareStatement("DELETE FROM eaglercraft_desktop_runtime_filesystem WHERE FileName = ?");
|
||||
this.renameStatement = conn.prepareStatement("UPDATE eaglercraft_desktop_runtime_filesystem SET FileName = ? WHERE FileName = ?");
|
||||
this.iterateNonRecursive = conn.prepareStatement("SELECT FileName FROM eaglercraft_desktop_runtime_filesystem WHERE FileName LIKE ? AND NOT FileName LIKE ?");
|
||||
this.iterateRecursive = conn.prepareStatement("SELECT FileName FROM eaglercraft_desktop_runtime_filesystem WHERE FileName LIKE ?");
|
||||
startCleanupThread();
|
||||
synchronized(jdbcFilesystems) {
|
||||
jdbcFilesystems.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNewFilesystem() {
|
||||
return newFilesystem;
|
||||
}
|
||||
|
||||
private static void startCleanupThread() {
|
||||
if(!cleanupThreadStarted) {
|
||||
cleanupThreadStarted = true;
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
synchronized(jdbcFilesystems) {
|
||||
if(!jdbcFilesystems.isEmpty()) {
|
||||
for(JDBCFilesystem fs : jdbcFilesystems) {
|
||||
fs.shutdown0();
|
||||
}
|
||||
jdbcFilesystems.clear();
|
||||
}
|
||||
}
|
||||
}, "JDBCFilesystemCleanup"));
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
shutdown0();
|
||||
synchronized(jdbcFilesystems) {
|
||||
jdbcFilesystems.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdown0() {
|
||||
synchronized(mutex) {
|
||||
if(!hasClosed) {
|
||||
hasClosed = true;
|
||||
logger.info("Disconnecting from database: \"{}\"", jdbcUri);
|
||||
try {
|
||||
shutdown1();
|
||||
}catch(Throwable t) {
|
||||
logger.error("Failed to disconnect from database: \"{}\"");
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdown1() throws SQLException {
|
||||
if(!conn.isClosed()) {
|
||||
quietClose(createStatement);
|
||||
quietClose(updateStatement);
|
||||
quietClose(readStatement);
|
||||
quietClose(existsStatement);
|
||||
quietClose(sizeStatement);
|
||||
quietClose(deleteStatement);
|
||||
quietClose(renameStatement);
|
||||
quietClose(iterateNonRecursive);
|
||||
quietClose(iterateRecursive);
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void quietClose(Statement stmt) {
|
||||
try {
|
||||
stmt.close();
|
||||
}catch(Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerDelete(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
deleteStatement.setString(1, pathName);
|
||||
int ret = deleteStatement.executeUpdate();
|
||||
if(ret == 0) {
|
||||
PlatformFilesystem.logger.warn("Tried to delete file that doesn't exist: \"{}\"", pathName);
|
||||
}
|
||||
return ret > 0;
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing delete!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer eaglerRead(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
readStatement.setString(1, pathName);
|
||||
byte[] has = null;
|
||||
try(ResultSet resultSet = readStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
has = resultSet.getBytes(1);
|
||||
}
|
||||
}
|
||||
if(has == null) {
|
||||
PlatformFilesystem.logger.warn("Tried to read file that doesn't exist: \"{}\"", pathName);
|
||||
return null;
|
||||
}
|
||||
ByteBuffer byteBuf = PlatformRuntime.allocateByteBuffer(has.length);
|
||||
byteBuf.put(has);
|
||||
byteBuf.flip();
|
||||
return byteBuf;
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing read!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerWrite(String pathName, ByteBuffer data) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
existsStatement.setString(1, pathName);
|
||||
boolean exists;
|
||||
try(ResultSet resultSet = existsStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
exists = resultSet.getInt(1) > 0;
|
||||
}else {
|
||||
exists = false;
|
||||
}
|
||||
}
|
||||
byte[] cp = new byte[data.remaining()];
|
||||
data.get(cp);
|
||||
if(exists) {
|
||||
updateStatement.setInt(1, cp.length);
|
||||
updateStatement.setBytes(2, cp);
|
||||
updateStatement.setString(3, pathName);
|
||||
if(updateStatement.executeUpdate() == 0) {
|
||||
throw new EaglerFileSystemException("SQL file update query did not update any rows!");
|
||||
}
|
||||
}else {
|
||||
createStatement.setString(1, pathName);
|
||||
createStatement.setInt(2, cp.length);
|
||||
createStatement.setBytes(3, cp);
|
||||
createStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing write!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerExists(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
existsStatement.setString(1, pathName);
|
||||
try(ResultSet resultSet = existsStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
return resultSet.getInt(1) > 0;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing exists!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eaglerMove(String pathNameOld, String pathNameNew) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
renameStatement.setString(1, pathNameNew);
|
||||
renameStatement.setString(2, pathNameOld);
|
||||
return renameStatement.executeUpdate() > 0;
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing move!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerCopy(String pathNameOld, String pathNameNew) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
readStatement.setString(1, pathNameOld);
|
||||
try(ResultSet resultSet = readStatement.executeQuery()) {
|
||||
byte[] has = null;
|
||||
if(resultSet.next()) {
|
||||
has = resultSet.getBytes(1);
|
||||
}
|
||||
if(has == null) {
|
||||
return -1;
|
||||
}
|
||||
existsStatement.setString(1, pathNameNew);
|
||||
boolean exists;
|
||||
try(ResultSet resultSet2 = existsStatement.executeQuery()) {
|
||||
if(resultSet2.next()) {
|
||||
exists = resultSet2.getInt(1) > 0;
|
||||
}else {
|
||||
exists = false;
|
||||
}
|
||||
}
|
||||
if(exists) {
|
||||
updateStatement.setInt(1, has.length);
|
||||
updateStatement.setBytes(2, has);
|
||||
updateStatement.setString(3, pathNameNew);
|
||||
if(updateStatement.executeUpdate() == 0) {
|
||||
throw new EaglerFileSystemException("SQL file update query did not update any rows!");
|
||||
}
|
||||
}else {
|
||||
createStatement.setString(1, pathNameNew);
|
||||
createStatement.setInt(2, has.length);
|
||||
createStatement.setBytes(3, has);
|
||||
createStatement.executeUpdate();
|
||||
}
|
||||
return has.length;
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing copy!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eaglerSize(String pathName) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
sizeStatement.setString(1, pathName);
|
||||
try(ResultSet resultSet = sizeStatement.executeQuery()) {
|
||||
if(resultSet.next()) {
|
||||
return resultSet.getInt(1);
|
||||
}else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing size!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eaglerIterate(String pathName, VFSFilenameIterator itr, boolean recursive) {
|
||||
try {
|
||||
synchronized(mutex) {
|
||||
if(hasClosed || conn.isClosed()) {
|
||||
throw new SQLException("Filesystem database connection is closed!");
|
||||
}
|
||||
PreparedStatement stmt;
|
||||
if(recursive) {
|
||||
stmt = iterateRecursive;
|
||||
stmt.setString(1, pathName + (!pathName.endsWith("/") ? "/%" : "%"));;
|
||||
}else {
|
||||
stmt = iterateNonRecursive;
|
||||
if(!pathName.endsWith("/")) {
|
||||
pathName += "/";
|
||||
}
|
||||
stmt.setString(1, pathName + "%");
|
||||
stmt.setString(2, pathName + "%/%");
|
||||
}
|
||||
try(ResultSet resultSet = stmt.executeQuery()) {
|
||||
while(resultSet.next()) {
|
||||
try {
|
||||
itr.next(resultSet.getString(1));
|
||||
}catch(VFSIterator2.BreakLoop exx) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(SQLException ex) {
|
||||
throw new EaglerFileSystemException("JDBC exception thrown while executing iterate!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem.IFilesystemProvider;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.EaglerFileSystemException;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class JDBCFilesystemConverter {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("JDBCFilesystemConverter");
|
||||
|
||||
public static void convertFilesystem(String title, File oldFS, IFilesystemProvider newFS, boolean deleteOld) {
|
||||
FilesystemConvertingDialog progressDialog = new FilesystemConvertingDialog(title);
|
||||
try {
|
||||
progressDialog.setProgressIndeterminate(true);
|
||||
progressDialog.setLocationRelativeTo(null);
|
||||
progressDialog.setVisible(true);
|
||||
|
||||
String slug = oldFS.getAbsolutePath();
|
||||
List<String> filesToCopy = new ArrayList();
|
||||
logger.info("Discovering files to convert...");
|
||||
iterateFolder(slug.length(), oldFS, filesToCopy);
|
||||
logger.info("Found {} files in the old directory", filesToCopy.size());
|
||||
|
||||
progressDialog.setProgressIndeterminate(false);
|
||||
progressDialog.setProgressValue(0);
|
||||
|
||||
int progCounter = 0;
|
||||
int lastProgUpdate = 0;
|
||||
byte[] copyArray = new byte[4096];
|
||||
|
||||
int l = filesToCopy.size();
|
||||
for(int i = 0; i < l; ++i) {
|
||||
String str = filesToCopy.get(i);
|
||||
File f = new File(oldFS, str);
|
||||
try(InputStream is = new FileInputStream(f)) {
|
||||
ByteBuffer copyBuffer = PlatformRuntime.allocateByteBuffer((int)f.length());
|
||||
try {
|
||||
int j;
|
||||
while(copyBuffer.hasRemaining() && (j = is.read(copyArray, 0, copyArray.length)) != -1) {
|
||||
copyBuffer.put(copyArray, 0, j);
|
||||
}
|
||||
copyBuffer.flip();
|
||||
progCounter += copyBuffer.remaining();
|
||||
newFS.eaglerWrite(str, copyBuffer);
|
||||
}finally {
|
||||
PlatformRuntime.freeByteBuffer(copyBuffer);
|
||||
}
|
||||
if(progCounter - lastProgUpdate > 25000) {
|
||||
lastProgUpdate = progCounter;
|
||||
logger.info("Converted {}/{} files, {} bytes to JDBC format...", (i + 1), l, progCounter);
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
throw new EaglerFileSystemException("Failed to convert file: \"" + f.getAbsolutePath() + "\"", ex);
|
||||
}
|
||||
progressDialog.setProgressValue(i * 512 / (l - 1));
|
||||
}
|
||||
|
||||
logger.info("Converted {}/{} files successfully!", l, l);
|
||||
|
||||
if(deleteOld) {
|
||||
logger.info("Deleting old filesystem...");
|
||||
progressDialog.setProgressIndeterminate(true);
|
||||
deleteOldFolder(oldFS);
|
||||
logger.info("Delete complete!");
|
||||
}
|
||||
}finally {
|
||||
progressDialog.setVisible(false);
|
||||
progressDialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void iterateFolder(int slug, File file, List<String> ret) {
|
||||
File[] f = file.listFiles();
|
||||
if(f == null) {
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < f.length; ++i) {
|
||||
File ff = f[i];
|
||||
if(ff.isDirectory()) {
|
||||
iterateFolder(slug, ff, ret);
|
||||
}else {
|
||||
String str = ff.getAbsolutePath();
|
||||
if(str.length() > slug) {
|
||||
str = str.substring(slug).replace('\\', '/');
|
||||
if(str.startsWith("/")) {
|
||||
str = str.substring(1);
|
||||
}
|
||||
ret.add(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteOldFolder(File file) {
|
||||
File[] f = file.listFiles();
|
||||
for(int i = 0; i < f.length; ++i) {
|
||||
if(f[i].isDirectory()) {
|
||||
deleteOldFolder(f[i]);
|
||||
}else {
|
||||
f[i].delete();
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import javax.swing.UnsupportedLookAndFeelException;
|
|||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformANGLE;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.program.ShaderSource;
|
||||
|
@ -43,15 +44,9 @@ public class LWJGLEntryPoint {
|
|||
|
||||
boolean hideRenderDocDialog = false;
|
||||
for(int i = 0; i < args.length; ++i) {
|
||||
if(args[i].equalsIgnoreCase("highp")) {
|
||||
ShaderSource.setHighP(true);
|
||||
}
|
||||
if(args[i].equalsIgnoreCase("hide-renderdoc")) {
|
||||
hideRenderDocDialog = true;
|
||||
}
|
||||
if(args[i].equalsIgnoreCase("fullscreen")) {
|
||||
PlatformInput.setStartupFullscreen(true);
|
||||
}
|
||||
}
|
||||
|
||||
if(!hideRenderDocDialog) {
|
||||
|
@ -66,7 +61,7 @@ public class LWJGLEntryPoint {
|
|||
lr.dispose();
|
||||
}
|
||||
|
||||
getANGLEPlatformFromArgs(args);
|
||||
getPlatformOptionsFromArgs(args);
|
||||
|
||||
RelayManager.relayManager.load(EagRuntime.getStorage("r"));
|
||||
|
||||
|
@ -81,12 +76,22 @@ public class LWJGLEntryPoint {
|
|||
|
||||
}
|
||||
|
||||
private static void getANGLEPlatformFromArgs(String[] args) {
|
||||
private static void getPlatformOptionsFromArgs(String[] args) {
|
||||
for(int i = 0; i < args.length; ++i) {
|
||||
EnumPlatformANGLE angle = EnumPlatformANGLE.fromId(args[i]);
|
||||
if(angle != EnumPlatformANGLE.DEFAULT) {
|
||||
PlatformRuntime.requestANGLE(angle);
|
||||
break;
|
||||
if(args[i].equalsIgnoreCase("fullscreen")) {
|
||||
PlatformInput.setStartupFullscreen(true);
|
||||
}else if(args[i].equalsIgnoreCase("highp")) {
|
||||
ShaderSource.setHighP(true);
|
||||
}else if(args[i].startsWith("jdbc:")) {
|
||||
if(i < args.length - 1) {
|
||||
PlatformFilesystem.setUseJDBC(args[i]);
|
||||
PlatformFilesystem.setJDBCDriverClass(args[++i]);
|
||||
}
|
||||
}else {
|
||||
EnumPlatformANGLE angle = EnumPlatformANGLE.fromId(args[i]);
|
||||
if(angle != EnumPlatformANGLE.DEFAULT) {
|
||||
PlatformRuntime.requestANGLE(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.internal.lwjgl;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.Display;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.Keyboard;
|
||||
import net.lax1dude.eaglercraft.v1_8.Mouse;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants;
|
||||
|
||||
public class TestProgram {
|
||||
|
||||
private static boolean grab = false;
|
||||
|
||||
public static void main_(String[] args) {
|
||||
|
||||
while(!Display.isCloseRequested()) {
|
||||
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
Display.update();
|
||||
|
||||
while(Keyboard.next()) {
|
||||
if(Keyboard.getEventKey() == KeyboardConstants.KEY_E && Keyboard.getEventKeyState()) {
|
||||
grab = !grab;
|
||||
Mouse.setGrabbed(grab);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("" + Mouse.getDX() + ", " + Mouse.getDY());
|
||||
|
||||
EagUtils.sleep(100l);
|
||||
}
|
||||
|
||||
EagRuntime.destroy();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -28,4 +28,8 @@ public class Config {
|
|||
public static boolean audioEnabled() {
|
||||
return Minecraft.getMinecraft().gameSettings.enableSound;
|
||||
}
|
||||
|
||||
public static boolean animateTick() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ public class Display {
|
|||
return PlatformInput.isCloseRequested();
|
||||
}
|
||||
|
||||
public static void setVSync(boolean enable) {
|
||||
PlatformInput.setVSync(enable);
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
PlatformInput.update();
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ public class EaglercraftVersion {
|
|||
|
||||
/// Customize these to fit your fork:
|
||||
|
||||
public static final String projectForkName = "EaglercraftX";
|
||||
public static final String projectForkVersion = "u27";
|
||||
public static final String projectForkVendor = "lax1dude";
|
||||
public static final String projectForkName = "EaglerfastX";
|
||||
public static final String projectForkVersion = "u29";
|
||||
public static final String projectForkVendor = "hoosiertransfer";
|
||||
|
||||
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
|
||||
|
||||
|
@ -20,7 +20,7 @@ public class EaglercraftVersion {
|
|||
public static final String projectOriginName = "EaglercraftX";
|
||||
public static final String projectOriginAuthor = "lax1dude";
|
||||
public static final String projectOriginRevision = "1.8";
|
||||
public static final String projectOriginVersion = "u27";
|
||||
public static final String projectOriginVersion = "u29";
|
||||
|
||||
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
|
||||
|
||||
|
@ -31,7 +31,7 @@ public class EaglercraftVersion {
|
|||
public static final boolean enableUpdateService = false;
|
||||
|
||||
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
|
||||
public static final int updateBundlePackageVersionInt = 24;
|
||||
public static final int updateBundlePackageVersionInt = 29;
|
||||
|
||||
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;
|
||||
|
||||
|
|
|
@ -67,4 +67,6 @@ public interface IClientConfigAdapter {
|
|||
boolean isCheckRelaysForUpdates();
|
||||
|
||||
boolean isEnableSignatureBadge();
|
||||
|
||||
boolean isAllowVoiceClient();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -152,7 +152,7 @@ public class EaglercraftGPU {
|
|||
currentList = null;
|
||||
}
|
||||
|
||||
public static void glCallList(int displayList) {
|
||||
public static final void glCallList(int displayList) {
|
||||
DisplayList dp = mapDisplayListsGL.get(displayList);
|
||||
if(dp == null) {
|
||||
throw new NullPointerException("Tried to call a display list that does not exist: " + displayList);
|
||||
|
@ -488,14 +488,24 @@ public class EaglercraftGPU {
|
|||
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 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);
|
||||
}
|
||||
|
||||
public static void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
|
||||
public static final void createFramebufferHDR16FTexture(int target, int level, int w, int h, int format, ByteBuffer pixelData) {
|
||||
createFramebufferHDR16FTexture(target, level, w, h, format, false, pixelData);
|
||||
}
|
||||
|
||||
|
@ -530,15 +540,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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
int internalFormat;
|
||||
switch(format) {
|
||||
|
@ -555,7 +565,7 @@ public class EaglercraftGPU {
|
|||
default:
|
||||
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 {
|
||||
if(allow16bitFallback) {
|
||||
if(hasFramebufferHDR16FSupport) {
|
||||
|
@ -585,7 +595,13 @@ public class EaglercraftGPU {
|
|||
}else {
|
||||
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.");
|
||||
}
|
||||
DrawUtils.init();
|
||||
|
@ -612,4 +628,12 @@ public class EaglercraftGPU {
|
|||
public static final boolean checkHasHDRFramebufferSupport() {
|
||||
return hasFramebufferHDR16FSupport || hasFramebufferHDR32FSupport;
|
||||
}
|
||||
|
||||
public static final boolean checkHasHDRFramebufferSupportWithFilter() {
|
||||
return hasFramebufferHDR16FSupport || (hasFramebufferHDR32FSupport && hasLinearHDR32FSupport);
|
||||
}
|
||||
|
||||
public static final boolean checkLinearHDR32FSupport() {
|
||||
return hasLinearHDR32FSupport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -983,6 +983,30 @@ public class GlStateManager {
|
|||
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) {
|
||||
stateColorR = colorRed;
|
||||
stateColorG = colorGreen;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -3984,11 +3984,11 @@ public class EaglerDeferredPipeline {
|
|||
}
|
||||
|
||||
public static final boolean isSupported() {
|
||||
return EaglercraftGPU.checkHasHDRFramebufferSupport();
|
||||
return EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter();
|
||||
}
|
||||
|
||||
public static final String getReasonUnsupported() {
|
||||
if(!EaglercraftGPU.checkHasHDRFramebufferSupport()) {
|
||||
if(!EaglercraftGPU.checkHasHDRFramebufferSupportWithFilter()) {
|
||||
return I18n.format("shaders.gui.unsupported.reason.hdrFramebuffer");
|
||||
}else {
|
||||
return null;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -43,7 +43,14 @@ public enum DefaultSkins {
|
|||
ZOMBIE(21, "Zombie", new ResourceLocation("eagler:skins/22.zombie.png"), SkinModel.ZOMBIE),
|
||||
PIG(22, "Pig", new ResourceLocation("eagler:skins/23.pig.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[29];
|
||||
public static final DefaultSkins[] defaultSkinsMap = new DefaultSkins[24];
|
||||
|
||||
public final int id;
|
||||
|
|
|
@ -38,8 +38,13 @@ public class EaglerProfile {
|
|||
|
||||
public static int presetSkinId;
|
||||
public static int customSkinId;
|
||||
|
||||
public static int presetCapeId;
|
||||
public static int customCapeId;
|
||||
|
||||
public static final List<CustomSkin> customSkins = new ArrayList();
|
||||
|
||||
public static final List<CustomCape> customCapes = new ArrayList();
|
||||
|
||||
public static final EaglercraftRandom rand;
|
||||
|
||||
|
@ -81,6 +86,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() {
|
||||
return Minecraft.getMinecraft().getSession().getProfile().getId();
|
||||
}
|
||||
|
@ -116,6 +140,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) {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
if(customSkins.get(i).name.equalsIgnoreCase(name)) {
|
||||
|
@ -125,6 +168,15 @@ public class EaglerProfile {
|
|||
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) {
|
||||
if(doesSkinExist(fileName)) {
|
||||
String newName;
|
||||
|
@ -141,6 +193,22 @@ public class EaglerProfile {
|
|||
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() {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
customSkins.get(i).delete();
|
||||
|
@ -148,6 +216,13 @@ public class EaglerProfile {
|
|||
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() {
|
||||
read(EagRuntime.getStorage("p"));
|
||||
}
|
||||
|
@ -195,6 +270,9 @@ public class EaglerProfile {
|
|||
presetSkinId = profile.getInteger("presetSkin");
|
||||
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();
|
||||
|
||||
if(!loadUsername.isEmpty()) {
|
||||
|
@ -220,6 +298,20 @@ public class EaglerProfile {
|
|||
newSkin.load();
|
||||
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(customSkinId < 0 || customSkinId >= customSkins.size()) {
|
||||
|
@ -239,6 +331,8 @@ public class EaglerProfile {
|
|||
NBTTagCompound profile = new NBTTagCompound();
|
||||
profile.setInteger("presetSkin", presetSkinId);
|
||||
profile.setInteger("customSkin", customSkinId);
|
||||
profile.setInteger("presetCape", presetCapeId);
|
||||
profile.setInteger("customCape", customCapeId);
|
||||
profile.setString("username", username);
|
||||
NBTTagList skinsList = new NBTTagList();
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
|
@ -250,6 +344,15 @@ public class EaglerProfile {
|
|||
skinsList.appendTag(skin);
|
||||
}
|
||||
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();
|
||||
try {
|
||||
CompressedStreamTools.writeCompressed(profile, bao);
|
||||
|
@ -280,9 +383,13 @@ public class EaglerProfile {
|
|||
|
||||
setName(username);
|
||||
|
||||
presetSkinId = rand.nextInt(DefaultSkins.defaultSkinsMap.length);
|
||||
do {
|
||||
presetSkinId = rand.nextInt(DefaultSkins.defaultSkinsMap.length);
|
||||
}while(DefaultSkins.defaultSkinsMap[presetSkinId].model.highPoly != null);
|
||||
customSkinId = -1;
|
||||
|
||||
|
||||
presetCapeId = 0;
|
||||
customCapeId = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
private boolean dropDownOpen = false;
|
||||
private String[] dropDownOptions;
|
||||
private int slotsVisible = 0;
|
||||
private int selectedSlot = 0;
|
||||
protected int selectedSlot = 0;
|
||||
private int scrollPos = -1;
|
||||
private int skinsHeight = 0;
|
||||
private boolean dragging = false;
|
||||
|
@ -102,10 +102,24 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xFFA0A0A0);
|
||||
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xFF000015);
|
||||
|
||||
int skid = selectedSlot - EaglerProfile.customSkins.size();
|
||||
if(skid < 0) {
|
||||
skid = 0;
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(skinX + 2, skinY - 9, 0.0f);
|
||||
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();
|
||||
if(dropDownOpen || newSkinWaitSteveOrAlex) {
|
||||
|
@ -113,6 +127,10 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}else {
|
||||
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;
|
||||
skinY = height / 6 + 82;
|
||||
|
@ -184,7 +202,6 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
|
||||
int xx = width / 2 - 80;
|
||||
int yy = height / 6 + 130;
|
||||
int numberOfCustomSkins = EaglerProfile.customSkins.size();
|
||||
|
||||
if(newSkinWaitSteveOrAlex && selectedSlot < numberOfCustomSkins) {
|
||||
skinWidth = 70;
|
||||
|
@ -217,8 +234,8 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
drawCenteredString(fontRendererObj, "Steve", skinX + skinWidth / 2, skinY + skinHeight + 6, cc);
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(newSkin.getResource());
|
||||
SkinPreviewRenderer.renderBiped(xx, yy, mx, my, SkinModel.STEVE);
|
||||
SkinPreviewRenderer.renderPreview(xx, yy, mx, my, false, SkinModel.STEVE, newSkin.getResource(),
|
||||
EaglerProfile.getActiveCapeResourceLocation());
|
||||
|
||||
skinX = width / 2 + 20;
|
||||
skinY = height / 4;
|
||||
|
@ -242,8 +259,8 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
drawCenteredString(fontRendererObj, "Alex", skinX + skinWidth / 2, skinY + skinHeight + 8, cc);
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(newSkin.getResource());
|
||||
SkinPreviewRenderer.renderBiped(xx, yy, mx, my, SkinModel.ALEX);
|
||||
SkinPreviewRenderer.renderPreview(xx, yy, mx, my, false, SkinModel.ALEX, newSkin.getResource(),
|
||||
EaglerProfile.getActiveCapeResourceLocation());
|
||||
}else {
|
||||
skinX = this.width / 2 - 120;
|
||||
skinY = this.height / 6 + 8;
|
||||
|
@ -251,20 +268,17 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
skinHeight = 130;
|
||||
|
||||
ResourceLocation texture;
|
||||
SkinModel model;
|
||||
if(selectedSlot < numberOfCustomSkins) {
|
||||
CustomSkin customSkin = EaglerProfile.customSkins.get(selectedSlot);
|
||||
texture = customSkin.getResource();
|
||||
model = customSkin.model;
|
||||
if(skid < 0) {
|
||||
texture = EaglerProfile.customSkins.get(selectedSlot).getResource();
|
||||
}else {
|
||||
DefaultSkins defaultSkin = DefaultSkins.defaultSkinsMap[selectedSlot - numberOfCustomSkins];
|
||||
texture = defaultSkin.location;
|
||||
model = defaultSkin.model;
|
||||
texture = DefaultSkins.getSkinFromId(skid).location;
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(texture);
|
||||
SkinPreviewRenderer.renderBiped(xx, yy, newSkinWaitSteveOrAlex ? width / 2 : mx, newSkinWaitSteveOrAlex ? height / 2 : my, model);
|
||||
SkinPreviewRenderer.renderPreview(xx, yy, newSkinWaitSteveOrAlex ? width / 2 : mx,
|
||||
newSkinWaitSteveOrAlex ? height / 2 : my, false, selectedSkinModel, texture,
|
||||
EaglerProfile.getActiveCapeResourceLocation());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void handleMouseInput() throws IOException {
|
||||
|
@ -287,12 +301,14 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
if(!dropDownOpen) {
|
||||
if(par1GuiButton.id == 0) {
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
this.mc.displayGuiScreen((GuiScreen) parent);
|
||||
}else if(par1GuiButton.id == 1) {
|
||||
EagRuntime.displayFileChooser("image/png", "png");
|
||||
}else if(par1GuiButton.id == 2) {
|
||||
EaglerProfile.clearCustomSkins();
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
updateOptions();
|
||||
selectedSlot = 0;
|
||||
}
|
||||
|
@ -335,6 +351,7 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
newSkinWaitSteveOrAlex = true;
|
||||
updateOptions();
|
||||
safeProfile();
|
||||
EaglerProfile.save();
|
||||
}
|
||||
}else {
|
||||
EagRuntime.showPopup("The selected image '" + result.fileName + "' is not the right size!\nEaglercraft only supports 64x32 or 64x64 skins");
|
||||
|
@ -387,21 +404,37 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
|
||||
protected void mouseClicked(int mx, int my, int button) {
|
||||
super.mouseClicked(mx, my, button);
|
||||
usernameField.mouseClicked(mx, my, 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();
|
||||
EaglerProfile.save();
|
||||
mc.displayGuiScreen(new GuiScreenImportExportProfile(this));
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
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) {
|
||||
int skinX = width / 2 - 90;
|
||||
int skinY = height / 4;
|
||||
skinX = width / 2 - 90;
|
||||
skinY = height / 4;
|
||||
int skinWidth = 70;
|
||||
int skinHeight = 120;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
|
@ -423,8 +456,8 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
return;
|
||||
}else if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
int skinX = width / 2 - 120;
|
||||
int skinY = height / 6 + 18;
|
||||
skinX = width / 2 - 120;
|
||||
skinY = height / 6 + 18;
|
||||
int skinWidth = 80;
|
||||
int skinHeight = 120;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
|
@ -434,8 +467,8 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
}
|
||||
}
|
||||
}
|
||||
int skinX = width / 2 + 140 - 40;
|
||||
int skinY = height / 6 + 82;
|
||||
skinX = width / 2 + 140 - 40;
|
||||
skinY = height / 6 + 82;
|
||||
|
||||
if(mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) {
|
||||
dropDownOpen = !dropDownOpen;
|
||||
|
@ -448,27 +481,26 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
int skinHeight = skinsHeight;
|
||||
|
||||
if(!(mx >= skinX && mx < (skinX + skinWidth) && my >= skinY && my < (skinY + skinHeight + 22))) {
|
||||
dropDownOpen = false;
|
||||
dragging = false;
|
||||
return;
|
||||
}
|
||||
|
||||
skinY += 21;
|
||||
|
||||
if(dropDownOpen && !dragging) {
|
||||
if(dropDownOpen) {
|
||||
dropDownOpen = false;
|
||||
return;
|
||||
}
|
||||
}else if(dropDownOpen && !dragging) {
|
||||
skinY += 21;
|
||||
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;
|
||||
}
|
||||
if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i * 10 + 5) && my < (skinY + i * 10 + 15)) {
|
||||
selectedSlot = i + scrollPos;
|
||||
dropDownOpen = false;
|
||||
dragging = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.mouseClicked(mx, my, button);
|
||||
}
|
||||
|
||||
protected void safeProfile() {
|
||||
|
@ -488,7 +520,6 @@ public class GuiScreenEditProfile extends GuiScreen {
|
|||
name = name.substring(0, 16);
|
||||
}
|
||||
EaglerProfile.setName(name);
|
||||
EaglerProfile.save();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
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 {
|
||||
// disable fnaw skins
|
||||
LONG_ARMS(null, null, null, null, null, null, 0.0f, null),
|
||||
WEIRD_CLIMBER_DUDE(null, null, null, null, null, null, 0.0f, null),
|
||||
LAXATIVE_DUDE(null, null, null, null, null, null, 0.0f, null),
|
||||
BABY_CHARLES(null, null, null, null, null, null, 0.0f, null),
|
||||
BABY_WINSTON(null, null, null, null, null, null, 0.0f, null);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -321,6 +321,7 @@ public class ServerSkinCache {
|
|||
}
|
||||
skinsCache.clear();
|
||||
waitingSkins.clear();
|
||||
evictedSkins.clear();
|
||||
}
|
||||
|
||||
public void evictSkin(EaglercraftUUID uuid) {
|
||||
|
|
|
@ -35,6 +35,56 @@ public class SkinConverter {
|
|||
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,
|
||||
int sy1, int sx2, int sy2, int imgSrcWidth, int imgDstWidth) {
|
||||
if(dx1 > dx2) {
|
||||
|
|
|
@ -19,15 +19,19 @@ import java.util.Map;
|
|||
*
|
||||
*/
|
||||
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 width;
|
||||
public final int height;
|
||||
public final String profileSkinType;
|
||||
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 SkinModel(int id, int w, int h, String profileSkinType, boolean sanitize) {
|
||||
|
@ -36,6 +40,16 @@ public enum SkinModel {
|
|||
this.height = h;
|
||||
this.profileSkinType = profileSkinType;
|
||||
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) {
|
||||
|
|
|
@ -58,6 +58,9 @@ public class SkinPackets {
|
|||
modelId = SkinModel.STEVE;
|
||||
}
|
||||
}
|
||||
if(modelId.highPoly != null) {
|
||||
modelId = SkinModel.STEVE;
|
||||
}
|
||||
int bytesToRead = modelId.width * modelId.height * 4;
|
||||
byte[] readSkin = new byte[bytesToRead];
|
||||
buffer.readBytes(readSkin);
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
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.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.client.model.ModelPlayer;
|
||||
import net.minecraft.client.model.ModelZombie;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
|
@ -36,7 +40,11 @@ public class SkinPreviewRenderer {
|
|||
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;
|
||||
switch(skinModel) {
|
||||
case STEVE:
|
||||
|
@ -49,6 +57,17 @@ public class SkinPreviewRenderer {
|
|||
case ZOMBIE:
|
||||
model = playerModelZombie;
|
||||
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();
|
||||
|
@ -65,12 +84,95 @@ public class SkinPreviewRenderer {
|
|||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
GlStateManager.translate(0.0f, 1.0f, 0.0f);
|
||||
GlStateManager.rotate(((y - my) * -0.06f), 1.0f, 0.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(((x - mx) * 0.06f), 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);
|
||||
|
||||
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.disableLighting();
|
||||
}
|
||||
|
|
|
@ -294,6 +294,19 @@ public class ConnectionHandshake {
|
|||
d.writeShort(packetSkin.length);
|
||||
d.write(packetSkin);
|
||||
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();
|
||||
if(packetSignatureData != null) {
|
||||
|
|
|
@ -140,4 +140,7 @@ public class GuiScreenAddRelay extends GuiScreen {
|
|||
super.drawScreen(par1, par2, par3);
|
||||
}
|
||||
|
||||
public boolean blockPTTKey() {
|
||||
return this.serverName.isFocused() || this.serverAddress.isFocused();
|
||||
}
|
||||
}
|
|
@ -117,7 +117,7 @@ public class GuiScreenLANConnecting extends GuiScreen {
|
|||
this.mc.clearTitles();
|
||||
networkManager.setConnectionState(EnumConnectionState.LOGIN);
|
||||
networkManager.setNetHandler(new NetHandlerSingleplayerLogin(networkManager, mc, parent));
|
||||
networkManager.sendPacket(new C00PacketLoginStart(this.mc.getSession().getProfile(), EaglerProfile.getSkinPacket()));
|
||||
networkManager.sendPacket(new C00PacketLoginStart(this.mc.getSession().getProfile(), EaglerProfile.getSkinPacket(), EaglerProfile.getCapePacket()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class GuiScreenSingleplayerConnecting extends GuiScreen {
|
|||
this.mc.clearTitles();
|
||||
this.networkManager.setConnectionState(EnumConnectionState.LOGIN);
|
||||
this.networkManager.setNetHandler(new NetHandlerSingleplayerLogin(this.networkManager, this.mc, this.menu));
|
||||
this.networkManager.sendPacket(new C00PacketLoginStart(this.mc.getSession().getProfile(), EaglerProfile.getSkinPacket()));
|
||||
this.networkManager.sendPacket(new C00PacketLoginStart(this.mc.getSession().getProfile(), EaglerProfile.getSkinPacket(), EaglerProfile.getCapePacket()));
|
||||
}
|
||||
try {
|
||||
this.networkManager.processReceivedPackets();
|
||||
|
|
|
@ -195,4 +195,8 @@ public class GuiShareToLan extends GuiScreen {
|
|||
super.updateScreen();
|
||||
this.codeTextField.updateCursorCounter();
|
||||
}
|
||||
|
||||
public boolean blockPTTKey() {
|
||||
return this.codeTextField.isFocused();
|
||||
}
|
||||
}
|
|
@ -361,6 +361,9 @@ public class EaglerIntegratedServerWorker {
|
|||
case IPCPacket17ConfigureLAN.ID: {
|
||||
|
||||
IPCPacket17ConfigureLAN pkt = (IPCPacket17ConfigureLAN)ipc;
|
||||
if(!pkt.iceServers.isEmpty() && ServerPlatformSingleplayer.getClientConfigAdapter().isAllowVoiceClient()) {
|
||||
currentProcess.enableVoice(pkt.iceServers.toArray(new String[pkt.iceServers.size()]));
|
||||
}
|
||||
currentProcess.getConfigurationManager().configureLAN(pkt.gamemode, pkt.cheats); // don't use iceServers
|
||||
|
||||
break;
|
||||
|
|
|
@ -16,7 +16,9 @@ import net.minecraft.world.EnumDifficulty;
|
|||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.WorldSettings;
|
||||
import net.minecraft.world.WorldSettings.GameType;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.server.skins.IntegratedCapeService;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.server.skins.IntegratedSkinService;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.server.voice.IntegratedVoiceService;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
|
@ -45,6 +47,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
protected boolean paused;
|
||||
protected EaglerSaveHandler saveHandler;
|
||||
protected IntegratedSkinService skinService;
|
||||
protected IntegratedCapeService capeService;
|
||||
protected IntegratedVoiceService voiceService;
|
||||
|
||||
private long lastTPSUpdate = 0l;
|
||||
|
||||
|
@ -62,6 +66,8 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
Bootstrap.register();
|
||||
this.saveHandler = new EaglerSaveHandler(savesDir, world);
|
||||
this.skinService = new IntegratedSkinService(new VFile2(saveHandler.getWorldDirectory(), "eagler/skulls"));
|
||||
this.capeService = new IntegratedCapeService();
|
||||
this.voiceService = null;
|
||||
this.setServerOwner(owner);
|
||||
logger.info("server owner: " + owner);
|
||||
this.setDemo(demo);
|
||||
|
@ -76,6 +82,27 @@ public class EaglerMinecraftServer extends MinecraftServer {
|
|||
return skinService;
|
||||
}
|
||||
|
||||
public IntegratedCapeService getCapeService() {
|
||||
return capeService;
|
||||
}
|
||||
|
||||
public IntegratedVoiceService getVoiceService() {
|
||||
return voiceService;
|
||||
}
|
||||
|
||||
public void enableVoice(String[] iceServers) {
|
||||
if(iceServers != null) {
|
||||
if(voiceService != null) {
|
||||
voiceService.changeICEServers(iceServers);
|
||||
}else {
|
||||
voiceService = new IntegratedVoiceService(iceServers);
|
||||
for(EntityPlayerMP player : getConfigurationManager().func_181057_v()) {
|
||||
voiceService.handlePlayerLoggedIn(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBaseServerProperties(EnumDifficulty difficulty, GameType gamemode) {
|
||||
this.difficulty = difficulty;
|
||||
this.gamemode = gamemode;
|
||||
|
|
|
@ -43,6 +43,8 @@ public class EaglerPlayerList extends ServerConfigurationManager {
|
|||
|
||||
public void playerLoggedOut(EntityPlayerMP playerIn) {
|
||||
super.playerLoggedOut(playerIn);
|
||||
((EaglerMinecraftServer)getServerInstance()).skinService.unregisterPlayer(playerIn.getUniqueID());
|
||||
EaglerMinecraftServer svr = (EaglerMinecraftServer)getServerInstance();
|
||||
svr.skinService.unregisterPlayer(playerIn.getUniqueID());
|
||||
svr.capeService.unregisterPlayer(playerIn.getUniqueID());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.server.skins;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
/**
|
||||
* 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 IntegratedCapePackets {
|
||||
|
||||
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 processPacket(byte[] data, EntityPlayerMP sender, IntegratedCapeService capeService) throws IOException {
|
||||
if(data.length == 0) {
|
||||
throw new IOException("Zero-length packet recieved");
|
||||
}
|
||||
int packetId = (int)data[0] & 0xFF;
|
||||
try {
|
||||
switch(packetId) {
|
||||
case PACKET_GET_OTHER_CAPE:
|
||||
processGetOtherCape(data, sender, capeService);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unknown packet type " + packetId);
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
throw ex;
|
||||
}catch(Throwable t) {
|
||||
throw new IOException("Unhandled exception handling packet type " + packetId, t);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processGetOtherCape(byte[] data, EntityPlayerMP sender, IntegratedCapeService capeService) throws IOException {
|
||||
if(data.length != 17) {
|
||||
throw new IOException("Invalid length " + data.length + " for skin request packet");
|
||||
}
|
||||
EaglercraftUUID searchUUID = IntegratedSkinPackets.bytesToUUID(data, 1);
|
||||
capeService.processGetOtherCape(searchUUID, sender);
|
||||
}
|
||||
|
||||
public static void registerEaglerPlayer(EaglercraftUUID clientUUID, byte[] bs, IntegratedCapeService capeService) throws IOException {
|
||||
if(bs.length == 0) {
|
||||
throw new IOException("Zero-length packet recieved");
|
||||
}
|
||||
byte[] generatedPacket;
|
||||
int packetType = (int)bs[0] & 0xFF;
|
||||
switch(packetType) {
|
||||
case PACKET_MY_CAPE_PRESET:
|
||||
if(bs.length != 5) {
|
||||
throw new IOException("Invalid length " + bs.length + " for preset cape packet");
|
||||
}
|
||||
generatedPacket = IntegratedCapePackets.makePresetResponse(clientUUID, (bs[1] << 24) | (bs[2] << 16) | (bs[3] << 8) | (bs[4] & 0xFF));
|
||||
break;
|
||||
case PACKET_MY_CAPE_CUSTOM:
|
||||
if(bs.length != 1174) {
|
||||
throw new IOException("Invalid length " + bs.length + " for custom cape packet");
|
||||
}
|
||||
generatedPacket = IntegratedCapePackets.makeCustomResponse(clientUUID, bs, 1, 1173);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unknown skin packet type: " + packetType);
|
||||
}
|
||||
capeService.registerEaglercraftPlayer(clientUUID, generatedPacket);
|
||||
}
|
||||
|
||||
public static void registerEaglerPlayerFallback(EaglercraftUUID clientUUID, IntegratedCapeService capeService) {
|
||||
capeService.registerEaglercraftPlayer(clientUUID, IntegratedCapePackets.makePresetResponse(clientUUID, 0));
|
||||
}
|
||||
|
||||
public static byte[] makePresetResponse(EaglercraftUUID uuid, int presetId) {
|
||||
byte[] ret = new byte[1 + 16 + 4];
|
||||
ret[0] = (byte)PACKET_OTHER_CAPE_PRESET;
|
||||
IntegratedSkinPackets.UUIDToBytes(uuid, ret, 1);
|
||||
ret[17] = (byte)(presetId >> 24);
|
||||
ret[18] = (byte)(presetId >> 16);
|
||||
ret[19] = (byte)(presetId >> 8);
|
||||
ret[20] = (byte)(presetId & 0xFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte[] makeCustomResponse(EaglercraftUUID uuid, byte[] pixels) {
|
||||
return makeCustomResponse(uuid, pixels, 0, pixels.length);
|
||||
}
|
||||
|
||||
public static byte[] makeCustomResponse(EaglercraftUUID uuid, byte[] pixels, int offset, int length) {
|
||||
byte[] ret = new byte[1 + 16 + length];
|
||||
ret[0] = (byte)PACKET_OTHER_CAPE_CUSTOM;
|
||||
IntegratedSkinPackets.UUIDToBytes(uuid, ret, 1);
|
||||
System.arraycopy(pixels, offset, ret, 17, length);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.server.skins;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
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.netty.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||
|
||||
/**
|
||||
* 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 IntegratedCapeService {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("IntegratedCapeService");
|
||||
|
||||
public static final int masterRateLimitPerPlayer = 250;
|
||||
|
||||
public static final String CHANNEL = "EAG|Capes-1.8";
|
||||
|
||||
private final Map<EaglercraftUUID, byte[]> capesCache = new HashMap();
|
||||
|
||||
public void processPacket(byte[] packetData, EntityPlayerMP sender) {
|
||||
try {
|
||||
IntegratedCapePackets.processPacket(packetData, sender, this);
|
||||
} catch (IOException e) {
|
||||
logger.error("Invalid skin request packet recieved from player {}!", sender.getName());
|
||||
logger.error(e);
|
||||
sender.playerNetServerHandler.kickPlayerFromServer("Invalid skin request packet recieved!");
|
||||
}
|
||||
}
|
||||
|
||||
public void processLoginPacket(byte[] packetData, EntityPlayerMP sender) {
|
||||
try {
|
||||
IntegratedCapePackets.registerEaglerPlayer(sender.getUniqueID(), packetData, this);
|
||||
} catch (IOException e) {
|
||||
logger.error("Invalid skin data packet recieved from player {}!", sender.getName());
|
||||
logger.error(e);
|
||||
sender.playerNetServerHandler.kickPlayerFromServer("Invalid skin data packet recieved!");
|
||||
}
|
||||
}
|
||||
|
||||
public void registerEaglercraftPlayer(EaglercraftUUID playerUUID, byte[] capePacket) {
|
||||
capesCache.put(playerUUID, capePacket);
|
||||
}
|
||||
|
||||
public void processGetOtherCape(EaglercraftUUID searchUUID, EntityPlayerMP sender) {
|
||||
byte[] maybeCape = capesCache.get(searchUUID);
|
||||
if(maybeCape == null) {
|
||||
maybeCape = IntegratedCapePackets.makePresetResponse(searchUUID, 0);
|
||||
}
|
||||
sender.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL, new PacketBuffer(Unpooled.buffer(maybeCape, maybeCape.length).writerIndex(maybeCape.length))));
|
||||
}
|
||||
|
||||
public void unregisterPlayer(EaglercraftUUID playerUUID) {
|
||||
synchronized(capesCache) {
|
||||
capesCache.remove(playerUUID);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.server.voice;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.netty.Unpooled;
|
||||
import net.lax1dude.eaglercraft.v1_8.voice.ExpiringSet;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||
|
||||
/**
|
||||
* 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 IntegratedVoiceService {
|
||||
|
||||
public static final Logger logger = LogManager.getLogger("IntegratedVoiceService");
|
||||
|
||||
public static final String CHANNEL = "EAG|Voice-1.8";
|
||||
|
||||
private byte[] iceServersPacket;
|
||||
|
||||
private final Map<EaglercraftUUID, EntityPlayerMP> voicePlayers = new HashMap<>();
|
||||
private final Map<EaglercraftUUID, ExpiringSet<EaglercraftUUID>> voiceRequests = new HashMap<>();
|
||||
private final Set<VoicePair> voicePairs = new HashSet<>();
|
||||
|
||||
public IntegratedVoiceService(String[] iceServers) {
|
||||
iceServersPacket = IntegratedVoiceSignalPackets.makeVoiceSignalPacketAllowed(true, iceServers);
|
||||
}
|
||||
|
||||
public void changeICEServers(String[] iceServers) {
|
||||
iceServersPacket = IntegratedVoiceSignalPackets.makeVoiceSignalPacketAllowed(true, iceServers);
|
||||
}
|
||||
|
||||
private static class VoicePair {
|
||||
|
||||
private final EaglercraftUUID uuid1;
|
||||
private final EaglercraftUUID uuid2;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return uuid1.hashCode() ^ uuid2.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
VoicePair other = (VoicePair) obj;
|
||||
return (uuid1.equals(other.uuid1) && uuid2.equals(other.uuid2))
|
||||
|| (uuid1.equals(other.uuid2) && uuid2.equals(other.uuid1));
|
||||
}
|
||||
|
||||
private VoicePair(EaglercraftUUID uuid1, EaglercraftUUID uuid2) {
|
||||
this.uuid1 = uuid1;
|
||||
this.uuid2 = uuid2;
|
||||
}
|
||||
|
||||
private boolean anyEquals(EaglercraftUUID uuid) {
|
||||
return uuid1.equals(uuid) || uuid2.equals(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public void handlePlayerLoggedIn(EntityPlayerMP player) {
|
||||
player.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL, new PacketBuffer(
|
||||
Unpooled.buffer(iceServersPacket, iceServersPacket.length).writerIndex(iceServersPacket.length))));
|
||||
}
|
||||
|
||||
public void handlePlayerLoggedOut(EntityPlayerMP player) {
|
||||
removeUser(player.getUniqueID());
|
||||
}
|
||||
|
||||
public void processPacket(PacketBuffer packetData, EntityPlayerMP sender) {
|
||||
try {
|
||||
IntegratedVoiceSignalPackets.processPacket(packetData, sender, this);
|
||||
} catch (IOException e) {
|
||||
logger.error("Invalid voice signal packet recieved from player {}!", sender.getName());
|
||||
logger.error(e);
|
||||
sender.playerNetServerHandler.kickPlayerFromServer("Invalid voice signal packet recieved!");
|
||||
}
|
||||
}
|
||||
|
||||
void handleVoiceSignalPacketTypeRequest(EaglercraftUUID player, EntityPlayerMP sender) {
|
||||
EaglercraftUUID senderUUID = sender.getUniqueID();
|
||||
if (senderUUID.equals(player))
|
||||
return; // prevent duplicates
|
||||
if (!voicePlayers.containsKey(senderUUID))
|
||||
return;
|
||||
EntityPlayerMP targetPlayerCon = voicePlayers.get(player);
|
||||
if (targetPlayerCon == null)
|
||||
return;
|
||||
VoicePair newPair = new VoicePair(player, senderUUID);
|
||||
if (voicePairs.contains(newPair))
|
||||
return; // already paired
|
||||
ExpiringSet<EaglercraftUUID> senderRequestSet = voiceRequests.get(senderUUID);
|
||||
if (senderRequestSet == null) {
|
||||
voiceRequests.put(senderUUID, senderRequestSet = new ExpiringSet<>(2000));
|
||||
}
|
||||
if (!senderRequestSet.add(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if other has requested earlier
|
||||
ExpiringSet<EaglercraftUUID> theSet;
|
||||
if ((theSet = voiceRequests.get(player)) != null && theSet.contains(senderUUID)) {
|
||||
theSet.remove(senderUUID);
|
||||
if (theSet.isEmpty())
|
||||
voiceRequests.remove(player);
|
||||
senderRequestSet.remove(player);
|
||||
if (senderRequestSet.isEmpty())
|
||||
voiceRequests.remove(senderUUID);
|
||||
// send each other add data
|
||||
voicePairs.add(newPair);
|
||||
targetPlayerCon.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
IntegratedVoiceSignalPackets.makeVoiceSignalPacketConnect(senderUUID, false)));
|
||||
sender.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
IntegratedVoiceSignalPackets.makeVoiceSignalPacketConnect(player, true)));
|
||||
}
|
||||
}
|
||||
|
||||
void handleVoiceSignalPacketTypeConnect(EntityPlayerMP sender) {
|
||||
if (voicePlayers.containsKey(sender.getUniqueID())) {
|
||||
return;
|
||||
}
|
||||
boolean hasNoOtherPlayers = voicePlayers.isEmpty();
|
||||
voicePlayers.put(sender.getUniqueID(), sender);
|
||||
if (hasNoOtherPlayers) {
|
||||
return;
|
||||
}
|
||||
byte[] packetToBroadcast = IntegratedVoiceSignalPackets.makeVoiceSignalPacketGlobal(voicePlayers.values());
|
||||
for (EntityPlayerMP userCon : voicePlayers.values()) {
|
||||
userCon.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL, new PacketBuffer(Unpooled
|
||||
.buffer(packetToBroadcast, packetToBroadcast.length).writerIndex(packetToBroadcast.length))));
|
||||
}
|
||||
}
|
||||
|
||||
void handleVoiceSignalPacketTypeICE(EaglercraftUUID player, String str, EntityPlayerMP sender) {
|
||||
VoicePair pair = new VoicePair(player, sender.getUniqueID());
|
||||
EntityPlayerMP pass = voicePairs.contains(pair) ? voicePlayers.get(player) : null;
|
||||
if (pass != null) {
|
||||
pass.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
IntegratedVoiceSignalPackets.makeVoiceSignalPacketICE(sender.getUniqueID(), str)));
|
||||
}
|
||||
}
|
||||
|
||||
void handleVoiceSignalPacketTypeDesc(EaglercraftUUID player, String str, EntityPlayerMP sender) {
|
||||
VoicePair pair = new VoicePair(player, sender.getUniqueID());
|
||||
EntityPlayerMP pass = voicePairs.contains(pair) ? voicePlayers.get(player) : null;
|
||||
if (pass != null) {
|
||||
pass.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
IntegratedVoiceSignalPackets.makeVoiceSignalPacketDesc(sender.getUniqueID(), str)));
|
||||
}
|
||||
}
|
||||
|
||||
void handleVoiceSignalPacketTypeDisconnect(EaglercraftUUID player, EntityPlayerMP sender) {
|
||||
if (player != null) {
|
||||
if (!voicePlayers.containsKey(player)) {
|
||||
return;
|
||||
}
|
||||
byte[] userDisconnectPacket = null;
|
||||
Iterator<VoicePair> pairsItr = voicePairs.iterator();
|
||||
while (pairsItr.hasNext()) {
|
||||
VoicePair voicePair = pairsItr.next();
|
||||
EaglercraftUUID target = null;
|
||||
if (voicePair.uuid1.equals(player)) {
|
||||
target = voicePair.uuid2;
|
||||
} else if (voicePair.uuid2.equals(player)) {
|
||||
target = voicePair.uuid1;
|
||||
}
|
||||
if (target != null) {
|
||||
pairsItr.remove();
|
||||
EntityPlayerMP conn = voicePlayers.get(target);
|
||||
if (conn != null) {
|
||||
if (userDisconnectPacket == null) {
|
||||
userDisconnectPacket = IntegratedVoiceSignalPackets.makeVoiceSignalPacketDisconnect(player);
|
||||
}
|
||||
conn.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
new PacketBuffer(Unpooled.buffer(userDisconnectPacket, userDisconnectPacket.length)
|
||||
.writerIndex(userDisconnectPacket.length))));
|
||||
}
|
||||
sender.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
IntegratedVoiceSignalPackets.makeVoiceSignalPacketDisconnectPB(target)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
removeUser(sender.getUniqueID());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeUser(EaglercraftUUID user) {
|
||||
if (voicePlayers.remove(user) == null) {
|
||||
return;
|
||||
}
|
||||
voiceRequests.remove(user);
|
||||
if (voicePlayers.size() > 0) {
|
||||
byte[] voicePlayersPkt = IntegratedVoiceSignalPackets.makeVoiceSignalPacketGlobal(voicePlayers.values());
|
||||
for (EntityPlayerMP userCon : voicePlayers.values()) {
|
||||
if (!user.equals(userCon.getUniqueID())) {
|
||||
userCon.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
new PacketBuffer(Unpooled.buffer(voicePlayersPkt, voicePlayersPkt.length)
|
||||
.writerIndex(voicePlayersPkt.length))));
|
||||
}
|
||||
}
|
||||
}
|
||||
byte[] userDisconnectPacket = null;
|
||||
Iterator<VoicePair> pairsItr = voicePairs.iterator();
|
||||
while (pairsItr.hasNext()) {
|
||||
VoicePair voicePair = pairsItr.next();
|
||||
EaglercraftUUID target = null;
|
||||
if (voicePair.uuid1.equals(user)) {
|
||||
target = voicePair.uuid2;
|
||||
} else if (voicePair.uuid2.equals(user)) {
|
||||
target = voicePair.uuid1;
|
||||
}
|
||||
if (target != null) {
|
||||
pairsItr.remove();
|
||||
if (voicePlayers.size() > 0) {
|
||||
EntityPlayerMP conn = voicePlayers.get(target);
|
||||
if (conn != null) {
|
||||
if (userDisconnectPacket == null) {
|
||||
userDisconnectPacket = IntegratedVoiceSignalPackets.makeVoiceSignalPacketDisconnect(user);
|
||||
}
|
||||
conn.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload(CHANNEL,
|
||||
new PacketBuffer(Unpooled.buffer(userDisconnectPacket, userDisconnectPacket.length)
|
||||
.writerIndex(userDisconnectPacket.length))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.sp.server.voice;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.netty.ByteBuf;
|
||||
import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
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 IntegratedVoiceSignalPackets {
|
||||
|
||||
static final int VOICE_SIGNAL_ALLOWED = 0;
|
||||
static final int VOICE_SIGNAL_REQUEST = 0;
|
||||
static final int VOICE_SIGNAL_CONNECT = 1;
|
||||
static final int VOICE_SIGNAL_DISCONNECT = 2;
|
||||
static final int VOICE_SIGNAL_ICE = 3;
|
||||
static final int VOICE_SIGNAL_DESC = 4;
|
||||
static final int VOICE_SIGNAL_GLOBAL = 5;
|
||||
|
||||
public static void processPacket(PacketBuffer buffer, EntityPlayerMP sender, IntegratedVoiceService voiceService) throws IOException {
|
||||
int packetId = -1;
|
||||
if(buffer.readableBytes() == 0) {
|
||||
throw new IOException("Zero-length packet recieved");
|
||||
}
|
||||
try {
|
||||
packetId = buffer.readUnsignedByte();
|
||||
switch(packetId) {
|
||||
case VOICE_SIGNAL_REQUEST: {
|
||||
voiceService.handleVoiceSignalPacketTypeRequest(buffer.readUuid(), sender);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_CONNECT: {
|
||||
voiceService.handleVoiceSignalPacketTypeConnect(sender);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_ICE: {
|
||||
voiceService.handleVoiceSignalPacketTypeICE(buffer.readUuid(), buffer.readStringFromBuffer(32767), sender);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_DESC: {
|
||||
voiceService.handleVoiceSignalPacketTypeDesc(buffer.readUuid(), buffer.readStringFromBuffer(32767), sender);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_DISCONNECT: {
|
||||
voiceService.handleVoiceSignalPacketTypeDisconnect(buffer.readableBytes() > 0 ? buffer.readUuid() : null, sender);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new IOException("Unknown packet type " + packetId);
|
||||
}
|
||||
}
|
||||
if(buffer.readableBytes() > 0) {
|
||||
throw new IOException("Voice packet is too long!");
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
throw ex;
|
||||
}catch(Throwable t) {
|
||||
throw new IOException("Unhandled exception handling voice packet type " + packetId, t);
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] makeVoiceSignalPacketAllowed(boolean allowed, String[] iceServers) {
|
||||
if (iceServers == null) {
|
||||
byte[] ret = new byte[2];
|
||||
ByteBuf wrappedBuffer = Unpooled.buffer(ret, ret.length);
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_ALLOWED);
|
||||
wrappedBuffer.writeBoolean(allowed);
|
||||
return ret;
|
||||
}
|
||||
byte[][] iceServersBytes = new byte[iceServers.length][];
|
||||
int totalLen = 2 + PacketBuffer.getVarIntSize(iceServers.length);
|
||||
for(int i = 0; i < iceServers.length; ++i) {
|
||||
byte[] b = iceServersBytes[i] = iceServers[i].getBytes(StandardCharsets.UTF_8);
|
||||
totalLen += PacketBuffer.getVarIntSize(b.length) + b.length;
|
||||
}
|
||||
byte[] ret = new byte[totalLen];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_ALLOWED);
|
||||
wrappedBuffer.writeBoolean(allowed);
|
||||
wrappedBuffer.writeVarIntToBuffer(iceServersBytes.length);
|
||||
for(int i = 0; i < iceServersBytes.length; ++i) {
|
||||
byte[] b = iceServersBytes[i];
|
||||
wrappedBuffer.writeVarIntToBuffer(b.length);
|
||||
wrappedBuffer.writeBytes(b);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static byte[] makeVoiceSignalPacketGlobal(Collection<EntityPlayerMP> users) {
|
||||
int cnt = users.size();
|
||||
byte[][] displayNames = new byte[cnt][];
|
||||
int i = 0;
|
||||
for(EntityPlayerMP user : users) {
|
||||
String name = user.getName();
|
||||
if(name.length() > 16) name = name.substring(0, 16);
|
||||
displayNames[i++] = name.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
int totalLength = 1 + PacketBuffer.getVarIntSize(cnt) + (cnt << 4);
|
||||
for(i = 0; i < cnt; ++i) {
|
||||
totalLength += PacketBuffer.getVarIntSize(displayNames[i].length) + displayNames[i].length;
|
||||
}
|
||||
byte[] ret = new byte[totalLength];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_GLOBAL);
|
||||
wrappedBuffer.writeVarIntToBuffer(cnt);
|
||||
for(EntityPlayerMP user : users) {
|
||||
wrappedBuffer.writeUuid(user.getUniqueID());
|
||||
}
|
||||
for(i = 0; i < cnt; ++i) {
|
||||
wrappedBuffer.writeVarIntToBuffer(displayNames[i].length);
|
||||
wrappedBuffer.writeBytes(displayNames[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketConnect(EaglercraftUUID player, boolean offer) {
|
||||
byte[] ret = new byte[18];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_CONNECT);
|
||||
wrappedBuffer.writeUuid(player);
|
||||
wrappedBuffer.writeBoolean(offer);
|
||||
return wrappedBuffer;
|
||||
}
|
||||
|
||||
static byte[] makeVoiceSignalPacketConnectAnnounce(EaglercraftUUID player) {
|
||||
byte[] ret = new byte[17];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_CONNECT);
|
||||
wrappedBuffer.writeUuid(player);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static byte[] makeVoiceSignalPacketDisconnect(EaglercraftUUID player) {
|
||||
if(player == null) {
|
||||
return new byte[] { (byte)VOICE_SIGNAL_DISCONNECT };
|
||||
}
|
||||
byte[] ret = new byte[17];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_DISCONNECT);
|
||||
wrappedBuffer.writeUuid(player);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketDisconnectPB(EaglercraftUUID player) {
|
||||
if(player == null) {
|
||||
byte[] ret = new byte[1];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_DISCONNECT);
|
||||
return wrappedBuffer;
|
||||
}
|
||||
byte[] ret = new byte[17];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_DISCONNECT);
|
||||
wrappedBuffer.writeUuid(player);
|
||||
return wrappedBuffer;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketICE(EaglercraftUUID player, String str) {
|
||||
byte[] strBytes = str.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] ret = new byte[17 + PacketBuffer.getVarIntSize(strBytes.length) + strBytes.length];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_ICE);
|
||||
wrappedBuffer.writeUuid(player);
|
||||
wrappedBuffer.writeVarIntToBuffer(strBytes.length);
|
||||
wrappedBuffer.writeBytes(strBytes);
|
||||
return wrappedBuffer;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketDesc(EaglercraftUUID player, String str) {
|
||||
byte[] strBytes = str.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] ret = new byte[17 + PacketBuffer.getVarIntSize(strBytes.length) + strBytes.length];
|
||||
PacketBuffer wrappedBuffer = new PacketBuffer(Unpooled.buffer(ret, ret.length));
|
||||
wrappedBuffer.writeByte(VOICE_SIGNAL_DESC);
|
||||
wrappedBuffer.writeUuid(player);
|
||||
wrappedBuffer.writeVarIntToBuffer(strBytes.length);
|
||||
wrappedBuffer.writeBytes(strBytes);
|
||||
return wrappedBuffer;
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,8 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
private int width;
|
||||
private int height;
|
||||
|
||||
private int totalHeightOffset = 0;
|
||||
|
||||
private boolean isIngame;
|
||||
private GuiScreen backScreen;
|
||||
|
||||
|
@ -61,10 +63,10 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
this.mc = mc;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
checkForUpdatesButton = new GuiButton(0, w - 150, 0, 150, 20, I18n.format("update.button") + " " + I18n.format(mc.gameSettings.enableUpdateSvc ? "gui.yes" : "gui.no"));
|
||||
startDownloadButton = new GuiButton(1, w - 115, 0, 115, 20, I18n.format("update.startDownload"));
|
||||
viewAllUpdatesButton = new GuiButton(2, w - 115, 0, 115, 20, I18n.format("update.viewAll", 0));
|
||||
dismissUpdatesButton = new GuiButton(3, w - 115, 0, 115, 20, I18n.format("update.dismiss"));
|
||||
checkForUpdatesButton = new GuiButton(0, 0, 0, 150, 20, I18n.format("update.button") + " " + I18n.format(mc.gameSettings.enableUpdateSvc ? "gui.yes" : "gui.no"));
|
||||
startDownloadButton = new GuiButton(1, 1, 0, 115, 20, I18n.format("update.startDownload"));
|
||||
viewAllUpdatesButton = new GuiButton(2, 1, 0, 115, 20, I18n.format("update.viewAll", 0));
|
||||
dismissUpdatesButton = new GuiButton(3, 1, 0, 115, 20, I18n.format("update.dismiss"));
|
||||
}
|
||||
|
||||
public void drawScreen(int mx, int my, float partialTicks) {
|
||||
|
@ -81,6 +83,7 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
startDownloadButton.visible = false;
|
||||
viewAllUpdatesButton.visible = false;
|
||||
dismissUpdatesButton.visible = false;
|
||||
totalHeightOffset = 0;
|
||||
|
||||
int i = UpdateService.getAvailableUpdates().size();
|
||||
boolean shownSP = i > 0 || !mc.isSingleplayer() || LANServerController.isHostingLAN();
|
||||
|
@ -95,7 +98,7 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
dismissUpdatesButton.visible = true;
|
||||
viewAllUpdatesButton.displayString = I18n.format("update.viewAll", i);
|
||||
str = I18n.format("update.found");
|
||||
mc.fontRendererObj.drawStringWithShadow(str, width - mc.fontRendererObj.getStringWidth(str) - 3, 22, 0xFFFFAA);
|
||||
mc.fontRendererObj.drawStringWithShadow(str, 3, 22, 0xFFFFAA);
|
||||
|
||||
int embedY = 35;
|
||||
int embedWidth = 115;
|
||||
|
@ -109,7 +112,7 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
}
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(width - embedWidth - 1, embedY, 0.0f);
|
||||
GlStateManager.translate(1.0f, embedY, 0.0f);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
int embedHeight2 = (int)(embedHeight / 0.75f);
|
||||
|
@ -143,16 +146,20 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
startDownloadButton.yPosition = embedHeight + embedY + 5;
|
||||
viewAllUpdatesButton.yPosition = startDownloadButton.yPosition + 22;
|
||||
dismissUpdatesButton.yPosition = viewAllUpdatesButton.yPosition + 22;
|
||||
|
||||
totalHeightOffset = dismissUpdatesButton.yPosition + 20;
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}else if(isIngame) {
|
||||
if(shownSP) {
|
||||
str = I18n.format("update.noneNew");
|
||||
mc.fontRendererObj.drawString(str, width - mc.fontRendererObj.getStringWidth(str) - 3, 22, 0xDDDDDD);
|
||||
mc.fontRendererObj.drawString(str, 3, 22, 0xDDDDDD);
|
||||
if(i > 0) {
|
||||
viewAllUpdatesButton.yPosition = 40;
|
||||
viewAllUpdatesButton.visible = true;
|
||||
viewAllUpdatesButton.displayString = I18n.format("update.viewAll", i);
|
||||
totalHeightOffset = 60;
|
||||
}else {
|
||||
totalHeightOffset = 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,23 +180,23 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
viewAllUpdatesButton.visible = false;
|
||||
dismissUpdatesButton.visible = false;
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(width, isIngame ? 0.0f : 10.0f, 0.0f);
|
||||
GlStateManager.translate(1.0f, isIngame ? 0.0f : 18.0f, 0.0f);
|
||||
String str = I18n.format("update.downloading");
|
||||
mc.fontRendererObj.drawStringWithShadow(str, -mc.fontRendererObj.getStringWidth(str) - 2, 2, 0xFFFFAA);
|
||||
mc.fontRendererObj.drawStringWithShadow(str, 2, 2, 0xFFFFAA);
|
||||
GlStateManager.translate(0.0f, 14.0f, 0.0f);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
if(!StringUtils.isAllBlank(progressState.statusString1)) {
|
||||
str = progressState.statusString1;
|
||||
mc.fontRendererObj.drawStringWithShadow(str, -mc.fontRendererObj.getStringWidth(str) - 3, 0, 0xFFFFFF);
|
||||
mc.fontRendererObj.drawStringWithShadow(str, 3, 0, 0xFFFFFF);
|
||||
}
|
||||
int cc = isIngame ? 0xBBBBBB : 0xFFFFFF;
|
||||
if(!StringUtils.isAllBlank(progressState.statusString2)) {
|
||||
str = progressState.statusString2;
|
||||
mc.fontRendererObj.drawStringWithShadow(str, -mc.fontRendererObj.getStringWidth(str) - 3, 11, cc);
|
||||
mc.fontRendererObj.drawStringWithShadow(str, 3, 11, cc);
|
||||
}
|
||||
int progX1 = -135;
|
||||
int progX1 = 3;
|
||||
int progY1 = 22;
|
||||
int progX2 = -3;
|
||||
int progX2 = 135;
|
||||
int progY2 = 32;
|
||||
float prog = progressState.progressBar;
|
||||
if(prog >= 0.0f) {
|
||||
|
@ -202,6 +209,7 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
drawGradientRect(progX1, progY1 + 1, progX1 + 1, progY2 - 1, 0xFF000000, 0xFF000000);
|
||||
drawGradientRect(progX2 - 1, progY1 + 1, progX2, progY2 - 1, 0xFF000000, 0xFF000000);
|
||||
}
|
||||
totalHeightOffset = 32;
|
||||
if(!StringUtils.isAllBlank(progressState.statusString3)) {
|
||||
GlStateManager.translate(0.0f, progY2 + 2, 0.0f);
|
||||
GlStateManager.scale(0.66f, 0.66f, 0.66f);
|
||||
|
@ -209,10 +217,12 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
List<String> wrappedURL = mc.fontRendererObj.listFormattedStringToWidth(str, (int)((progX2 - progX1) * 1.5f));
|
||||
for(int i = 0, l = wrappedURL.size(); i < l; ++i) {
|
||||
str = wrappedURL.get(i);
|
||||
mc.fontRendererObj.drawStringWithShadow(str, -mc.fontRendererObj.getStringWidth(str) - 5, i * 11, cc);
|
||||
mc.fontRendererObj.drawStringWithShadow(str, 5, i * 11, cc);
|
||||
}
|
||||
totalHeightOffset += (int)(wrappedURL.size() * 5.5f);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
}
|
||||
|
||||
public void mouseClicked(int mx, int my, int btn) {
|
||||
|
@ -244,4 +254,8 @@ public class GuiUpdateCheckerOverlay extends Gui {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getSharedWorldInfoYOffset() {
|
||||
return totalHeightOffset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
/**
|
||||
* Copyright (c) 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 enum EnumVoiceChannelPeerState {
|
||||
FAILED, SUCCESS, LOADING;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
/**
|
||||
* Copyright (c) 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 enum EnumVoiceChannelReadyState {
|
||||
NONE, ABORTED, DEVICE_INITIALIZED;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
/**
|
||||
* 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 EnumVoiceChannelStatus {
|
||||
DISCONNECTED, CONNECTING, CONNECTED, UNAVAILABLE;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
/**
|
||||
* 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 EnumVoiceChannelType {
|
||||
NONE, GLOBAL, PROXIMITY;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 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 ExpiringSet<T> extends HashSet<T> {
|
||||
private final long expiration;
|
||||
private final ExpiringEvent<T> event;
|
||||
|
||||
private final Map<T, Long> timestamps = new HashMap<>();
|
||||
|
||||
public ExpiringSet(long expiration) {
|
||||
this.expiration = expiration;
|
||||
this.event = null;
|
||||
}
|
||||
|
||||
public ExpiringSet(long expiration, ExpiringEvent<T> event) {
|
||||
this.expiration = expiration;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public interface ExpiringEvent<T> {
|
||||
void onExpiration(T item);
|
||||
}
|
||||
|
||||
public void checkForExpirations() {
|
||||
Iterator<T> iterator = this.timestamps.keySet().iterator();
|
||||
long now = System.currentTimeMillis();
|
||||
while (iterator.hasNext()) {
|
||||
T element = iterator.next();
|
||||
if (super.contains(element)) {
|
||||
if (this.timestamps.get(element) + this.expiration < now) {
|
||||
if (this.event != null) this.event.onExpiration(element);
|
||||
iterator.remove();
|
||||
super.remove(element);
|
||||
}
|
||||
} else {
|
||||
iterator.remove();
|
||||
super.remove(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean add(T o) {
|
||||
checkForExpirations();
|
||||
boolean success = super.add(o);
|
||||
if (success) timestamps.put(o, System.currentTimeMillis());
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
checkForExpirations();
|
||||
boolean success = super.remove(o);
|
||||
if (success) timestamps.remove(o);
|
||||
return success;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.timestamps.clear();
|
||||
super.clear();
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
checkForExpirations();
|
||||
return super.contains(o);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,772 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.Keyboard;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiSlider2;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
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.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class GuiVoiceMenu extends Gui {
|
||||
|
||||
public class AbortedException extends RuntimeException {
|
||||
}
|
||||
|
||||
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
|
||||
|
||||
protected final GuiScreen parent;
|
||||
|
||||
protected Minecraft mc;
|
||||
protected FontRenderer fontRendererObj;
|
||||
protected int width;
|
||||
protected int height;
|
||||
|
||||
protected int voiceButtonOFFposX;
|
||||
protected int voiceButtonOFFposY;
|
||||
protected int voiceButtonOFFposW;
|
||||
protected int voiceButtonOFFposH;
|
||||
|
||||
protected int voiceButtonRADIUSposX;
|
||||
protected int voiceButtonRADIUSposY;
|
||||
protected int voiceButtonRADIUSposW;
|
||||
protected int voiceButtonRADIUSposH;
|
||||
|
||||
protected int voiceButtonGLOBALposX;
|
||||
protected int voiceButtonGLOBALposY;
|
||||
protected int voiceButtonGLOBALposW;
|
||||
protected int voiceButtonGLOBALposH;
|
||||
|
||||
protected int voiceScreenButtonOFFposX;
|
||||
protected int voiceScreenButtonOFFposY;
|
||||
protected int voiceScreenButtonOFFposW;
|
||||
protected int voiceScreenButtonOFFposH;
|
||||
|
||||
protected int voiceScreenButtonRADIUSposX;
|
||||
protected int voiceScreenButtonRADIUSposY;
|
||||
protected int voiceScreenButtonRADIUSposW;
|
||||
protected int voiceScreenButtonRADIUSposH;
|
||||
|
||||
protected int voiceScreenButtonGLOBALposX;
|
||||
protected int voiceScreenButtonGLOBALposY;
|
||||
protected int voiceScreenButtonGLOBALposW;
|
||||
protected int voiceScreenButtonGLOBALposH;
|
||||
|
||||
protected int voiceScreenButtonChangeRadiusposX;
|
||||
protected int voiceScreenButtonChangeRadiusposY;
|
||||
protected int voiceScreenButtonChangeRadiusposW;
|
||||
protected int voiceScreenButtonChangeRadiusposH;
|
||||
|
||||
protected int voiceScreenVolumeIndicatorX;
|
||||
protected int voiceScreenVolumeIndicatorY;
|
||||
protected int voiceScreenVolumeIndicatorW;
|
||||
protected int voiceScreenVolumeIndicatorH;
|
||||
|
||||
protected boolean showSliderBlocks = false;
|
||||
protected boolean showSliderVolume = false;
|
||||
protected boolean showPTTKeyConfig = false;
|
||||
protected int showNewPTTKey = 0;
|
||||
protected GuiSlider2 sliderBlocks = null;
|
||||
protected GuiSlider2 sliderListenVolume = null;
|
||||
protected GuiSlider2 sliderSpeakVolume = null;
|
||||
|
||||
protected GuiButton applyRadiusButton = null;
|
||||
protected GuiButton applyVolumeButton = null;
|
||||
protected GuiButton noticeContinueButton = null;
|
||||
protected GuiButton noticeCancelButton = null;
|
||||
|
||||
protected static boolean showingCompatWarning = false;
|
||||
protected static boolean showCompatWarning = true;
|
||||
|
||||
protected static boolean showingTrackingWarning = false;
|
||||
protected static boolean showTrackingWarning = true;
|
||||
|
||||
protected static EnumVoiceChannelType continueChannel = null;
|
||||
|
||||
public GuiVoiceMenu(GuiScreen parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setResolution(Minecraft mc, int w, int h) {
|
||||
this.mc = mc;
|
||||
this.fontRendererObj = mc.fontRendererObj;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
initGui();
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
this.sliderBlocks = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 20, 150, 20, (VoiceClientController.getVoiceProximity() - 5) / 17.0f, 1.0f) {
|
||||
public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
|
||||
if(super.mousePressed(par1Minecraft, par2, par3)) {
|
||||
this.displayString = "" + (int)((sliderValue * 17.0f) + 5.0f) + " Blocks";
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public void mouseDragged(Minecraft par1Minecraft, int par2, int par3) {
|
||||
super.mouseDragged(par1Minecraft, par2, par3);
|
||||
this.displayString = "" + (int)((sliderValue * 17.0f) + 5.0f) + " Blocks";
|
||||
}
|
||||
};
|
||||
sliderBlocks.displayString = "" + VoiceClientController.getVoiceProximity() + " Blocks";
|
||||
this.sliderListenVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 10, 150, 20, VoiceClientController.getVoiceListenVolume(), 1.0f);
|
||||
this.sliderSpeakVolume = new GuiSlider2(-1, (width - 150) / 2, height / 3 + 56, 150, 20, VoiceClientController.getVoiceSpeakVolume(), 1.0f);
|
||||
|
||||
applyRadiusButton = new GuiButton(2, (width - 150) / 2, height / 3 + 49, 150, 20, I18n.format("voice.apply"));
|
||||
applyVolumeButton = new GuiButton(3, (width - 150) / 2, height / 3 + 90, 150, 20, I18n.format("voice.apply"));
|
||||
noticeContinueButton = new GuiButton(5, (width - 150) / 2, height / 3 + 60, 150, 20, I18n.format("voice.unsupportedWarning10"));
|
||||
noticeCancelButton = new GuiButton(6, (width - 150) / 2, height / 3 + 90, 150, 20, I18n.format("voice.unsupportedWarning11"));
|
||||
applyRadiusButton.visible = applyVolumeButton.visible = noticeContinueButton.visible = noticeCancelButton.visible = false;
|
||||
}
|
||||
|
||||
private void drawButtons(int mx, int my, float partialTicks) {
|
||||
applyRadiusButton.drawButton(mc, mx, my);
|
||||
applyVolumeButton.drawButton(mc, mx, my);
|
||||
noticeContinueButton.drawButton(mc, mx, my);
|
||||
noticeCancelButton.drawButton(mc, mx, my);
|
||||
}
|
||||
|
||||
public void drawScreen(int mx, int my, float partialTicks) {
|
||||
String txt = I18n.format("voice.title");
|
||||
drawString(fontRendererObj, txt, width - 5 - fontRendererObj.getStringWidth(txt), 5, 0xFFCC22);
|
||||
|
||||
applyRadiusButton.visible = showSliderBlocks;
|
||||
applyVolumeButton.visible = showSliderVolume;
|
||||
|
||||
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
|
||||
|
||||
drawRect(0, 0, this.width, this.height, 0xB0101010);
|
||||
|
||||
if(showSliderBlocks) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 4 - 1, this.width / 2 + 86, height / 3 + 64 + height / 16, 0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 4 + 0, this.width / 2 + 85, height / 3 + 63 + height / 16, 0xFF333333);
|
||||
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.radiusTitle"), this.width / 2, height / 4 + 9, 16777215);
|
||||
drawString(this.fontRendererObj, I18n.format("voice.radiusLabel"), (this.width - 150) / 2 + 3, height / 3 + 6, 0xCCCCCC);
|
||||
sliderBlocks.drawButton(mc, mx, my);
|
||||
|
||||
}else if(showSliderVolume) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 4 - 11, this.width / 2 + 86, height / 3 + 104 + height / 16, 0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 4 - 10, this.width / 2 + 85, height / 3 + 103 + height / 16, 0xFF333333);
|
||||
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.volumeTitle"), this.width / 2, height / 4 - 1, 16777215);
|
||||
drawString(this.fontRendererObj, I18n.format("voice.volumeListen"), (this.width - 150) / 2 + 3, height / 3 - 4, 0xCCCCCC);
|
||||
sliderListenVolume.drawButton(mc, mx, my);
|
||||
|
||||
drawString(this.fontRendererObj, I18n.format("voice.volumeSpeak"), (this.width - 150) / 2 + 3, height / 3 + 42, 0xCCCCCC);
|
||||
sliderSpeakVolume.drawButton(mc, mx, my);
|
||||
|
||||
}else if(showPTTKeyConfig) {
|
||||
|
||||
drawRect(width / 2 - 86, height / 3 - 10, this.width / 2 + 86, height / 3 + 35, 0xFFDDDDDD);
|
||||
drawRect(width / 2 - 85, height / 3 - 9, this.width / 2 + 85, height / 3 + 34, 0xFF333333);
|
||||
|
||||
if(showNewPTTKey > 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(this.width / 2, height / 3 + 5, 0.0f);
|
||||
GlStateManager.scale(2.0f, 2.0f, 2.0f);
|
||||
drawCenteredString(this.fontRendererObj, Keyboard.getKeyName(mc.gameSettings.voicePTTKey), 0, 0, 0xFFCC11);
|
||||
GlStateManager.popMatrix();
|
||||
}else {
|
||||
drawCenteredString(this.fontRendererObj, I18n.format("voice.pttChangeDesc"), this.width / 2, height / 3 + 8, 16777215);
|
||||
}
|
||||
}
|
||||
|
||||
drawButtons(mx, my, partialTicks);
|
||||
throw new AbortedException();
|
||||
}
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GlStateManager.translate(width - 6, 15, 0.0f);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
if(!VoiceClientController.isClientSupported()) {
|
||||
txt = I18n.format("voice.titleVoiceUnavailable");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 6, 0xFF7777);
|
||||
txt = I18n.format("voice.titleVoiceBrowserError");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 19, 0xAA4444);
|
||||
GlStateManager.popMatrix();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!VoiceClientController.isServerSupported()) {
|
||||
txt = I18n.format("voice.titleNoVoice");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xFF7777);
|
||||
GlStateManager.popMatrix();
|
||||
return;
|
||||
}
|
||||
|
||||
int xo = 0;
|
||||
// this feature is optional
|
||||
//if(VoiceClientController.voiceRelayed()) {
|
||||
// txt = I18n.format("voice.warning1");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 8, 0xBB9999);
|
||||
// txt = I18n.format("voice.warning2");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 18, 0xBB9999);
|
||||
// txt = I18n.format("voice.warning3");
|
||||
// drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 28, 0xBB9999);
|
||||
// xo = 43;
|
||||
// GlStateManager.translate(0.0f, xo, 0.0f);
|
||||
//}
|
||||
|
||||
EnumVoiceChannelStatus status = VoiceClientController.getVoiceStatus();
|
||||
EnumVoiceChannelType channel = VoiceClientController.getVoiceChannel();
|
||||
|
||||
boolean flag = false;
|
||||
|
||||
if(channel == EnumVoiceChannelType.NONE) {
|
||||
flag = true;
|
||||
}else {
|
||||
if(status == EnumVoiceChannelStatus.CONNECTED) {
|
||||
|
||||
if(channel == EnumVoiceChannelType.PROXIMITY) {
|
||||
txt = I18n.format("voice.connectedRadius").replace("$radius$", "" + VoiceClientController.getVoiceProximity()).replace("$f$", "");
|
||||
int w = fontRendererObj.getStringWidth(txt);
|
||||
int xx = width - 5 - (w * 3 / 4);
|
||||
int yy = 15 + (xo * 3 / 4);
|
||||
voiceScreenButtonChangeRadiusposX = xx;
|
||||
voiceScreenButtonChangeRadiusposY = yy;
|
||||
voiceScreenButtonChangeRadiusposW = width - 3 - xx;
|
||||
voiceScreenButtonChangeRadiusposH = 12;
|
||||
if(mx >= xx && my >= yy && mx < xx + voiceScreenButtonChangeRadiusposW && my < yy + 12) {
|
||||
txt = I18n.format("voice.connectedRadius").replace("$radius$", "" + VoiceClientController.getVoiceProximity())
|
||||
.replace("$f$", "" + EnumChatFormatting.UNDERLINE) + EnumChatFormatting.RESET;
|
||||
}
|
||||
}else {
|
||||
txt = I18n.format("voice.connectedGlobal");
|
||||
}
|
||||
|
||||
voiceScreenVolumeIndicatorX = width - 15 - (104 * 3 / 4);
|
||||
voiceScreenVolumeIndicatorY = 15 + (xo * 3 / 4) + 30;
|
||||
voiceScreenVolumeIndicatorW = width - voiceScreenVolumeIndicatorX - 4;
|
||||
voiceScreenVolumeIndicatorH = 23;
|
||||
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0x66DD66);
|
||||
|
||||
drawRect(-90, 42, 2, 52, 0xFFAAAAAA);
|
||||
drawRect(-89, 43, 1, 51, 0xFF222222);
|
||||
|
||||
float vol = VoiceClientController.getVoiceListenVolume();
|
||||
drawRect(-89, 43, -89 + (int)(vol * 90), 51, 0xFF993322);
|
||||
|
||||
for(float f = 0.07f; f < vol; f += 0.08f) {
|
||||
int ww = (int)(f * 90);
|
||||
drawRect(-89 + ww, 43, -89 + ww + 1, 51, 0xFF999999);
|
||||
}
|
||||
|
||||
drawRect(-90, 57, 2, 67, 0xFFAAAAAA);
|
||||
drawRect(-89, 58, 1, 66, 0xFF222222);
|
||||
|
||||
vol = VoiceClientController.getVoiceSpeakVolume();
|
||||
drawRect(-89, 58, -89 + (int)(vol * 90), 66, 0xFF993322);
|
||||
|
||||
for(float f = 0.07f; f < vol; f += 0.08f) {
|
||||
int ww = (int)(f * 90);
|
||||
drawRect(-89 + ww, 58, -89 + ww + 1, 66, 0xFF999999);
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
GlStateManager.color(0.7f, 0.7f, 0.7f, 1.0f);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-104.0f, 41.5f, 0.0f);
|
||||
GlStateManager.scale(0.7f, 0.7f, 0.7f);
|
||||
drawTexturedModalRect(0, 0, 64, 144, 16, 16);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-104.0f, 56.5f, 0.0f);
|
||||
GlStateManager.scale(0.7f, 0.7f, 0.7f);
|
||||
if((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
|
||||
GlStateManager.color(0.9f, 0.4f, 0.4f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 64, 16, 16);
|
||||
}else {
|
||||
drawTexturedModalRect(0, 0, 64, 32, 16, 16);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
txt = I18n.format("voice.ptt", Keyboard.getKeyName(mc.gameSettings.voicePTTKey));
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt) - 10, 76, 0x66DD66);
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
GlStateManager.color(0.4f, 0.9f, 0.4f, 1.0f);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-7.0f, 74.5f, 0.0f);
|
||||
GlStateManager.scale(0.35f, 0.35f, 0.35f);
|
||||
drawTexturedModalRect(0, 0, 32, 224, 32, 32);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
txt = I18n.format("voice.playersListening");
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0f, 98.0f, 0.0f);
|
||||
GlStateManager.scale(1.2f, 1.2f, 1.2f);
|
||||
drawString(fontRendererObj, txt, -fontRendererObj.getStringWidth(txt), 0, 0xFF7777);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
List<EaglercraftUUID> playersToRender = VoiceClientController.getVoiceRecent();
|
||||
|
||||
if(playersToRender.size() > 0) {
|
||||
EaglercraftUUID uuid;
|
||||
Set<EaglercraftUUID> playersSpeaking = VoiceClientController.getVoiceSpeaking();
|
||||
Set<EaglercraftUUID> playersMuted = VoiceClientController.getVoiceMuted();
|
||||
for(int i = 0, l = playersToRender.size(); i < l; ++i) {
|
||||
uuid = playersToRender.get(i);
|
||||
txt = VoiceClientController.getVoiceUsername(uuid);
|
||||
|
||||
boolean muted = playersMuted.contains(uuid);
|
||||
boolean speaking = !muted && playersSpeaking.contains(uuid);
|
||||
|
||||
int mhy = voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 33 + i * 9;
|
||||
boolean hovered = mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9;
|
||||
float cm = hovered ? 1.5f : 1.0f;
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-100.0f, 115.0f + i * 12.0f, 0.0f);
|
||||
GlStateManager.scale(0.78f, 0.78f, 0.78f);
|
||||
|
||||
if(muted) {
|
||||
GlStateManager.color(1.0f * cm, 0.2f * cm, 0.2f * cm, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 208, 16, 16);
|
||||
}else if(speaking) {
|
||||
GlStateManager.color(1.0f * cm, 1.0f * cm, 1.0f * cm, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
}else {
|
||||
GlStateManager.color(0.65f * cm, 0.65f * cm, 0.65f * cm, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 144, 16, 16);
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(muted) {
|
||||
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0xCC4444, cm));
|
||||
}else if(speaking) {
|
||||
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0xCCCCCC, cm));
|
||||
}else {
|
||||
drawString(fontRendererObj, txt, -84, 117 + i * 12, attenuate(0x999999, cm));
|
||||
}
|
||||
|
||||
}
|
||||
}else {
|
||||
txt = "(none)";
|
||||
drawString(fontRendererObj, txt, -fontRendererObj.getStringWidth(txt), 112, 0xAAAAAA);
|
||||
}
|
||||
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTING) {
|
||||
float fadeTimer = MathHelper.sin((float)((System.currentTimeMillis() % 700l) * 0.0014d) * 3.14159f) * 0.35f + 0.3f;
|
||||
txt = I18n.format("voice.connecting");
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, (0xFFDD77 | ((int)(Math.pow(fadeTimer, 1.0d / 2.2d) * 255.0f) << 24)));
|
||||
GlStateManager.disableBlend();
|
||||
}else if(status == EnumVoiceChannelStatus.UNAVAILABLE) {
|
||||
txt = I18n.format("voice.unavailable");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xFF3333);
|
||||
}else {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(flag) {
|
||||
txt = I18n.format("voice.notConnected");
|
||||
drawString(fontRendererObj, txt, 1 - fontRendererObj.getStringWidth(txt), 5, 0xBB9999);
|
||||
}
|
||||
|
||||
String OFFstring = I18n.format("voice.off");
|
||||
String RADIUSstring = I18n.format("voice.radius");
|
||||
String GLOBALstring = I18n.format("voice.global");
|
||||
|
||||
int OFFwidth = fontRendererObj.getStringWidth(OFFstring);
|
||||
int RADIUSwidth = fontRendererObj.getStringWidth(RADIUSstring);
|
||||
int GLOBALwidth = fontRendererObj.getStringWidth(GLOBALstring);
|
||||
|
||||
voiceButtonOFFposX = 0 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth;
|
||||
voiceButtonOFFposY = 20;
|
||||
voiceButtonOFFposW = OFFwidth + 5;
|
||||
voiceButtonOFFposH = 15;
|
||||
|
||||
voiceScreenButtonOFFposX = voiceButtonOFFposX * 3 / 4 + width - 6;
|
||||
voiceScreenButtonOFFposY = 15 + (voiceButtonOFFposY + xo) * 3 / 4;
|
||||
voiceScreenButtonOFFposW = voiceButtonOFFposW * 3 / 4;
|
||||
voiceScreenButtonOFFposH = voiceButtonOFFposH * 3 / 4;
|
||||
|
||||
voiceButtonRADIUSposX = 0 - RADIUSwidth - 8 - GLOBALwidth;
|
||||
voiceButtonRADIUSposY = 20;
|
||||
voiceButtonRADIUSposW = RADIUSwidth + 5;
|
||||
voiceButtonRADIUSposH = 15;
|
||||
|
||||
voiceScreenButtonRADIUSposX = voiceButtonRADIUSposX * 3 / 4 + width - 6;
|
||||
voiceScreenButtonRADIUSposY = 15 + (voiceButtonRADIUSposY + xo) * 3 / 4;
|
||||
voiceScreenButtonRADIUSposW = voiceButtonRADIUSposW * 3 / 4;
|
||||
voiceScreenButtonRADIUSposH = voiceButtonRADIUSposH * 3 / 4;
|
||||
|
||||
voiceButtonGLOBALposX = 0 - GLOBALwidth;
|
||||
voiceButtonGLOBALposY = 20;
|
||||
voiceButtonGLOBALposW = GLOBALwidth + 5;
|
||||
voiceButtonGLOBALposH = 15;
|
||||
|
||||
voiceScreenButtonGLOBALposX = voiceButtonGLOBALposX * 3 / 4 + width - 6;
|
||||
voiceScreenButtonGLOBALposY = 15 + (voiceButtonGLOBALposY + xo) * 3 / 4;
|
||||
voiceScreenButtonGLOBALposW = voiceButtonGLOBALposW * 3 / 4;
|
||||
voiceScreenButtonGLOBALposH = voiceButtonGLOBALposH * 3 / 4;
|
||||
|
||||
if(channel == EnumVoiceChannelType.NONE) {
|
||||
drawOutline(voiceButtonOFFposX, voiceButtonOFFposY, voiceButtonOFFposW, voiceButtonOFFposH, 0xFFCCCCCC);
|
||||
drawRect(voiceButtonOFFposX + 1, voiceButtonOFFposY + 1, voiceButtonOFFposX + voiceButtonOFFposW - 2,
|
||||
voiceButtonOFFposY + voiceButtonOFFposH - 1, 0xFF222222);
|
||||
}else if(mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
|
||||
voiceScreenButtonOFFposW && my < voiceScreenButtonOFFposY + voiceScreenButtonOFFposH) {
|
||||
drawOutline(voiceButtonOFFposX, voiceButtonOFFposY, voiceButtonOFFposW, voiceButtonOFFposH, 0xFF777777);
|
||||
}
|
||||
|
||||
if(channel == EnumVoiceChannelType.PROXIMITY) {
|
||||
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH, 0xFFCCCCCC);
|
||||
drawRect(voiceButtonRADIUSposX + 1, voiceButtonRADIUSposY + 1, voiceButtonRADIUSposX + voiceButtonRADIUSposW - 2,
|
||||
voiceButtonRADIUSposY + voiceButtonRADIUSposH - 1, 0xFF222222);
|
||||
}else if(mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY && mx < voiceScreenButtonRADIUSposX +
|
||||
voiceScreenButtonRADIUSposW && my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
|
||||
drawOutline(voiceButtonRADIUSposX, voiceButtonRADIUSposY, voiceButtonRADIUSposW, voiceButtonRADIUSposH, 0xFF777777);
|
||||
}
|
||||
|
||||
if(channel == EnumVoiceChannelType.GLOBAL) {
|
||||
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH, 0xFFCCCCCC);
|
||||
drawRect(voiceButtonGLOBALposX + 1, voiceButtonGLOBALposY + 1, voiceButtonGLOBALposX + voiceButtonGLOBALposW - 2,
|
||||
voiceButtonGLOBALposY + voiceButtonGLOBALposH - 1, 0xFF222222);
|
||||
}else if(mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY && mx < voiceScreenButtonGLOBALposX +
|
||||
voiceScreenButtonGLOBALposW && my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
|
||||
drawOutline(voiceButtonGLOBALposX, voiceButtonGLOBALposY, voiceButtonGLOBALposW, voiceButtonGLOBALposH, 0xFF777777);
|
||||
}
|
||||
|
||||
int enabledColor = (status == EnumVoiceChannelStatus.CONNECTED || channel == EnumVoiceChannelType.NONE) ? 0x66DD66 : 0xDDCC66;
|
||||
int disabledColor = 0xDD4444;
|
||||
|
||||
if(channel != EnumVoiceChannelType.NONE && status == EnumVoiceChannelStatus.UNAVAILABLE) {
|
||||
enabledColor = disabledColor;
|
||||
}
|
||||
|
||||
drawString(fontRendererObj, OFFstring, 3 - OFFwidth - 8 - RADIUSwidth - 8 - GLOBALwidth, 24, channel == EnumVoiceChannelType.NONE ? enabledColor : disabledColor);
|
||||
drawString(fontRendererObj, RADIUSstring, 3 - RADIUSwidth - 8 - GLOBALwidth, 24, channel == EnumVoiceChannelType.PROXIMITY ? enabledColor : disabledColor);
|
||||
drawString(fontRendererObj, GLOBALstring, 3 - GLOBALwidth, 24, channel == EnumVoiceChannelType.GLOBAL ? enabledColor : disabledColor);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(showingCompatWarning) {
|
||||
|
||||
drawNotice(I18n.format("voice.unsupportedWarning1"), false, I18n.format("voice.unsupportedWarning2"), I18n.format("voice.unsupportedWarning3"),
|
||||
"", I18n.format("voice.unsupportedWarning4"), I18n.format("voice.unsupportedWarning5"), I18n.format("voice.unsupportedWarning6"),
|
||||
I18n.format("voice.unsupportedWarning7"), I18n.format("voice.unsupportedWarning8"), I18n.format("voice.unsupportedWarning9"));
|
||||
|
||||
noticeContinueButton.visible = true;
|
||||
noticeCancelButton.visible = false;
|
||||
}else if(showingTrackingWarning) {
|
||||
|
||||
drawNotice(I18n.format("voice.ipGrabWarning1"), true, I18n.format("voice.ipGrabWarning2"), I18n.format("voice.ipGrabWarning3"),
|
||||
I18n.format("voice.ipGrabWarning4"), "", I18n.format("voice.ipGrabWarning5"), I18n.format("voice.ipGrabWarning6"),
|
||||
I18n.format("voice.ipGrabWarning7"), I18n.format("voice.ipGrabWarning8"), I18n.format("voice.ipGrabWarning9"),
|
||||
I18n.format("voice.ipGrabWarning10"), I18n.format("voice.ipGrabWarning11"), I18n.format("voice.ipGrabWarning12"));
|
||||
|
||||
noticeContinueButton.visible = true;
|
||||
noticeCancelButton.visible = true;
|
||||
}else {
|
||||
noticeContinueButton.visible = false;
|
||||
noticeCancelButton.visible = false;
|
||||
}
|
||||
|
||||
drawButtons(mx, my, partialTicks);
|
||||
|
||||
if(showingCompatWarning || showingTrackingWarning) {
|
||||
throw new AbortedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void drawNotice(String title, boolean showCancel, String... lines) {
|
||||
|
||||
int widthAccum = 0;
|
||||
|
||||
for(int i = 0; i < lines.length; ++i) {
|
||||
int w = fontRendererObj.getStringWidth(lines[i]);
|
||||
if(widthAccum < w) {
|
||||
widthAccum = w;
|
||||
}
|
||||
}
|
||||
|
||||
int margin = 15;
|
||||
|
||||
int x = (width - widthAccum) / 2;
|
||||
int y = (height - lines.length * 10 - 60 - margin) / 2;
|
||||
|
||||
drawRect(x - margin - 1, y - margin - 1, x + widthAccum + margin + 1,
|
||||
y + lines.length * 10 + 49 + margin, 0xFFCCCCCC);
|
||||
drawRect(x - margin, y - margin, x + widthAccum + margin,
|
||||
y + lines.length * 10 + 48 + margin, 0xFF111111);
|
||||
|
||||
drawCenteredString(fontRendererObj, EnumChatFormatting.BOLD + title, width / 2, y, 0xFF7766);
|
||||
|
||||
for(int i = 0; i < lines.length; ++i) {
|
||||
drawString(fontRendererObj, lines[i], x, y + i * 10 + 18, 0xDDAAAA);
|
||||
}
|
||||
|
||||
if(!showCancel) {
|
||||
noticeContinueButton.width = 150;
|
||||
noticeContinueButton.xPosition = (width - 150) / 2;
|
||||
noticeContinueButton.yPosition = y + lines.length * 10 + 29;
|
||||
}else {
|
||||
noticeContinueButton.width = widthAccum / 2 - 10;
|
||||
noticeContinueButton.xPosition = (width - widthAccum) / 2 + widthAccum / 2 + 3;
|
||||
noticeContinueButton.yPosition = y + lines.length * 10 + 28;
|
||||
noticeCancelButton.width = widthAccum / 2 - 10;
|
||||
noticeCancelButton.xPosition = (width - widthAccum) / 2 + 4;
|
||||
noticeCancelButton.yPosition = y + lines.length * 10 + 28;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int attenuate(int cin, float f) {
|
||||
return attenuate(cin, f, f, f, 1.0f);
|
||||
}
|
||||
|
||||
public static int attenuate(int cin, float r, float g, float b, float a) {
|
||||
float var10 = (float) (cin >> 24 & 255) / 255.0F;
|
||||
float var6 = (float) (cin >> 16 & 255) / 255.0F;
|
||||
float var7 = (float) (cin >> 8 & 255) / 255.0F;
|
||||
float var8 = (float) (cin & 255) / 255.0F;
|
||||
var10 *= a;
|
||||
var6 *= r;
|
||||
var7 *= g;
|
||||
var8 *= b;
|
||||
if(var10 > 1.0f) {
|
||||
var10 = 1.0f;
|
||||
}
|
||||
if(var6 > 1.0f) {
|
||||
var6 = 1.0f;
|
||||
}
|
||||
if(var7 > 1.0f) {
|
||||
var7 = 1.0f;
|
||||
}
|
||||
if(var8 > 1.0f) {
|
||||
var8 = 1.0f;
|
||||
}
|
||||
return (((int)(var10 * 255.0f) << 24) | ((int)(var6 * 255.0f) << 16) | ((int)(var7 * 255.0f) << 8) | (int)(var8 * 255.0f));
|
||||
}
|
||||
|
||||
private void drawOutline(int x, int y, int w, int h, int color) {
|
||||
drawRect(x, y, x + w, y + 1, color);
|
||||
drawRect(x + w - 1, y + 1, x + w, y + h - 1, color);
|
||||
drawRect(x, y + h - 1, x + w, y + h, color);
|
||||
drawRect(x, y + 1, x + 1, y + h - 1, color);
|
||||
}
|
||||
|
||||
public void mouseReleased(int par1, int par2, int par3) {
|
||||
applyRadiusButton.mouseReleased(par1, par2);
|
||||
applyVolumeButton.mouseReleased(par1, par2);
|
||||
noticeContinueButton.mouseReleased(par1, par2);
|
||||
noticeCancelButton.mouseReleased(par1, par2);
|
||||
if(showSliderBlocks || showSliderVolume) {
|
||||
if(showSliderBlocks) {
|
||||
if(par3 == 0) {
|
||||
sliderBlocks.mouseReleased(par1, par2);
|
||||
}
|
||||
}else if(showSliderVolume) {
|
||||
if(par3 == 0) {
|
||||
sliderListenVolume.mouseReleased(par1, par2);
|
||||
sliderSpeakVolume.mouseReleased(par1, par2);
|
||||
}
|
||||
}
|
||||
throw new AbortedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void keyTyped(char par1, int par2) {
|
||||
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig) {
|
||||
if(showPTTKeyConfig) {
|
||||
if(par2 == 1) {
|
||||
showPTTKeyConfig = false;
|
||||
}else {
|
||||
mc.gameSettings.voicePTTKey = par2;
|
||||
showNewPTTKey = 10;
|
||||
}
|
||||
}
|
||||
throw new AbortedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseClicked(int mx, int my, int button) {
|
||||
if(showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning || showingTrackingWarning) {
|
||||
if(showSliderBlocks) {
|
||||
sliderBlocks.mousePressed(mc, mx, my);
|
||||
}else if(showSliderVolume) {
|
||||
sliderListenVolume.mousePressed(mc, mx, my);
|
||||
sliderSpeakVolume.mousePressed(mc, mx, my);
|
||||
}
|
||||
if(button == 0) {
|
||||
if(applyRadiusButton.mousePressed(mc, mx, my)) actionPerformed(applyRadiusButton);
|
||||
if(applyVolumeButton.mousePressed(mc, mx, my)) actionPerformed(applyVolumeButton);
|
||||
if(noticeContinueButton.mousePressed(mc, mx, my)) actionPerformed(noticeContinueButton);
|
||||
if(noticeCancelButton.mousePressed(mc, mx, my)) actionPerformed(noticeCancelButton);
|
||||
}
|
||||
throw new AbortedException();
|
||||
}
|
||||
|
||||
EnumVoiceChannelStatus status = VoiceClientController.getVoiceStatus();
|
||||
EnumVoiceChannelType channel = VoiceClientController.getVoiceChannel();
|
||||
|
||||
if(button == 0) {
|
||||
if(VoiceClientController.isSupported()) {
|
||||
if(mx >= voiceScreenButtonOFFposX && my >= voiceScreenButtonOFFposY && mx < voiceScreenButtonOFFposX +
|
||||
voiceScreenButtonOFFposW && my < voiceScreenButtonOFFposY + voiceScreenButtonOFFposH) {
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(mx >= voiceScreenButtonRADIUSposX && my >= voiceScreenButtonRADIUSposY && mx < voiceScreenButtonRADIUSposX +
|
||||
voiceScreenButtonRADIUSposW && my < voiceScreenButtonRADIUSposY + voiceScreenButtonRADIUSposH) {
|
||||
|
||||
if(showCompatWarning) {
|
||||
continueChannel = EnumVoiceChannelType.PROXIMITY;
|
||||
showingCompatWarning = true;
|
||||
}else if(showTrackingWarning) {
|
||||
continueChannel = EnumVoiceChannelType.PROXIMITY;
|
||||
showingTrackingWarning = true;
|
||||
}else {
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.PROXIMITY);
|
||||
}
|
||||
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
|
||||
}else if(mx >= voiceScreenButtonGLOBALposX && my >= voiceScreenButtonGLOBALposY && mx < voiceScreenButtonGLOBALposX +
|
||||
voiceScreenButtonGLOBALposW && my < voiceScreenButtonGLOBALposY + voiceScreenButtonGLOBALposH) {
|
||||
|
||||
if(showCompatWarning) {
|
||||
continueChannel = EnumVoiceChannelType.GLOBAL;
|
||||
showingCompatWarning = true;
|
||||
}else if(showTrackingWarning) {
|
||||
continueChannel = EnumVoiceChannelType.GLOBAL;
|
||||
showingTrackingWarning = true;
|
||||
}else {
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.GLOBAL);
|
||||
}
|
||||
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(channel == EnumVoiceChannelType.PROXIMITY && status == EnumVoiceChannelStatus.CONNECTED && mx >= voiceScreenButtonChangeRadiusposX &&
|
||||
my >= voiceScreenButtonChangeRadiusposY && mx < voiceScreenButtonChangeRadiusposX + voiceScreenButtonChangeRadiusposW &&
|
||||
my < voiceScreenButtonChangeRadiusposY + voiceScreenButtonChangeRadiusposH) {
|
||||
showSliderBlocks = true;
|
||||
sliderBlocks.sliderValue = (VoiceClientController.getVoiceProximity() - 5) / 17.0f;
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE && mx >= voiceScreenVolumeIndicatorX &&
|
||||
my >= voiceScreenVolumeIndicatorY && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW &&
|
||||
my < voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH) {
|
||||
showSliderVolume = true;
|
||||
sliderListenVolume.sliderValue = VoiceClientController.getVoiceListenVolume();
|
||||
sliderSpeakVolume.sliderValue = VoiceClientController.getVoiceSpeakVolume();
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTED && channel != EnumVoiceChannelType.NONE && mx >= voiceScreenVolumeIndicatorX - 1 &&
|
||||
my >= voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 2 && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 &&
|
||||
my < voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 12) {
|
||||
showPTTKeyConfig = true;
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
}else if(status == EnumVoiceChannelStatus.CONNECTED) {
|
||||
List<EaglercraftUUID> playersToRender = VoiceClientController.getVoiceRecent();
|
||||
if(playersToRender.size() > 0) {
|
||||
Set<EaglercraftUUID> playersMuted = VoiceClientController.getVoiceMuted();
|
||||
for(int i = 0, l = playersToRender.size(); i < l; ++i) {
|
||||
EaglercraftUUID uuid = playersToRender.get(i);
|
||||
String txt = VoiceClientController.getVoiceUsername(uuid);
|
||||
boolean muted = playersMuted.contains(uuid);
|
||||
int mhy = voiceScreenVolumeIndicatorY + voiceScreenVolumeIndicatorH + 33 + i * 9;
|
||||
if(mx >= voiceScreenVolumeIndicatorX - 3 && my >= mhy && mx < voiceScreenVolumeIndicatorX + voiceScreenVolumeIndicatorW + 2 && my < mhy + 9) {
|
||||
VoiceClientController.setVoiceMuted(uuid, !muted);
|
||||
this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void actionPerformed(GuiButton btn) {
|
||||
if(btn.id == 2) {
|
||||
showSliderBlocks = false;
|
||||
VoiceClientController.setVoiceProximity(mc.gameSettings.voiceListenRadius = (int)((sliderBlocks.sliderValue * 17.0f) + 5.0f));
|
||||
mc.gameSettings.saveOptions();
|
||||
}else if(btn.id == 3) {
|
||||
showSliderVolume = false;
|
||||
VoiceClientController.setVoiceListenVolume(mc.gameSettings.voiceListenVolume = sliderListenVolume.sliderValue);
|
||||
VoiceClientController.setVoiceSpeakVolume(mc.gameSettings.voiceSpeakVolume = sliderSpeakVolume.sliderValue);
|
||||
mc.gameSettings.saveOptions();
|
||||
}else if(btn.id == 4) {
|
||||
showPTTKeyConfig = false;
|
||||
mc.gameSettings.saveOptions();
|
||||
}else if(btn.id == 5) {
|
||||
if(showingCompatWarning) {
|
||||
showingCompatWarning = false;
|
||||
showCompatWarning = false;
|
||||
if(showTrackingWarning) {
|
||||
showingTrackingWarning = true;
|
||||
}else {
|
||||
VoiceClientController.setVoiceChannel(continueChannel);
|
||||
}
|
||||
}else if(showingTrackingWarning) {
|
||||
showingTrackingWarning = false;
|
||||
showTrackingWarning = false;
|
||||
VoiceClientController.setVoiceChannel(continueChannel);
|
||||
}
|
||||
}else if(btn.id == 6) {
|
||||
if(showingTrackingWarning) {
|
||||
showingTrackingWarning = false;
|
||||
VoiceClientController.setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScreen() {
|
||||
if(showNewPTTKey > 0) {
|
||||
--showNewPTTKey;
|
||||
if(showNewPTTKey == 0) {
|
||||
showPTTKeyConfig = false;
|
||||
mc.gameSettings.saveOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBlockingInput() {
|
||||
return showSliderBlocks || showSliderVolume || showPTTKeyConfig || showingCompatWarning || showingTrackingWarning;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.GL_GREATER;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.Keyboard;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiChat;
|
||||
import net.minecraft.client.gui.GuiIngameMenu;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class GuiVoiceOverlay extends Gui {
|
||||
|
||||
public final Minecraft mc;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
private long pttTimer = 0l;
|
||||
|
||||
public GuiVoiceOverlay(Minecraft mc) {
|
||||
this.mc = mc;
|
||||
}
|
||||
|
||||
public void setResolution(int w, int h) {
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
}
|
||||
|
||||
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
|
||||
|
||||
public void drawOverlay() {
|
||||
if(mc.theWorld != null && VoiceClientController.getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED && VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.NONE &&
|
||||
!(mc.currentScreen != null && (mc.currentScreen instanceof GuiIngameMenu))) {
|
||||
|
||||
if(mc.currentScreen != null && mc.currentScreen.doesGuiPauseGame()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.alphaFunc(GL_GREATER, 0.1F);
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
if(mc.currentScreen == null || (mc.currentScreen instanceof GuiChat)) {
|
||||
GlStateManager.translate(width / 2 + 77, height - 56, 0.0f);
|
||||
if(mc.thePlayer == null || mc.thePlayer.capabilities.isCreativeMode) {
|
||||
GlStateManager.translate(0.0f, 16.0f, 0.0f);
|
||||
}
|
||||
}else {
|
||||
GlStateManager.translate(width / 2 + 10, 4, 0.0f);
|
||||
}
|
||||
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
|
||||
String txxt = "press '" + Keyboard.getKeyName(mc.gameSettings.voicePTTKey) + "'";
|
||||
drawString(mc.fontRendererObj, txxt, -3 - mc.fontRendererObj.getStringWidth(txxt), 9, 0xDDDDDD);
|
||||
|
||||
GlStateManager.scale(0.66f, 0.66f, 0.66f);
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
if((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey)) {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(pttTimer == 0l) {
|
||||
pttTimer = millis;
|
||||
}
|
||||
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 64, 32, 32);
|
||||
GlStateManager.translate(-1.5f, -1.5f, 0.0f);
|
||||
if(millis - pttTimer < 1050l) {
|
||||
if((millis - pttTimer) % 300l < 150l) {
|
||||
GlStateManager.color(0.9f, 0.2f, 0.2f, 1.0f);
|
||||
}else {
|
||||
GlStateManager.color(0.9f, 0.7f, 0.7f, 1.0f);
|
||||
}
|
||||
}else {
|
||||
GlStateManager.color(0.9f, 0.3f, 0.3f, 1.0f);
|
||||
}
|
||||
drawTexturedModalRect(0, 0, 0, 64, 32, 32);
|
||||
}else {
|
||||
pttTimer = 0l;
|
||||
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
|
||||
GlStateManager.translate(-1.5f, -1.5f, 0.0f);
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
|
||||
GlStateManager.translate(-0.5f, -0.5f, 0.0f);
|
||||
drawTexturedModalRect(0, 0, 0, 32, 32, 32);
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if(VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) {
|
||||
Set<EaglercraftUUID> listeners = VoiceClientController.getVoiceListening();
|
||||
if(listeners.size() > 0) {
|
||||
Set<EaglercraftUUID> speakers = VoiceClientController.getVoiceSpeaking();
|
||||
Set<EaglercraftUUID> muted = VoiceClientController.getVoiceMuted();
|
||||
|
||||
List<EaglercraftUUID> listenerList = new ArrayList();
|
||||
listenerList.addAll(listeners);
|
||||
listenerList.removeAll(muted);
|
||||
|
||||
while(listenerList.size() > 5) {
|
||||
boolean flag = false;
|
||||
for(int i = 0, l = listenerList.size(); i < l; ++i) {
|
||||
if(!speakers.contains(listenerList.get(i))) {
|
||||
listenerList.remove(i);
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int more = listenerList.size() - 5;
|
||||
|
||||
int ww = width;
|
||||
int hh = height;
|
||||
|
||||
if(mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
|
||||
hh -= 15;
|
||||
}
|
||||
|
||||
List<String> listenerListStr = new ArrayList(Math.min(5, listenerList.size()));
|
||||
|
||||
int left = 50;
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
String txt = VoiceClientController.getVoiceUsername(listenerList.get(i));
|
||||
listenerListStr.add(txt);
|
||||
int j = mc.fontRendererObj.getStringWidth(txt) + 4;
|
||||
if(j > left) {
|
||||
left = j;
|
||||
}
|
||||
}
|
||||
|
||||
if(more > 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left + 3, hh - 10, left);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
drawString(mc.fontRendererObj, "(" + more + " more)", 0, 0, 0xBBBBBB);
|
||||
GlStateManager.popMatrix();
|
||||
hh -= 9;
|
||||
}
|
||||
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
boolean speaking = speakers.contains(listenerList.get(i));
|
||||
float speakf = speaking ? 1.0f : 0.75f;
|
||||
|
||||
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11, speaking ? 0xEEEEEE : 0xBBBBBB);
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left - 14, hh - 14 - i * 11, 0.0f);
|
||||
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
GlStateManager.color(speakf * 0.2f, speakf * 0.2f, speakf * 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
|
||||
GlStateManager.translate(0.25f, 0.25f, 0.0f);
|
||||
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
|
||||
|
||||
GlStateManager.translate(-1.25f, -1.25f, 0.0f);
|
||||
GlStateManager.color(speakf, speakf, speakf, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, speaking ? 176 : 208, 16, 16);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}else if(VoiceClientController.getVoiceChannel() == EnumVoiceChannelType.GLOBAL) {
|
||||
Set<EaglercraftUUID> speakers = VoiceClientController.getVoiceSpeaking();
|
||||
Set<EaglercraftUUID> muted = VoiceClientController.getVoiceMuted();
|
||||
|
||||
List<EaglercraftUUID> listenerList = new ArrayList();
|
||||
listenerList.addAll(speakers);
|
||||
listenerList.removeAll(muted);
|
||||
|
||||
int more = listenerList.size() - 5;
|
||||
|
||||
int ww = width;
|
||||
int hh = height;
|
||||
|
||||
if(mc.currentScreen != null && (mc.currentScreen instanceof GuiChat)) {
|
||||
hh -= 15;
|
||||
}
|
||||
|
||||
List<String> listenerListStr = new ArrayList(Math.min(5, listenerList.size()));
|
||||
|
||||
int left = 50;
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
String txt = VoiceClientController.getVoiceUsername(listenerList.get(i));
|
||||
listenerListStr.add(txt);
|
||||
int j = mc.fontRendererObj.getStringWidth(txt) + 4;
|
||||
if(j > left) {
|
||||
left = j;
|
||||
}
|
||||
}
|
||||
|
||||
if(more > 0) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left + 3, hh - 10, left);
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
drawString(mc.fontRendererObj, "(" + more + " more)", 0, 0, 0xBBBBBB);
|
||||
GlStateManager.popMatrix();
|
||||
hh -= 9;
|
||||
}
|
||||
|
||||
for(int i = 0, l = listenerList.size(); i < l && i < 5; ++i) {
|
||||
drawString(mc.fontRendererObj, listenerListStr.get(i), ww - left, hh - 13 - i * 11, 0xEEEEEE);
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(ww - left - 14, hh - 14 - i * 11, 0.0f);
|
||||
|
||||
GlStateManager.scale(0.75f, 0.75f, 0.75f);
|
||||
GlStateManager.color(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
GlStateManager.translate(0.25f, 0.25f, 0.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
|
||||
GlStateManager.translate(-1.25f, -1.25f, 0.0f);
|
||||
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
drawTexturedModalRect(0, 0, 64, 176, 16, 16);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.Keyboard;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformVoiceClient;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.profile.EaglerProfile;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class VoiceClientController {
|
||||
|
||||
public static final String SIGNAL_CHANNEL = "EAG|Voice-1.8";
|
||||
|
||||
static final Logger logger = LogManager.getLogger("VoiceClientController");
|
||||
|
||||
private static boolean clientSupport = false;
|
||||
private static boolean serverSupport = false;
|
||||
private static Consumer<PacketBuffer> packetSendCallback = null;
|
||||
private static EnumVoiceChannelType voiceChannel = EnumVoiceChannelType.NONE;
|
||||
private static final HashSet<EaglercraftUUID> nearbyPlayers = new HashSet<>();
|
||||
private static final ExpiringSet<EaglercraftUUID> recentlyNearbyPlayers = new ExpiringSet<>(5000, uuid -> {
|
||||
if (!nearbyPlayers.contains(uuid)) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
});
|
||||
private static final Map<EaglercraftUUID, String> uuidToNameLookup = new HashMap<>(256);
|
||||
|
||||
public static boolean isSupported() {
|
||||
return isClientSupported() && isServerSupported();
|
||||
}
|
||||
|
||||
private static boolean checked = false;
|
||||
|
||||
public static boolean isClientSupported() {
|
||||
if (!checked) {
|
||||
checked = true;
|
||||
clientSupport = EagRuntime.getConfiguration().isAllowVoiceClient() && PlatformVoiceClient.isSupported();
|
||||
}
|
||||
return clientSupport;
|
||||
}
|
||||
|
||||
public static boolean isServerSupported() {
|
||||
return serverSupport;
|
||||
}
|
||||
|
||||
public static void initializeVoiceClient(Consumer<PacketBuffer> signalSendCallbackIn) {
|
||||
packetSendCallback = signalSendCallbackIn;
|
||||
uuidToNameLookup.clear();
|
||||
if (getVoiceChannel() != EnumVoiceChannelType.NONE) sendInitialVoice();
|
||||
}
|
||||
|
||||
public static void handleVoiceSignalPacket(PacketBuffer packetData) {
|
||||
VoiceSignalPackets.handleVoiceSignal(packetData);
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeGlobal(EaglercraftUUID[] voicePlayers, String[] voiceNames) {
|
||||
uuidToNameLookup.clear();
|
||||
for (int i = 0; i < voicePlayers.length; i++) {
|
||||
if(voiceNames != null) {
|
||||
uuidToNameLookup.put(voicePlayers[i], voiceNames[i]);
|
||||
}
|
||||
sendPacketRequestIfNeeded(voicePlayers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleServerDisconnect() {
|
||||
if(!isClientSupported()) return;
|
||||
serverSupport = false;
|
||||
uuidToNameLookup.clear();
|
||||
for (EaglercraftUUID uuid : nearbyPlayers) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
for (EaglercraftUUID uuid : recentlyNearbyPlayers) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
nearbyPlayers.clear();
|
||||
recentlyNearbyPlayers.clear();
|
||||
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
|
||||
for (EaglercraftUUID uuid : antiConcurrentModificationUUIDs) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
activateVoice(false);
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeAllowed(boolean voiceAvailableStat, String[] servs) {
|
||||
serverSupport = voiceAvailableStat;
|
||||
PlatformVoiceClient.setICEServers(servs);
|
||||
if(isSupported()) {
|
||||
EnumVoiceChannelType ch = getVoiceChannel();
|
||||
setVoiceChannel(EnumVoiceChannelType.NONE);
|
||||
setVoiceChannel(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeConnect(EaglercraftUUID user, boolean offer) {
|
||||
PlatformVoiceClient.signalConnect(user, offer);
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeConnectAnnounce(EaglercraftUUID user) {
|
||||
sendPacketRequest(user);
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeDisconnect(EaglercraftUUID user) {
|
||||
PlatformVoiceClient.signalDisconnect(user, true);
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeICECandidate(EaglercraftUUID user, String ice) {
|
||||
PlatformVoiceClient.signalICECandidate(user, ice);
|
||||
}
|
||||
|
||||
static void handleVoiceSignalPacketTypeDescription(EaglercraftUUID user, String desc) {
|
||||
PlatformVoiceClient.signalDescription(user, desc);
|
||||
}
|
||||
|
||||
public static void tickVoiceClient(Minecraft mc) {
|
||||
if(!isClientSupported()) return;
|
||||
recentlyNearbyPlayers.checkForExpirations();
|
||||
speakingSet.clear();
|
||||
PlatformVoiceClient.tickVoiceClient();
|
||||
|
||||
if (getVoiceChannel() != EnumVoiceChannelType.NONE && (getVoiceStatus() == EnumVoiceChannelStatus.CONNECTING || getVoiceStatus() == EnumVoiceChannelStatus.CONNECTED)) {
|
||||
activateVoice((mc.currentScreen == null || !mc.currentScreen.blockPTTKey()) && Keyboard.isKeyDown(mc.gameSettings.voicePTTKey));
|
||||
|
||||
if (mc.theWorld != null && mc.thePlayer != null) {
|
||||
HashSet<EaglercraftUUID> seenPlayers = new HashSet<>();
|
||||
for (EntityPlayer player : mc.theWorld.playerEntities) {
|
||||
if (player == mc.thePlayer) continue;
|
||||
if (getVoiceChannel() == EnumVoiceChannelType.PROXIMITY) updateVoicePosition(player.getUniqueID(), player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
int prox = 22;
|
||||
// cube
|
||||
if (Math.abs(mc.thePlayer.posX - player.posX) <= prox && Math.abs(mc.thePlayer.posY - player.posY) <= prox && Math.abs(mc.thePlayer.posZ - player.posZ) <= prox) {
|
||||
if (!uuidToNameLookup.containsKey(player.getUniqueID())) {
|
||||
uuidToNameLookup.put(player.getUniqueID(), player.getName());
|
||||
}
|
||||
if (addNearbyPlayer(player.getUniqueID())) {
|
||||
seenPlayers.add(player.getUniqueID());
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanupNearbyPlayers(seenPlayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final boolean addNearbyPlayer(EaglercraftUUID uuid) {
|
||||
recentlyNearbyPlayers.remove(uuid);
|
||||
if (nearbyPlayers.add(uuid)) {
|
||||
sendPacketRequestIfNeeded(uuid);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final void removeNearbyPlayer(EaglercraftUUID uuid) {
|
||||
if (nearbyPlayers.remove(uuid)) {
|
||||
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED || getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE) return;
|
||||
if (voiceChannel == EnumVoiceChannelType.PROXIMITY) recentlyNearbyPlayers.add(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void cleanupNearbyPlayers(HashSet<EaglercraftUUID> existingPlayers) {
|
||||
nearbyPlayers.stream().filter(ud -> !existingPlayers.contains(ud)).collect(Collectors.toSet()).forEach(VoiceClientController::removeNearbyPlayer);
|
||||
}
|
||||
|
||||
public static final void updateVoicePosition(EaglercraftUUID uuid, double x, double y, double z) {
|
||||
PlatformVoiceClient.updateVoicePosition(uuid, x, y, z);
|
||||
}
|
||||
|
||||
public static void setVoiceChannel(EnumVoiceChannelType channel) {
|
||||
if (voiceChannel == channel) return;
|
||||
if (channel != EnumVoiceChannelType.NONE) PlatformVoiceClient.initializeDevices();
|
||||
PlatformVoiceClient.resetPeerStates();
|
||||
if (channel == EnumVoiceChannelType.NONE) {
|
||||
for (EaglercraftUUID uuid : nearbyPlayers) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
for (EaglercraftUUID uuid : recentlyNearbyPlayers) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
nearbyPlayers.clear();
|
||||
recentlyNearbyPlayers.clear();
|
||||
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
|
||||
for (EaglercraftUUID uuid : antiConcurrentModificationUUIDs) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
sendPacketDisconnect(null);
|
||||
activateVoice(false);
|
||||
} else if (voiceChannel == EnumVoiceChannelType.PROXIMITY) {
|
||||
for (EaglercraftUUID uuid : nearbyPlayers) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
for (EaglercraftUUID uuid : recentlyNearbyPlayers) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
nearbyPlayers.clear();
|
||||
recentlyNearbyPlayers.clear();
|
||||
sendPacketDisconnect(null);
|
||||
} else if(voiceChannel == EnumVoiceChannelType.GLOBAL) {
|
||||
Set<EaglercraftUUID> antiConcurrentModificationUUIDs = new HashSet<>(listeningSet);
|
||||
antiConcurrentModificationUUIDs.removeAll(nearbyPlayers);
|
||||
antiConcurrentModificationUUIDs.removeAll(recentlyNearbyPlayers);
|
||||
for (EaglercraftUUID uuid : antiConcurrentModificationUUIDs) {
|
||||
PlatformVoiceClient.signalDisconnect(uuid, false);
|
||||
}
|
||||
sendPacketDisconnect(null);
|
||||
}
|
||||
voiceChannel = channel;
|
||||
if (channel != EnumVoiceChannelType.NONE) {
|
||||
sendInitialVoice();
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendInitialVoice() {
|
||||
sendPacketConnect();
|
||||
for (EaglercraftUUID uuid : nearbyPlayers) {
|
||||
sendPacketRequest(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public static EnumVoiceChannelType getVoiceChannel() {
|
||||
return voiceChannel;
|
||||
}
|
||||
|
||||
private static boolean voicePeerErrored() {
|
||||
return PlatformVoiceClient.getPeerState() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateConnect() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateInitial() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateDesc() == EnumVoiceChannelPeerState.FAILED || PlatformVoiceClient.getPeerStateIce() == EnumVoiceChannelPeerState.FAILED;
|
||||
}
|
||||
public static EnumVoiceChannelStatus getVoiceStatus() {
|
||||
return (!isClientSupported() || !isServerSupported()) ? EnumVoiceChannelStatus.UNAVAILABLE :
|
||||
(PlatformVoiceClient.getReadyState() != EnumVoiceChannelReadyState.DEVICE_INITIALIZED ?
|
||||
EnumVoiceChannelStatus.CONNECTING : (voicePeerErrored() ? EnumVoiceChannelStatus.UNAVAILABLE : EnumVoiceChannelStatus.CONNECTED));
|
||||
}
|
||||
|
||||
private static boolean talkStatus = false;
|
||||
|
||||
public static void activateVoice(boolean talk) {
|
||||
if (talkStatus != talk) {
|
||||
PlatformVoiceClient.activateVoice(talk);
|
||||
talkStatus = talk;
|
||||
}
|
||||
}
|
||||
|
||||
private static int proximity = 16;
|
||||
|
||||
public static void setVoiceProximity(int prox) {
|
||||
PlatformVoiceClient.setVoiceProximity(prox);
|
||||
proximity = prox;
|
||||
}
|
||||
|
||||
public static int getVoiceProximity() {
|
||||
return proximity;
|
||||
}
|
||||
|
||||
private static float volumeListen = 0.5f;
|
||||
|
||||
public static void setVoiceListenVolume(float f) {
|
||||
PlatformVoiceClient.setVoiceListenVolume(f);
|
||||
volumeListen = f;
|
||||
}
|
||||
|
||||
public static float getVoiceListenVolume() {
|
||||
return volumeListen;
|
||||
}
|
||||
|
||||
private static float volumeSpeak = 0.5f;
|
||||
|
||||
public static void setVoiceSpeakVolume(float f) {
|
||||
if (volumeSpeak != f) {
|
||||
PlatformVoiceClient.setMicVolume(f);
|
||||
}
|
||||
volumeSpeak = f;
|
||||
}
|
||||
|
||||
public static float getVoiceSpeakVolume() {
|
||||
return volumeSpeak;
|
||||
}
|
||||
|
||||
private static final Set<EaglercraftUUID> listeningSet = new HashSet<>();
|
||||
private static final Set<EaglercraftUUID> speakingSet = new HashSet<>();
|
||||
private static final Set<EaglercraftUUID> mutedSet = new HashSet<>();
|
||||
|
||||
public static Set<EaglercraftUUID> getVoiceListening() {
|
||||
return listeningSet;
|
||||
}
|
||||
|
||||
public static Set<EaglercraftUUID> getVoiceSpeaking() {
|
||||
return speakingSet;
|
||||
}
|
||||
|
||||
public static void setVoiceMuted(EaglercraftUUID uuid, boolean mute) {
|
||||
PlatformVoiceClient.mutePeer(uuid, mute);
|
||||
if (mute) {
|
||||
mutedSet.add(uuid);
|
||||
} else {
|
||||
mutedSet.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<EaglercraftUUID> getVoiceMuted() {
|
||||
return mutedSet;
|
||||
}
|
||||
|
||||
public static List<EaglercraftUUID> getVoiceRecent() {
|
||||
return new ArrayList<>(listeningSet);
|
||||
}
|
||||
|
||||
public static String getVoiceUsername(EaglercraftUUID uuid) {
|
||||
if(uuid == null) {
|
||||
return "null";
|
||||
}
|
||||
String ret = uuidToNameLookup.get(uuid);
|
||||
return ret == null ? uuid.toString() : ret;
|
||||
}
|
||||
|
||||
public static void sendPacketICE(EaglercraftUUID peerId, String candidate) {
|
||||
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketICE(peerId, candidate));
|
||||
}
|
||||
|
||||
public static void sendPacketDesc(EaglercraftUUID peerId, String desc) {
|
||||
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketDesc(peerId, desc));
|
||||
}
|
||||
|
||||
public static void sendPacketDisconnect(EaglercraftUUID peerId) {
|
||||
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketDisconnect(peerId));
|
||||
}
|
||||
|
||||
public static void sendPacketConnect() {
|
||||
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketConnect());
|
||||
}
|
||||
|
||||
public static void sendPacketRequest(EaglercraftUUID peerId) {
|
||||
packetSendCallback.accept(VoiceSignalPackets.makeVoiceSignalPacketRequest(peerId));
|
||||
}
|
||||
|
||||
private static void sendPacketRequestIfNeeded(EaglercraftUUID uuid) {
|
||||
if (getVoiceStatus() == EnumVoiceChannelStatus.DISCONNECTED || getVoiceStatus() == EnumVoiceChannelStatus.UNAVAILABLE) return;
|
||||
if(uuid.equals(EaglerProfile.getPlayerUUID())) return;
|
||||
if (!getVoiceListening().contains(uuid)) sendPacketRequest(uuid);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class VoiceSignalPackets {
|
||||
|
||||
static final int VOICE_SIGNAL_ALLOWED = 0;
|
||||
static final int VOICE_SIGNAL_REQUEST = 0;
|
||||
static final int VOICE_SIGNAL_CONNECT = 1;
|
||||
static final int VOICE_SIGNAL_DISCONNECT = 2;
|
||||
static final int VOICE_SIGNAL_ICE = 3;
|
||||
static final int VOICE_SIGNAL_DESC = 4;
|
||||
static final int VOICE_SIGNAL_GLOBAL = 5;
|
||||
|
||||
static void handleVoiceSignal(PacketBuffer streamIn) {
|
||||
try {
|
||||
int sig = streamIn.readUnsignedByte();
|
||||
switch(sig) {
|
||||
case VOICE_SIGNAL_ALLOWED: {
|
||||
boolean voiceAvailableStat = streamIn.readUnsignedByte() == 1;
|
||||
String[] servs = null;
|
||||
if(voiceAvailableStat) {
|
||||
servs = new String[streamIn.readVarIntFromBuffer()];
|
||||
for(int i = 0; i < servs.length; i++) {
|
||||
servs[i] = streamIn.readStringFromBuffer(1024);
|
||||
}
|
||||
}
|
||||
VoiceClientController.handleVoiceSignalPacketTypeAllowed(voiceAvailableStat, servs);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_GLOBAL: {
|
||||
if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.GLOBAL) return;
|
||||
EaglercraftUUID[] voiceIds = new EaglercraftUUID[streamIn.readVarIntFromBuffer()];
|
||||
for(int i = 0; i < voiceIds.length; i++) {
|
||||
voiceIds[i] = streamIn.readUuid();
|
||||
}
|
||||
String[] voiceNames = null;
|
||||
if (streamIn.isReadable()) {
|
||||
voiceNames = new String[voiceIds.length];
|
||||
for(int i = 0; i < voiceNames.length; i++) {
|
||||
voiceNames[i] = streamIn.readStringFromBuffer(16);
|
||||
}
|
||||
}
|
||||
VoiceClientController.handleVoiceSignalPacketTypeGlobal(voiceIds, voiceNames);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_CONNECT: {
|
||||
EaglercraftUUID uuid = streamIn.readUuid();
|
||||
if (streamIn.isReadable()) {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeConnect(uuid, streamIn.readBoolean());
|
||||
} else if (VoiceClientController.getVoiceChannel() != EnumVoiceChannelType.PROXIMITY || VoiceClientController.getVoiceListening().contains(uuid)) {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeConnectAnnounce(uuid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_DISCONNECT: {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeDisconnect(streamIn.readableBytes() > 0 ? streamIn.readUuid() : null);
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_ICE: {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeICECandidate(streamIn.readUuid(), streamIn.readStringFromBuffer(32767));
|
||||
break;
|
||||
}
|
||||
case VOICE_SIGNAL_DESC: {
|
||||
VoiceClientController.handleVoiceSignalPacketTypeDescription(streamIn.readUuid(), streamIn.readStringFromBuffer(32767));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
VoiceClientController.logger.error("Unknown voice signal packet '{}'!", sig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}catch(Throwable ex) {
|
||||
VoiceClientController.logger.error("Failed to handle signal packet!");
|
||||
VoiceClientController.logger.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketRequest(EaglercraftUUID user) {
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(17, 17));
|
||||
ret.writeByte(VOICE_SIGNAL_REQUEST);
|
||||
ret.writeUuid(user);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketICE(EaglercraftUUID user, String icePacket) {
|
||||
byte[] str = icePacket.getBytes(StandardCharsets.UTF_8);
|
||||
int estLen = 17 + PacketBuffer.getVarIntSize(str.length) + str.length;
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(estLen, estLen));
|
||||
ret.writeByte(VOICE_SIGNAL_ICE);
|
||||
ret.writeUuid(user);
|
||||
ret.writeByteArray(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketDesc(EaglercraftUUID user, String descPacket) {
|
||||
byte[] str = descPacket.getBytes(StandardCharsets.UTF_8);
|
||||
int estLen = 17 + PacketBuffer.getVarIntSize(str.length) + str.length;
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(estLen, estLen));
|
||||
ret.writeByte(VOICE_SIGNAL_DESC);
|
||||
ret.writeUuid(user);
|
||||
ret.writeByteArray(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PacketBuffer makeVoiceSignalPacketDisconnect(EaglercraftUUID user) {
|
||||
if (user == null) {
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(1, 1));
|
||||
ret.writeByte(VOICE_SIGNAL_DISCONNECT);
|
||||
return ret;
|
||||
}
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(17, 17));
|
||||
ret.writeByte(VOICE_SIGNAL_DISCONNECT);
|
||||
ret.writeUuid(user);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static PacketBuffer makeVoiceSignalPacketConnect() {
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(1, 1));
|
||||
ret.writeByte(VOICE_SIGNAL_CONNECT);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.voice;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityOtherPlayerMP;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
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 VoiceTagRenderer {
|
||||
|
||||
private static final ResourceLocation voiceGuiIcons = new ResourceLocation("eagler:gui/eagler_gui.png");
|
||||
|
||||
private static final Set<EaglercraftUUID> voiceTagsDrawnThisFrame = new HashSet();
|
||||
|
||||
public static void renderVoiceNameTag(Minecraft mc, EntityOtherPlayerMP player, int offset) {
|
||||
EaglercraftUUID uuid = player.getUniqueID();
|
||||
boolean mute = VoiceClientController.getVoiceMuted().contains(uuid);
|
||||
if((mute || VoiceClientController.getVoiceSpeaking().contains(uuid)) && voiceTagsDrawnThisFrame.add(uuid)) {
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.disableTexture2D();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.depthMask(false);
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.enableBlend();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(-8.0f, -18.0f + offset, 0.0f);
|
||||
|
||||
GlStateManager.scale(16.0f, 16.0f, 16.0f);
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
|
||||
worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
|
||||
float a = 0.25F;
|
||||
worldrenderer.pos(-0.02, -0.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
|
||||
worldrenderer.pos(-0.02, 1.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
|
||||
worldrenderer.pos(1.02, 1.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
|
||||
worldrenderer.pos(1.02, -0.02, 0.0).color(0.0F, 0.0F, 0.0F, a).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
GlStateManager.enableTexture2D();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.alphaFunc(GL_GREATER, 0.02f);
|
||||
|
||||
mc.getTextureManager().bindTexture(voiceGuiIcons);
|
||||
|
||||
int u = 0;
|
||||
int v = mute ? 192 : 160;
|
||||
|
||||
float var7 = 0.00390625F;
|
||||
float var8 = 0.00390625F;
|
||||
|
||||
if(mute) {
|
||||
GlStateManager.color(0.9F, 0.3F, 0.3F, 0.125F);
|
||||
}else {
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 0.125F);
|
||||
}
|
||||
|
||||
worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
|
||||
worldrenderer.pos(0, 1.0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
|
||||
worldrenderer.pos(1.0, 1.0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
|
||||
worldrenderer.pos(1.0, 0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
|
||||
worldrenderer.pos(0, 0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
GlStateManager.alphaFunc(GL_GREATER, 0.1f);
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.depthMask(true);
|
||||
|
||||
if(mute) {
|
||||
GlStateManager.color(0.9F, 0.3F, 0.3F, 1.0F);
|
||||
}else {
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
|
||||
worldrenderer.pos(0, 1.0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
|
||||
worldrenderer.pos(1.0, 1.0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 32 - 0.2f) * var8)).endVertex();
|
||||
worldrenderer.pos(1.0, 0, 0).tex((double) ((float) (u + 32 - 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
|
||||
worldrenderer.pos(0, 0, 0).tex((double) ((float) (u + 0.2f) * var7), (double) ((float) (v + 0.2f) * var8)).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearTagsDrawnSet() {
|
||||
voiceTagsDrawnThisFrame.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -99,7 +99,7 @@ public class BlockRedstoneWire extends Block {
|
|||
BlockPos posTmp = new BlockPos(0, 0, 0);
|
||||
Block block = worldIn.getBlockState(blockpos).getBlock();
|
||||
if (!canConnectTo(worldIn.getBlockState(blockpos), direction) && (block.isBlockNormalCube()
|
||||
|| !canConnectUpwardsTo(worldIn.getBlockState(blockpos.offsetEvenFaster(EnumFacing.UP, posTmp))))) {
|
||||
|| !canConnectUpwardsTo(worldIn.getBlockState(blockpos.offsetEvenFaster(EnumFacing.DOWN, posTmp))))) {
|
||||
Block block1 = worldIn.getBlockState(pos.up()).getBlock();
|
||||
return !block1.isBlockNormalCube() && block.isBlockNormalCube()
|
||||
&& canConnectUpwardsTo(worldIn.getBlockState(blockpos.offsetEvenFaster(EnumFacing.UP, posTmp)))
|
||||
|
@ -177,11 +177,13 @@ public class BlockRedstoneWire extends Block {
|
|||
if (worldIn.getBlockState(blockpos).getBlock().isNormalCube()
|
||||
&& !worldIn.getBlockState(pos1.up()).getBlock().isNormalCube()) {
|
||||
if (flag && pos1.getY() >= pos2.getY()) {
|
||||
l = this.getMaxCurrentStrength(worldIn, blockpos.up(), l);
|
||||
++blockpos.y;
|
||||
l = this.getMaxCurrentStrength(worldIn, blockpos, l);
|
||||
}
|
||||
} else if (!worldIn.getBlockState(blockpos).getBlock().isNormalCube() && flag
|
||||
&& pos1.getY() <= pos2.getY()) {
|
||||
l = this.getMaxCurrentStrength(worldIn, blockpos.down(), l);
|
||||
--blockpos.y;
|
||||
l = this.getMaxCurrentStrength(worldIn, blockpos, l);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,6 +207,7 @@ public class BlockRedstoneWire extends Block {
|
|||
|
||||
this.blocksNeedingUpdate.add(pos1);
|
||||
|
||||
facings = EnumFacing._VALUES;
|
||||
for (int m = 0; m < facings.length; ++m) {
|
||||
this.blocksNeedingUpdate.add(pos1.offset(facings[m]));
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import com.google.common.collect.Lists;
|
|||
|
||||
import net.hoosiertransfer.CullingMod;
|
||||
import net.hoosiertransfer.Alfheim.ILightUpdatesProcessor;
|
||||
import net.hoosiertransfer.Config;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.Display;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerXBungeeVersion;
|
||||
|
@ -38,6 +40,7 @@ import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
|||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerFolderResourcePack;
|
||||
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.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
|
@ -65,6 +68,8 @@ import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiScreenIntegratedServerBusy;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.gui.GuiScreenSingleplayerConnecting;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.lan.LANServerController;
|
||||
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.material.Material;
|
||||
import net.minecraft.client.audio.MusicTicker;
|
||||
|
@ -306,6 +311,12 @@ public class Minecraft implements IThreadListener {
|
|||
|
||||
public SkullCommand eagskullCommand;
|
||||
|
||||
public GuiVoiceOverlay voiceOverlay;
|
||||
|
||||
public float startZoomValue = 18.0f;
|
||||
public float adjustedZoomValue = 18.0f;
|
||||
public boolean isZoomKey = false;
|
||||
|
||||
public Minecraft(GameConfiguration gameConfig) {
|
||||
theMinecraft = this;
|
||||
StringTranslate.initClient();
|
||||
|
@ -423,6 +434,7 @@ public class Minecraft implements IThreadListener {
|
|||
this.mcResourceManager.registerReloadListener(new MetalsLUT());
|
||||
this.mcResourceManager.registerReloadListener(new EmissiveItems());
|
||||
this.mcResourceManager.registerReloadListener(new BlockVertexIDs());
|
||||
this.mcResourceManager.registerReloadListener(new EaglerMeshLoader());
|
||||
AchievementList.openInventory.setStatStringFormatter(new IStatStringFormat() {
|
||||
public String formatString(String parString1) {
|
||||
try {
|
||||
|
@ -473,6 +485,9 @@ public class Minecraft implements IThreadListener {
|
|||
this.checkGLError("Post startup");
|
||||
this.ingameGUI = new GuiIngame(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);
|
||||
EaglerProfile.read();
|
||||
|
@ -871,6 +886,7 @@ public class Minecraft implements IThreadListener {
|
|||
|
||||
public void updateDisplay() {
|
||||
this.mcProfiler.startSection("display_update");
|
||||
Display.setVSync(this.gameSettings.enableVsync);
|
||||
Display.update();
|
||||
this.mcProfiler.endSection();
|
||||
this.checkWindowResize();
|
||||
|
@ -1217,12 +1233,14 @@ public class Minecraft implements IThreadListener {
|
|||
private void resize(int width, int height) {
|
||||
this.displayWidth = Math.max(1, width);
|
||||
this.displayHeight = Math.max(1, height);
|
||||
ScaledResolution scaledresolution = new ScaledResolution(this);
|
||||
if (this.currentScreen != null) {
|
||||
ScaledResolution scaledresolution = new ScaledResolution(this);
|
||||
this.currentScreen.onResize(this, scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight());
|
||||
}
|
||||
|
||||
this.loadingScreen = new LoadingScreenRenderer(this);
|
||||
|
||||
this.voiceOverlay.setResolution(scaledresolution.getScaledWidth(), scaledresolution.getScaledHeight());
|
||||
}
|
||||
|
||||
public MusicTicker func_181535_r() {
|
||||
|
@ -1262,6 +1280,9 @@ public class Minecraft implements IThreadListener {
|
|||
this.ingameGUI.updateTick();
|
||||
}
|
||||
|
||||
this.mcProfiler.endStartSection("eaglerVoice");
|
||||
VoiceClientController.tickVoiceClient(this);
|
||||
|
||||
this.mcProfiler.endSection();
|
||||
this.entityRenderer.getMouseOver(1.0F);
|
||||
this.mcProfiler.startSection("gameMode");
|
||||
|
@ -1349,7 +1370,9 @@ public class Minecraft implements IThreadListener {
|
|||
if (i1 <= 200L) {
|
||||
int j = Mouse.getEventDWheel();
|
||||
if (j != 0) {
|
||||
if (this.thePlayer.isSpectator()) {
|
||||
if (this.isZoomKey) {
|
||||
this.adjustedZoomValue = MathHelper.clamp_float(adjustedZoomValue - j * 4.0f, 5.0f, 32.0f);
|
||||
} else if (this.thePlayer.isSpectator()) {
|
||||
j = j < 0 ? -1 : 1;
|
||||
if (this.ingameGUI.getSpectatorGui().func_175262_a()) {
|
||||
this.ingameGUI.getSpectatorGui().func_175259_b(-j);
|
||||
|
@ -1538,6 +1561,12 @@ public class Minecraft implements IThreadListener {
|
|||
}
|
||||
}
|
||||
|
||||
boolean zoomKey = this.gameSettings.keyBindZoomCamera.isKeyDown();
|
||||
if (zoomKey != isZoomKey) {
|
||||
adjustedZoomValue = startZoomValue;
|
||||
isZoomKey = zoomKey;
|
||||
}
|
||||
|
||||
boolean flag = this.gameSettings.chatVisibility != EntityPlayer.EnumChatVisibility.HIDDEN;
|
||||
|
||||
while (this.gameSettings.keyBindInventory.isPressed()) {
|
||||
|
@ -1638,12 +1667,12 @@ public class Minecraft implements IThreadListener {
|
|||
this.entityRenderer.func_181022_b();
|
||||
}
|
||||
|
||||
if (!this.isGamePaused) {
|
||||
if (!this.isGamePaused && Config.audioEnabled()) {
|
||||
this.mcMusicTicker.update();
|
||||
this.mcSoundHandler.update();
|
||||
}
|
||||
|
||||
if (this.theWorld != null) {
|
||||
if (this.theWorld != null) {
|
||||
if (!this.isGamePaused) {
|
||||
this.theWorld.setAllowedSpawnTypes(this.theWorld.getDifficulty() != EnumDifficulty.PEACEFUL, true);
|
||||
|
||||
|
@ -1663,7 +1692,7 @@ public class Minecraft implements IThreadListener {
|
|||
}
|
||||
|
||||
this.mcProfiler.endStartSection("animateTick");
|
||||
if (!this.isGamePaused && this.theWorld != null) {
|
||||
if (!this.isGamePaused && this.theWorld != null && Config.animateTick()) {
|
||||
this.theWorld.doVoidFogParticles(MathHelper.floor_double(this.thePlayer.posX),
|
||||
MathHelper.floor_double(this.thePlayer.posY), MathHelper.floor_double(this.thePlayer.posZ));
|
||||
}
|
||||
|
@ -1730,6 +1759,7 @@ public class Minecraft implements IThreadListener {
|
|||
*/
|
||||
public void launchIntegratedServer(String folderName, String worldName, WorldSettings worldSettingsIn) {
|
||||
this.loadWorld((WorldClient) null);
|
||||
Minecraft.getMinecraft().getRenderManager().setEnableFNAWSkins(this.gameSettings.enableFNAWSkins);
|
||||
session.reset();
|
||||
SingleplayerServerController.launchEaglercraftServer(folderName, gameSettings.difficulty.getDifficultyId(),
|
||||
Math.max(gameSettings.renderDistanceChunks, 2), worldSettingsIn);
|
||||
|
@ -2273,4 +2303,12 @@ public class Minecraft implements IThreadListener {
|
|||
public void clearTitles() {
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package net.minecraft.client.entity;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.mojang.authlib.GameProfile;
|
||||
import net.lax1dude.eaglercraft.v1_8.profile.SkinModel;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.network.NetworkPlayerInfo;
|
||||
import net.minecraft.client.resources.DefaultPlayerSkin;
|
||||
|
@ -35,6 +36,14 @@ import net.minecraft.world.WorldSettings;
|
|||
public abstract class AbstractClientPlayer extends EntityPlayer {
|
||||
private NetworkPlayerInfo playerInfo;
|
||||
|
||||
public long eaglerHighPolyAnimationTick = System.currentTimeMillis();
|
||||
public float eaglerHighPolyAnimationFloat1 = 0.0f;
|
||||
public float eaglerHighPolyAnimationFloat2 = 0.0f;
|
||||
public float eaglerHighPolyAnimationFloat3 = 0.0f;
|
||||
public float eaglerHighPolyAnimationFloat4 = 0.0f;
|
||||
public float eaglerHighPolyAnimationFloat5 = 0.0f;
|
||||
public float eaglerHighPolyAnimationFloat6 = 0.0f;
|
||||
|
||||
public AbstractClientPlayer(World worldIn, GameProfile playerProfile) {
|
||||
super(worldIn, playerProfile);
|
||||
}
|
||||
|
@ -92,6 +101,11 @@ public abstract class AbstractClientPlayer extends EntityPlayer {
|
|||
: networkplayerinfo.getSkinType();
|
||||
}
|
||||
|
||||
public SkinModel getEaglerSkinModel() {
|
||||
NetworkPlayerInfo networkplayerinfo = this.getPlayerInfo();
|
||||
return networkplayerinfo == null ? SkinModel.STEVE : networkplayerinfo.getEaglerSkinModel();
|
||||
}
|
||||
|
||||
public float getFovModifier() {
|
||||
float f = 1.0F;
|
||||
if (this.capabilities.isFlying) {
|
||||
|
|
|
@ -32,8 +32,8 @@ import net.minecraft.util.ResourceLocation;
|
|||
*/
|
||||
public class GuiButton extends Gui {
|
||||
protected static final ResourceLocation buttonTextures = new ResourceLocation("textures/gui/widgets.png");
|
||||
protected int width;
|
||||
protected int height;
|
||||
public int width;
|
||||
public int height;
|
||||
public int xPosition;
|
||||
public int yPosition;
|
||||
public String displayString;
|
||||
|
|