HumanSkinLoader.java 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package me.km.entities;
  2. import java.net.HttpURLConnection;
  3. import java.net.URL;
  4. import java.util.HashMap;
  5. import java.util.HashSet;
  6. import java.util.function.Consumer;
  7. import net.minecraft.client.Minecraft;
  8. import net.minecraft.client.renderer.texture.DynamicTexture;
  9. import net.minecraft.client.renderer.texture.NativeImage;
  10. import net.minecraft.client.renderer.texture.TextureManager;
  11. import net.minecraft.util.ResourceLocation;
  12. import net.minecraftforge.api.distmarker.Dist;
  13. import net.minecraftforge.api.distmarker.OnlyIn;
  14. import org.apache.logging.log4j.LogManager;
  15. @OnlyIn(Dist.CLIENT)
  16. public class HumanSkinLoader
  17. {
  18. public final static HumanSkinLoader INSTANCE = new HumanSkinLoader();
  19. private static final ResourceLocation TEXTURE_STEVE = new ResourceLocation("textures/entity/steve.png");
  20. private final HashMap<String, ResourceLocation> skins = new HashMap<>();
  21. private final HashSet<String> loading = new HashSet<>();
  22. private final TextureManager manager = Minecraft.getInstance().getRenderManager().textureManager;
  23. private HumanSkinLoader()
  24. {
  25. }
  26. public ResourceLocation getTexture(String name)
  27. {
  28. ResourceLocation loc = skins.get(name);
  29. if(loc != null)
  30. {
  31. return loc;
  32. }
  33. if(loading.add(name))
  34. {
  35. downloadSkin(name, image ->
  36. {
  37. ResourceLocation rloc = manager.getDynamicTextureLocation("skin_" + name.toLowerCase(), new DynamicTexture(image));
  38. skins.put(name, rloc);
  39. loading.remove(name);
  40. });
  41. }
  42. return TEXTURE_STEVE;
  43. }
  44. private void downloadSkin(String name, Consumer<NativeImage> delayed)
  45. {
  46. new Thread(() ->
  47. {
  48. HttpURLConnection httpurlconnection = null;
  49. try
  50. {
  51. URL url = new URL("http://skins.hammerle.me/skins/" + name + ".png");
  52. httpurlconnection = (HttpURLConnection) url.openConnection(Minecraft.getInstance().getProxy());
  53. httpurlconnection.setDoInput(true);
  54. httpurlconnection.setDoOutput(false);
  55. httpurlconnection.connect();
  56. int code = httpurlconnection.getResponseCode();
  57. if(code != 200)
  58. {
  59. // Failed own server, trying crafatar
  60. httpurlconnection.disconnect();
  61. httpurlconnection = (HttpURLConnection) (new URL("https://crafatar.com/skins/" + name + ".png"))
  62. .openConnection(Minecraft.getInstance().getProxy());
  63. httpurlconnection.setDoInput(true);
  64. httpurlconnection.setDoOutput(false);
  65. httpurlconnection.connect();
  66. code = httpurlconnection.getResponseCode();
  67. if(code != 200)
  68. {
  69. LogManager.getLogger().warn("Server response code did return " + code + ", skin servers might be down.");
  70. return;
  71. }
  72. }
  73. NativeImage image = convert(NativeImage.read(httpurlconnection.getInputStream()));
  74. Minecraft.getInstance().enqueue(() -> delayed.accept(image));
  75. }
  76. catch(Exception ex)
  77. {
  78. LogManager.getLogger().warn("Error occurred when downloading skin, however, skin servers seem to be up.");
  79. }
  80. finally
  81. {
  82. if(httpurlconnection != null)
  83. {
  84. httpurlconnection.disconnect();
  85. }
  86. }
  87. }).start();
  88. }
  89. private NativeImage convert(NativeImage old)
  90. {
  91. boolean flag = old.getHeight() == 32;
  92. if (flag)
  93. {
  94. NativeImage nativeimage = new NativeImage(64, 64, true);
  95. nativeimage.copyImageData(old);
  96. old.close();
  97. old = nativeimage;
  98. nativeimage.fillAreaRGBA(0, 32, 64, 32, 0);
  99. nativeimage.copyAreaRGBA(4, 16, 16, 32, 4, 4, true, false);
  100. nativeimage.copyAreaRGBA(8, 16, 16, 32, 4, 4, true, false);
  101. nativeimage.copyAreaRGBA(0, 20, 24, 32, 4, 12, true, false);
  102. nativeimage.copyAreaRGBA(4, 20, 16, 32, 4, 12, true, false);
  103. nativeimage.copyAreaRGBA(8, 20, 8, 32, 4, 12, true, false);
  104. nativeimage.copyAreaRGBA(12, 20, 16, 32, 4, 12, true, false);
  105. nativeimage.copyAreaRGBA(44, 16, -8, 32, 4, 4, true, false);
  106. nativeimage.copyAreaRGBA(48, 16, -8, 32, 4, 4, true, false);
  107. nativeimage.copyAreaRGBA(40, 20, 0, 32, 4, 12, true, false);
  108. nativeimage.copyAreaRGBA(44, 20, -8, 32, 4, 12, true, false);
  109. nativeimage.copyAreaRGBA(48, 20, -16, 32, 4, 12, true, false);
  110. nativeimage.copyAreaRGBA(52, 20, -8, 32, 4, 12, true, false);
  111. }
  112. setAreaOpaque(old, 0, 0, 32, 16);
  113. if (flag)
  114. {
  115. setAreaTransparent(old, 32, 0, 64, 32);
  116. }
  117. setAreaOpaque(old, 0, 16, 64, 32);
  118. setAreaOpaque(old, 16, 48, 48, 64);
  119. return old;
  120. }
  121. private static void setAreaTransparent(NativeImage image, int x, int y, int width, int height)
  122. {
  123. for(int i = x; i < width; ++i)
  124. {
  125. for(int j = y; j < height; ++j)
  126. {
  127. int k = image.getPixelRGBA(i, j);
  128. if((k >> 24 & 255) < 128)
  129. {
  130. return;
  131. }
  132. }
  133. }
  134. for(int l = x; l < width; ++l)
  135. {
  136. for(int i1 = y; i1 < height; ++i1)
  137. {
  138. image.setPixelRGBA(l, i1, image.getPixelRGBA(l, i1) & 16777215);
  139. }
  140. }
  141. }
  142. private static void setAreaOpaque(NativeImage image, int x, int y, int width, int height)
  143. {
  144. for(int i = x; i < width; ++i)
  145. {
  146. for(int j = y; j < height; ++j)
  147. {
  148. image.setPixelRGBA(i, j, image.getPixelRGBA(i, j) | -16777216);
  149. }
  150. }
  151. }
  152. }