Make plugin disable hack more compatible

This commit is contained in:
fullwall 2021-07-15 19:41:03 +08:00
parent c3a70e27ed
commit dfc48ec475
3 changed files with 38 additions and 51 deletions

View File

@ -77,7 +77,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
private final List<NPCRegistry> citizensBackedRegistries = Lists.newArrayList();
private final CommandManager commands = new CommandManager();
private Settings config;
private boolean loaded;
private boolean enabled;
private CitizensNPCRegistry npcRegistry;
private NPCDataStore saves;
private NPCSelector selector;
@ -98,6 +98,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
};
private CitizensSpeechFactory speechFactory;
private final Map<String, NPCRegistry> storedRegistries = Maps.newHashMap();
private CitizensTraitFactory traitFactory;
@Override
@ -145,19 +146,6 @@ 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())
@ -290,7 +278,15 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
@Override
public void onDisable() {
disable();
if (!enabled)
return;
Bukkit.getPluginManager().callEvent(new CitizensDisableEvent());
Editor.leaveAll();
despawnNPCs(true);
npcRegistry = null;
NMS.shutdown();
enabled = false;
CitizensAPI.shutdown();
}
@Override
@ -300,15 +296,14 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
setupTranslator();
// Disable if the server is not using the compatible Minecraft version
String mcVersion = Util.getMinecraftRevision();
loaded = true;
try {
NMS.loadBridge(mcVersion);
} catch (Exception e) {
loaded = false;
if (Messaging.isDebugging()) {
e.printStackTrace();
}
Messaging.severeTr(Messages.CITIZENS_INCOMPATIBLE, getDescription().getVersion(), mcVersion);
enabled = true;
Bukkit.getPluginManager().disablePlugin(this);
return;
}
@ -500,6 +495,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
}
private class CitizensLoadTask implements Runnable {
@Override
public void run() {
saves.loadInto(npcRegistry);
@ -508,6 +504,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
scheduleSaveTask(Setting.SAVE_TASK_DELAY.asInt());
Bukkit.getPluginManager().callEvent(new CitizensEnableEvent());
new PlayerUpdateTask().runTaskTimer(Citizens.this, 0, 1);
enabled = true;
}
}

View File

@ -1,6 +1,5 @@
package net.citizensnpcs;
import java.lang.invoke.MethodHandle;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -53,7 +52,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.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitRunnable;
import com.google.common.base.Predicates;
@ -231,28 +230,6 @@ 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
*/
@ -586,6 +563,19 @@ public class EventListen implements Listener {
skinUpdateTracker.updatePlayer(event.getPlayer(), 15, true);
}
@EventHandler
public void onPluginDisable(PluginDisableEvent event) {
// hack: Spigot now unloads plugin classes on disable in reverse order so prefer unloading at the start of
// plugin disable cycle
PluginDescriptionFile file = event.getPlugin().getDescription();
for (String plugin : Iterables.concat(file.getDepend(), file.getSoftDepend())) {
if (plugin.equalsIgnoreCase("citizens")) {
CitizensAPI.getPlugin().onDisable();
break;
}
}
}
@EventHandler(ignoreCancelled = true)
public void onPotionSplashEvent(PotionSplashEvent event) {
for (LivingEntity entity : event.getAffectedEntities()) {
@ -742,6 +732,4 @@ public class EventListen implements Listener {
}
return npc.spawn(spawn, SpawnReason.CHUNK_LOAD);
}
private static MethodHandle CLASSES_FIELD = null;
}

View File

@ -3,14 +3,17 @@ package net.citizensnpcs.editor;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.util.Messages;
// TODO: convert to non-static?
public abstract class Editor implements Listener {
public abstract void begin();
@ -18,15 +21,14 @@ public abstract class Editor implements Listener {
private static void enter(Player player, Editor editor) {
editor.begin();
player.getServer().getPluginManager().registerEvents(editor,
player.getServer().getPluginManager().getPlugin("Citizens"));
EDITING.put(player.getName(), editor);
player.getServer().getPluginManager().registerEvents(editor, CitizensAPI.getPlugin());
EDITING.put(player.getUniqueId(), editor);
}
public static void enterOrLeave(Player player, Editor editor) {
if (editor == null)
return;
Editor edit = EDITING.get(player.getName());
Editor edit = EDITING.get(player.getUniqueId());
if (edit == null) {
enter(player, editor);
} else if (edit.getClass() == editor.getClass()) {
@ -37,24 +39,24 @@ public abstract class Editor implements Listener {
}
public static boolean hasEditor(Player player) {
return EDITING.containsKey(player.getName());
return EDITING.containsKey(player.getUniqueId());
}
public static void leave(Player player) {
if (!hasEditor(player))
return;
Editor editor = EDITING.remove(player.getName());
Editor editor = EDITING.remove(player.getUniqueId());
HandlerList.unregisterAll(editor);
editor.end();
}
public static void leaveAll() {
for (Entry<String, Editor> entry : EDITING.entrySet()) {
for (Entry<UUID, Editor> entry : EDITING.entrySet()) {
entry.getValue().end();
HandlerList.unregisterAll(entry.getValue());
}
EDITING.clear();
}
private static final Map<String, Editor> EDITING = new HashMap<String, Editor>();
private static final Map<UUID, Editor> EDITING = new HashMap<UUID, Editor>();
}