Skip to content

Commit 9e89ca5

Browse files
committed
issue-1 fix GameProfile Skulls
Signed-off-by: Stanislav Panchenko <[email protected]>
1 parent 2c4e974 commit 9e89ca5

File tree

4 files changed

+69
-73
lines changed

4 files changed

+69
-73
lines changed

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# AbstractMenus
22

33
<a href="https://github.com/AbstractMenus/plugin/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-red.svg" alt="license"/></a>
4-
<a href="https://github.com/AbstractMenus/plugin/blob/master/LICENSE"><img src="https://img.shields.io/badge/version-1.17.4--beta-blue" alt="license"/></a>
4+
<a href="https://github.com/AbstractMenus/plugin/blob/master/LICENSE"><img src="https://img.shields.io/badge/version-1.17.5--beta-blue" alt="license"/></a>
55

66
AbstractMenus is a GUI plugin for SpigotMC servers that allows server owners and developers to create custom GUIs with ease. The plugin is designed to be user-friendly and easy to use, with a wide range of features and options to customize the GUIs to your liking. The plugin is also highly customizable, allowing you to create GUIs that fit your server's theme and style.
77

@@ -10,6 +10,7 @@ This allows us to keep the code clean without using a bunch of wrappers for back
1010

1111
## 🔭Table of contents
1212
- [Links](#links)
13+
- [Supported versions](#supported-versions)
1314
- [Installation and build](#installation-and-build)
1415
- [Contributions and feedback](#contributions-and-feedback)
1516
- [Licence](#licence)
@@ -20,6 +21,11 @@ This allows us to keep the code clean without using a bunch of wrappers for back
2021
- [Discord](https://discord.gg/kt4P9Cgw)
2122
- [Documentation](https://abstractmenus.github.io/docs/index.html)
2223

24+
## 💊Supported versions
25+
- ❓1.21.3
26+
- ✅1.21.1
27+
- ❌<1.21.x
28+
2329
## Installation and build
2430
Requirements:
2531

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ java {
4040

4141

4242
group 'ru.abstractmenus'
43-
version '1.17.4-beta'
43+
version '1.17.5-beta'
4444

4545
repositories {
4646
mavenLocal()
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package ru.abstractmenus.services;
22

3-
import com.mojang.authlib.GameProfile;
4-
import com.mojang.authlib.properties.Property;
3+
import com.destroystokyo.paper.profile.PlayerProfile;
4+
import org.bukkit.Bukkit;
55
import org.bukkit.entity.Player;
66
import org.bukkit.event.EventHandler;
77
import org.bukkit.event.EventPriority;
88
import org.bukkit.event.Listener;
99
import org.bukkit.event.player.PlayerJoinEvent;
10-
import ru.abstractmenus.api.Logger;
11-
import ru.abstractmenus.util.bukkit.MojangApi;
12-
import ru.abstractmenus.util.bukkit.BukkitTasks;
10+
import org.bukkit.profile.PlayerTextures;
1311
import ru.abstractmenus.util.StringUtil;
12+
import ru.abstractmenus.util.bukkit.BukkitTasks;
1413

15-
import java.lang.reflect.Method;
16-
import java.util.Collection;
1714
import java.util.HashMap;
1815
import java.util.Map;
1916
import java.util.UUID;
@@ -22,9 +19,9 @@ public final class ProfileStorage implements Listener {
2219

2320
private static ProfileStorage instance;
2421

25-
public static final GameProfile DEF_PROFILE = new GameProfile(UUID.randomUUID(), StringUtil.generateRandom(16));
22+
public static final PlayerProfile DEF_PROFILE = Bukkit.createProfile(UUID.randomUUID(), StringUtil.generateRandom(16));
2623

27-
private final Map<String, GameProfile> profiles = new HashMap<>();
24+
private final Map<String, PlayerProfile> profiles = new HashMap<>();
2825

2926
public ProfileStorage() {
3027
instance = this;
@@ -36,11 +33,11 @@ public ProfileStorage() {
3633
* @param playerName Player name
3734
* @return Found texture or null
3835
*/
39-
public GameProfile getProfile(String playerName) {
36+
public PlayerProfile getProfile(String playerName) {
4037
return profiles.get(playerName.toLowerCase());
4138
}
4239

43-
public void add(String playerName, GameProfile profile) {
40+
public void add(String playerName, PlayerProfile profile) {
4441
profiles.put(playerName.toLowerCase(), profile);
4542
}
4643

@@ -55,31 +52,23 @@ public static ProfileStorage instance() {
5552
@EventHandler(priority = EventPriority.MONITOR)
5653
public void onPlayerJoin(PlayerJoinEvent event) {
5754
BukkitTasks.runTaskAsync(() -> {
58-
GameProfile profile = fetchProfile(event.getPlayer());
59-
60-
add(event.getPlayer().getName(), profile);
61-
62-
if (profile != null) {
63-
Collection<Property> texture = profile.getProperties().get("textures");
55+
Player player = event.getPlayer();
56+
PlayerProfile profile = player.getPlayerProfile();
6457

65-
if (texture == null || texture.isEmpty())
66-
profile = MojangApi.loadProfileWithSkin(event.getPlayer().getName());
58+
try {
59+
if (!profile.isComplete()) {
60+
profile.complete(true);
61+
}
6762

68-
if (profile != null) {
69-
add(event.getPlayer().getName(), profile);
63+
PlayerTextures textures = profile.getTextures();
64+
if (textures.getSkin() == null) {
65+
add(player.getName(), DEF_PROFILE);
66+
} else {
67+
add(player.getName(), profile);
7068
}
69+
} catch (Exception e) {
70+
add(player.getName(), DEF_PROFILE);
7171
}
7272
});
7373
}
74-
75-
private GameProfile fetchProfile(Player player) {
76-
try {
77-
Method method = player.getClass().getMethod("getProfile");
78-
return (GameProfile) method.invoke(player);
79-
} catch (Throwable t) {
80-
Logger.warning("Cannot fetch game profile: " + t.getMessage());
81-
return null;
82-
}
83-
}
84-
8574
}
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,79 @@
11
package ru.abstractmenus.util.bukkit;
22

3-
import com.mojang.authlib.GameProfile;
3+
import com.destroystokyo.paper.profile.PlayerProfile;
4+
import org.bukkit.Bukkit;
45
import org.bukkit.inventory.ItemStack;
56
import org.bukkit.inventory.meta.SkullMeta;
6-
import ru.abstractmenus.api.Logger;
7+
import org.bukkit.profile.PlayerTextures;
78
import ru.abstractmenus.services.ProfileStorage;
89

9-
import java.lang.reflect.Field;
10-
import java.lang.reflect.InvocationTargetException;
11-
import java.lang.reflect.Method;
10+
import java.net.MalformedURLException;
11+
import java.net.URI;
12+
import java.net.URISyntaxException;
13+
import java.util.UUID;
1214

1315
public final class Skulls {
1416

1517
private Skulls() {
1618
}
1719

1820
public static ItemStack getCustomSkull(String url) {
19-
GameProfile profile = MojangApi.createProfile(url);
20-
return getCustomSkull(profile);
21-
}
22-
23-
public static ItemStack getCustomSkull(GameProfile profile) {
2421
ItemStack head = createSkullItem();
25-
26-
if (profile == null) return head;
22+
if (url == null || url.isEmpty()) {
23+
return head;
24+
}
2725

2826
SkullMeta headMeta = (SkullMeta) head.getItemMeta();
27+
if (headMeta == null) {
28+
return null;
29+
}
2930

30-
if (headMeta == null) return null;
31-
32-
Field profileField;
31+
PlayerProfile profile = Bukkit.createProfile(UUID.randomUUID());
3332

3433
try {
35-
Method method = headMeta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
36-
method.setAccessible(true);
37-
method.invoke(headMeta, profile);
38-
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
39-
try {
40-
profileField = headMeta.getClass().getDeclaredField("profile");
41-
profileField.setAccessible(true);
42-
profileField.set(headMeta, profile);
43-
} catch (NoSuchFieldException | IllegalAccessException ex2) {
44-
ex2.printStackTrace();
45-
}
34+
PlayerTextures textures = profile.getTextures();
35+
textures.setSkin(new URI(url).toURL());
36+
profile.setTextures(textures);
37+
38+
headMeta.setPlayerProfile(profile);
39+
head.setItemMeta(headMeta);
40+
} catch (MalformedURLException | URISyntaxException e) {
41+
throw new RuntimeException(String.format("Bad URL [%s] for texture [%s]", url, profile.getTextures()), e);
4642
}
4743

44+
return head;
45+
}
46+
47+
public static ItemStack getCustomSkull(PlayerProfile profile) {
48+
ItemStack head = createSkullItem();
49+
if (profile == null) return head;
50+
51+
SkullMeta headMeta = (SkullMeta) head.getItemMeta();
52+
if (headMeta == null) return null;
53+
54+
headMeta.setPlayerProfile(profile);
4855
head.setItemMeta(headMeta);
4956

5057
return head;
5158
}
5259

5360
public static ItemStack getPlayerSkull(String playerName) {
54-
GameProfile profile = ProfileStorage.instance().getProfile(playerName);
61+
PlayerProfile profile = ProfileStorage.instance().getProfile(playerName);
5562

5663
if (profile == null) {
57-
Logger.info("Profile '" + playerName + "' not found. Trying to load ...");
58-
59-
profile = MojangApi.loadProfileWithSkin(playerName);
60-
61-
if (profile == null)
64+
profile = Bukkit.createProfile(null, playerName);
65+
try {
66+
profile.complete(true);
67+
} catch (Exception e) {
6268
profile = ProfileStorage.DEF_PROFILE;
63-
69+
}
6470
ProfileStorage.instance().add(playerName, profile);
6571
}
6672

6773
return getCustomSkull(profile);
6874
}
6975

7076
public static ItemStack createSkullItem() {
71-
try {
72-
return new ItemStack(ItemUtil.getHeadMaterial(), 1, (short) 3);
73-
} catch (Throwable t) {
74-
return new ItemStack(ItemUtil.getHeadMaterial());
75-
}
77+
return new ItemStack(ItemUtil.getHeadMaterial());
7678
}
77-
7879
}

0 commit comments

Comments
 (0)