Upgrade skull saving

This commit is contained in:
fullwall 2022-12-27 13:07:12 +08:00
parent 7577a049d9
commit 4590193673
9 changed files with 60 additions and 131 deletions

View File

@ -111,10 +111,9 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
private final SkullMetaProvider skullMetaProvider = new SkullMetaProvider() {
@Override
public String getTexture(SkullMeta meta) {
if (NMS.getProfile(meta) == null)
return null;
return Iterables.getFirst(NMS.getProfile(meta).getProperties().get("textures"), new Property("", ""))
.getValue();
GameProfile profile = NMS.getProfile(meta);
return profile == null ? null
: Iterables.getFirst(profile.getProperties().get("textures"), new Property("", "")).getValue();
}
@Override

View File

@ -1,11 +1,8 @@
package net.citizensnpcs;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -54,7 +51,6 @@ import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitRunnable;
@ -64,16 +60,12 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.ai.event.NavigationBeginEvent;
import net.citizensnpcs.api.ai.event.NavigationCompleteEvent;
import net.citizensnpcs.api.event.CitizensDeserialiseMetaEvent;
import net.citizensnpcs.api.event.CitizensPreReloadEvent;
import net.citizensnpcs.api.event.CitizensSerialiseMetaEvent;
import net.citizensnpcs.api.event.CommandSenderCreateNPCEvent;
import net.citizensnpcs.api.event.DespawnReason;
import net.citizensnpcs.api.event.EntityTargetNPCEvent;
@ -96,9 +88,7 @@ import net.citizensnpcs.api.event.SpawnReason;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.SpigotUtil;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.npc.skin.SkinUpdateTracker;
import net.citizensnpcs.trait.ClickRedirectTrait;
@ -337,61 +327,6 @@ public class EventListen implements Listener {
Bukkit.getPluginManager().callEvent(new EntityTargetNPCEvent(event, npc));
}
@EventHandler
public void onMetaDeserialise(CitizensDeserialiseMetaEvent event) {
if (event.getKey().keyExists("skull")) {
String owner = event.getKey().getString("skull.owner", "");
UUID uuid = event.getKey().keyExists("skull.uuid") ? UUID.fromString(event.getKey().getString("skull.uuid"))
: null;
if (owner.isEmpty() && uuid == null) {
return;
}
GameProfile profile = new GameProfile(uuid, owner);
for (DataKey sub : event.getKey().getRelative("skull.properties").getSubKeys()) {
String propertyName = sub.name();
for (DataKey property : sub.getIntegerSubKeys()) {
profile.getProperties().put(propertyName,
new Property(property.getString("name"), property.getString("value"),
property.keyExists("signature") ? property.getString("signature") : null));
}
}
Material mat = SpigotUtil.isUsing1_13API() ? Material.SKELETON_SKULL : Material.valueOf("SKULL_ITEM");
SkullMeta meta = (SkullMeta) Bukkit.getItemFactory().getItemMeta(mat);
NMS.setProfile(meta, profile);
event.getItemStack().setItemMeta(meta);
}
}
@EventHandler
public void onMetaSerialise(CitizensSerialiseMetaEvent event) {
if (!(event.getMeta() instanceof SkullMeta))
return;
SkullMeta meta = (SkullMeta) event.getMeta();
GameProfile profile = NMS.getProfile(meta);
if (profile == null)
return;
if (profile.getName() != null) {
event.getKey().setString("skull.owner", profile.getName());
}
if (profile.getId() != null) {
event.getKey().setString("skull.uuid", profile.getId().toString());
}
if (profile.getProperties() != null) {
for (Entry<String, Collection<Property>> entry : profile.getProperties().asMap().entrySet()) {
DataKey relative = event.getKey().getRelative("skull.properties." + entry.getKey());
int i = 0;
for (Property value : entry.getValue()) {
relative.getRelative(i).setString("name", value.getName());
if (value.getSignature() != null) {
relative.getRelative(i).setString("signature", value.getSignature());
}
relative.getRelative(i).setString("value", value.getValue());
i++;
}
}
}
}
@EventHandler
public void onNavigationBegin(NavigationBeginEvent event) {
skinUpdateTracker.onNPCNavigationBegin(event.getNPC());
@ -793,5 +728,6 @@ public class EventListen implements Listener {
}
}
private static boolean SUPPORT_OWNING_PLAYER = true;
private static boolean SUPPORT_STOP_USE_ITEM = true;
}

View File

@ -1289,6 +1289,7 @@ public class NMSImpl implements NMSBridge {
return;
}
}
try {
SKULL_PROFILE_FIELD.set(meta, profile);
} catch (Exception e) {

View File

@ -1326,15 +1326,16 @@ public class NMSImpl implements NMSBridge {
@Override
public void setProfile(SkullMeta meta, GameProfile profile) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SET_PROFILE_METHOD == null) {
SET_PROFILE_METHOD = NMS.getMethodHandle(meta.getClass(), "setProfile", true, GameProfile.class);
if (SET_PROFILE_METHOD == null) {
return;
}
}
try {
SKULL_PROFILE_FIELD.set(meta, profile);
} catch (Exception e) {
SET_PROFILE_METHOD.invoke(meta, profile);
} catch (Throwable t) {
t.printStackTrace();
}
}
@ -2254,6 +2255,7 @@ public class NMSImpl implements NMSBridge {
true, EntityPlayer.class, boolean.class);
private static final Map<Class<?>, EntityTypes<?>> CITIZENS_ENTITY_TYPES = Maps.newHashMap();
private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle");
private static final float DEFAULT_SPEED = 1F;
private static final MethodHandle ENDERDRAGON_BATTLE_FIELD = NMS.getGetter(EntityEnderDragon.class, "bN");
@ -2296,6 +2298,7 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle REPAIR_INVENTORY = NMS.getGetter(ContainerAnvil.class, "repairInventory");
private static final MethodHandle RESULT_INVENTORY = NMS.getGetter(ContainerAnvil.class, "resultInventory");
private static final MethodHandle SET_POSE = NMS.getMethodHandle(Entity.class, "setPose", true, EntityPose.class);
private static MethodHandle SET_PROFILE_METHOD;
private static final MethodHandle SIZE_FIELD_GETTER = NMS.getGetter(Entity.class, "size");
private static final MethodHandle SIZE_FIELD_SETTER = NMS.getSetter(Entity.class, "size");

View File

@ -1363,15 +1363,16 @@ public class NMSImpl implements NMSBridge {
@Override
public void setProfile(SkullMeta meta, GameProfile profile) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SET_PROFILE_METHOD == null) {
SET_PROFILE_METHOD = NMS.getMethodHandle(meta.getClass(), "setProfile", true, GameProfile.class);
if (SET_PROFILE_METHOD == null) {
return;
}
}
try {
SKULL_PROFILE_FIELD.set(meta, profile);
} catch (Exception e) {
SET_PROFILE_METHOD.invoke(meta, profile);
} catch (Throwable t) {
t.printStackTrace();
}
}
@ -2231,6 +2232,7 @@ public class NMSImpl implements NMSBridge {
EntityType.SHULKER, EntityType.PHANTOM);
private static final MethodHandle BEHAVIOR_MAP = NMS.getGetter(BehaviorController.class, "e");
private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity");
private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(PlayerChunkMap.class, "a",
true, EntityPlayer.class, boolean.class);
@ -2275,6 +2277,7 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle PUFFERFISH_D = NMS.getSetter(EntityPufferFish.class, "d");
private static final MethodHandle RABBIT_DATAWATCHER_FIELD = NMS.getGetter(EntityRabbit.class, "bo");
private static final Random RANDOM = Util.getFastRandom();
private static MethodHandle SET_PROFILE_METHOD;
private static final MethodHandle SIZE_FIELD_GETTER = NMS.getGetter(Entity.class, "size");
private static final MethodHandle SIZE_FIELD_SETTER = NMS.getSetter(Entity.class, "size");
private static Field SKULL_PROFILE_FIELD;

View File

