mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 08:14:23 +01:00
Update SkinServer to be more extensible.
This commit is contained in:
parent
a92a121a5b
commit
89ecc9f916
5 changed files with 81 additions and 38 deletions
|
@ -4,15 +4,13 @@ import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.ELYTRA;
|
||||||
import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.SKIN;
|
import static com.mojang.authlib.minecraft.MinecraftProfileTexture.Type.SKIN;
|
||||||
import static net.minecraft.client.renderer.GlStateManager.*;
|
import static net.minecraft.client.renderer.GlStateManager.*;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||||
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
|
import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
|
||||||
import com.voxelmodpack.hdskins.HDSkinManager;
|
import com.voxelmodpack.hdskins.HDSkinManager;
|
||||||
import com.voxelmodpack.hdskins.skins.SkinUploadResponse;
|
import com.voxelmodpack.hdskins.skins.SkinUploadResponse;
|
||||||
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG;
|
import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Gui;
|
import net.minecraft.client.gui.Gui;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
@ -37,13 +35,17 @@ import org.lwjgl.opengl.GL11;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.DoubleBuffer;
|
import java.nio.DoubleBuffer;
|
||||||
import java.nio.file.Path;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
public class GuiSkins extends GuiScreen {
|
||||||
|
|
||||||
public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResponse> {
|
|
||||||
private static final int MAX_SKIN_DIMENSION = 1024;
|
private static final int MAX_SKIN_DIMENSION = 1024;
|
||||||
private int updateCounter = 0;
|
private int updateCounter = 0;
|
||||||
|
|
||||||
|
@ -490,7 +492,8 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
enableDepth();
|
enableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX, float partialTick) {
|
private void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, float mouseY, float mouseX,
|
||||||
|
float partialTick) {
|
||||||
enableColorMaterial();
|
enableColorMaterial();
|
||||||
pushMatrix();
|
pushMatrix();
|
||||||
translate(xPosition, yPosition, 300.0F);
|
translate(xPosition, yPosition, 300.0F);
|
||||||
|
@ -551,38 +554,44 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
private void clearUploadedSkin(Session session) {
|
private void clearUploadedSkin(Session session) {
|
||||||
this.uploadingSkin = true;
|
this.uploadingSkin = true;
|
||||||
this.skinUploadMessage = I18n.format("hdskins.request");
|
this.skinUploadMessage = I18n.format("hdskins.request");
|
||||||
Futures.addCallback(HDSkinManager.INSTANCE.getGatewayServer().uploadSkin(session, null, this.textureType, this.thinArmType), this);
|
HDSkinManager.INSTANCE.getGatewayServer()
|
||||||
|
.uploadSkin(session, null, this.textureType, getMetadata())
|
||||||
|
.thenAccept(this::onUploadComplete)
|
||||||
|
.exceptionally(this::onFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadSkin(Session session, @Nullable File skinFile) {
|
private void uploadSkin(Session session, @Nullable File skinFile) {
|
||||||
this.uploadingSkin = true;
|
this.uploadingSkin = true;
|
||||||
this.skinUploadMessage = I18n.format("hdskins.upload");
|
this.skinUploadMessage = I18n.format("hdskins.upload");
|
||||||
Path path = skinFile == null ? null : skinFile.toPath();
|
URI path = skinFile == null ? null : skinFile.toURI();
|
||||||
Futures.addCallback(HDSkinManager.INSTANCE.getGatewayServer().uploadSkin(session, path, this.textureType, this.thinArmType), this);
|
HDSkinManager.INSTANCE.getGatewayServer()
|
||||||
|
.uploadSkin(session, path, this.textureType, getMetadata())
|
||||||
|
.thenAccept(this::onUploadComplete)
|
||||||
|
.exceptionally(this::onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getMetadata() {
|
||||||
|
return ImmutableMap.of("model", this.thinArmType ? "slim" : "default");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUploadError(@Nullable String error) {
|
private void setUploadError(@Nullable String error) {
|
||||||
this.uploadError = error != null && error.startsWith("ERROR: ") ? error.substring(7) : error;
|
this.uploadError = error;
|
||||||
this.btnUpload.enabled = true;
|
this.btnUpload.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(@Nullable SkinUploadResponse result) {
|
|
||||||
if (result != null)
|
|
||||||
onUploadComplete(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private Void onFailure(Throwable t) {
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
LogManager.getLogger().warn("Upload failed", t);
|
LogManager.getLogger().warn("Upload failed", t);
|
||||||
this.setUploadError(t.toString());
|
this.setUploadError(t.toString());
|
||||||
this.uploadingSkin = false;
|
this.uploadingSkin = false;
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onUploadComplete(SkinUploadResponse response) {
|
private void onUploadComplete(SkinUploadResponse response) {
|
||||||
LiteLoaderLogger.info("Upload completed with: %s", response);
|
LiteLoaderLogger.info("Upload completed with: %s", response);
|
||||||
this.uploadingSkin = false;
|
this.uploadingSkin = false;
|
||||||
if (!"OK".equalsIgnoreCase(response.getMessage())) {
|
if (!response.isSuccess()) {
|
||||||
this.setUploadError(response.getMessage());
|
this.setUploadError(response.getMessage());
|
||||||
} else {
|
} else {
|
||||||
this.pendingRemoteSkinRefresh = true;
|
this.pendingRemoteSkinRefresh = true;
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.voxelmodpack.hdskins.skins;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
public class CallableFutures {
|
||||||
|
|
||||||
|
public static <T> CompletableFuture<T> asyncFailableFuture(Callable<T> call, Executor exec) {
|
||||||
|
CompletableFuture<T> ret = new CompletableFuture<>();
|
||||||
|
exec.execute(() -> {
|
||||||
|
try {
|
||||||
|
ret.complete(call.call());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
ret.completeExceptionally(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> CompletableFuture<T> failedFuture(Exception e) {
|
||||||
|
CompletableFuture<T> ret = new CompletableFuture<>();
|
||||||
|
ret.completeExceptionally(e);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,6 @@ package com.voxelmodpack.hdskins.skins;
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
import com.mojang.authlib.exceptions.AuthenticationException;
|
||||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||||
|
@ -20,13 +18,15 @@ import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class LegacySkinServer implements SkinServer {
|
public class LegacySkinServer implements SkinServer {
|
||||||
|
@ -88,19 +88,24 @@ public class LegacySkinServer implements SkinServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type, boolean thinSkinType) {
|
public CompletableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable URI image,
|
||||||
|
MinecraftProfileTexture.Type type, Map<String, String> metadata) {
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(this.gateway))
|
if (Strings.isNullOrEmpty(this.gateway)) {
|
||||||
return Futures.immediateFailedFuture(new NullPointerException("gateway url is blank"));
|
return CallableFutures.failedFuture(new NullPointerException("gateway url is blank"));
|
||||||
|
}
|
||||||
|
|
||||||
return HDSkinManager.skinUploadExecutor.submit(() -> {
|
return CallableFutures.asyncFailableFuture(() -> {
|
||||||
verifyServerConnection(session, SERVER_ID);
|
verifyServerConnection(session, SERVER_ID);
|
||||||
|
String model = metadata.getOrDefault("model", "default");
|
||||||
Map<String, ?> data = image == null ? getClearData(session, type) : getUploadData(session, type, (thinSkinType ? "slim" : "default"), image);
|
Map<String, ?> data = image == null ? getClearData(session, type) : getUploadData(session, type, model, image);
|
||||||
ThreadMultipartPostUpload upload = new ThreadMultipartPostUpload(this.gateway, data);
|
ThreadMultipartPostUpload upload = new ThreadMultipartPostUpload(this.gateway, data);
|
||||||
String response = upload.uploadMultipart();
|
String response = upload.uploadMultipart();
|
||||||
|
if (response.startsWith("ERROR: "))
|
||||||
|
response = response.substring(7);
|
||||||
return new SkinUploadResponse(response.equalsIgnoreCase("OK"), response);
|
return new SkinUploadResponse(response.equalsIgnoreCase("OK"), response);
|
||||||
});
|
|
||||||
|
}, HDSkinManager.skinUploadExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, ?> getData(Session session, MinecraftProfileTexture.Type type, String model, String param, Object val) {
|
private static Map<String, ?> getData(Session session, MinecraftProfileTexture.Type type, String model, String param, Object val) {
|
||||||
|
@ -116,7 +121,7 @@ public class LegacySkinServer implements SkinServer {
|
||||||
return getData(session, type, "default", "clear", "1");
|
return getData(session, type, "default", "clear", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, ?> getUploadData(Session session, MinecraftProfileTexture.Type type, String model, Path skinFile) {
|
private static Map<String, ?> getUploadData(Session session, MinecraftProfileTexture.Type type, String model, URI skinFile) {
|
||||||
return getData(session, type, model, type.toString().toLowerCase(Locale.US), skinFile);
|
return getData(session, type, model, type.toString().toLowerCase(Locale.US), skinFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package com.voxelmodpack.hdskins.skins;
|
package com.voxelmodpack.hdskins.skins;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||||
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
|
import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
|
||||||
import net.minecraft.util.Session;
|
import net.minecraft.util.Session;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public interface SkinServer {
|
public interface SkinServer {
|
||||||
|
@ -18,9 +20,12 @@ public interface SkinServer {
|
||||||
|
|
||||||
Optional<MinecraftTexturesPayload> loadProfileData(GameProfile profile);
|
Optional<MinecraftTexturesPayload> loadProfileData(GameProfile profile);
|
||||||
|
|
||||||
Optional<MinecraftProfileTexture> getPreviewTexture(MinecraftProfileTexture.Type type, GameProfile profile);
|
default Optional<MinecraftProfileTexture> getPreviewTexture(MinecraftProfileTexture.Type type, GameProfile profile) {
|
||||||
|
return loadProfileData(profile).map(data -> data.getTextures().get(type));
|
||||||
|
}
|
||||||
|
|
||||||
ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type, boolean thinArmType);
|
CompletableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable URI image,
|
||||||
|
MinecraftProfileTexture.Type type, Map<String, String> metadata);
|
||||||
|
|
||||||
static SkinServer from(String server) {
|
static SkinServer from(String server) {
|
||||||
int i = server.indexOf(':');
|
int i = server.indexOf(':');
|
||||||
|
@ -36,4 +41,5 @@ public interface SkinServer {
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@ package com.voxelmodpack.hdskins.skins;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public class SkinUploadResponse {
|
public class SkinUploadResponse {
|
||||||
|
|
||||||
private final boolean success;
|
private final boolean success;
|
||||||
|
@ -18,7 +16,6 @@ public class SkinUploadResponse {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue