Add workaround for spigot disable issue

This commit is contained in:
fullwall 2021-07-14 21:23:55 +08:00
parent 65f5d870db
commit c3a70e27ed
5 changed files with 117 additions and 13 deletions

View File

@ -76,8 +76,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
private final List<NPCRegistry> anonymousRegistries = Lists.newArrayList();
private final List<NPCRegistry> citizensBackedRegistries = Lists.newArrayList();
private final CommandManager commands = new CommandManager();
private boolean compatible;
private Settings config;
private boolean loaded;
private CitizensNPCRegistry npcRegistry;
private NPCDataStore saves;
private NPCSelector selector;
@ -145,6 +145,19 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
}
}
public void disable() {
if (loaded) {
Bukkit.getPluginManager().callEvent(new CitizensDisableEvent());
Editor.leaveAll();
despawnNPCs(true);
npcRegistry = null;
NMS.shutdown();
loaded = false;
}
CitizensAPI.shutdown();
}
private void enableSubPlugins() {
File root = new File(getDataFolder(), Setting.SUBPLUGIN_FOLDER.asString());
if (!root.exists() || !root.isDirectory())
@ -277,16 +290,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
@Override
public void onDisable() {
Bukkit.getPluginManager().callEvent(new CitizensDisableEvent());
Editor.leaveAll();
if (compatible) {
despawnNPCs(true);
npcRegistry = null;
NMS.shutdown();
}
CitizensAPI.shutdown();
disable();
}
@Override
@ -296,11 +300,11 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
setupTranslator();
// Disable if the server is not using the compatible Minecraft version
String mcVersion = Util.getMinecraftRevision();
compatible = true;
loaded = true;
try {
NMS.loadBridge(mcVersion);
} catch (Exception e) {
compatible = false;
loaded = false;
if (Messaging.isDebugging()) {
e.printStackTrace();
}

View File

@ -1,5 +1,6 @@
package net.citizensnpcs;
import java.lang.invoke.MethodHandle;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -42,6 +43,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
@ -51,6 +53,7 @@ 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.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import com.google.common.base.Predicates;
@ -228,6 +231,28 @@ public class EventListen implements Listener {
checkCreationEvent(event);
}
@EventHandler
public void onDisable(PluginDisableEvent event) {
// hack: Spigot now unloads plugin classes on disable in reverse order so prefer unloading at the start of
// plugin disable cycle
if (event.getPlugin() instanceof JavaPlugin) {
try {
MethodHandle field = CLASSES_FIELD == null
? CLASSES_FIELD = NMS.getGetter(event.getPlugin().getPluginLoader().getClass(), "classes")
: CLASSES_FIELD;
Map<String, Class<?>> classes = (Map<String, Class<?>>) field
.invoke(event.getPlugin().getPluginLoader());
if (classes.containsKey("net.citizensnpcs.api.CitizensAPI")) {
CitizensAPI.getPlugin().onDisable();
}
} catch (Throwable e) {
CitizensAPI.getPlugin().onDisable();
}
} else {
CitizensAPI.getPlugin().onDisable();
}
}
/*
* Entity events
*/
@ -717,4 +742,6 @@ public class EventListen implements Listener {
}
return npc.spawn(spawn, SpawnReason.CHUNK_LOAD);
}
private static MethodHandle CLASSES_FIELD = null;
}

View File

@ -114,6 +114,8 @@ import net.citizensnpcs.trait.RabbitType;
import net.citizensnpcs.trait.ScoreboardTrait;
import net.citizensnpcs.trait.ScriptTrait;
import net.citizensnpcs.trait.SheepTrait;
import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.trait.ShopTrait.NPCShop;
import net.citizensnpcs.trait.SkinLayers;
import net.citizensnpcs.trait.SkinLayers.Layer;
import net.citizensnpcs.trait.SkinTrait;
@ -1919,6 +1921,29 @@ public class NPCCommands {
}
}
@Command(
aliases = { "npc" },
usage = "shop (name) (editr)",
desc = "NPC shop edit/show",
modifiers = { "shop" },
min = 1,
max = 3,
permission = "citizens.npc.shop")
public void shop(CommandContext args, Player sender, NPC npc) throws CommandException {
ShopTrait trait = npc.getOrAddTrait(ShopTrait.class);
if (args.argsLength() > 1) {
NPCShop shop = trait.getShop(args.getString(1));
if (args.getString(1).equalsIgnoreCase("edit")) {
} else if (args.getString(1).equalsIgnoreCase("show") && args.argsLength() == 3) {
shop.display(sender);
} else {
throw new CommandUsageException();
}
} else {
trait.getDefaultShop().display(sender);
}
}
@Command(
aliases = { "npc" },
usage = "skin (-c -l(atest)) [name] (or --url [url] or -t [uuid/name] [data] [signature])",

View File

@ -46,6 +46,7 @@ import net.citizensnpcs.trait.Saddle;
import net.citizensnpcs.trait.ScoreboardTrait;
import net.citizensnpcs.trait.ScriptTrait;
import net.citizensnpcs.trait.SheepTrait;
import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.trait.SkinLayers;
import net.citizensnpcs.trait.SkinTrait;
import net.citizensnpcs.trait.SlimeSize;
@ -92,6 +93,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(SkinTrait.class));
registerTrait(TraitInfo.create(MountTrait.class));
registerTrait(TraitInfo.create(SlimeSize.class));
registerTrait(TraitInfo.create(ShopTrait.class));
registerTrait(TraitInfo.create(Spawned.class));
registerTrait(TraitInfo.create(Speech.class));
registerTrait(TraitInfo.create(Text.class));

View File

@ -0,0 +1,46 @@
package net.citizensnpcs.trait;
import java.util.Map;
import org.bukkit.entity.Player;
import com.google.common.collect.Maps;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
/**
* Shop trait for NPC GUI shops.
*/
@TraitName("shop")
public class ShopTrait extends Trait {
public ShopTrait() {
super("shop");
}
public NPCShop getDefaultShop() {
return NPC_SHOPS.get(npc.getUniqueId().toString());
}
public NPCShop getShop(String name) {
return SHOPS.get(name);
}
public static class NPCShop {
@Persist
String name;
private NPCShop(String name) {
this.name = name;
}
public void display(Player sender) {
}
}
@Persist(value = "npcShops", namespace = "shopstrait")
private static Map<String, NPCShop> NPC_SHOPS = Maps.newHashMap();
@Persist(value = "namedShops", namespace = "shopstrait")
private static Map<String, NPCShop> SHOPS = Maps.newHashMap();
}