@ -1358,15 +1358,16 @@ public class NMSImpl implements NMSBridge {
@Override
public void setProfile(SkullMeta meta, GameProfile profile) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SET_PROFILE_METHOD == null) {
SET_PROFILE_METHOD = NMS.getMethodHandle(meta.getClass(), "setProfile", true, GameProfile.class);
if (SET_PROFILE_METHOD == null) {
return;
}
}
try {
SKULL_PROFILE_FIELD.set(meta, profile);
} catch (Exception e) {
SET_PROFILE_METHOD.invoke(meta, profile);
} catch (Throwable t) {
t.printStackTrace();
}
}
@ -2224,6 +2225,7 @@ public class NMSImpl implements NMSBridge {
EntityType.SHULKER, EntityType.PHANTOM);
private static final MethodHandle BEHAVIOR_MAP = NMS.getGetter(Brain.class, "f");
private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity");
private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class, "a", true,
ServerPlayer.class, boolean.class);
@ -2262,6 +2264,7 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle PUFFERFISH_D = NMS.getSetter(Pufferfish.class, "bT");
private static EntityDataAccessor<Integer> RABBIT_TYPE_DATAWATCHER = null;
private static final Random RANDOM = Util.getFastRandom();
private static MethodHandle SET_PROFILE_METHOD;
private static final MethodHandle SIZE_FIELD_GETTER = NMS.getFirstGetter(Entity.class, EntityDimensions.class);
private static final MethodHandle SIZE_FIELD_SETTER = NMS.getFirstSetter(Entity.class, EntityDimensions.class);
private static Field SKULL_PROFILE_FIELD;

View File

