mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2024-12-01 16:27:59 +01:00
Correct more really awkward code formatting decisions (I blame Mumfrey)
This commit is contained in:
parent
0d47368bce
commit
dfd3c6f2ea
14 changed files with 192 additions and 197 deletions
|
@ -11,14 +11,11 @@ import com.google.common.collect.Lists;
|
|||
import com.google.common.collect.Maps;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
|
||||
import com.mojang.util.UUIDTypeAdapter;
|
||||
import com.mumfrey.liteloader.core.LiteLoader;
|
||||
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
|
||||
import com.voxelmodpack.hdskins.gui.GuiSkins;
|
||||
|
@ -32,7 +29,6 @@ import com.voxelmodpack.hdskins.util.AsyncCacheLoader;
|
|||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IImageBuffer;
|
||||
import net.minecraft.client.renderer.texture.ITextureObject;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.DefaultPlayerSkin;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
|
@ -61,12 +57,9 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public final class HDSkinManager implements IResourceManagerReloadListener {
|
||||
public final class HDSkinManager implements IResourceManagerReloadListener, ISkinModifier {
|
||||
|
||||
private static final ResourceLocation LOADING = new ResourceLocation("LOADING");
|
||||
private static final Gson GSON = new GsonBuilder()
|
||||
.registerTypeAdapter(UUID.class, new UUIDTypeAdapter())
|
||||
.create();
|
||||
|
||||
private static final ExecutorService skinDownloadExecutor = Executors.newFixedThreadPool(8);
|
||||
public static final ListeningExecutorService skinUploadExecutor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
|
||||
|
@ -92,12 +85,18 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
private List<ISkinModifier> skinModifiers = Lists.newArrayList();
|
||||
|
||||
private SkinResourceManager resources = new SkinResourceManager();
|
||||
// private ExecutorService executor = Executors.newCachedThreadPool();
|
||||
|
||||
private Class<? extends GuiSkins> skinsClass = null;
|
||||
|
||||
private HDSkinManager() {
|
||||
public static void clearSkinCache() {
|
||||
INSTANCE.clearSKinCache();
|
||||
}
|
||||
|
||||
public static PreviewTextureManager getPreviewTextureManager(GameProfile profile) {
|
||||
return new PreviewTextureManager(INSTANCE.getGatewayServer().getPreviewTextures(profile));
|
||||
}
|
||||
|
||||
private HDSkinManager() {
|
||||
// register default skin server types
|
||||
addSkinServerType(LegacySkinServer.class);
|
||||
addSkinServerType(ValhallaSkinServer.class);
|
||||
|
@ -135,7 +134,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
Property textures = Iterables.getFirst(profile1.getProperties().get("textures"), null);
|
||||
if (textures != null) {
|
||||
String json = new String(Base64.getDecoder().decode(textures.getValue()), StandardCharsets.UTF_8);
|
||||
MinecraftTexturesPayload texturePayload = GSON.fromJson(json, MinecraftTexturesPayload.class);
|
||||
MinecraftTexturesPayload texturePayload = SkinServer.gson.fromJson(json, MinecraftTexturesPayload.class);
|
||||
if (texturePayload != null) {
|
||||
// name is optional
|
||||
String name = texturePayload.getProfileName();
|
||||
|
@ -177,75 +176,77 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
return url + (url.indexOf('?') > -1 ? '&' : '?') + Long.toString(new Date().getTime() / 1000);
|
||||
}
|
||||
|
||||
private void loadTexture(GameProfile profile, final Type type, final SkinAvailableCallback callback) {
|
||||
if (profile.getId() != null) {
|
||||
Map<Type, MinecraftProfileTexture> data = getProfileData(profile);
|
||||
final MinecraftProfileTexture texture = data.get(type);
|
||||
private void loadTexture(GameProfile profile, Type type, SkinAvailableCallback callback) {
|
||||
if (profile.getId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftProfileTexture texture = getProfileData(profile).get(type);
|
||||
|
||||
String skinDir = type.toString().toLowerCase() + "s/";
|
||||
final ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash());
|
||||
File file2 = new File(LiteLoader.getAssetsDirectory(), "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash());
|
||||
|
||||
final IImageBuffer imagebufferdownload = type == Type.SKIN ? new ImageBufferDownloadHD() : null;
|
||||
ResourceLocation skin = new ResourceLocation("hdskins", skinDir + texture.getHash());
|
||||
|
||||
ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl()),
|
||||
DefaultPlayerSkin.getDefaultSkinLegacy(),
|
||||
new IImageBuffer() {
|
||||
File etag = new File(LiteLoader.getAssetsDirectory(), "hd/" + skinDir + texture.getHash().substring(0, 2) + "/" + texture.getHash());
|
||||
|
||||
IImageBuffer buffer = new ImageBufferDownloadHD() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public BufferedImage parseUserSkin(@Nonnull BufferedImage image) {
|
||||
BufferedImage image1 = image;
|
||||
if (imagebufferdownload != null) {
|
||||
image1 = imagebufferdownload.parseUserSkin(image);
|
||||
}
|
||||
return image1 == null ? image : image1;
|
||||
if (type != Type.SKIN) {
|
||||
return image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skinAvailable() {
|
||||
if (imagebufferdownload != null) {
|
||||
imagebufferdownload.skinAvailable();
|
||||
BufferedImage converted = super.parseUserSkin(image);
|
||||
|
||||
return converted == null ? image : converted;
|
||||
}
|
||||
callback.skinAvailable(type, skin, texture);
|
||||
}
|
||||
});
|
||||
}.withCallback(() -> callback.skinAvailable(type, skin, texture));
|
||||
|
||||
// schedule texture loading on the main thread.
|
||||
TextureLoader.loadTexture(skin, texObject);
|
||||
}
|
||||
TextureLoader.loadTexture(skin, new ThreadDownloadImageETag(etag, bustCache(texture.getUrl()), DefaultPlayerSkin.getDefaultSkinLegacy(), buffer));
|
||||
}
|
||||
|
||||
private Map<Type, MinecraftProfileTexture> loadProfileData(GameProfile profile) {
|
||||
Map<Type, MinecraftProfileTexture> textures = Maps.newEnumMap(Type.class);
|
||||
for (SkinServer server : skinServers) {
|
||||
Optional<MinecraftTexturesPayload> profileData = server.loadProfileData(profile);
|
||||
profileData.map(MinecraftTexturesPayload::getTextures).ifPresent(it -> it.forEach(textures::putIfAbsent));
|
||||
|
||||
if (profileData.isPresent()) {
|
||||
profileData.get().getTextures().forEach(textures::putIfAbsent);
|
||||
}
|
||||
|
||||
if (textures.size() == Type.values().length) {
|
||||
break;
|
||||
return textures;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return textures;
|
||||
}
|
||||
|
||||
public Map<Type, MinecraftProfileTexture> getProfileData(GameProfile profile) {
|
||||
boolean was = !skins.asMap().containsKey(profile);
|
||||
|
||||
Map<Type, MinecraftProfileTexture> textures = skins.getUnchecked(profile);
|
||||
|
||||
// This is the initial value. Refreshing will load it asynchronously.
|
||||
if (was) {
|
||||
skins.refresh(profile);
|
||||
}
|
||||
|
||||
return textures;
|
||||
}
|
||||
|
||||
public void addSkinServerType(Class<? extends SkinServer> type) {
|
||||
Preconditions.checkArgument(!type.isInterface(), "type cannot be an interface");
|
||||
Preconditions.checkArgument(!Modifier.isAbstract(type.getModifiers()), "type cannot be abstract");
|
||||
|
||||
ServerType st = type.getAnnotation(ServerType.class);
|
||||
if (st == null) {
|
||||
throw new IllegalArgumentException("class is not annotated with @ServerType");
|
||||
}
|
||||
this.skinServerTypes.put(st.value(), type);
|
||||
|
||||
Preconditions.checkArgument(st != null, "class is not annotated with @ServerType");
|
||||
|
||||
skinServerTypes.put(st.value(), type);
|
||||
}
|
||||
|
||||
public Class<? extends SkinServer> getSkinServerClass(String type) {
|
||||
|
@ -265,15 +266,11 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public static PreviewTextureManager getPreviewTextureManager(GameProfile profile) {
|
||||
return new PreviewTextureManager(INSTANCE.getGatewayServer().getPreviewTextures(profile));
|
||||
}
|
||||
|
||||
public void addClearListener(ISkinCacheClearListener listener) {
|
||||
clearListeners.add(listener);
|
||||
}
|
||||
|
||||
public static void clearSkinCache() {
|
||||
private void clearSKinCache() {
|
||||
LiteLoaderLogger.info("Clearing local player skin cache");
|
||||
|
||||
try {
|
||||
|
@ -282,20 +279,17 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
|
||||
TextureManager textures = Minecraft.getMinecraft().getTextureManager();
|
||||
|
||||
INSTANCE.skinCache.values().stream().flatMap(m -> m.values().stream())
|
||||
.forEach(textures::deleteTexture);
|
||||
INSTANCE.skinCache.clear();
|
||||
INSTANCE.skins.invalidateAll();
|
||||
skinCache.values().stream().flatMap(m -> m.values().stream()).forEach(textures::deleteTexture);
|
||||
skinCache.clear();
|
||||
skins.invalidateAll();
|
||||
} catch (IOException var1) {
|
||||
var1.printStackTrace();
|
||||
}
|
||||
|
||||
INSTANCE.clearListeners = INSTANCE.clearListeners.stream()
|
||||
.filter(HDSkinManager::onSkinCacheCleared)
|
||||
.collect(Collectors.toList());
|
||||
clearListeners = clearListeners.stream().filter(this::onSkinCacheCleared).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static boolean onSkinCacheCleared(ISkinCacheClearListener callback) {
|
||||
private boolean onSkinCacheCleared(ISkinCacheClearListener callback) {
|
||||
try {
|
||||
return callback.onSkinCacheCleared();
|
||||
} catch (Exception e) {
|
||||
|
@ -314,6 +308,13 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
|
|||
return loc == null ? res : loc;
|
||||
}
|
||||
|
||||
public void convertSkin(BufferedImage image) {
|
||||
Graphics graphics = image.getGraphics();
|
||||
convertSkin(image, graphics);
|
||||
graphics.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertSkin(BufferedImage image, Graphics dest) {
|
||||
skinModifiers.forEach(a -> a.convertSkin(image, dest));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.voxelmodpack.hdskins;
|
||||
|
||||
/**
|
||||
* Callback for when a skin is loaded.
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ISkinAvailableCallback {
|
||||
/**
|
||||
* Called when a skin loads.
|
||||
*/
|
||||
void skinAvailable();
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.voxelmodpack.hdskins;
|
|||
import net.minecraft.client.renderer.IImageBuffer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
|
@ -12,6 +13,13 @@ public class ImageBufferDownloadHD implements IImageBuffer {
|
|||
private Graphics graphics;
|
||||
private BufferedImage image;
|
||||
|
||||
private ISkinAvailableCallback callback;
|
||||
|
||||
public ImageBufferDownloadHD withCallback(ISkinAvailableCallback callback) {
|
||||
this.callback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@SuppressWarnings({"SuspiciousNameCombination", "NullableProblems"})
|
||||
|
@ -19,6 +27,7 @@ public class ImageBufferDownloadHD implements IImageBuffer {
|
|||
if (downloadedImage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int imageWidth = downloadedImage.getWidth();
|
||||
int imageHeight = downloadedImage.getHeight();
|
||||
if (imageHeight == imageWidth) {
|
||||
|
@ -61,5 +70,8 @@ public class ImageBufferDownloadHD implements IImageBuffer {
|
|||
|
||||
@Override
|
||||
public void skinAvailable() {
|
||||
if (callback != null) {
|
||||
callback.skinAvailable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ public class PreviewTexture extends ThreadDownloadImageData {
|
|||
}
|
||||
|
||||
public boolean isTextureUploaded() {
|
||||
return uploaded && this.getGlTextureId() > -1;
|
||||
return uploaded && getGlTextureId() > -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,10 +6,9 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
|
|||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IImageBuffer;
|
||||
import net.minecraft.client.resources.SkinManager;
|
||||
import net.minecraft.client.resources.SkinManager.SkinAvailableCallback;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -26,37 +25,21 @@ public class PreviewTextureManager {
|
|||
this.textures = textures;
|
||||
}
|
||||
|
||||
private IImageBuffer getPreviewImageBuffer(MinecraftProfileTexture texture, ResourceLocation location, Type type, SkinManager.SkinAvailableCallback callback) {
|
||||
if (type != Type.SKIN) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IImageBuffer buffer = new ImageBufferDownloadHD();
|
||||
|
||||
return new IImageBuffer() {
|
||||
@Override
|
||||
@Nullable
|
||||
public BufferedImage parseUserSkin(BufferedImage image) {
|
||||
return buffer.parseUserSkin(image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skinAvailable() {
|
||||
if (callback != null) {
|
||||
callback.skinAvailable(type, location, new MinecraftProfileTexture(texture.getUrl(), Maps.newHashMap()));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PreviewTexture getPreviewTexture(ResourceLocation location, Type type, ResourceLocation def, @Nullable SkinManager.SkinAvailableCallback callback) {
|
||||
public PreviewTexture getPreviewTexture(ResourceLocation location, Type type, ResourceLocation def, @Nullable SkinAvailableCallback callback) {
|
||||
if (!textures.containsKey(type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MinecraftProfileTexture texture = textures.get(type);
|
||||
PreviewTexture skinTexture = new PreviewTexture(texture, def, getPreviewImageBuffer(texture, location, type, callback));
|
||||
|
||||
IImageBuffer buffer = type != Type.SKIN ? null : new ImageBufferDownloadHD().withCallback(() -> {
|
||||
if (callback != null) {
|
||||
callback.skinAvailable(type, location, new MinecraftProfileTexture(texture.getUrl(), Maps.newHashMap()));
|
||||
}
|
||||
});
|
||||
|
||||
PreviewTexture skinTexture = new PreviewTexture(texture, def, buffer);
|
||||
|
||||
Minecraft.getMinecraft().getTextureManager().loadTexture(location, skinTexture);
|
||||
|
||||
|
|
|
@ -93,19 +93,22 @@ public class GuiSkins extends GuiScreen {
|
|||
private boolean thinArmType = false;
|
||||
|
||||
public GuiSkins() {
|
||||
instance = this;
|
||||
|
||||
Minecraft minecraft = Minecraft.getMinecraft();
|
||||
GameProfile profile = minecraft.getSession().getProfile();
|
||||
|
||||
localPlayer = getModel(profile);
|
||||
remotePlayer = getModel(profile);
|
||||
RenderManager rm = Minecraft.getMinecraft().getRenderManager();
|
||||
|
||||
RenderManager rm = minecraft.getRenderManager();
|
||||
rm.renderEngine = minecraft.getTextureManager();
|
||||
rm.options = minecraft.gameSettings;
|
||||
rm.renderViewEntity = localPlayer;
|
||||
reloadRemoteSkin();
|
||||
fetchingSkin = true;
|
||||
|
||||
instance = this;
|
||||
reloadRemoteSkin();
|
||||
|
||||
fetchingSkin = true;
|
||||
|
||||
panorama = new CubeMap(this);
|
||||
initPanorama();
|
||||
|
@ -125,6 +128,7 @@ public class GuiSkins extends GuiScreen {
|
|||
if (!(Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_RIGHT))) {
|
||||
updateCounter++;
|
||||
}
|
||||
|
||||
panorama.update();
|
||||
|
||||
localPlayer.updateModel();
|
||||
|
@ -185,7 +189,9 @@ public class GuiSkins extends GuiScreen {
|
|||
|
||||
@Override
|
||||
public void initGui() {
|
||||
enableDnd();
|
||||
GLWindow.current().setDropTargetListener((FileDropListener) files -> {
|
||||
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
||||
});
|
||||
|
||||
panorama.init();
|
||||
|
||||
|
@ -215,12 +221,6 @@ public class GuiSkins extends GuiScreen {
|
|||
|
||||
}
|
||||
|
||||
private void enableDnd() {
|
||||
GLWindow.current().setDropTargetListener((FileDropListener) files -> {
|
||||
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
super.onGuiClosed();
|
||||
|
@ -438,8 +438,7 @@ public class GuiSkins extends GuiScreen {
|
|||
drawHoveringText(I18n.format(text), mouseX, y);
|
||||
}
|
||||
if (btnAbout.isMouseOver()) {
|
||||
SkinServer gateway = HDSkinManager.INSTANCE.getGatewayServer();
|
||||
drawHoveringText(Splitter.on("\r\n").splitToList(gateway.toString()), mouseX, mouseY);
|
||||
drawHoveringText(Splitter.on("\r\n").splitToList(HDSkinManager.INSTANCE.getGatewayServer().toString()), mouseX, mouseY);
|
||||
}
|
||||
|
||||
if (fetchingSkin) {
|
||||
|
|
|
@ -8,25 +8,18 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@Mixin(ImageBufferDownload.class)
|
||||
public abstract class MixinImageBufferDownload implements IImageBuffer {
|
||||
|
||||
@Inject(
|
||||
method = "parseUserSkin(Ljava/awt/image/BufferedImage;)Ljava/awt/image/BufferedImage;",
|
||||
// convert skins from the mojang server
|
||||
@Inject(method = "parseUserSkin(Ljava/awt/image/BufferedImage;)Ljava/awt/image/BufferedImage;",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
private void update(BufferedImage image, CallbackInfoReturnable<BufferedImage> ci) {
|
||||
// convert skins from mojang server
|
||||
BufferedImage image2 = ci.getReturnValue();
|
||||
boolean isLegacy = image.getHeight() == 32;
|
||||
if (isLegacy) {
|
||||
Graphics graphics = image2.getGraphics();
|
||||
HDSkinManager.INSTANCE.convertSkin(image2, graphics);
|
||||
graphics.dispose();
|
||||
if (image.getHeight() == 32) {
|
||||
HDSkinManager.INSTANCE.convertSkin(ci.getReturnValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,32 +12,27 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(NetworkPlayerInfo.class)
|
||||
public abstract class MixinPlayerInfo {
|
||||
|
||||
@Shadow
|
||||
public abstract GameProfile getGameProfile();
|
||||
|
||||
@Inject(
|
||||
method = "getLocationSkin",
|
||||
@Inject(method = "getLocationSkin",
|
||||
cancellable = true,
|
||||
at = @At("RETURN"))
|
||||
private void getLocationSkin(CallbackInfoReturnable<ResourceLocation> ci) {
|
||||
getTextureLocation(ci, Type.SKIN);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "getLocationCape",
|
||||
@Inject(method = "getLocationCape",
|
||||
cancellable = true,
|
||||
at = @At("RETURN"))
|
||||
private void getLocationCape(CallbackInfoReturnable<ResourceLocation> ci) {
|
||||
getTextureLocation(ci, Type.CAPE);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "getLocationElytra",
|
||||
@Inject(method = "getLocationElytra",
|
||||
cancellable = true,
|
||||
at = @At("RETURN"))
|
||||
private void getLocationElytra(CallbackInfoReturnable<ResourceLocation> ci) {
|
||||
|
@ -45,24 +40,20 @@ public abstract class MixinPlayerInfo {
|
|||
}
|
||||
|
||||
private void getTextureLocation(CallbackInfoReturnable<ResourceLocation> ci, Type type) {
|
||||
Optional<ResourceLocation> texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), type, true);
|
||||
texture.ifPresent(ci::setReturnValue);
|
||||
HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), type, true).ifPresent(ci::setReturnValue);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "getSkinType",
|
||||
@Inject(method = "getSkinType",
|
||||
cancellable = true,
|
||||
at = @At("RETURN"))
|
||||
private void getSkinType(CallbackInfoReturnable<String> ci) {
|
||||
MinecraftProfileTexture skin = HDSkinManager.INSTANCE.getProfileData(getGameProfile()).get(Type.SKIN);
|
||||
if (skin != null) {
|
||||
HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), Type.SKIN, false).ifPresent(res -> {
|
||||
String type = skin.getMetadata("model");
|
||||
if (type == null)
|
||||
type = "default";
|
||||
String type1 = type;
|
||||
Optional<ResourceLocation> texture = HDSkinManager.INSTANCE.getSkinLocation(getGameProfile(), Type.SKIN, false);
|
||||
|
||||
texture.ifPresent((res) -> ci.setReturnValue(type1));
|
||||
ci.setReturnValue(type == null ? "default" : type);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.voxelmodpack.hdskins.mixin;
|
|||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
|
||||
import com.voxelmodpack.hdskins.HDSkinManager;
|
||||
import com.voxelmodpack.hdskins.util.Optionals;
|
||||
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.tileentity.TileEntitySkull;
|
||||
|
@ -13,27 +15,20 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(TileEntitySkullRenderer.class)
|
||||
public abstract class MixinSkullRenderer extends TileEntitySpecialRenderer<TileEntitySkull> {
|
||||
|
||||
@Redirect(
|
||||
method = "renderSkull",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
@Redirect(method = "renderSkull",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/tileentity/TileEntitySkullRenderer;bindTexture(Lnet/minecraft/util/ResourceLocation;)V",
|
||||
ordinal = 4))
|
||||
private void onBindTexture(TileEntitySkullRenderer tesr, ResourceLocation rl, float x, float y, float z, EnumFacing facing, float rotation, int meta,
|
||||
@Nullable GameProfile profile, int p_180543_8_, float ticks) {
|
||||
@Nullable GameProfile profile, int a, float ticks) {
|
||||
if (profile != null) {
|
||||
Optional<ResourceLocation> skin = HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true);
|
||||
if (skin.isPresent())
|
||||
// rebind
|
||||
bindTexture(skin.get());
|
||||
else
|
||||
bindTexture(rl);
|
||||
} else
|
||||
bindTexture(Optionals.getOrDefault(HDSkinManager.INSTANCE.getSkinLocation(profile, Type.SKIN, true), rl));
|
||||
} else {
|
||||
bindTexture(rl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public class ImageLoader implements Supplier<ResourceLocation> {
|
|||
private final ResourceLocation original;
|
||||
|
||||
public ImageLoader(ResourceLocation loc) {
|
||||
this.original = loc;
|
||||
original = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,7 +49,6 @@ public class ImageLoader implements Supplier<ResourceLocation> {
|
|||
|
||||
@Nullable
|
||||
private static BufferedImage getImage(ResourceLocation res) {
|
||||
|
||||
try (InputStream in = mc.getResourceManager().getResource(res).getInputStream()) {
|
||||
return TextureUtil.readBufferedImage(in);
|
||||
} catch (IOException e) {
|
||||
|
@ -59,9 +58,9 @@ public class ImageLoader implements Supplier<ResourceLocation> {
|
|||
|
||||
@Nullable
|
||||
private ResourceLocation loadSkin(BufferedImage image) {
|
||||
|
||||
ResourceLocation conv = new ResourceLocation(original.getResourceDomain() + "-converted", original.getResourcePath());
|
||||
boolean success = mc.getTextureManager().loadTexture(conv, new DynamicTextureImage(image));
|
||||
|
||||
return success ? conv : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import javax.annotation.Nullable;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
@ -25,8 +26,9 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.Future;
|
||||
|
||||
public class SkinResourceManager implements IResourceManagerReloadListener {
|
||||
private final Gson GSON = new Gson();
|
||||
|
||||
private ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
private ExecutorService executor;
|
||||
|
||||
private Map<UUID, Skin> uuidSkins = Maps.newHashMap();
|
||||
private Map<String, Skin> namedSkins = Maps.newHashMap();
|
||||
|
@ -41,15 +43,16 @@ public class SkinResourceManager implements IResourceManagerReloadListener {
|
|||
executor = Executors.newSingleThreadExecutor();
|
||||
inProgress.clear();
|
||||
converted.clear();
|
||||
|
||||
for (String domain : resourceManager.getResourceDomains()) {
|
||||
try {
|
||||
for (IResource res : resourceManager.getAllResources(new ResourceLocation(domain, "textures/skins/skins.json"))) {
|
||||
try {
|
||||
SkinData data = getSkinData(res.getInputStream());
|
||||
for (Skin s : data.skins) {
|
||||
for (Skin s : getSkinData(res.getInputStream())) {
|
||||
if (s.uuid != null) {
|
||||
uuidSkins.put(s.uuid, s);
|
||||
}
|
||||
|
||||
if (s.name != null) {
|
||||
namedSkins.put(s.name, s);
|
||||
}
|
||||
|
@ -58,16 +61,13 @@ public class SkinResourceManager implements IResourceManagerReloadListener {
|
|||
LiteLoaderLogger.warning(je, "Invalid skins.json in %s", res.getResourcePackName());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SkinData getSkinData(InputStream stream) {
|
||||
private List<Skin> getSkinData(InputStream stream) {
|
||||
try {
|
||||
return new Gson().fromJson(new InputStreamReader(stream), SkinData.class);
|
||||
return GSON.fromJson(new InputStreamReader(stream), SkinData.class).skins;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
|
@ -75,16 +75,14 @@ public class SkinResourceManager implements IResourceManagerReloadListener {
|
|||
|
||||
@Nullable
|
||||
public ResourceLocation getPlayerTexture(GameProfile profile, Type type) {
|
||||
if (type != Type.SKIN)
|
||||
// not supported
|
||||
return null;
|
||||
|
||||
if (type == Type.SKIN) {
|
||||
Skin skin = getSkin(profile);
|
||||
if (skin != null) {
|
||||
final ResourceLocation res = skin.getTexture();
|
||||
return getConvertedResource(res);
|
||||
return getConvertedResource(skin.getTexture());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null; // not supported
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,31 +97,29 @@ public class SkinResourceManager implements IResourceManagerReloadListener {
|
|||
return converted.get(res);
|
||||
}
|
||||
|
||||
private void loadSkinResource(@Nullable final ResourceLocation res) {
|
||||
/**
|
||||
* read and convert in a new thread
|
||||
*/
|
||||
private void loadSkinResource(@Nullable ResourceLocation res) {
|
||||
if (res != null) {
|
||||
// read and convert in a new thread
|
||||
this.inProgress.computeIfAbsent(res, r -> CompletableFuture.supplyAsync(new ImageLoader(r), executor)
|
||||
.whenComplete((loc, t) -> {
|
||||
if (loc != null)
|
||||
inProgress.computeIfAbsent(res, r -> CompletableFuture.supplyAsync(new ImageLoader(r), executor).whenComplete((loc, t) -> {
|
||||
if (loc != null) {
|
||||
converted.put(res, loc);
|
||||
else {
|
||||
} else {
|
||||
LogManager.getLogger().warn("Errored while processing {}. Using original.", res, t);
|
||||
converted.put(res, res);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Skin getSkin(GameProfile profile) {
|
||||
Skin skin = this.uuidSkins.get(profile.getId());
|
||||
if (skin == null) {
|
||||
skin = this.namedSkins.get(profile.getName());
|
||||
}
|
||||
Skin skin = uuidSkins.get(profile.getId());
|
||||
if (skin != null) {
|
||||
return skin;
|
||||
}
|
||||
|
||||
return namedSkins.get(profile.getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import javax.annotation.Nullable;
|
|||
|
||||
public interface SkinServer extends Exposable {
|
||||
|
||||
static final Gson gson = new GsonBuilder()
|
||||
public static final Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(UUID.class, new UUIDTypeAdapter())
|
||||
.create();
|
||||
|
||||
|
|
|
@ -21,12 +21,9 @@ public abstract class ThreadOpenFile extends Thread {
|
|||
*/
|
||||
protected final IOpenFileCallback parentScreen;
|
||||
|
||||
private JFileChooser fileDialog;
|
||||
|
||||
private static String lastChosenFile = null;
|
||||
|
||||
protected ThreadOpenFile(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback)
|
||||
throws IllegalStateException {
|
||||
protected ThreadOpenFile(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback) throws IllegalStateException {
|
||||
if (minecraft.isFullScreen()) {
|
||||
throw new IllegalStateException("Cannot open an awt window whilst minecraft is in full screen mode!");
|
||||
}
|
||||
|
@ -37,13 +34,13 @@ public abstract class ThreadOpenFile extends Thread {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
fileDialog = new JFileChooser();
|
||||
fileDialog.setDialogTitle(this.dialogTitle);
|
||||
JFileChooser fileDialog = new JFileChooser();
|
||||
fileDialog.setDialogTitle(dialogTitle);
|
||||
|
||||
if (lastChosenFile != null) {
|
||||
fileDialog.setSelectedFile(new File(lastChosenFile));
|
||||
}
|
||||
fileDialog.setFileFilter(this.getFileFilter());
|
||||
fileDialog.setFileFilter(getFileFilter());
|
||||
|
||||
int dialogResult = fileDialog.showOpenDialog(InternalDialog.getAWTContext());
|
||||
|
||||
|
@ -53,7 +50,7 @@ public abstract class ThreadOpenFile extends Thread {
|
|||
lastChosenFile = f.getAbsolutePath();
|
||||
}
|
||||
|
||||
this.parentScreen.onFileOpenDialogClosed(fileDialog, dialogResult);
|
||||
parentScreen.onFileOpenDialogClosed(fileDialog, dialogResult);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.voxelmodpack.hdskins.util;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Silly optionals
|
||||
*/
|
||||
public final class Optionals {
|
||||
public static <T> T nullableOf(Optional<T> optional) {
|
||||
return getOrDefault(optional, null);
|
||||
}
|
||||
|
||||
public static <T> T getOrDefault(Optional<T> optional, T def) {
|
||||
return optional.isPresent() ? optional.get() : def;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue