mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 02:48:14 -05:00
Update #51 - Protocol and FPS improvements, better workspace
This commit is contained in:
@ -210,7 +210,6 @@ public class EaglerProfile {
|
||||
public static void handleForceSkinPreset(int preset) {
|
||||
isServerSkinOverride = true;
|
||||
overridePresetSkinId = preset;
|
||||
ServerSkinCache.needReloadClientSkin = true;
|
||||
}
|
||||
|
||||
public static void handleForceSkinCustom(int modelID, byte[] datav3) {
|
||||
@ -229,13 +228,11 @@ public class EaglerProfile {
|
||||
}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) {
|
||||
@ -252,7 +249,6 @@ public class EaglerProfile {
|
||||
}else {
|
||||
overrideCustomCape.copyPixelsIn(pixels32x32);
|
||||
}
|
||||
ServerCapeCache.needReloadClientCape = true;
|
||||
}
|
||||
|
||||
public static void clearServerSkinOverride() {
|
||||
|
@ -19,7 +19,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.minecraft.EnumInputEvent;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.ConnectionHandshake;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.GuiHandshakeApprove;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.HandshakePacketTypes;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@ -64,7 +64,7 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
||||
|
||||
public void initGui() {
|
||||
if(authTypeForWarning != Integer.MAX_VALUE) {
|
||||
GuiScreen scr = ConnectionHandshake.displayAuthProtocolConfirm(authTypeForWarning, parent, this);
|
||||
GuiScreen scr = GuiHandshakeApprove.displayAuthProtocolConfirm(authTypeForWarning, parent, this);
|
||||
authTypeForWarning = Integer.MAX_VALUE;
|
||||
if(scr != null) {
|
||||
mc.displayGuiScreen(scr);
|
||||
@ -90,7 +90,7 @@ public class GuiAuthenticationScreen extends GuiScreen {
|
||||
|
||||
protected void actionPerformed(GuiButton parGuiButton) {
|
||||
if(parGuiButton.id == 1) {
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, password.getText()));
|
||||
this.mc.displayGuiScreen(new GuiConnecting(retAfterAuthScreen, password.getText(), allowPlaintext));
|
||||
}else {
|
||||
this.mc.displayGuiScreen(parent);
|
||||
}
|
||||
|
@ -1,250 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
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.protocol.pkt.client.CPacketGetOtherCapeEAG;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class ServerCapeCache {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger("ServerCapeCache");
|
||||
|
||||
public class CapeCacheEntry {
|
||||
|
||||
protected final boolean isPresetCape;
|
||||
protected final int presetCapeId;
|
||||
protected final CacheCustomCape customCape;
|
||||
|
||||
protected long lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
|
||||
protected CapeCacheEntry(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation) {
|
||||
this.isPresetCape = false;
|
||||
this.presetCapeId = -1;
|
||||
this.customCape = new CacheCustomCape(textureInstance, resourceLocation);
|
||||
ServerCapeCache.this.textureManager.loadTexture(resourceLocation, textureInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use only for the constant for the client player
|
||||
*/
|
||||
protected CapeCacheEntry(ResourceLocation resourceLocation) {
|
||||
this.isPresetCape = false;
|
||||
this.presetCapeId = -1;
|
||||
this.customCape = new CacheCustomCape(null, resourceLocation);
|
||||
}
|
||||
|
||||
protected CapeCacheEntry(int presetSkinId) {
|
||||
this.isPresetCape = true;
|
||||
this.presetCapeId = presetSkinId;
|
||||
this.customCape = null;
|
||||
}
|
||||
|
||||
public ResourceLocation getResourceLocation() {
|
||||
if(isPresetCape) {
|
||||
return DefaultCapes.getCapeFromId(presetCapeId).location;
|
||||
}else {
|
||||
if(customCape != null) {
|
||||
return customCape.resourceLocation;
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void free() {
|
||||
if(!isPresetCape && customCape.resourceLocation != null) {
|
||||
ServerCapeCache.this.textureManager.deleteTexture(customCape.resourceLocation);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class CacheCustomCape {
|
||||
|
||||
protected final EaglerSkinTexture textureInstance;
|
||||
protected final ResourceLocation resourceLocation;
|
||||
|
||||
protected CacheCustomCape(EaglerSkinTexture textureInstance, ResourceLocation resourceLocation) {
|
||||
this.textureInstance = textureInstance;
|
||||
this.resourceLocation = resourceLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final CapeCacheEntry defaultCacheEntry = new CapeCacheEntry(0);
|
||||
private final Map<EaglercraftUUID, CapeCacheEntry> capesCache = new HashMap<>();
|
||||
private final Map<EaglercraftUUID, Long> waitingCapes = new HashMap<>();
|
||||
private final Map<EaglercraftUUID, Long> evictedCapes = new HashMap<>();
|
||||
|
||||
private final NetHandlerPlayClient netHandler;
|
||||
protected final TextureManager textureManager;
|
||||
|
||||
private final EaglercraftUUID clientPlayerId;
|
||||
private CapeCacheEntry clientPlayerCacheEntry;
|
||||
|
||||
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(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());
|
||||
}
|
||||
|
||||
public CapeCacheEntry getClientPlayerCape() {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
|
||||
public CapeCacheEntry getCape(EaglercraftUUID player) {
|
||||
if(player.equals(clientPlayerId)) {
|
||||
return clientPlayerCacheEntry;
|
||||
}
|
||||
CapeCacheEntry etr = capesCache.get(player);
|
||||
if(etr == null) {
|
||||
if(!waitingCapes.containsKey(player) && !evictedCapes.containsKey(player)) {
|
||||
waitingCapes.put(player, EagRuntime.steadyTimeMillis());
|
||||
netHandler.sendEaglerMessage(new CPacketGetOtherCapeEAG(player.msb, player.lsb));
|
||||
}
|
||||
return defaultCacheEntry;
|
||||
}else {
|
||||
etr.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
return etr;
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheCapePreset(EaglercraftUUID player, int presetId) {
|
||||
if(waitingCapes.remove(player) != null) {
|
||||
CapeCacheEntry etr = capesCache.remove(player);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
capesCache.put(player, new CapeCacheEntry(presetId));
|
||||
}else {
|
||||
logger.error("Unsolicited cape response recieved for \"{}\"! (preset {})", player, presetId);
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheCapeCustom(EaglercraftUUID player, byte[] pixels) {
|
||||
if(waitingCapes.remove(player) != null) {
|
||||
CapeCacheEntry etr = capesCache.remove(player);
|
||||
if(etr != null) {
|
||||
etr.free();
|
||||
}
|
||||
byte[] pixels32x32 = new byte[4096];
|
||||
SkinConverter.convertCape23x17RGBto32x32RGBA(pixels, pixels32x32);
|
||||
try {
|
||||
etr = new CapeCacheEntry(new EaglerSkinTexture(pixels32x32, 32, 32),
|
||||
new ResourceLocation("eagler:capes/multiplayer/tex_" + texId++));
|
||||
}catch(Throwable t) {
|
||||
etr = new CapeCacheEntry(0);
|
||||
logger.error("Could not process custom skin packet for \"{}\"!", player);
|
||||
logger.error(t);
|
||||
}
|
||||
capesCache.put(player, etr);
|
||||
}else {
|
||||
logger.error("Unsolicited skin response recieved for \"{}\"!", player);
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
long millis = EagRuntime.steadyTimeMillis();
|
||||
if(millis - lastFlushReq > 5000l) {
|
||||
lastFlushReq = millis;
|
||||
if(!waitingCapes.isEmpty()) {
|
||||
Iterator<Long> waitingItr = waitingCapes.values().iterator();
|
||||
while(waitingItr.hasNext()) {
|
||||
if(millis - waitingItr.next().longValue() > 30000l) {
|
||||
waitingItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(millis - lastFlushEvict > 1000l) {
|
||||
lastFlushEvict = millis;
|
||||
if(!evictedCapes.isEmpty()) {
|
||||
Iterator<Long> evictItr = evictedCapes.values().iterator();
|
||||
while(evictItr.hasNext()) {
|
||||
if(millis - evictItr.next().longValue() > 3000l) {
|
||||
evictItr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(millis - lastFlush > 60000l) {
|
||||
lastFlush = millis;
|
||||
if(!capesCache.isEmpty()) {
|
||||
Iterator<CapeCacheEntry> entryItr = capesCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
CapeCacheEntry etr = entryItr.next();
|
||||
if(millis - etr.lastCacheHit > 900000l) { // 15 minutes
|
||||
entryItr.remove();
|
||||
etr.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(needReloadClientCape) {
|
||||
reloadClientPlayerCape();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Iterator<CapeCacheEntry> entryItr = capesCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
entryItr.next().free();
|
||||
}
|
||||
capesCache.clear();
|
||||
waitingCapes.clear();
|
||||
evictedCapes.clear();
|
||||
}
|
||||
|
||||
public void evictCape(EaglercraftUUID uuid) {
|
||||
evictedCapes.put(uuid, Long.valueOf(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,336 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.lax1dude.eaglercraft.v1_8.profile;
|
||||
|
||||
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.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.util.ResourceLocation;
|
||||
|
||||
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 = EagRuntime.steadyTimeMillis();
|
||||
|
||||
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 NetHandlerPlayClient netHandler;
|
||||
protected final TextureManager textureManager;
|
||||
|
||||
private final EaglercraftUUID clientPlayerId;
|
||||
private SkinCacheEntry clientPlayerCacheEntry;
|
||||
|
||||
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(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());
|
||||
}
|
||||
|
||||
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(EagRuntime.steadyTimeMillis(), null));
|
||||
netHandler.sendEaglerMessage(new CPacketGetOtherSkinEAG(player.msb, player.lsb));
|
||||
}
|
||||
return defaultCacheEntry;
|
||||
}else {
|
||||
etr.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
return etr;
|
||||
}
|
||||
}
|
||||
|
||||
public SkinCacheEntry getSkin(String url, SkinModel skinModelResponse) {
|
||||
if(url.length() > 0x7F00) {
|
||||
return skinModelResponse == SkinModel.ALEX ? defaultSlimCacheEntry : defaultCacheEntry;
|
||||
}
|
||||
EaglercraftUUID generatedUUID = SkinPackets.createEaglerURLSkinUUID(url);
|
||||
SkinCacheEntry etr = skinsCache.get(generatedUUID);
|
||||
if(etr != null) {
|
||||
etr.lastCacheHit = EagRuntime.steadyTimeMillis();
|
||||
return etr;
|
||||
}else {
|
||||
if(!waitingSkins.containsKey(generatedUUID) && !evictedSkins.containsKey(generatedUUID)) {
|
||||
waitingSkins.put(generatedUUID, new WaitingSkin(EagRuntime.steadyTimeMillis(), skinModelResponse));
|
||||
netHandler.sendEaglerMessage(new CPacketGetSkinByURLEAG(generatedUUID.msb, generatedUUID.lsb, url));
|
||||
}
|
||||
}
|
||||
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 = 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 > 20000l) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(needReloadClientSkin) {
|
||||
reloadClientPlayerSkin();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Iterator<SkinCacheEntry> entryItr = skinsCache.values().iterator();
|
||||
while(entryItr.hasNext()) {
|
||||
entryItr.next().free();
|
||||
}
|
||||
skinsCache.clear();
|
||||
waitingSkins.clear();
|
||||
evictedSkins.clear();
|
||||
}
|
||||
|
||||
public void evictSkin(EaglercraftUUID uuid) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -72,6 +72,14 @@ public enum SkinModel {
|
||||
return STEVE;
|
||||
}
|
||||
}
|
||||
|
||||
public static SkinModel getSanitizedModelFromId(int id) {
|
||||
SkinModel ret = getModelFromId(id & 0x7F);
|
||||
if((id & 0x80) != 0 && ret.sanitize) {
|
||||
ret = STEVE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static {
|
||||
SkinModel[] arr = values();
|
||||
|
Reference in New Issue
Block a user