11package me .hsgamer .bettergui .modifier ;
22
3+ import com .google .gson .Gson ;
4+ import com .google .gson .JsonObject ;
35import com .mojang .authlib .GameProfile ;
46import com .mojang .authlib .properties .Property ;
57import me .hsgamer .hscore .bukkit .item .modifier .ItemMetaModifier ;
@@ -36,7 +38,6 @@ public class SkullModifier implements ItemMetaModifier {
3638 private static final Pattern MOJANG_SHA256_APPROX = Pattern .compile ("[0-9a-z]{55,70}" );
3739 private static final SkullMeta delegateSkullMeta ;
3840 private static final SkullHandler skullHandler = getSkullHandler ();
39- private static final Map <String , GameProfile > cache = new ConcurrentHashMap <>();
4041
4142 static {
4243 ItemStack itemStack ;
@@ -61,6 +62,12 @@ private static SkullHandler getSkullHandler() {
6162 }
6263
6364 private static void setSkull (SkullMeta meta , String skull ) {
65+ Optional <byte []> base64 = Validate .getBase64 (skull );
66+ if (base64 .isPresent ()) {
67+ skullHandler .setSkullByBase64 (meta , base64 .get ());
68+ return ;
69+ }
70+
6471 Optional <URL > url = Validate .getURL (skull );
6572 if (url .isPresent ()) {
6673 skullHandler .setSkullByURL (meta , url .get ());
@@ -137,10 +144,13 @@ default void setSkullByURL(SkullMeta meta, String url) {
137144 }
138145 }
139146
147+ void setSkullByBase64 (SkullMeta meta , byte [] base64 );
148+
140149 String getSkullValue (SkullMeta meta );
141150 }
142151
143152 private static class OldSkullHandler implements SkullHandler {
153+ private final Map <String , GameProfile > cache = new ConcurrentHashMap <>();
144154 private final Method getProfileMethod ;
145155
146156 private OldSkullHandler () {
@@ -169,14 +179,7 @@ public void setSkullByPlayer(SkullMeta meta, OfflinePlayer player) {
169179 }
170180 }
171181
172- @ Override
173- public void setSkullByURL (SkullMeta meta , URL url ) {
174- GameProfile profile = cache .computeIfAbsent (url .toString (), s -> {
175- GameProfile gameProfile = new GameProfile (UUID .randomUUID (), "" );
176- gameProfile .getProperties ().put ("textures" , new Property ("textures" , Base64 .getEncoder ().encodeToString (String .format ("{textures:{SKIN:{url:\" %s\" }}}" , url ).getBytes ())));
177- return gameProfile ;
178- });
179-
182+ private void setSkullByGameProfile (SkullMeta meta , GameProfile profile ) {
180183 try {
181184 Method setProfile = meta .getClass ().getMethod ("setProfile" , GameProfile .class );
182185 setProfile .setAccessible (true );
@@ -192,6 +195,23 @@ public void setSkullByURL(SkullMeta meta, URL url) {
192195 }
193196 }
194197
198+ @ Override
199+ public void setSkullByURL (SkullMeta meta , URL url ) {
200+ GameProfile profile = cache .computeIfAbsent (url .toString (), url1 -> {
201+ GameProfile gameProfile = new GameProfile (UUID .randomUUID (), "" );
202+ gameProfile .getProperties ().put ("textures" , new Property ("textures" , Base64 .getEncoder ().encodeToString (String .format ("{textures:{SKIN:{url:\" %s\" }}}" , url1 ).getBytes ())));
203+ return gameProfile ;
204+ });
205+ setSkullByGameProfile (meta , profile );
206+ }
207+
208+ @ Override
209+ public void setSkullByBase64 (SkullMeta meta , byte [] base64 ) {
210+ GameProfile gameProfile = new GameProfile (UUID .randomUUID (), "" );
211+ gameProfile .getProperties ().put ("textures" , new Property ("textures" , Base64 .getEncoder ().encodeToString (base64 )));
212+ setSkullByGameProfile (meta , gameProfile );
213+ }
214+
195215 @ Override
196216 public String getSkullValue (SkullMeta meta ) {
197217 GameProfile profile ;
@@ -225,7 +245,7 @@ public String getSkullValue(SkullMeta meta) {
225245 }
226246
227247 private static class NewSkullHandler implements SkullHandler {
228- private final Map <URL , PlayerProfile > profileMap = new HashMap <>();
248+ private final Map <String , PlayerProfile > profileMap = new ConcurrentHashMap <>();
229249
230250 @ Override
231251 public void setSkullByPlayer (SkullMeta meta , OfflinePlayer player ) {
@@ -234,15 +254,27 @@ public void setSkullByPlayer(SkullMeta meta, OfflinePlayer player) {
234254
235255 @ Override
236256 public void setSkullByURL (SkullMeta meta , URL url ) {
237- PlayerProfile profile = profileMap .computeIfAbsent (url , url1 -> {
257+ PlayerProfile profile = profileMap .computeIfAbsent (url . toString (), u -> {
238258 PlayerProfile newProfile = Bukkit .createPlayerProfile (UUID .randomUUID (), "" );
239259 PlayerTextures textures = newProfile .getTextures ();
240- textures .setSkin (url1 );
260+ textures .setSkin (url );
241261 return newProfile ;
242262 });
243263 meta .setOwnerProfile (profile );
244264 }
245265
266+ @ Override
267+ public void setSkullByBase64 (SkullMeta meta , byte [] base64 ) {
268+ try {
269+ String decoded = new String (Base64 .getDecoder ().decode (base64 ));
270+ JsonObject json = new Gson ().fromJson (decoded , JsonObject .class );
271+ String url = json .getAsJsonObject ("textures" ).getAsJsonObject ("SKIN" ).get ("url" ).getAsString ();
272+ setSkullByURL (meta , url );
273+ } catch (Exception e ) {
274+ throw new RuntimeException (e );
275+ }
276+ }
277+
246278 @ Override
247279 public String getSkullValue (SkullMeta meta ) {
248280 PlayerProfile profile = meta .getOwnerProfile ();
0 commit comments