diff --git a/build.number b/build.number index 6bc4a40b..a647a8ff 100644 --- a/build.number +++ b/build.number @@ -1,3 +1,4 @@ #Build Number for ANT. Do not edit! -#Wed Jul 11 12:06:53 CAT 2018 -build.number=503 +#Sun Jul 08 20:46:02 CAT 2018 +build.number=500 +>>>>>>> Build number pls diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index a6599cbd..bf36474a 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -24,6 +24,7 @@ import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.voxelmodpack.hdskins.gui.GuiSkins; import com.voxelmodpack.hdskins.resource.SkinResourceManager; import com.voxelmodpack.hdskins.skins.AsyncCacheLoader; +import com.voxelmodpack.hdskins.skins.BethlehemSkinServer; import com.voxelmodpack.hdskins.skins.LegacySkinServer; import com.voxelmodpack.hdskins.skins.ServerType; import com.voxelmodpack.hdskins.skins.SkinServer; @@ -98,6 +99,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { // register default skin server types addSkinServerType(LegacySkinServer.class); addSkinServerType(ValhallaSkinServer.class); + addSkinServerType(BethlehemSkinServer.class); } public void setPrefferedSkinsGuiClass(Class clazz) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mod/LiteModHDSkinsMod.java b/src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java similarity index 90% rename from src/hdskins/java/com/voxelmodpack/hdskins/mod/LiteModHDSkinsMod.java rename to src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java index b6c295aa..2b9d17a3 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mod/LiteModHDSkinsMod.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java @@ -1,14 +1,16 @@ -package com.voxelmodpack.hdskins.mod; +package com.voxelmodpack.hdskins; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; +import com.mumfrey.liteloader.Configurable; +import com.mumfrey.liteloader.InitCompleteListener; +import com.mumfrey.liteloader.ViewportListener; import com.mumfrey.liteloader.core.LiteLoader; import com.mumfrey.liteloader.modconfig.AdvancedExposable; import com.mumfrey.liteloader.modconfig.ConfigPanel; import com.mumfrey.liteloader.modconfig.ConfigStrategy; import com.mumfrey.liteloader.modconfig.ExposableOptions; import com.mumfrey.liteloader.util.ModUtilities; -import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.gui.EntityPlayerModel; import com.voxelmodpack.hdskins.gui.GLWindow; import com.voxelmodpack.hdskins.gui.HDSkinsConfigPanel; @@ -23,7 +25,7 @@ import java.io.File; import java.util.List; @ExposableOptions(strategy = ConfigStrategy.Unversioned, filename = "hdskins") -public class LiteModHDSkinsMod implements HDSkinsMod, AdvancedExposable { +public class LiteModHDSkins implements InitCompleteListener, ViewportListener, Configurable, AdvancedExposable { @Expose public List skin_servers = SkinServer.defaultServers; diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java index 06d24a48..ed2b89e5 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java @@ -5,7 +5,7 @@ import com.mumfrey.liteloader.core.LiteLoader; import com.mumfrey.liteloader.modconfig.ConfigPanel; import com.mumfrey.liteloader.modconfig.ConfigPanelHost; import com.voxelmodpack.hdskins.HDSkinManager; -import com.voxelmodpack.hdskins.mod.LiteModHDSkinsMod; +import com.voxelmodpack.hdskins.LiteModHDSkins; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; @@ -16,11 +16,11 @@ public class HDSkinsConfigPanel implements ConfigPanel { private GuiCheckbox checkbox; - private LiteModHDSkinsMod mod; + private LiteModHDSkins mod; @Override public void onPanelShown(ConfigPanelHost host) { - this.mod = LiteLoader.getInstance().getMod(LiteModHDSkinsMod.class); + this.mod = LiteLoader.getInstance().getMod(LiteModHDSkins.class); this.button = new GuiButton(0, 40, 70, 100, 20, "Clear Skin Cache"); this.checkbox = new GuiCheckbox(1, 40, 40, "Experimental Skin Drop"); diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/mod/HDSkinsMod.java b/src/hdskins/java/com/voxelmodpack/hdskins/mod/HDSkinsMod.java deleted file mode 100644 index 082415f2..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/mod/HDSkinsMod.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.voxelmodpack.hdskins.mod; - -import com.mumfrey.liteloader.Configurable; -import com.mumfrey.liteloader.InitCompleteListener; -import com.mumfrey.liteloader.ViewportListener; - -public interface HDSkinsMod extends InitCompleteListener, ViewportListener, Configurable { -} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java new file mode 100644 index 00000000..6b05aa88 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/BethlehemSkinServer.java @@ -0,0 +1,91 @@ +package com.voxelmodpack.hdskins.skins; + +import java.net.URI; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.gson.JsonObject; +import com.google.gson.annotations.Expose; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; +import com.mojang.util.UUIDTypeAdapter; +import com.voxelmodpack.hdskins.HDSkinManager; +import net.minecraft.util.Session; + +@ServerType("bethlehem") +public class BethlehemSkinServer implements SkinServer { + + private static final String SERVER_ID = "7853dfddc358333843ad55a2c7485c4aa0380a51"; + + @Expose + private final String address; + + private BethlehemSkinServer(String address) { + this.address = address; + } + + @Override + public Optional loadProfileData(GameProfile profile) { + NetClient client = new NetClient("GET", getPath(profile)); + + String json = client.getResponseText(); + + JsonObject s = gson.fromJson(json, JsonObject.class); + + if (s.has("success") && s.get("success").getAsBoolean()) { + s = s.get("data").getAsJsonObject(); + + return Optional.ofNullable(gson.fromJson(s, MinecraftTexturesPayload.class)); + } + + return Optional.empty(); + } + + @Override + public CompletableFuture uploadSkin(Session session, URI image, Type type, Map metadata) { + return CallableFutures.asyncFailableFuture(() -> { + SkinServer.verifyServerConnection(session, SERVER_ID); + + NetClient client = new NetClient("POST", address).putHeaders(createHeaders(session, type, image, metadata)); + + if (image != null) { + client.putFile(type.toString().toLowerCase(Locale.US), "image/png", image); + } + + return new SkinUploadResponse(client.send(), client.getResponseText()); + }, HDSkinManager.skinUploadExecutor); + } + + protected Map createHeaders(Session session, Type type, URI image, Map metadata) { + Builder builder = ImmutableMap.builder() + .put("accessToken", session.getToken()) + .put("user", session.getUsername()) + .put("uuid", UUIDTypeAdapter.fromUUID(session.getProfile().getId())) + .put("type", type.toString().toLowerCase(Locale.US)); + + if (image == null) { + builder.put("clear", "1"); + } else { + builder.put("model", metadata.getOrDefault("mode", "default")); + } + + return builder.build(); + } + + private String getPath(GameProfile profile) { + return String.format("%s/profile/%s", address, UUIDTypeAdapter.fromUUID(profile.getId())); + } + + @Override + public String toString() { + return new ToStringBuilder(this, IndentedToStringStyle.INSTANCE) + .append("address", address) + .build(); + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/IndentedToStringStyle.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/IndentedToStringStyle.java index 150f8d40..44255b78 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/IndentedToStringStyle.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/IndentedToStringStyle.java @@ -5,6 +5,8 @@ import org.apache.commons.lang3.builder.ToStringStyle; public class IndentedToStringStyle extends ToStringStyle { + private static final long serialVersionUID = 2031593562293731492L; + public static final ToStringStyle INSTANCE = new IndentedToStringStyle(); private IndentedToStringStyle() { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java index a15b4557..afbdfcf1 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/LegacySkinServer.java @@ -4,14 +4,11 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.gson.annotations.Expose; import com.mojang.authlib.GameProfile; -import com.mojang.authlib.exceptions.AuthenticationException; import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.upload.ThreadMultipartPostUpload; -import net.minecraft.client.Minecraft; import net.minecraft.util.Session; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.logging.log4j.LogManager; @@ -83,25 +80,18 @@ public class LegacySkinServer implements SkinServer { return Optional.empty(); } - return Optional.of(new TexturesPayloadBuilder() - .profileId(profile.getId()) - .profileName(profile.getName()) - .timestamp(System.currentTimeMillis()) - .isPublic(true) - .textures(map) - .build()); + return Optional.of(TexturesPayloadBuilder.createTexuresPayload(profile, map)); } + @SuppressWarnings("deprecation") @Override - public CompletableFuture uploadSkin(Session session, @Nullable URI image, - MinecraftProfileTexture.Type type, Map metadata) { - + public CompletableFuture uploadSkin(Session session, @Nullable URI image, MinecraftProfileTexture.Type type, Map metadata) { if (Strings.isNullOrEmpty(this.gateway)) { return CallableFutures.failedFuture(new NullPointerException("gateway url is blank")); } return CallableFutures.asyncFailableFuture(() -> { - verifyServerConnection(session, SERVER_ID); + SkinServer.verifyServerConnection(session, SERVER_ID); String model = metadata.getOrDefault("model", "default"); Map data = image == null ? getClearData(session, type) : getUploadData(session, type, model, image); ThreadMultipartPostUpload upload = new ThreadMultipartPostUpload(this.gateway, data); @@ -137,11 +127,6 @@ public class LegacySkinServer implements SkinServer { return String.format("%s/%s/%s.png", address, path, uuid); } - private static void verifyServerConnection(Session session, String serverId) throws AuthenticationException { - MinecraftSessionService service = Minecraft.getMinecraft().getSessionService(); - service.joinServer(session.getProfile(), session.getToken(), serverId); - } - @Override public String toString() { return new ToStringBuilder(this, IndentedToStringStyle.INSTANCE) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/NetClient.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/NetClient.java new file mode 100644 index 00000000..0e91c50d --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/NetClient.java @@ -0,0 +1,102 @@ +package com.voxelmodpack.hdskins.skins; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URI; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.methods.RequestBuilder; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.HttpClients; + +/** + * Ew. Why so many builders? >.< + */ +public class NetClient { + + private final RequestBuilder rqBuilder; + + private Map headers; + + private CloseableHttpResponse response = null; + + public NetClient(String method, String uri) { + rqBuilder = RequestBuilder.create(method).setUri(uri); + } + + public NetClient putFile(String key, String contentType, URI file) { + File f = new File(file); + HttpEntity entity = MultipartEntityBuilder.create().addBinaryBody(key, f, ContentType.create(contentType), f.getName()).build(); + + rqBuilder.setEntity(entity); + + return this; + } + + public NetClient putHeaders(Map headers) { + this.headers = headers; + + return this; + } + + public boolean send() { + HttpUriRequest request = rqBuilder.build(); + + for (Map.Entry parameter : headers.entrySet()) { + request.addHeader(parameter.getKey(), parameter.getValue().toString()); + } + + try { + response = HttpClients.createSystem().execute(request); + + return getResponseCode() == HttpStatus.SC_OK; + } catch (IOException e) { } + + return false; + } + + public int getResponseCode() { + if (response == null) { + send(); + } + + return response.getStatusLine().getStatusCode(); + } + + public String getResponseText() { + if (response == null) { + if (!send()) { + return ""; + } + } + + BufferedReader reader = null; + + try { + reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + + StringBuilder builder = new StringBuilder(); + + int ch; + while ((ch = reader.read()) != -1) { + builder.append((char)ch); + } + + return builder.toString(); + } catch (IOException e) { + + } finally { + IOUtils.closeQuietly(reader); + } + + return ""; + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java index 6310aba6..dce9d855 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServer.java @@ -1,9 +1,17 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.exceptions.AuthenticationException; import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; +import com.mojang.util.UUIDTypeAdapter; +import com.mumfrey.liteloader.modconfig.Exposable; + +import net.minecraft.client.Minecraft; import net.minecraft.util.Session; import java.net.URI; @@ -11,11 +19,16 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import javax.annotation.Nullable; -public interface SkinServer { +public interface SkinServer extends Exposable { + + static final Gson gson = new GsonBuilder() + .registerTypeAdapter(UUID.class, new UUIDTypeAdapter()) + .create(); List defaultServers = Lists.newArrayList(new LegacySkinServer( "http://skins.voxelmodpack.com", @@ -27,7 +40,11 @@ public interface SkinServer { return loadProfileData(profile).map(MinecraftTexturesPayload::getTextures).orElse(Collections.emptyMap()); } - CompletableFuture uploadSkin(Session session, @Nullable URI image, - MinecraftProfileTexture.Type type, Map metadata); + CompletableFuture uploadSkin(Session session, @Nullable URI image, MinecraftProfileTexture.Type type, Map metadata); + + public static void verifyServerConnection(Session session, String serverId) throws AuthenticationException { + MinecraftSessionService service = Minecraft.getMinecraft().getSessionService(); + service.joinServer(session.getProfile(), session.getToken(), serverId); + } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServerSerializer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServerSerializer.java index 42f9139e..f4992bed 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServerSerializer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/SkinServerSerializer.java @@ -17,18 +17,21 @@ public class SkinServerSerializer implements JsonSerializer, JsonDes @Override public JsonElement serialize(SkinServer src, Type typeOfSrc, JsonSerializationContext context) { ServerType serverType = src.getClass().getAnnotation(ServerType.class); + if (serverType == null) { throw new JsonIOException("Skin server class did not have a type: " + typeOfSrc); } + JsonObject obj = context.serialize(src).getAsJsonObject(); obj.addProperty("type", serverType.value()); + return obj; } @Override public SkinServer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String type = json.getAsJsonObject().get("type").getAsString(); - Class clas = HDSkinManager.INSTANCE.getSkinServerClass(type); - return context.deserialize(json, clas); + + return context.deserialize(json, HDSkinManager.INSTANCE.getSkinServerClass(type)); } } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayloadBuilder.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayloadBuilder.java index 9bbb49b6..0e284663 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayloadBuilder.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/TexturesPayloadBuilder.java @@ -3,7 +3,9 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.collect.Maps; 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.yggdrasil.response.MinecraftTexturesPayload; import com.mojang.util.UUIDTypeAdapter; @@ -20,46 +22,26 @@ public class TexturesPayloadBuilder { private static Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create(); + public static MinecraftTexturesPayload createTexuresPayload(GameProfile profile, Map textures) { + return gson.fromJson(gson.toJson(new TexturesPayloadBuilder(profile, textures)), MinecraftTexturesPayload.class); + } + private long timestamp; + private UUID profileId; private String profileName; + private boolean isPublic; - private Map textures; - public TexturesPayloadBuilder timestamp(long time) { - this.timestamp = time; - return this; - } + private Map textures; - public TexturesPayloadBuilder profileId(UUID uuid) { - this.profileId = uuid; - return this; - } + public TexturesPayloadBuilder(GameProfile profile, Map textures) { + profileId = profile.getId(); + profileName = profile.getName(); + timestamp = System.currentTimeMillis(); - public TexturesPayloadBuilder profileName(String name) { - this.profileName = name; - return this; - } + isPublic = true; - public TexturesPayloadBuilder isPublic(boolean pub) { - this.isPublic = pub; - return this; - } - - public TexturesPayloadBuilder texture(MinecraftProfileTexture.Type type, MinecraftProfileTexture texture) { - if (textures == null) textures = Maps.newEnumMap(MinecraftProfileTexture.Type.class); - this.textures.put(type, texture); - return this; - } - - public TexturesPayloadBuilder textures(Map textures) { this.textures = textures; - return this; } - - public MinecraftTexturesPayload build() { - return gson.fromJson(gson.toJson(this), MinecraftTexturesPayload.class); - } - - } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java index ffd4c8c4..81637d1e 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/skins/ValhallaSkinServer.java @@ -1,8 +1,6 @@ package com.voxelmodpack.hdskins.skins; import com.google.common.base.Preconditions; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; import com.mojang.authlib.GameProfile; @@ -46,9 +44,6 @@ public class ValhallaSkinServer implements SkinServer { @Expose private final String address; - private final Gson gson = new GsonBuilder() - .registerTypeAdapter(UUID.class, new UUIDTypeAdapter()) - .create(); private transient String accessToken; @@ -73,8 +68,7 @@ public class ValhallaSkinServer implements SkinServer { } @Override - public CompletableFuture uploadSkin(Session session, @Nullable URI image, - MinecraftProfileTexture.Type type, Map metadata) { + public CompletableFuture uploadSkin(Session session, @Nullable URI image, MinecraftProfileTexture.Type type, Map metadata) { return CallableFutures.asyncFailableFuture(() -> { try (CloseableHttpClient client = HttpClients.createSystem()) { authorize(client, session); @@ -104,8 +98,7 @@ public class ValhallaSkinServer implements SkinServer { .build()); } - private SkinUploadResponse uploadFile(CloseableHttpClient client, File file, GameProfile profile, MinecraftProfileTexture.Type type, - Map metadata) throws IOException { + private SkinUploadResponse uploadFile(CloseableHttpClient client, File file, GameProfile profile, MinecraftProfileTexture.Type type, Map metadata) throws IOException { MultipartEntityBuilder b = MultipartEntityBuilder.create(); b.addBinaryBody("file", file, ContentType.create("image/png"), file.getName()); metadata.forEach(b::addTextBody); @@ -117,8 +110,7 @@ public class ValhallaSkinServer implements SkinServer { .build()); } - private SkinUploadResponse uploadUrl(CloseableHttpClient client, URI uri, GameProfile profile, MinecraftProfileTexture.Type type, - Map metadata) throws IOException { + private SkinUploadResponse uploadUrl(CloseableHttpClient client, URI uri, GameProfile profile, MinecraftProfileTexture.Type type, Map metadata) throws IOException { return upload(client, RequestBuilder.post() .setUri(buildUserTextureUri(profile, type))