mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 02:48:14 -05:00
Update #37 - Touch support without userscript, many other feats
This commit is contained in:
@ -1,11 +1,5 @@
|
||||
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.
|
||||
*
|
||||
@ -25,42 +19,6 @@ 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),
|
||||
@ -74,10 +32,4 @@ public class CapePackets {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -40,12 +40,34 @@ public class EaglerProfile {
|
||||
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 boolean isServerSkinOverride = false;
|
||||
public static int overridePresetSkinId = -1;
|
||||
public static final ResourceLocation overrideCustomSkinTexture = new ResourceLocation("eagler:skins/custom/tex_server_override");
|
||||
public static EaglerSkinTexture overrideCustomSkin = null;
|
||||
public static SkinModel overrideCustomSkinModel = SkinModel.STEVE;
|
||||
|
||||
public static boolean isServerCapeOverride = false;
|
||||
public static int overridePresetCapeId = -1;
|
||||
public static final ResourceLocation overrideCustomCapeTexture = new ResourceLocation("eagler:capes/custom/tex_server_override");
|
||||
public static EaglerSkinTexture overrideCustomCape = null;
|
||||
|
||||
public static final List<CustomSkin> customSkins = new ArrayList<>();
|
||||
public static final List<CustomCape> customCapes = new ArrayList<>();
|
||||
|
||||
public static final EaglercraftRandom rand;
|
||||
|
||||
public static ResourceLocation getActiveSkinResourceLocation() {
|
||||
if(isServerSkinOverride) {
|
||||
if(overridePresetSkinId == -1) {
|
||||
return overrideCustomSkinTexture;
|
||||
}else {
|
||||
if(overridePresetSkinId >= 0 && overridePresetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return DefaultSkins.defaultSkinsMap[overridePresetSkinId].location;
|
||||
}else {
|
||||
return DefaultSkins.defaultSkinsMap[0].location;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return customSkins.get(customSkinId).getResource();
|
||||
@ -65,6 +87,17 @@ public class EaglerProfile {
|
||||
}
|
||||
|
||||
public static SkinModel getActiveSkinModel() {
|
||||
if(isServerSkinOverride) {
|
||||
if(overridePresetSkinId == -1) {
|
||||
return overrideCustomSkinModel;
|
||||
}else {
|
||||
if(overridePresetSkinId >= 0 && overridePresetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return DefaultSkins.defaultSkinsMap[overridePresetSkinId].model;
|
||||
}else {
|
||||
return DefaultSkins.defaultSkinsMap[0].model;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return customSkins.get(customSkinId).model;
|
||||
@ -84,6 +117,17 @@ public class EaglerProfile {
|
||||
}
|
||||
|
||||
public static ResourceLocation getActiveCapeResourceLocation() {
|
||||
if(isServerCapeOverride) {
|
||||
if(overridePresetCapeId == -1) {
|
||||
return overrideCustomCapeTexture;
|
||||
}else {
|
||||
if(overridePresetCapeId >= 0 && overridePresetCapeId < DefaultCapes.defaultCapesMap.length) {
|
||||
return DefaultCapes.defaultCapesMap[overridePresetCapeId].location;
|
||||
}else {
|
||||
return DefaultCapes.defaultCapesMap[0].location;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(presetCapeId == -1) {
|
||||
if(customCapeId >= 0 && customCapeId < customCapes.size()) {
|
||||
return customCapes.get(customCapeId).getResource();
|
||||
@ -118,10 +162,15 @@ public class EaglerProfile {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getSkinPacket() {
|
||||
public static byte[] getSkinPacket(int vers) {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return SkinPackets.writeMySkinCustom(customSkins.get(customSkinId));
|
||||
CustomSkin toSend = customSkins.get(customSkinId);
|
||||
if(vers <= 3) {
|
||||
return SkinPackets.writeMySkinCustomV3(toSend);
|
||||
}else {
|
||||
return SkinPackets.writeMySkinCustomV4(toSend);
|
||||
}
|
||||
}else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
@ -156,6 +205,59 @@ public class EaglerProfile {
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleForceSkinPreset(int preset) {
|
||||
isServerSkinOverride = true;
|
||||
overridePresetSkinId = preset;
|
||||
ServerSkinCache.needReloadClientSkin = true;
|
||||
}
|
||||
|
||||
public static void handleForceSkinCustom(int modelID, byte[] datav3) {
|
||||
if(datav3.length != 16384) {
|
||||
return;
|
||||
}
|
||||
isServerSkinOverride = true;
|
||||
overridePresetSkinId = -1;
|
||||
overrideCustomSkinModel = SkinModel.getModelFromId(modelID);
|
||||
if(overrideCustomSkinModel.highPoly != null) {
|
||||
overrideCustomSkinModel = SkinModel.STEVE;
|
||||
}
|
||||
if(overrideCustomSkin == null) {
|
||||
overrideCustomSkin = new EaglerSkinTexture(datav3, 64, 64);
|
||||
Minecraft.getMinecraft().getTextureManager().loadTexture(overrideCustomSkinTexture, overrideCustomSkin);
|
||||
}else {
|
||||
overrideCustomSkin.copyPixelsIn(datav3);
|
||||
}
|
||||
ServerSkinCache.needReloadClientSkin = true;
|
||||
}
|
||||
|
||||
public static void handleForceCapePreset(int preset) {
|
||||
isServerCapeOverride = true;
|
||||
overridePresetCapeId = preset;
|
||||
ServerCapeCache.needReloadClientCape = true;
|
||||
}
|
||||
|
||||
public static void handleForceCapeCustom(byte[] custom) {
|
||||
if(custom.length != 1173) {
|
||||
return;
|
||||
}
|
||||
byte[] pixels32x32 = new byte[4096];
|
||||
SkinConverter.convertCape23x17RGBto32x32RGBA(custom, pixels32x32);
|
||||
isServerCapeOverride = true;
|
||||
overridePresetCapeId = -1;
|
||||
if(overrideCustomCape == null) {
|
||||
overrideCustomCape = new EaglerSkinTexture(pixels32x32, 32, 32);
|
||||
Minecraft.getMinecraft().getTextureManager().loadTexture(overrideCustomCapeTexture, overrideCustomCape);
|
||||
}else {
|
||||
overrideCustomCape.copyPixelsIn(pixels32x32);
|
||||
}
|
||||
ServerCapeCache.needReloadClientCape = true;
|
||||
}
|
||||
|
||||
public static void clearServerSkinOverride() {
|
||||
isServerSkinOverride = false;
|
||||
isServerCapeOverride = false;
|
||||
}
|
||||
|
||||
private static boolean doesSkinExist(String name) {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
if(customSkins.get(i).name.equalsIgnoreCase(name)) {
|
||||
|
@ -44,15 +44,23 @@ public class EaglerSkinTexture implements ITextureObject {
|
||||
if(pixels.length != width * height * 4) {
|
||||
throw new IllegalArgumentException("Wrong data length " + pixels.length + " for " + width + "x" + height + " texture");
|
||||
}
|
||||
this.pixels = convertToInt(pixels);
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public static int[] convertToInt(byte[] pixels) {
|
||||
int[] p = new int[pixels.length >> 2];
|
||||
for(int i = 0, j; i < p.length; ++i) {
|
||||
j = i << 2;
|
||||
p[i] = (((int) pixels[j] & 0xFF) << 24) | (((int) pixels[j + 1] & 0xFF) << 16)
|
||||
| (((int) pixels[j + 2] & 0xFF) << 8) | ((int) pixels[j + 3] & 0xFF);
|
||||
}
|
||||
this.pixels = p;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
return p;
|
||||
}
|
||||
|
||||
public void copyPixelsIn(byte[] pixels) {
|
||||
copyPixelsIn(convertToInt(pixels));
|
||||
}
|
||||
|
||||
public void copyPixelsIn(int[] pixels) {
|
||||
@ -93,4 +101,16 @@ public class EaglerSkinTexture implements ITextureObject {
|
||||
textureId = -1;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int[] getData() {
|
||||
return pixels;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.Keyboard;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformNetworking;
|
||||
import net.lax1dude.eaglercraft.v1_8.minecraft.EnumInputEvent;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.ConnectionHandshake;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.HandshakePacketTypes;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
@ -92,9 +92,6 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, password.getText()));
|
||||
}else {
|
||||
this.mc.displayGuiScreen(parent);
|
||||
if (!PlatformNetworking.playConnectionState().isClosed()) {
|
||||
PlatformNetworking.playDisconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,4 +119,14 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
||||
this.password.mouseClicked(parInt1, parInt2, parInt3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showCopyPasteButtons() {
|
||||
return password.isFocused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireInputEvent(EnumInputEvent event, String param) {
|
||||
password.fireInputEvent(event, param);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ 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.PointerInputAbstraction;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.EnumCursorType;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.FileChooserResult;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
@ -51,7 +52,6 @@ public class GuiScreenEditCape extends GuiScreen {
|
||||
|
||||
public GuiScreenEditCape(GuiScreenEditProfile parent) {
|
||||
this.parent = parent;
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
@ -61,6 +61,7 @@ public class GuiScreenEditCape extends GuiScreen {
|
||||
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")));
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
private void updateOptions() {
|
||||
@ -243,7 +244,7 @@ public class GuiScreenEditCape extends GuiScreen {
|
||||
if(EagRuntime.fileChooserHasResult()) {
|
||||
FileChooserResult result = EagRuntime.getFileChooserResult();
|
||||
if(result != null) {
|
||||
ImageData loadedCape = ImageData.loadImageFile(result.fileData);
|
||||
ImageData loadedCape = ImageData.loadImageFile(result.fileData, ImageData.getMimeFromType(result.fileName));
|
||||
if(loadedCape != null) {
|
||||
if((loadedCape.width == 32 || loadedCape.width == 64) && loadedCape.height == 32) {
|
||||
byte[] resized = new byte[1173];
|
||||
@ -258,12 +259,12 @@ public class GuiScreenEditCape extends GuiScreen {
|
||||
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!");
|
||||
EagRuntime.showPopup("The selected file '" + result.fileName + "' is not a supported format!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(dropDownOpen) {
|
||||
if(Mouse.isButtonDown(0)) {
|
||||
if(PointerInputAbstraction.getVCursorButtonDown(0)) {
|
||||
int skinX = width / 2 - 20;
|
||||
int skinY = height / 6 + 73;
|
||||
int skinWidth = 140;
|
||||
|
@ -3,8 +3,10 @@ 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.PointerInputAbstraction;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.EnumCursorType;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.FileChooserResult;
|
||||
import net.lax1dude.eaglercraft.v1_8.minecraft.EnumInputEvent;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
@ -57,7 +59,6 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
|
||||
public GuiScreenEditProfile(GuiScreen parent) {
|
||||
this.parent = parent;
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
@ -66,10 +67,12 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
usernameField = new GuiTextField(0, fontRendererObj, width / 2 - 20 + 1, height / 6 + 24 + 1, 138, 20);
|
||||
usernameField.setFocused(true);
|
||||
usernameField.setText(EaglerProfile.getName());
|
||||
usernameField.setMaxStringLength(16);
|
||||
selectedSlot = EaglerProfile.presetSkinId == -1 ? EaglerProfile.customSkinId : (EaglerProfile.presetSkinId + EaglerProfile.customSkins.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 + 110, 71, 20, I18n.format("editProfile.addSkin")));
|
||||
buttonList.add(new GuiButton(2, width / 2 - 21 + 71, height / 6 + 110, 72, 20, I18n.format("editProfile.clearSkin")));
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
private void updateOptions() {
|
||||
@ -330,7 +333,7 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
if(EagRuntime.fileChooserHasResult()) {
|
||||
FileChooserResult result = EagRuntime.getFileChooserResult();
|
||||
if(result != null) {
|
||||
ImageData loadedSkin = ImageData.loadImageFile(result.fileData);
|
||||
ImageData loadedSkin = ImageData.loadImageFile(result.fileData, ImageData.getMimeFromType(result.fileName));
|
||||
if(loadedSkin != null) {
|
||||
boolean isLegacy = loadedSkin.width == 64 && loadedSkin.height == 32;
|
||||
boolean isModern = loadedSkin.width == 64 && loadedSkin.height == 64;
|
||||
@ -367,12 +370,12 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
EagRuntime.showPopup("The selected image '" + result.fileName + "' is not the right size!\nEaglercraft only supports 64x32 or 64x64 skins");
|
||||
}
|
||||
}else {
|
||||
EagRuntime.showPopup("The selected file '" + result.fileName + "' is not a PNG file!");
|
||||
EagRuntime.showPopup("The selected file '" + result.fileName + "' is not a supported format!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(dropDownOpen) {
|
||||
if(Mouse.isButtonDown(0)) {
|
||||
if(PointerInputAbstraction.getVCursorButtonDown(0)) {
|
||||
int skinX = width / 2 - 20;
|
||||
int skinY = height / 6 + 103;
|
||||
int skinWidth = 140;
|
||||
@ -532,4 +535,14 @@ public class GuiScreenEditProfile extends GuiScreen {
|
||||
EaglerProfile.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showCopyPasteButtons() {
|
||||
return usernameField.isFocused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireInputEvent(EnumInputEvent event, String param) {
|
||||
usernameField.fireInputEvent(event, param);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ public class GuiScreenImportProfile extends GuiScreen {
|
||||
}else {
|
||||
mc.loadingScreen.eaglerShow(I18n.format("settingsBackup.importing.1"), I18n.format("settingsBackup.importing.2"));
|
||||
try {
|
||||
List<String> list1 = new ArrayList(mc.gameSettings.resourcePacks);
|
||||
List<String> list2 = new ArrayList(mc.gameSettings.field_183018_l);
|
||||
List<String> list1 = new ArrayList<>(mc.gameSettings.resourcePacks);
|
||||
List<String> list2 = new ArrayList<>(mc.gameSettings.field_183018_l);
|
||||
importer.importProfileAndSettings(doImportProfile, doImportSettings, doImportServers, doImportResourcePacks);
|
||||
boolean resourcePacksChanged = !mc.gameSettings.resourcePacks.equals(list1) || !mc.gameSettings.field_183018_l.equals(list2);
|
||||
if(resourcePacksChanged || (doImportResourcePacks && (list1.size() > 0 || list2.size() > 0))) {
|
||||
|
@ -2,6 +2,7 @@ package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglerMeshLoader;
|
||||
@ -158,7 +159,7 @@ public class RenderHighPoly extends RenderPlayer {
|
||||
|
||||
if(highPolySkin.headModel != null) {
|
||||
if(highPolySkin == HighPolySkin.BABY_CHARLES) {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
float partialTicks = (float) ((millis - abstractclientplayer.eaglerHighPolyAnimationTick) * 0.02);
|
||||
//long l50 = millis / 50l * 50l;
|
||||
//boolean runTick = par1EntityPlayer.eaglerHighPolyAnimationTick < l50 && millis >= l50;
|
||||
|
@ -1,17 +1,16 @@
|
||||
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.EagRuntime;
|
||||
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.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.client.CPacketGetOtherCapeEAG;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
@ -39,7 +38,7 @@ public class ServerCapeCache {
|
||||
protected final int presetCapeId;
|
||||
protected final CacheCustomCape customCape;
|
||||
|
||||
protected long lastCacheHit = System.currentTimeMillis();
|
||||
protected long lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
|
||||
protected CapeCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation) {
|
||||
this.isPresetCape = false;
|
||||
@ -96,26 +95,32 @@ public class ServerCapeCache {
|
||||
}
|
||||
|
||||
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 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;
|
||||
private final NetHandlerPlayClient netHandler;
|
||||
protected final TextureManager textureManager;
|
||||
|
||||
private final EaglercraftUUID clientPlayerId;
|
||||
private final CapeCacheEntry clientPlayerCacheEntry;
|
||||
private CapeCacheEntry clientPlayerCacheEntry;
|
||||
|
||||
private long lastFlush = System.currentTimeMillis();
|
||||
private long lastFlushReq = System.currentTimeMillis();
|
||||
private long lastFlushEvict = System.currentTimeMillis();
|
||||
private long lastFlush = EagRuntime.steadyTimeMillis();
|
||||
private long lastFlushReq = EagRuntime.steadyTimeMillis();
|
||||
private long lastFlushEvict = EagRuntime.steadyTimeMillis();
|
||||
|
||||
private static int texId = 0;
|
||||
public static boolean needReloadClientCape = false;
|
||||
|
||||
public ServerCapeCache(EaglercraftNetworkManager networkManager, TextureManager textureManager) {
|
||||
this.networkManager = networkManager;
|
||||
public ServerCapeCache(NetHandlerPlayClient netHandler, TextureManager textureManager) {
|
||||
this.netHandler = netHandler;
|
||||
this.textureManager = textureManager;
|
||||
this.clientPlayerId = EaglerProfile.getPlayerUUID();
|
||||
reloadClientPlayerCape();
|
||||
}
|
||||
|
||||
public void reloadClientPlayerCape() {
|
||||
needReloadClientCape = false;
|
||||
this.clientPlayerCacheEntry = new CapeCacheEntry(EaglerProfile.getActiveCapeResourceLocation());
|
||||
}
|
||||
|
||||
@ -130,20 +135,12 @@ public class ServerCapeCache {
|
||||
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));
|
||||
waitingCapes.put(player, EagRuntime.steadyTimeMillis());
|
||||
netHandler.sendEaglerMessage(new CPacketGetOtherCapeEAG(player.msb, player.lsb));
|
||||
}
|
||||
return defaultCacheEntry;
|
||||
}else {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
etr.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
return etr;
|
||||
}
|
||||
}
|
||||
@ -183,7 +180,7 @@ public class ServerCapeCache {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
if(millis - lastFlushReq > 5000l) {
|
||||
lastFlushReq = millis;
|
||||
if(!waitingCapes.isEmpty()) {
|
||||
@ -219,6 +216,9 @@ public class ServerCapeCache {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(needReloadClientCape) {
|
||||
reloadClientPlayerCape();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
@ -232,7 +232,14 @@ public class ServerCapeCache {
|
||||
}
|
||||
|
||||
public void evictCape(EaglercraftUUID uuid) {
|
||||
evictedCapes.put(uuid, Long.valueOf(System.currentTimeMillis()));
|
||||
evictedCapes.put(uuid, Long.valueOf(EagRuntime.steadyTimeMillis()));
|
||||
CapeCacheEntry etr = capesCache.remove(uuid);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleInvalidate(EaglercraftUUID uuid) {
|
||||
CapeCacheEntry etr = capesCache.remove(uuid);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
|
@ -1,19 +1,19 @@
|
||||
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.EagRuntime;
|
||||
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.mojang.authlib.GameProfile;
|
||||
import net.lax1dude.eaglercraft.v1_8.mojang.authlib.TexturesProperty;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.EaglercraftNetworkManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.client.CPacketGetOtherSkinEAG;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.client.CPacketGetSkinByURLEAG;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
@ -41,7 +41,7 @@ public class ServerSkinCache {
|
||||
protected final int presetSkinId;
|
||||
protected final CacheCustomSkin customSkin;
|
||||
|
||||
protected long lastCacheHit = System.currentTimeMillis();
|
||||
protected long lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
|
||||
protected SkinCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation, SkinModel model) {
|
||||
this.isPresetSkin = false;
|
||||
@ -125,26 +125,32 @@ public class ServerSkinCache {
|
||||
|
||||
private final SkinCacheEntry defaultCacheEntry = new SkinCacheEntry(0);
|
||||
private final SkinCacheEntry defaultSlimCacheEntry = new SkinCacheEntry(1);
|
||||
private final Map<EaglercraftUUID, SkinCacheEntry> skinsCache = new HashMap();
|
||||
private final Map<EaglercraftUUID, WaitingSkin> waitingSkins = new HashMap();
|
||||
private final Map<EaglercraftUUID, Long> evictedSkins = new HashMap();
|
||||
private final Map<EaglercraftUUID, SkinCacheEntry> skinsCache = new HashMap<>();
|
||||
private final Map<EaglercraftUUID, WaitingSkin> waitingSkins = new HashMap<>();
|
||||
private final Map<EaglercraftUUID, Long> evictedSkins = new HashMap<>();
|
||||
|
||||
private final EaglercraftNetworkManager networkManager;
|
||||
private final NetHandlerPlayClient netHandler;
|
||||
protected final TextureManager textureManager;
|
||||
|
||||
private final EaglercraftUUID clientPlayerId;
|
||||
private final SkinCacheEntry clientPlayerCacheEntry;
|
||||
private SkinCacheEntry clientPlayerCacheEntry;
|
||||
|
||||
private long lastFlush = System.currentTimeMillis();
|
||||
private long lastFlushReq = System.currentTimeMillis();
|
||||
private long lastFlushEvict = System.currentTimeMillis();
|
||||
private long lastFlush = EagRuntime.steadyTimeMillis();
|
||||
private long lastFlushReq = EagRuntime.steadyTimeMillis();
|
||||
private long lastFlushEvict = EagRuntime.steadyTimeMillis();
|
||||
|
||||
private static int texId = 0;
|
||||
public static boolean needReloadClientSkin = false;
|
||||
|
||||
public ServerSkinCache(EaglercraftNetworkManager networkManager, TextureManager textureManager) {
|
||||
this.networkManager = networkManager;
|
||||
public ServerSkinCache(NetHandlerPlayClient netHandler, TextureManager textureManager) {
|
||||
this.netHandler = netHandler;
|
||||
this.textureManager = textureManager;
|
||||
this.clientPlayerId = EaglerProfile.getPlayerUUID();
|
||||
reloadClientPlayerSkin();
|
||||
}
|
||||
|
||||
public void reloadClientPlayerSkin() {
|
||||
needReloadClientSkin = false;
|
||||
this.clientPlayerCacheEntry = new SkinCacheEntry(EaglerProfile.getActiveSkinResourceLocation(), EaglerProfile.getActiveSkinModel());
|
||||
}
|
||||
|
||||
@ -184,20 +190,12 @@ public class ServerSkinCache {
|
||||
SkinCacheEntry etr = skinsCache.get(player);
|
||||
if(etr == null) {
|
||||
if(!waitingSkins.containsKey(player) && !evictedSkins.containsKey(player)) {
|
||||
waitingSkins.put(player, new WaitingSkin(System.currentTimeMillis(), null));
|
||||
PacketBuffer buffer;
|
||||
try {
|
||||
buffer = SkinPackets.writeGetOtherSkin(player);
|
||||
}catch(IOException ex) {
|
||||
logger.error("Could not write skin request packet!");
|
||||
logger.error(ex);
|
||||
return defaultCacheEntry;
|
||||
}
|
||||
networkManager.sendPacket(new C17PacketCustomPayload("EAG|Skins-1.8", buffer));
|
||||
waitingSkins.put(player, new WaitingSkin(EagRuntime.steadyTimeMillis(), null));
|
||||
netHandler.sendEaglerMessage(new CPacketGetOtherSkinEAG(player.msb, player.lsb));
|
||||
}
|
||||
return defaultCacheEntry;
|
||||
}else {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
etr.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
return etr;
|
||||
}
|
||||
}
|
||||
@ -209,20 +207,12 @@ public class ServerSkinCache {
|
||||
EaglercraftUUID generatedUUID = SkinPackets.createEaglerURLSkinUUID(url);
|
||||
SkinCacheEntry etr = skinsCache.get(generatedUUID);
|
||||
if(etr != null) {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
etr.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
return etr;
|
||||
}else {
|
||||
if(!waitingSkins.containsKey(generatedUUID) && !evictedSkins.containsKey(generatedUUID)) {
|
||||
waitingSkins.put(generatedUUID, new WaitingSkin(System.currentTimeMillis(), skinModelResponse));
|
||||
PacketBuffer buffer;
|
||||
try {
|
||||
buffer = SkinPackets.writeGetSkinByURL(generatedUUID, url);
|
||||
}catch(IOException ex) {
|
||||
logger.error("Could not write skin request packet!");
|
||||
logger.error(ex);
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
}
|
||||
networkManager.sendPacket(new C17PacketCustomPayload("EAG|Skins-1.8", buffer));
|
||||
waitingSkins.put(generatedUUID, new WaitingSkin(EagRuntime.steadyTimeMillis(), skinModelResponse));
|
||||
netHandler.sendEaglerMessage(new CPacketGetSkinByURLEAG(generatedUUID.msb, generatedUUID.lsb, url));
|
||||
}
|
||||
}
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
@ -276,13 +266,13 @@ public class ServerSkinCache {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
long millis = System.currentTimeMillis();
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
if(millis - lastFlushReq > 5000l) {
|
||||
lastFlushReq = millis;
|
||||
if(!waitingSkins.isEmpty()) {
|
||||
Iterator<WaitingSkin> waitingItr = waitingSkins.values().iterator();
|
||||
while(waitingItr.hasNext()) {
|
||||
if(millis - waitingItr.next().timeout > 30000l) {
|
||||
if(millis - waitingItr.next().timeout > 20000l) {
|
||||
waitingItr.remove();
|
||||
}
|
||||
}
|
||||
@ -312,6 +302,9 @@ public class ServerSkinCache {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(needReloadClientSkin) {
|
||||
reloadClientPlayerSkin();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
@ -325,7 +318,14 @@ public class ServerSkinCache {
|
||||
}
|
||||
|
||||
public void evictSkin(EaglercraftUUID uuid) {
|
||||
evictedSkins.put(uuid, Long.valueOf(System.currentTimeMillis()));
|
||||
evictedSkins.put(uuid, Long.valueOf(EagRuntime.steadyTimeMillis()));
|
||||
SkinCacheEntry etr = skinsCache.remove(uuid);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleInvalidate(EaglercraftUUID uuid) {
|
||||
SkinCacheEntry etr = skinsCache.remove(uuid);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
|
@ -32,7 +32,7 @@ public enum SkinModel {
|
||||
public final HighPolySkin highPoly;
|
||||
|
||||
public static final SkinModel[] skinModels = new SkinModel[8];
|
||||
private static final Map<String, SkinModel> skinModelsByName = new HashMap();
|
||||
private static final Map<String, SkinModel> skinModelsByName = new HashMap<>();
|
||||
|
||||
private SkinModel(int id, int w, int h, String profileSkinType, boolean sanitize) {
|
||||
this.id = id;
|
||||
|
@ -1,12 +1,8 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.ArrayUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.lax1dude.eaglercraft.v1_8.crypto.MD5Digest;
|
||||
import net.lax1dude.eaglercraft.v1_8.netty.Unpooled;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
@ -27,97 +23,33 @@ public class SkinPackets {
|
||||
|
||||
public static final int PACKET_MY_SKIN_PRESET = 0x01;
|
||||
public static final int PACKET_MY_SKIN_CUSTOM = 0x02;
|
||||
public static final int PACKET_GET_OTHER_SKIN = 0x03;
|
||||
public static final int PACKET_OTHER_SKIN_PRESET = 0x04;
|
||||
public static final int PACKET_OTHER_SKIN_CUSTOM = 0x05;
|
||||
public static final int PACKET_GET_SKIN_BY_URL = 0x06;
|
||||
public static final int PACKET_INSTALL_NEW_SKIN = 0x07;
|
||||
|
||||
public static void readPluginMessage(PacketBuffer buffer, ServerSkinCache skinCache) throws IOException {
|
||||
try {
|
||||
int type = (int)buffer.readByte() & 0xFF;
|
||||
switch(type) {
|
||||
case PACKET_OTHER_SKIN_PRESET: {
|
||||
EaglercraftUUID responseUUID = buffer.readUuid();
|
||||
int responsePreset = buffer.readInt();
|
||||
if(buffer.isReadable()) {
|
||||
throw new IOException("PACKET_OTHER_SKIN_PRESET had " + buffer.readableBytes() + " remaining bytes!");
|
||||
}
|
||||
skinCache.cacheSkinPreset(responseUUID, responsePreset);
|
||||
break;
|
||||
}
|
||||
case PACKET_OTHER_SKIN_CUSTOM: {
|
||||
EaglercraftUUID responseUUID = buffer.readUuid();
|
||||
int model = (int)buffer.readByte() & 0xFF;
|
||||
SkinModel modelId;
|
||||
if(model == (byte)0xFF) {
|
||||
modelId = skinCache.getRequestedSkinType(responseUUID);
|
||||
}else {
|
||||
modelId = SkinModel.getModelFromId(model & 0x7F);
|
||||
if((model & 0x80) != 0 && modelId.sanitize) {
|
||||
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);
|
||||
if(buffer.isReadable()) {
|
||||
throw new IOException("PACKET_MY_SKIN_CUSTOM had " + buffer.readableBytes() + " remaining bytes!");
|
||||
}
|
||||
skinCache.cacheSkinCustom(responseUUID, readSkin, modelId);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IOException("Unknown skin packet type: " + type);
|
||||
}
|
||||
}catch(IOException ex) {
|
||||
throw ex;
|
||||
}catch(Throwable t) {
|
||||
throw new IOException("Failed to parse skin packet!", t);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] writeMySkinPreset(int skinId) {
|
||||
return new byte[] { (byte) PACKET_MY_SKIN_PRESET, (byte) (skinId >>> 24), (byte) (skinId >>> 16),
|
||||
(byte) (skinId >>> 8), (byte) (skinId & 0xFF) };
|
||||
}
|
||||
|
||||
public static byte[] writeMySkinCustom(CustomSkin customSkin) {
|
||||
byte[] packet = new byte[2 + customSkin.texture.length];
|
||||
public static byte[] writeMySkinCustomV3(CustomSkin customSkin) {
|
||||
byte[] packet = new byte[2 + 16384];
|
||||
packet[0] = (byte) PACKET_MY_SKIN_CUSTOM;
|
||||
packet[1] = (byte) customSkin.model.id;
|
||||
System.arraycopy(customSkin.texture, 0, packet, 2, customSkin.texture.length);
|
||||
System.arraycopy(customSkin.texture, 0, packet, 2, 16384);
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static PacketBuffer writeCreateCustomSkull(byte[] customSkin) {
|
||||
int len = 3 + customSkin.length;
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(len, len));
|
||||
ret.writeByte(PACKET_INSTALL_NEW_SKIN);
|
||||
ret.writeShort(customSkin.length);
|
||||
ret.writeBytes(customSkin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static PacketBuffer writeGetOtherSkin(EaglercraftUUID skinId) throws IOException {
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(17, 17));
|
||||
ret.writeByte(PACKET_GET_OTHER_SKIN);
|
||||
ret.writeUuid(skinId);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static PacketBuffer writeGetSkinByURL(EaglercraftUUID skinId, String skinUrl) throws IOException {
|
||||
int len = 19 + skinUrl.length();
|
||||
PacketBuffer ret = new PacketBuffer(Unpooled.buffer(len, len));
|
||||
ret.writeByte(PACKET_GET_SKIN_BY_URL);
|
||||
ret.writeUuid(skinId);
|
||||
byte[] url = ArrayUtils.asciiString(skinUrl);
|
||||
ret.writeShort((int)url.length);
|
||||
ret.writeBytes(url);
|
||||
return ret;
|
||||
public static byte[] writeMySkinCustomV4(CustomSkin customSkin) {
|
||||
byte[] packet = new byte[2 + 12288];
|
||||
packet[0] = (byte) PACKET_MY_SKIN_CUSTOM;
|
||||
packet[1] = (byte) customSkin.model.id;
|
||||
byte[] v3data = customSkin.texture;
|
||||
for(int i = 0, j, k; i < 4096; ++i) {
|
||||
j = i << 2;
|
||||
k = i * 3 + 2;
|
||||
packet[k] = v3data[j + 1];
|
||||
packet[k + 1] = v3data[j + 2];
|
||||
packet[k + 2] = (byte)((v3data[j + 3] >>> 1) | (v3data[j] & 0x80));
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static EaglercraftUUID createEaglerURLSkinUUID(String skinUrl){
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglerMeshLoader;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
@ -98,7 +99,7 @@ public class SkinPreviewRenderer {
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(skinTexture);
|
||||
}
|
||||
|
||||
model.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625f);
|
||||
model.render(null, 0.0f, 0.0f, (float)(EagRuntime.steadyTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625f);
|
||||
|
||||
if(capeTexture != null && model instanceof ModelPlayer) {
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(capeTexture);
|
||||
|
Reference in New Issue
Block a user