@ -1,7 +1,6 @@
package net.citizensnpcs.nms.v1_18_R2.util;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.net.SocketAddress;
import java.net.URL;
import java.util.ArrayList;
@ -594,15 +593,17 @@ public class NMSImpl implements NMSBridge {
@Override
public GameProfile getProfile(SkullMeta meta) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SKULL_META_PROFILE == null) {
SKULL_META_PROFILE = NMS.getFirstGetter(meta.getClass(), GameProfile.class);
if (SKULL_META_PROFILE == null) {
return null;
}
}
try {
return (GameProfile) SKULL_PROFILE_FIELD.get(meta);
} catch (Exception e) {
return (GameProfile) SKULL_META_PROFILE.invoke(meta);
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}
@ -1365,15 +1366,16 @@ public class NMSImpl implements NMSBridge {
@Override
public void setProfile(SkullMeta meta, GameProfile profile) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SET_PROFILE_METHOD == null) {
SET_PROFILE_METHOD = NMS.getMethodHandle(meta.getClass(), "setProfile", true, GameProfile.class);
if (SET_PROFILE_METHOD == null) {
return;
}
}
try {
SKULL_PROFILE_FIELD.set(meta, profile);
} catch (Exception e) {
SET_PROFILE_METHOD.invoke(meta, profile);
} catch (Throwable t) {
t.printStackTrace();
}
}
@ -2260,6 +2262,7 @@ public class NMSImpl implements NMSBridge {
}
private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFinalSetter(ServerPlayer.class, "cr");
private static final Set<EntityType> BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.BEE,
EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT,
EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST,
@ -2310,9 +2313,10 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle PUFFERFISH_D = NMS.getSetter(Pufferfish.class, "bW");
private static EntityDataAccessor<Integer> RABBIT_TYPE_DATAWATCHER = null;
private static final Random RANDOM = Util.getFastRandom();
private static MethodHandle SET_PROFILE_METHOD;
private static final MethodHandle SIZE_FIELD_GETTER = NMS.getFirstGetter(Entity.class, EntityDimensions.class);
private static final MethodHandle SIZE_FIELD_SETTER = NMS.getFirstSetter(Entity.class, EntityDimensions.class);
private static Field SKULL_PROFILE_FIELD;
private static MethodHandle SKULL_META_PROFILE;
private static MethodHandle TEAM_FIELD;
static {
try {

View File

@ -16,10 +16,6 @@
<id>viaversion-repo</id>
<url>https://repo.viaversion.com</url>
</repository>
<repository>
<id>opencollab-snapshot</id>
<url>https://repo.opencollab.dev/maven-snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
@ -41,12 +37,6 @@
<version>4.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.floodgate</groupId>
<artifactId>api</artifactId>
<version>2.2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean package install</defaultGoal>

View File

@ -1,7 +1,6 @@
package net.citizensnpcs.nms.v1_19_R2.util;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.net.SocketAddress;
import java.net.URL;
import java.util.ArrayList;
@ -51,7 +50,6 @@ import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.plugin.PluginLoadOrder;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.Vector;
import org.geysermc.floodgate.api.FloodgateApi;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
@ -614,15 +612,16 @@ public class NMSImpl implements NMSBridge {
@Override
public GameProfile getProfile(SkullMeta meta) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SKULL_META_PROFILE == null) {
SKULL_META_PROFILE = NMS.getFirstGetter(meta.getClass(), GameProfile.class);
if (SKULL_META_PROFILE == null) {
return null;
}
}
try {
return (GameProfile) SKULL_PROFILE_FIELD.get(meta);
} catch (Exception e) {
return (GameProfile) SKULL_META_PROFILE.invoke(meta);
} catch (Throwable e) {
e.printStackTrace();
return null;
}
@ -866,13 +865,6 @@ public class NMSImpl implements NMSBridge {
} catch (Throwable t) {
VIA_ENABLED = false;
}
try {
FloodgateApi.getInstance();
FLOODGATE_ENABLED = true;
} catch (Throwable t) {
FLOODGATE_ENABLED = false;
}
}
private void loadEntityTypes() {
@ -1264,10 +1256,6 @@ public class NMSImpl implements NMSBridge {
NMSImpl.sendPacket(recipient, packet);
if (FLOODGATE_ENABLED == true) {
return FloodgateApi.getInstance().isFloodgatePlayer(recipient.getUniqueId());
}
if (VIA_ENABLED == true) {
int version = Via.getAPI().getPlayerVersion(recipient);
return version < 761;
@ -1463,15 +1451,16 @@ public class NMSImpl implements NMSBridge {
@Override
public void setProfile(SkullMeta meta, GameProfile profile) {
if (SKULL_PROFILE_FIELD == null) {
SKULL_PROFILE_FIELD = NMS.getField(meta.getClass(), "profile", false);
if (SKULL_PROFILE_FIELD == null) {
if (SET_PROFILE_METHOD == null) {
SET_PROFILE_METHOD = NMS.getMethodHandle(meta.getClass(), "setProfile", true, GameProfile.class);
if (SET_PROFILE_METHOD == null) {
return;
}
}
try {
SKULL_PROFILE_FIELD.set(meta, profile);
} catch (Exception e) {
SET_PROFILE_METHOD.invoke(meta, profile);
} catch (Throwable t) {
t.printStackTrace();
}
}
@ -2378,6 +2367,7 @@ public class NMSImpl implements NMSBridge {
EntityType.SHULKER, EntityType.PHANTOM);
private static final MethodHandle BEHAVIOR_TREE_MAP = NMS.getGetter(Brain.class, "f");
private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity");
private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class, "a", true,
ServerPlayer.class, boolean.class);
@ -2398,7 +2388,6 @@ public class NMSImpl implements NMSBridge {
true, PortalInfo.class, ServerLevel.class);
// first int of block of 4
private static final MethodHandle FISHING_HOOK_LIFE = NMS.getSetter(FishingHook.class, "aq");
private static Boolean FLOODGATE_ENABLED = null;
private static final MethodHandle FLYING_MOVECONTROL_FLOAT_GETTER = NMS.getFirstGetter(FlyingMoveControl.class,
boolean.class);
private static final MethodHandle FLYING_MOVECONTROL_FLOAT_SETTER = NMS.getFirstSetter(FlyingMoveControl.class,
@ -2427,9 +2416,10 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle PUFFERFISH_D = NMS.getSetter(Pufferfish.class, "bY");
private static EntityDataAccessor<Integer> RABBIT_TYPE_DATAWATCHER = null;
private static final Random RANDOM = Util.getFastRandom();
private static MethodHandle SET_PROFILE_METHOD;
private static final MethodHandle SIZE_FIELD_GETTER = NMS.getFirstGetter(Entity.class, EntityDimensions.class);
private static final MethodHandle SIZE_FIELD_SETTER = NMS.getFirstSetter(Entity.class, EntityDimensions.class);
private static Field SKULL_PROFILE_FIELD;
private static MethodHandle SKULL_META_PROFILE;
private static MethodHandle TEAM_FIELD;
private static Boolean VIA_ENABLED = null;