mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #0 - First Release
This commit is contained in:
@ -0,0 +1,56 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class CustomSkin {
|
||||
|
||||
public final String name;
|
||||
public final byte[] texture;
|
||||
public SkinModel model;
|
||||
|
||||
private EaglerSkinTexture textureInstance;
|
||||
private ResourceLocation resourceLocation;
|
||||
|
||||
private static int texId = 0;
|
||||
|
||||
public CustomSkin(String name, byte[] texture, SkinModel model) {
|
||||
this.name = name;
|
||||
this.texture = texture;
|
||||
this.model = model;
|
||||
this.textureInstance = new EaglerSkinTexture(texture, model.width, model.height);
|
||||
this.resourceLocation = null;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
if(resourceLocation == null) {
|
||||
resourceLocation = new ResourceLocation("eagler:skins/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,78 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public enum DefaultSkins {
|
||||
|
||||
DEFAULT_STEVE(0, "Default Steve", new ResourceLocation("eagler:skins/01.default_steve.png"), SkinModel.STEVE),
|
||||
DEFAULT_ALEX(1, "Default Alex", new ResourceLocation("eagler:skins/02.default_alex.png"), SkinModel.ALEX),
|
||||
TENNIS_STEVE(2, "Tennis Steve", new ResourceLocation("eagler:skins/03.tennis_steve.png"), SkinModel.STEVE),
|
||||
TENNIS_ALEX(3, "Tennis Alex", new ResourceLocation("eagler:skins/04.tennis_alex.png"), SkinModel.ALEX),
|
||||
TUXEDO_STEVE(4, "Tuxedo Steve", new ResourceLocation("eagler:skins/05.tuxedo_steve.png"), SkinModel.STEVE),
|
||||
TUXEDO_ALEX(5, "Tuxedo Alex", new ResourceLocation("eagler:skins/06.tuxedo_alex.png"), SkinModel.ALEX),
|
||||
ATHLETE_STEVE(6, "Athlete Steve", new ResourceLocation("eagler:skins/07.athlete_steve.png"), SkinModel.STEVE),
|
||||
ATHLETE_ALEX(7, "Athlete Alex", new ResourceLocation("eagler:skins/08.athlete_alex.png"), SkinModel.ALEX),
|
||||
CYCLIST_STEVE(8, "Cyclist Steve", new ResourceLocation("eagler:skins/09.cyclist_steve.png"), SkinModel.STEVE),
|
||||
CYCLIST_ALEX(9, "Cyclist Alex", new ResourceLocation("eagler:skins/10.cyclist_alex.png"), SkinModel.ALEX),
|
||||
BOXER_STEVE(10, "Boxer Steve", new ResourceLocation("eagler:skins/11.boxer_steve.png"), SkinModel.STEVE),
|
||||
BOXER_ALEX(11, "Boxer Alex", new ResourceLocation("eagler:skins/12.boxer_alex.png"), SkinModel.ALEX),
|
||||
PRISONER_STEVE(12, "Prisoner Steve", new ResourceLocation("eagler:skins/13.prisoner_steve.png"), SkinModel.STEVE),
|
||||
PRISONER_ALEX(13, "Prisoner Alex", new ResourceLocation("eagler:skins/14.prisoner_alex.png"), SkinModel.ALEX),
|
||||
SCOTTISH_STEVE(14, "Scottish Steve", new ResourceLocation("eagler:skins/15.scottish_steve.png"), SkinModel.STEVE),
|
||||
SCOTTISH_ALEX(15, "Scottish Alex", new ResourceLocation("eagler:skins/16.scottish_alex.png"), SkinModel.ALEX),
|
||||
DEVELOPER_STEVE(16, "Developer Steve", new ResourceLocation("eagler:skins/17.developer_steve.png"), SkinModel.STEVE),
|
||||
DEVELOPER_ALEX(17, "Developer Alex", new ResourceLocation("eagler:skins/18.developer_alex.png"), SkinModel.ALEX),
|
||||
HEROBRINE(18, "Herobrine", new ResourceLocation("eagler:skins/19.herobrine.png"), SkinModel.ZOMBIE),
|
||||
NOTCH(19, "Notch", new ResourceLocation("eagler:skins/20.notch.png"), SkinModel.STEVE),
|
||||
CREEPER(20, "Creeper", new ResourceLocation("eagler:skins/21.creeper.png"), SkinModel.STEVE),
|
||||
ZOMBIE(21, "Zombie", new ResourceLocation("eagler:skins/22.zombie.png"), SkinModel.ZOMBIE),
|
||||
PIG(22, "Pig", new ResourceLocation("eagler:skins/23.pig.png"), SkinModel.STEVE),
|
||||
MOOSHROOM(23, "Mooshroom", new ResourceLocation("eagler:skins/24.mooshroom.png"), SkinModel.STEVE);
|
||||
|
||||
public static final DefaultSkins[] defaultSkinsMap = new DefaultSkins[24];
|
||||
|
||||
public final int id;
|
||||
public final String name;
|
||||
public final ResourceLocation location;
|
||||
public final SkinModel model;
|
||||
|
||||
private DefaultSkins(int id, String name, ResourceLocation location, SkinModel model) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.location = location;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public static DefaultSkins getSkinFromId(int id) {
|
||||
DefaultSkins e = null;
|
||||
if(id >= 0 && id < defaultSkinsMap.length) {
|
||||
e = defaultSkinsMap[id];
|
||||
}
|
||||
if(e != null) {
|
||||
return e;
|
||||
}else {
|
||||
return DEFAULT_STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
DefaultSkins[] skins = values();
|
||||
for(int i = 0; i < skins.length; ++i) {
|
||||
defaultSkinsMap[skins[i].id] = skins[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,251 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class EaglerProfile {
|
||||
|
||||
private static String username;
|
||||
|
||||
public static int presetSkinId;
|
||||
public static int customSkinId;
|
||||
|
||||
public static final List<CustomSkin> customSkins = new ArrayList();
|
||||
|
||||
public static final EaglercraftRandom rand;
|
||||
|
||||
public static ResourceLocation getActiveSkinResourceLocation() {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return customSkins.get(customSkinId).getResource();
|
||||
}else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].location;
|
||||
}
|
||||
}else {
|
||||
if(presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return DefaultSkins.defaultSkinsMap[presetSkinId].location;
|
||||
}else {
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SkinModel getActiveSkinModel() {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return customSkins.get(customSkinId).model;
|
||||
}else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].model;
|
||||
}
|
||||
}else {
|
||||
if(presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return DefaultSkins.defaultSkinsMap[presetSkinId].model;
|
||||
}else {
|
||||
presetSkinId = 0;
|
||||
return DefaultSkins.defaultSkinsMap[0].model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static EaglercraftUUID getPlayerUUID() {
|
||||
return Minecraft.getMinecraft().getSession().getProfile().getId();
|
||||
}
|
||||
|
||||
public static String getName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public static void setName(String str) {
|
||||
username = str;
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if(mc != null) {
|
||||
mc.getSession().reset();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getSkinPacket() throws IOException {
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId >= 0 && customSkinId < customSkins.size()) {
|
||||
return SkinPackets.writeMySkinCustom(customSkins.get(customSkinId));
|
||||
}else {
|
||||
customSkinId = -1;
|
||||
presetSkinId = 0;
|
||||
return SkinPackets.writeMySkinPreset(0);
|
||||
}
|
||||
}else {
|
||||
if(presetSkinId >= 0 && presetSkinId < DefaultSkins.defaultSkinsMap.length) {
|
||||
return SkinPackets.writeMySkinPreset(presetSkinId);
|
||||
}else {
|
||||
presetSkinId = 0;
|
||||
return SkinPackets.writeMySkinPreset(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean doesSkinExist(String name) {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
if(customSkins.get(i).name.equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int addCustomSkin(String fileName, byte[] rawSkin) {
|
||||
if(doesSkinExist(fileName)) {
|
||||
String newName;
|
||||
int i = 2;
|
||||
while(doesSkinExist(newName = fileName + " (" + i + ")")) {
|
||||
++i;
|
||||
}
|
||||
fileName = newName;
|
||||
}
|
||||
CustomSkin newSkin = new CustomSkin(fileName, rawSkin, SkinModel.STEVE);
|
||||
newSkin.load();
|
||||
int r = customSkins.size();
|
||||
customSkins.add(newSkin);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static void clearCustomSkins() {
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
customSkins.get(i).delete();
|
||||
}
|
||||
customSkins.clear();
|
||||
}
|
||||
|
||||
public static void read() {
|
||||
byte[] profileStorage = EagRuntime.getStorage("p");
|
||||
|
||||
if (profileStorage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
NBTTagCompound profile;
|
||||
try {
|
||||
profile = CompressedStreamTools.readCompressed(new EaglerInputStream(profileStorage));
|
||||
}catch(IOException ex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (profile == null || profile.hasNoTags()) {
|
||||
return;
|
||||
}
|
||||
|
||||
presetSkinId = profile.getInteger("presetSkin");
|
||||
customSkinId = profile.getInteger("customSkin");
|
||||
|
||||
String loadUsername = profile.getString("username").trim();
|
||||
|
||||
if(!loadUsername.isEmpty()) {
|
||||
username = loadUsername.replaceAll("[^A-Za-z0-9]", "_");
|
||||
}
|
||||
|
||||
clearCustomSkins();
|
||||
|
||||
NBTTagList skinsList = profile.getTagList("skins", 10);
|
||||
for(int i = 0, l = skinsList.tagCount(); i < l; ++i) {
|
||||
NBTTagCompound skin = skinsList.getCompoundTagAt(i);
|
||||
String skinName = skin.getString("name");
|
||||
byte[] skinData = skin.getByteArray("data");
|
||||
if(skinData.length != 16384) continue;
|
||||
for(int y = 20; y < 32; ++y) {
|
||||
for(int x = 16; x < 40; ++x) {
|
||||
skinData[(y << 8) | (x << 2)] = (byte)0xff;
|
||||
}
|
||||
}
|
||||
int skinModel = skin.getByte("model");
|
||||
CustomSkin newSkin = new CustomSkin(skinName, skinData, SkinModel.getModelFromId(skinModel));
|
||||
newSkin.load();
|
||||
customSkins.add(newSkin);
|
||||
}
|
||||
|
||||
if(presetSkinId == -1) {
|
||||
if(customSkinId < 0 || customSkinId >= customSkins.size()) {
|
||||
presetSkinId = 0;
|
||||
customSkinId = -1;
|
||||
}
|
||||
}else {
|
||||
customSkinId = -1;
|
||||
if(presetSkinId < 0 || presetSkinId >= DefaultSkins.defaultSkinsMap.length) {
|
||||
presetSkinId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void write() {
|
||||
NBTTagCompound profile = new NBTTagCompound();
|
||||
profile.setInteger("presetSkin", presetSkinId);
|
||||
profile.setInteger("customSkin", customSkinId);
|
||||
profile.setString("username", username);
|
||||
NBTTagList skinsList = new NBTTagList();
|
||||
for(int i = 0, l = customSkins.size(); i < l; ++i) {
|
||||
CustomSkin sk = customSkins.get(i);
|
||||
NBTTagCompound skin = new NBTTagCompound();
|
||||
skin.setString("name", sk.name);
|
||||
skin.setByteArray("data", sk.texture);
|
||||
skin.setByte("model", (byte)sk.model.id);
|
||||
skinsList.appendTag(skin);
|
||||
}
|
||||
profile.setTag("skins", skinsList);
|
||||
ByteArrayOutputStream bao = new ByteArrayOutputStream();
|
||||
try {
|
||||
CompressedStreamTools.writeCompressed(profile, bao);
|
||||
} catch (IOException e) {
|
||||
return;
|
||||
}
|
||||
EagRuntime.setStorage("p", bao.toByteArray());
|
||||
}
|
||||
|
||||
static {
|
||||
String[] defaultNames = new String[] {
|
||||
"Yeeish", "Yeeish", "Yee", "Yee", "Yeer", "Yeeler", "Eagler", "Eagl",
|
||||
"Darver", "Darvler", "Vool", "Vigg", "Vigg", "Deev", "Yigg", "Yeeg"
|
||||
};
|
||||
|
||||
rand = new EaglercraftRandom();
|
||||
|
||||
do {
|
||||
username = defaultNames[rand.nextInt(defaultNames.length)] + defaultNames[rand.nextInt(defaultNames.length)] + (100 + rand.nextInt(900));
|
||||
}while(username.length() > 16);
|
||||
|
||||
setName(username);
|
||||
|
||||
presetSkinId = rand.nextInt(DefaultSkins.defaultSkinsMap.length);
|
||||
customSkinId = -1;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
import net.minecraft.client.renderer.texture.ITextureObject;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class EaglerSkinTexture implements ITextureObject {
|
||||
|
||||
private final int[] pixels;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
private int textureId = -1;
|
||||
|
||||
public EaglerSkinTexture(int[] pixels, int width, int height) {
|
||||
if(pixels.length != width * height) {
|
||||
throw new IllegalArgumentException("Wrong data length " + pixels.length * 4 + " for " + width + "x" + height + " texture");
|
||||
}
|
||||
this.pixels = pixels;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public EaglerSkinTexture(byte[] pixels, int width, int height) {
|
||||
if(pixels.length != width * height * 4) {
|
||||
throw new IllegalArgumentException("Wrong data length " + pixels.length + " for " + width + "x" + height + " texture");
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
public void copyPixelsIn(int[] pixels) {
|
||||
if(this.pixels.length != pixels.length) {
|
||||
throw new IllegalArgumentException("Tried to copy " + pixels.length + " pixels into a " + this.pixels.length + " pixel texture");
|
||||
}
|
||||
System.arraycopy(pixels, 0, this.pixels, 0, pixels.length);
|
||||
if(textureId != -1) {
|
||||
TextureUtil.uploadTextureImageAllocate(textureId, new ImageData(width, height, pixels, true), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTexture(IResourceManager var1) throws IOException {
|
||||
if(textureId == -1) {
|
||||
textureId = GlStateManager.generateTexture();
|
||||
TextureUtil.uploadTextureImageAllocate(textureId, new ImageData(width, height, pixels, true), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlTextureId() {
|
||||
return textureId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlurMipmap(boolean var1, boolean var2) {
|
||||
// no
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreLastBlurMipmap() {
|
||||
// no
|
||||
}
|
||||
|
||||
public void free() {
|
||||
GlStateManager.deleteTexture(textureId);
|
||||
textureId = -1;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
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.socket.ConnectionHandshake;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.HandshakePacketTypes;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.multiplayer.GuiConnecting;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class GuiAuthenticationScreen extends GuiScreen {
|
||||
|
||||
private final GuiConnecting retAfterAuthScreen;
|
||||
private final GuiScreen parent;
|
||||
private GuiButton continueButton;
|
||||
private final String message;
|
||||
|
||||
private GuiPasswordTextField password;
|
||||
private int authTypeForWarning = Integer.MAX_VALUE;
|
||||
private boolean allowPlaintext = false;
|
||||
|
||||
public GuiAuthenticationScreen(GuiConnecting retAfterAuthScreen, GuiScreen parent, String message) {
|
||||
this.retAfterAuthScreen = retAfterAuthScreen;
|
||||
this.parent = parent;
|
||||
String authRequired = HandshakePacketTypes.AUTHENTICATION_REQUIRED;
|
||||
if(message.startsWith(authRequired)) {
|
||||
message = message.substring(authRequired.length()).trim();
|
||||
}
|
||||
if(message.length() > 0 && message.charAt(0) == '[') {
|
||||
int idx = message.indexOf(']', 1);
|
||||
if(idx != -1) {
|
||||
String authType = message.substring(1, idx);
|
||||
int type = Integer.MAX_VALUE;
|
||||
try {
|
||||
type = Integer.parseInt(authType);
|
||||
}catch(NumberFormatException ex) {
|
||||
}
|
||||
if(type != Integer.MAX_VALUE) {
|
||||
authTypeForWarning = type;
|
||||
message = message.substring(idx + 1).trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
if(authTypeForWarning != Integer.MAX_VALUE) {
|
||||
GuiScreen scr = ConnectionHandshake.displayAuthProtocolConfirm(authTypeForWarning, parent, this);
|
||||
authTypeForWarning = Integer.MAX_VALUE;
|
||||
if(scr != null) {
|
||||
mc.displayGuiScreen(scr);
|
||||
allowPlaintext = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(continueButton = new GuiButton(1, this.width / 2 - 100, this.height / 4 + 80 + 12,
|
||||
I18n.format("auth.continue", new Object[0])));
|
||||
continueButton.enabled = false;
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 80 + 37,
|
||||
I18n.format("gui.cancel", new Object[0])));
|
||||
this.password = new GuiPasswordTextField(2, this.fontRendererObj, this.width / 2 - 100, this.height / 4 + 40, 200, 20); // 116
|
||||
this.password.setFocused(true);
|
||||
this.password.setCanLoseFocus(false);
|
||||
}
|
||||
|
||||
public void onGuiClosed() {
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
}
|
||||
|
||||
protected void actionPerformed(GuiButton parGuiButton) {
|
||||
if(parGuiButton.id == 1) {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, password.getText()));
|
||||
}else {
|
||||
this.mc.displayGuiScreen(parent);
|
||||
if (!PlatformNetworking.playConnectionState().isClosed()) {
|
||||
PlatformNetworking.playDisconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void drawScreen(int i, int j, float var3) {
|
||||
drawBackground(0);
|
||||
this.password.drawTextBox();
|
||||
this.drawCenteredString(this.fontRendererObj, I18n.format("auth.required", new Object[0]), this.width / 2,
|
||||
this.height / 4 - 5, 16777215);
|
||||
this.drawCenteredString(this.fontRendererObj, message, this.width / 2, this.height / 4 + 15, 0xAAAAAA);
|
||||
super.drawScreen(i, j, var3);
|
||||
}
|
||||
|
||||
protected void keyTyped(char parChar1, int parInt1) {
|
||||
String pass = password.getText();
|
||||
if(parInt1 == KeyboardConstants.KEY_RETURN && pass.length() > 0) {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, pass, allowPlaintext));
|
||||
}else {
|
||||
this.password.textboxKeyTyped(parChar1, parInt1);
|
||||
this.continueButton.enabled = password.getText().length() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void mouseClicked(int parInt1, int parInt2, int parInt3) {
|
||||
super.mouseClicked(parInt1, parInt2, parInt3);
|
||||
this.password.mouseClicked(parInt1, parInt2, parInt3);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class GuiPasswordTextField extends GuiTextField {
|
||||
|
||||
public GuiPasswordTextField(int componentId, FontRenderer fontrendererObj, int x, int y, int par5Width,
|
||||
int par6Height) {
|
||||
super(componentId, fontrendererObj, x, y, par5Width, par6Height);
|
||||
}
|
||||
|
||||
public void drawTextBox() {
|
||||
String oldText = text;
|
||||
text = stars(text.length());
|
||||
super.drawTextBox();
|
||||
text = oldText;
|
||||
}
|
||||
|
||||
public void mouseClicked(int parInt1, int parInt2, int parInt3) {
|
||||
String oldText = text;
|
||||
text = stars(text.length());
|
||||
super.mouseClicked(parInt1, parInt2, parInt3);
|
||||
text = oldText;
|
||||
}
|
||||
|
||||
public static String stars(int len) {
|
||||
return new String(STARS, 0, len > STARS.length ? STARS.length : len);
|
||||
}
|
||||
|
||||
private static final char[] STARS = new char[] { '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*',
|
||||
'*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*', '*' };
|
||||
|
||||
}
|
@ -0,0 +1,463 @@
|
||||
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.FileChooserResult;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class GuiScreenEditProfile extends GuiScreen {
|
||||
|
||||
private final GuiScreen parent;
|
||||
private GuiTextField usernameField;
|
||||
|
||||
private boolean dropDownOpen = false;
|
||||
private String[] dropDownOptions;
|
||||
private int slotsVisible = 0;
|
||||
private int selectedSlot = 0;
|
||||
private int scrollPos = -1;
|
||||
private int skinsHeight = 0;
|
||||
private boolean dragging = false;
|
||||
private int mousex = 0;
|
||||
private int mousey = 0;
|
||||
|
||||
private boolean newSkinWaitSteveOrAlex = false;
|
||||
|
||||
private static final ResourceLocation eaglerGui = new ResourceLocation("eagler:gui/eagler_gui.png");
|
||||
|
||||
protected String screenTitle = "Edit Profile";
|
||||
|
||||
public GuiScreenEditProfile(GuiScreen parent) {
|
||||
this.parent = parent;
|
||||
updateOptions();
|
||||
}
|
||||
|
||||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
screenTitle = I18n.format("editProfile.title");
|
||||
usernameField = new GuiTextField(0, fontRendererObj, width / 2 - 20 + 1, height / 6 + 24 + 1, 138, 20);
|
||||
usernameField.setFocused(true);
|
||||
usernameField.setText(EaglerProfile.getName());
|
||||
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")));
|
||||
}
|
||||
|
||||
private void updateOptions() {
|
||||
int numCustom = EaglerProfile.customSkins.size();
|
||||
String[] n = new String[numCustom + DefaultSkins.defaultSkinsMap.length];
|
||||
for(int i = 0; i < numCustom; ++i) {
|
||||
n[i] = EaglerProfile.customSkins.get(i).name;
|
||||
}
|
||||
int numDefault = DefaultSkins.defaultSkinsMap.length;
|
||||
for(int j = 0; j < numDefault; ++j) {
|
||||
n[numCustom + j] = DefaultSkins.defaultSkinsMap[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("editProfile.username"), width / 2 - 20, height / 6 + 8, 10526880);
|
||||
drawString(fontRendererObj, I18n.format("editProfile.playerSkin"), width / 2 - 20, height / 6 + 66, 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.customSkins.size();
|
||||
if(skid < 0) {
|
||||
skid = 0;
|
||||
}
|
||||
|
||||
usernameField.drawTextBox();
|
||||
if(dropDownOpen || newSkinWaitSteveOrAlex) {
|
||||
super.drawScreen(0, 0, partialTicks);
|
||||
}else {
|
||||
super.drawScreen(mx, my, partialTicks);
|
||||
}
|
||||
|
||||
skinX = width / 2 - 20;
|
||||
skinY = height / 6 + 82;
|
||||
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 + 103;
|
||||
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);
|
||||
}
|
||||
|
||||
int xx = width / 2 - 80;
|
||||
int yy = height / 6 + 130;
|
||||
int numberOfCustomSkins = EaglerProfile.customSkins.size();
|
||||
|
||||
if(newSkinWaitSteveOrAlex && selectedSlot < numberOfCustomSkins) {
|
||||
skinWidth = 70;
|
||||
skinHeight = 120;
|
||||
|
||||
CustomSkin newSkin = EaglerProfile.customSkins.get(selectedSlot);
|
||||
|
||||
GlStateManager.clear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
skinX = width / 2 - 90;
|
||||
skinY = height / 4;
|
||||
xx = skinX + 35;
|
||||
yy = skinY + 117;
|
||||
|
||||
boolean mouseOver = mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight;
|
||||
int cc = mouseOver ? 0xFFDDDD99 : 0xFF555555;
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawRect(0, 0, width, height, 0xbb000000);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xbb000000);
|
||||
GlStateManager.disableBlend();
|
||||
|
||||
drawRect(skinX, skinY, skinX + 1, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + 1, cc);
|
||||
drawRect(skinX + skinWidth - 1, skinY, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY + skinHeight - 1, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
|
||||
if(mouseOver) {
|
||||
drawCenteredString(fontRendererObj, "Steve", skinX + skinWidth / 2, skinY + skinHeight + 6, cc);
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(newSkin.getResource());
|
||||
SkinPreviewRenderer.renderBiped(xx, yy, mx, my, SkinModel.STEVE);
|
||||
|
||||
skinX = width / 2 + 20;
|
||||
skinY = height / 4;
|
||||
xx = skinX + 35;
|
||||
yy = skinY + 117;
|
||||
|
||||
mouseOver = mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight;
|
||||
cc = mouseOver ? 0xFFDDDD99 : 0xFF555555;
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, 0xbb000000);
|
||||
GlStateManager.disableBlend();
|
||||
|
||||
drawRect(skinX, skinY, skinX + 1, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY, skinX + skinWidth, skinY + 1, cc);
|
||||
drawRect(skinX + skinWidth - 1, skinY, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
drawRect(skinX, skinY + skinHeight - 1, skinX + skinWidth, skinY + skinHeight, cc);
|
||||
|
||||
if(mouseOver) {
|
||||
drawCenteredString(fontRendererObj, "Alex", skinX + skinWidth / 2, skinY + skinHeight + 8, cc);
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(newSkin.getResource());
|
||||
SkinPreviewRenderer.renderBiped(xx, yy, mx, my, SkinModel.ALEX);
|
||||
}else {
|
||||
skinX = this.width / 2 - 120;
|
||||
skinY = this.height / 6 + 8;
|
||||
skinWidth = 80;
|
||||
skinHeight = 130;
|
||||
|
||||
ResourceLocation texture;
|
||||
SkinModel model;
|
||||
if(selectedSlot < numberOfCustomSkins) {
|
||||
CustomSkin customSkin = EaglerProfile.customSkins.get(selectedSlot);
|
||||
texture = customSkin.getResource();
|
||||
model = customSkin.model;
|
||||
}else {
|
||||
DefaultSkins defaultSkin = DefaultSkins.defaultSkinsMap[selectedSlot - numberOfCustomSkins];
|
||||
texture = defaultSkin.location;
|
||||
model = defaultSkin.model;
|
||||
}
|
||||
|
||||
mc.getTextureManager().bindTexture(texture);
|
||||
SkinPreviewRenderer.renderBiped(xx, yy, newSkinWaitSteveOrAlex ? width / 2 : mx, newSkinWaitSteveOrAlex ? height / 2 : my, model);
|
||||
}
|
||||
}
|
||||
|
||||
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.clearCustomSkins();
|
||||
safeProfile();
|
||||
updateOptions();
|
||||
selectedSlot = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScreen() {
|
||||
usernameField.updateCursorCounter();
|
||||
if(EagRuntime.fileChooserHasResult()) {
|
||||
FileChooserResult result = EagRuntime.getFileChooserResult();
|
||||
if(result != null) {
|
||||
ImageData loadedSkin = ImageData.loadImageFile(result.fileData);
|
||||
if(loadedSkin != null) {
|
||||
boolean isLegacy = loadedSkin.width == 64 && loadedSkin.height == 32;
|
||||
boolean isModern = loadedSkin.width == 64 && loadedSkin.height == 64;
|
||||
if(isLegacy) {
|
||||
ImageData newSkin = new ImageData(64, 64, true);
|
||||
SkinConverter.convert64x32to64x64(loadedSkin, newSkin);
|
||||
loadedSkin = newSkin;
|
||||
isModern = true;
|
||||
}
|
||||
if(isModern) {
|
||||
byte[] rawSkin = new byte[16384];
|
||||
for(int i = 0, j, k; i < 4096; ++i) {
|
||||
j = i << 2;
|
||||
k = loadedSkin.pixels[i];
|
||||
rawSkin[j] = (byte)(k >> 24);
|
||||
rawSkin[j + 1] = (byte)(k >> 16);
|
||||
rawSkin[j + 2] = (byte)(k >> 8);
|
||||
rawSkin[j + 3] = (byte)(k & 0xFF);
|
||||
}
|
||||
for(int y = 20; y < 32; ++y) {
|
||||
for(int x = 16; x < 40; ++x) {
|
||||
rawSkin[(y << 8) | (x << 2)] = (byte)0xff;
|
||||
}
|
||||
}
|
||||
int k;
|
||||
if((k = EaglerProfile.addCustomSkin(result.fileName, rawSkin)) != -1) {
|
||||
selectedSlot = k;
|
||||
newSkinWaitSteveOrAlex = true;
|
||||
updateOptions();
|
||||
safeProfile();
|
||||
}
|
||||
}else {
|
||||
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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(dropDownOpen) {
|
||||
if(Mouse.isButtonDown(0)) {
|
||||
int skinX = width / 2 - 20;
|
||||
int skinY = height / 6 + 103;
|
||||
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) {
|
||||
usernameField.textboxKeyTyped(c, k);
|
||||
|
||||
String text = usernameField.getText();
|
||||
if(text.length() > 16) text = text.substring(0, 16);
|
||||
text = text.replaceAll("[^A-Za-z0-9]", "_");
|
||||
usernameField.updateText(text);
|
||||
|
||||
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) {
|
||||
super.mouseClicked(mx, my, button);
|
||||
usernameField.mouseClicked(mx, my, button);
|
||||
if (button == 0) {
|
||||
if(newSkinWaitSteveOrAlex) {
|
||||
int skinX = width / 2 - 90;
|
||||
int skinY = height / 4;
|
||||
int skinWidth = 70;
|
||||
int skinHeight = 120;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
newSkinWaitSteveOrAlex = false;
|
||||
EaglerProfile.customSkins.get(selectedSlot).model = SkinModel.STEVE;
|
||||
safeProfile();
|
||||
}
|
||||
return;
|
||||
}
|
||||
skinX = width / 2 + 20;
|
||||
skinY = height / 4;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
EaglerProfile.customSkins.get(selectedSlot).model = SkinModel.ALEX;
|
||||
newSkinWaitSteveOrAlex = false;
|
||||
safeProfile();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}else if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
int skinX = width / 2 - 120;
|
||||
int skinY = height / 6 + 18;
|
||||
int skinWidth = 80;
|
||||
int skinHeight = 120;
|
||||
if(mx >= skinX && my >= skinY && mx < skinX + skinWidth && my < skinY + skinHeight) {
|
||||
if(selectedSlot < EaglerProfile.customSkins.size()) {
|
||||
newSkinWaitSteveOrAlex = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
int skinX = width / 2 + 140 - 40;
|
||||
int skinY = height / 6 + 82;
|
||||
|
||||
if(mx >= skinX && mx < (skinX + 20) && my >= skinY && my < (skinY + 22)) {
|
||||
dropDownOpen = !dropDownOpen;
|
||||
return;
|
||||
}
|
||||
|
||||
skinX = width / 2 - 20;
|
||||
skinY = height / 6 + 82;
|
||||
int skinWidth = 140;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void safeProfile() {
|
||||
int customLen = EaglerProfile.customSkins.size();
|
||||
if(selectedSlot < customLen) {
|
||||
EaglerProfile.presetSkinId = -1;
|
||||
EaglerProfile.customSkinId = selectedSlot;
|
||||
}else {
|
||||
EaglerProfile.presetSkinId = selectedSlot - customLen;
|
||||
EaglerProfile.customSkinId = -1;
|
||||
}
|
||||
String name = usernameField.getText().trim();
|
||||
while(name.length() < 3) {
|
||||
name = name + "_";
|
||||
}
|
||||
if(name.length() > 16) {
|
||||
name = name.substring(0, 16);
|
||||
}
|
||||
EaglerProfile.setName(name);
|
||||
EaglerProfile.write();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,332 @@
|
||||
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.mojang.authlib.GameProfile;
|
||||
import net.lax1dude.eaglercraft.v1_8.mojang.authlib.TexturesProperty;
|
||||
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 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class ServerSkinCache {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("ServerSkinCache");
|
||||
|
||||
public class SkinCacheEntry {
|
||||
|
||||
protected final boolean isPresetSkin;
|
||||
protected final int presetSkinId;
|
||||
protected final CacheCustomSkin customSkin;
|
||||
|
||||
protected long lastCacheHit = System.currentTimeMillis();
|
||||
|
||||
protected SkinCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation, SkinModel model) {
|
||||
this.isPresetSkin = false;
|
||||
this.presetSkinId = -1;
|
||||
this.customSkin = new CacheCustomSkin(textureInstance, resourceLocation, model);
|
||||
ServerSkinCache.this.textureManager.loadTexture(resourceLocation, textureInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use only for the constant for the client player
|
||||
*/
|
||||
protected SkinCacheEntry(ResourceLocation resourceLocation, SkinModel model) {
|
||||
this.isPresetSkin = false;
|
||||
this.presetSkinId = -1;
|
||||
this.customSkin = new CacheCustomSkin(null, resourceLocation, model);
|
||||
}
|
||||
|
||||
protected SkinCacheEntry(int presetSkinId) {
|
||||
this.isPresetSkin = true;
|
||||
this.presetSkinId = presetSkinId;
|
||||
this.customSkin = null;
|
||||
}
|
||||
|
||||
public ResourceLocation getResourceLocation() {
|
||||
if(isPresetSkin) {
|
||||
return DefaultSkins.getSkinFromId(presetSkinId).location;
|
||||
}else {
|
||||
if(customSkin != null) {
|
||||
return customSkin.resourceLocation;
|
||||
}else {
|
||||
return DefaultSkins.DEFAULT_STEVE.location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SkinModel getSkinModel() {
|
||||
if(isPresetSkin) {
|
||||
return DefaultSkins.getSkinFromId(presetSkinId).model;
|
||||
}else {
|
||||
if(customSkin != null) {
|
||||
return customSkin.model;
|
||||
}else {
|
||||
return DefaultSkins.DEFAULT_STEVE.model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void free() {
|
||||
if(!isPresetSkin) {
|
||||
ServerSkinCache.this.textureManager.deleteTexture(customSkin.resourceLocation);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class CacheCustomSkin {
|
||||
|
||||
protected final EaglerSkinTexture textureInstance;
|
||||
protected final ResourceLocation resourceLocation;
|
||||
protected final SkinModel model;
|
||||
|
||||
protected CacheCustomSkin(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation, SkinModel model) {
|
||||
this.textureInstance = textureInstance;
|
||||
this.resourceLocation = resourceLocation;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class WaitingSkin {
|
||||
|
||||
protected final long timeout;
|
||||
protected final SkinModel model;
|
||||
|
||||
protected WaitingSkin(long timeout, SkinModel model) {
|
||||
this.timeout = timeout;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 EaglercraftNetworkManager networkManager;
|
||||
protected final TextureManager textureManager;
|
||||
|
||||
private final EaglercraftUUID clientPlayerId;
|
||||
private final SkinCacheEntry clientPlayerCacheEntry;
|
||||
|
||||
private long lastFlush = System.currentTimeMillis();
|
||||
private long lastFlushReq = System.currentTimeMillis();
|
||||
private long lastFlushEvict = System.currentTimeMillis();
|
||||
|
||||
private static int texId = 0;
|
||||
|
||||
public ServerSkinCache(EaglercraftNetworkManager networkManager, TextureManager textureManager) {
|
||||
this.networkManager = networkManager;
|
||||
this.textureManager = textureManager;
|
||||
this.clientPlayerId = EaglerProfile.getPlayerUUID();
|
||||
this.clientPlayerCacheEntry = new SkinCacheEntry(EaglerProfile.getActiveSkinResourceLocation(), EaglerProfile.getActiveSkinModel());
|
||||
}
|
||||
|
||||
public SkinCacheEntry getClientPlayerSkin() {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
|
||||
public SkinCacheEntry getSkin(GameProfile player) {
|
||||
EaglercraftUUID uuid = player.getId();
|
||||
if(uuid != null && uuid.equals(clientPlayerId)) {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
TexturesProperty props = player.getTextures();
|
||||
if(props.eaglerPlayer || props.skin == null) {
|
||||
if(uuid != null) {
|
||||
return _getSkin(uuid);
|
||||
}else {
|
||||
if("slim".equalsIgnoreCase(props.model)) {
|
||||
return defaultSlimCacheEntry;
|
||||
}else {
|
||||
return defaultCacheEntry;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
return getSkin(props.skin, SkinModel.getModelFromId(props.model));
|
||||
}
|
||||
}
|
||||
|
||||
public SkinCacheEntry getSkin(EaglercraftUUID player) {
|
||||
if(player.equals(clientPlayerId)) {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
return _getSkin(player);
|
||||
}
|
||||
|
||||
private SkinCacheEntry _getSkin(EaglercraftUUID player) {
|
||||
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));
|
||||
}
|
||||
return defaultCacheEntry;
|
||||
}else {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
return etr;
|
||||
}
|
||||
}
|
||||
|
||||
public SkinCacheEntry getSkin(String url, SkinModel skinModelResponse) {
|
||||
if(url.length() > 0xFFFF) {
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
}
|
||||
EaglercraftUUID generatedUUID = SkinPackets.createEaglerURLSkinUUID(url);
|
||||
SkinCacheEntry etr = skinsCache.get(generatedUUID);
|
||||
if(etr != null) {
|
||||
etr.lastCacheHit = System.currentTimeMillis();
|
||||
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));
|
||||
}
|
||||
}
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
}
|
||||
|
||||
public void cacheSkinPreset(EaglercraftUUID player, int presetId) {
|
||||
if(waitingSkins.remove(player) != null) {
|
||||
SkinCacheEntry etr = skinsCache.remove(player);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
skinsCache.put(player, new SkinCacheEntry(presetId));
|
||||
}else {
|
||||
logger.error("Unsolicited skin response recieved for \"{}\"! (preset {})", player, presetId);
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheSkinCustom(EaglercraftUUID player, byte[] pixels, SkinModel model) {
|
||||
WaitingSkin waitingSkin;
|
||||
if((waitingSkin = waitingSkins.remove(player)) != null) {
|
||||
SkinCacheEntry etr = skinsCache.remove(player);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
if(waitingSkin.model != null) {
|
||||
model = waitingSkin.model;
|
||||
}else if(model == null) {
|
||||
model = (player.hashCode() & 1) != 0 ? SkinModel.ALEX : SkinModel.STEVE;
|
||||
}
|
||||
try {
|
||||
etr = new SkinCacheEntry(new EaglerSkinTexture(pixels, model.width, model.height),
|
||||
new ResourceLocation("eagler:skins/multiplayer/tex_" + texId++), model);
|
||||
}catch(Throwable t) {
|
||||
etr = new SkinCacheEntry(0);
|
||||
logger.error("Could not process custom skin packet for \"{}\"!", player);
|
||||
logger.error(t);
|
||||
}
|
||||
skinsCache.put(player, etr);
|
||||
}else {
|
||||
logger.error("Unsolicited skin response recieved for \"{}\"! (custom {}x{})", player, model.width, model.height);
|
||||
}
|
||||
}
|
||||
|
||||
public SkinModel getRequestedSkinType(EaglercraftUUID waiting) {
|
||||
WaitingSkin waitingSkin;
|
||||
if((waitingSkin = waitingSkins.get(waiting)) != null) {
|
||||
return waitingSkin.model;
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
long millis = System.currentTimeMillis();
|
||||
if(millis - lastFlushReq > 5000l) {
|
||||
lastFlushReq = millis;
|
||||
if(!waitingSkins.isEmpty()) {
|
||||
Iterator<WaitingSkin> waitingItr = waitingSkins.values().iterator();
|
||||
while(waitingItr.hasNext()) {
|
||||
if(millis - waitingItr.next().timeout > 30000l) {
|
||||
waitingItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(millis - lastFlushEvict > 1000l) {
|
||||
lastFlushEvict = millis;
|
||||
if(!evictedSkins.isEmpty()) {
|
||||
Iterator<Long> evictItr = evictedSkins.values().iterator();
|
||||
while(evictItr.hasNext()) {
|
||||
if(millis - evictItr.next().longValue() > 3000l) {
|
||||
evictItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(millis - lastFlush > 60000l) {
|
||||
lastFlush = millis;
|
||||
if(!skinsCache.isEmpty()) {
|
||||
Iterator<SkinCacheEntry> entryItr = skinsCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
SkinCacheEntry etr = entryItr.next();
|
||||
if(millis - etr.lastCacheHit > 900000l) { // 15 minutes
|
||||
entryItr.remove();
|
||||
etr.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Iterator<SkinCacheEntry> entryItr = skinsCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
entryItr.next().free();
|
||||
}
|
||||
skinsCache.clear();
|
||||
waitingSkins.clear();
|
||||
}
|
||||
|
||||
public void evictSkin(EaglercraftUUID uuid) {
|
||||
evictedSkins.put(uuid, Long.valueOf(System.currentTimeMillis()));
|
||||
SkinCacheEntry etr = skinsCache.remove(uuid);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class SkinConverter {
|
||||
|
||||
public static void convert64x32to64x64(ImageData skinIn, ImageData skinOut) {
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 0, 0, 0, 0, 64, 32, 64, 64, false);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 24, 48, 20, 52, 4, 16, 8, 20, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 28, 48, 24, 52, 8, 16, 12, 20, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 20, 52, 16, 64, 8, 20, 12, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 24, 52, 20, 64, 4, 20, 8, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 28, 52, 24, 64, 0, 20, 4, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 32, 52, 28, 64, 12, 20, 16, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 40, 48, 36, 52, 44, 16, 48, 20, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 44, 48, 40, 52, 48, 16, 52, 20, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 36, 52, 32, 64, 48, 20, 52, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 40, 52, 36, 64, 44, 20, 48, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 44, 52, 40, 64, 40, 20, 44, 32, 64, 64);
|
||||
copyRawPixels(skinIn.pixels, skinOut.pixels, 48, 52, 44, 64, 52, 20, 56, 32, 64, 64);
|
||||
}
|
||||
|
||||
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) {
|
||||
copyRawPixels(imageIn, imageOut, sx1, sy1, dx2, dy1, sx2 - sx1, sy2 - sy1, imgSrcWidth, imgDstWidth, true);
|
||||
} else {
|
||||
copyRawPixels(imageIn, imageOut, sx1, sy1, dx1, dy1, sx2 - sx1, sy2 - sy1, imgSrcWidth, imgDstWidth, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyRawPixels(int[] imageIn, int[] imageOut, int srcX, int srcY, int dstX, int dstY, int width,
|
||||
int height, int imgSrcWidth, int imgDstWidth, boolean flip) {
|
||||
int i, j;
|
||||
for(int y = 0; y < height; ++y) {
|
||||
for(int x = 0; x < width; ++x) {
|
||||
i = imageIn[(srcY + y) * imgSrcWidth + srcX + x];
|
||||
if(flip) {
|
||||
j = (dstY + y) * imgDstWidth + dstX + width - x - 1;
|
||||
}else {
|
||||
j = (dstY + y) * imgDstWidth + dstX + x;
|
||||
}
|
||||
imageOut[j] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public enum SkinModel {
|
||||
STEVE(0, 64, 64, "default", false), ALEX(1, 64, 64, "slim", false), ZOMBIE(2, 64, 64, "zombie", true);
|
||||
|
||||
public final int id;
|
||||
public final int width;
|
||||
public final int height;
|
||||
public final String profileSkinType;
|
||||
public final boolean sanitize;
|
||||
|
||||
public static final SkinModel[] skinModels = new SkinModel[3];
|
||||
private static final Map<String, SkinModel> skinModelsByName = new HashMap();
|
||||
|
||||
private SkinModel(int id, int w, int h, String profileSkinType, boolean sanitize) {
|
||||
this.id = id;
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
this.profileSkinType = profileSkinType;
|
||||
this.sanitize = sanitize;
|
||||
}
|
||||
|
||||
public static SkinModel getModelFromId(String str) {
|
||||
SkinModel mdl = skinModelsByName.get(str.toLowerCase());
|
||||
if(mdl == null) {
|
||||
return skinModels[0];
|
||||
}
|
||||
return mdl;
|
||||
}
|
||||
|
||||
public static SkinModel getModelFromId(int id) {
|
||||
SkinModel s = null;
|
||||
if(id >= 0 && id < skinModels.length) {
|
||||
s = skinModels[id];
|
||||
}
|
||||
if(s != null) {
|
||||
return s;
|
||||
}else {
|
||||
return STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
SkinModel[] arr = values();
|
||||
for(int i = 0; i < arr.length; ++i) {
|
||||
skinModels[arr[i].id] = arr[i];
|
||||
skinModelsByName.put(arr[i].profileSkinType, arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
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 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
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) throws IOException {
|
||||
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) throws IOException {
|
||||
byte[] packet = new byte[2 + customSkin.texture.length];
|
||||
packet[0] = (byte) PACKET_MY_SKIN_CUSTOM;
|
||||
packet[1] = (byte) customSkin.model.id;
|
||||
System.arraycopy(customSkin.texture, 0, packet, 2, customSkin.texture.length);
|
||||
return packet;
|
||||
}
|
||||
|
||||
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 EaglercraftUUID createEaglerURLSkinUUID(String skinUrl){
|
||||
MD5Digest dg = new MD5Digest();
|
||||
byte[] bytes = ArrayUtils.asciiString("EaglercraftSkinURL:" + skinUrl);
|
||||
dg.update(bytes, 0, bytes.length);
|
||||
byte[] md5Bytes = new byte[16];
|
||||
dg.doFinal(md5Bytes, 0);
|
||||
md5Bytes[6] &= 0x0f;
|
||||
md5Bytes[6] |= 0x30;
|
||||
md5Bytes[8] &= 0x3f;
|
||||
md5Bytes[8] |= 0x80;
|
||||
return new EaglercraftUUID(md5Bytes);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.client.model.ModelPlayer;
|
||||
import net.minecraft.client.model.ModelZombie;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
|
||||
*
|
||||
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
|
||||
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
|
||||
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
|
||||
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
|
||||
*
|
||||
* NOT FOR COMMERCIAL OR MALICIOUS USE
|
||||
*
|
||||
* (please read the 'LICENSE' file this repo's root directory for more info)
|
||||
*
|
||||
*/
|
||||
public class SkinPreviewRenderer {
|
||||
|
||||
private static ModelPlayer playerModelSteve = null;
|
||||
private static ModelPlayer playerModelAlex = null;
|
||||
private static ModelZombie playerModelZombie = null;
|
||||
|
||||
public static void initialize() {
|
||||
playerModelSteve = new ModelPlayer(0.0f, false);
|
||||
playerModelSteve.isChild = false;
|
||||
playerModelAlex = new ModelPlayer(0.0f, true);
|
||||
playerModelAlex.isChild = false;
|
||||
playerModelZombie = new ModelZombie(0.0f, true);
|
||||
playerModelZombie.isChild = false;
|
||||
}
|
||||
|
||||
public static void renderBiped(int x, int y, int mx, int my, SkinModel skinModel) {
|
||||
ModelBiped model;
|
||||
switch(skinModel) {
|
||||
case STEVE:
|
||||
default:
|
||||
model = playerModelSteve;
|
||||
break;
|
||||
case ALEX:
|
||||
model = playerModelAlex;
|
||||
break;
|
||||
case ZOMBIE:
|
||||
model = playerModelZombie;
|
||||
break;
|
||||
}
|
||||
|
||||
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.translate(0.0f, -1.0f, 0.0f);
|
||||
|
||||
model.render(null, 0.0f, 0.0f, (float)(System.currentTimeMillis() % 2000000) / 50f, ((x - mx) * 0.06f), ((y - my) * -0.1f), 0.0625f);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.disableLighting();
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user