diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index e8d714eb0..d2428ee3d 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -18,6 +18,7 @@ package com.earth2me.essentials; import com.earth2me.essentials.commands.*; +import com.earth2me.essentials.craftbukkit.ServerState; import com.earth2me.essentials.items.AbstractItemDb; import com.earth2me.essentials.items.CustomItemResolver; import com.earth2me.essentials.items.FlatItemDb; @@ -367,7 +368,15 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { user.setVanished(false); user.sendMessage(tl("unvanishedReload")); } - user.stopTransaction(); + if (ServerState.isStopping()) { + user.setLastLocation(); + if (!user.isHidden()) { + user.setLastLogout(System.currentTimeMillis()); + } + user.cleanup(); + } else { + user.stopTransaction(); + } } cleanupOpenInventories(); if (i18n != null) { diff --git a/Essentials/src/com/earth2me/essentials/craftbukkit/ServerState.java b/Essentials/src/com/earth2me/essentials/craftbukkit/ServerState.java new file mode 100644 index 000000000..8f9fef052 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/craftbukkit/ServerState.java @@ -0,0 +1,66 @@ +package com.earth2me.essentials.craftbukkit; + +import net.ess3.nms.refl.ReflUtil; +import org.bukkit.Bukkit; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class ServerState { + + private static final MethodHandle isStopping; //Only in Paper + private static final MethodHandle nmsHasStopped; + private static final MethodHandle nmsIsRunning; + private static final Object nmsServer; + + static { + MethodHandle isStoppingHandle = null; + MethodHandle nmsHasStoppedHandle = null; + MethodHandle nmsIsRunningHandle = null; + Object nmsServerObject = null; + try { + isStoppingHandle = MethodHandles.lookup().findStatic(Bukkit.class, "isStopping", MethodType.methodType(boolean.class)); + } catch (Throwable e) { + try { + Class nmsClass = ReflUtil.getNMSClass("MinecraftServer"); + if (nmsClass != null) { + nmsServerObject = ReflUtil.getMethodCached(nmsClass, "getServer").invoke(null); + nmsIsRunningHandle = MethodHandles.lookup().findVirtual(nmsClass, "isRunning", MethodType.methodType(boolean.class)); + nmsHasStoppedHandle = MethodHandles.lookup().findVirtual(nmsClass, "hasStopped", MethodType.methodType(boolean.class)); + } + } catch (Throwable ignored) { + } + } + isStopping = isStoppingHandle; + nmsHasStopped = nmsHasStoppedHandle; + nmsIsRunning = nmsIsRunningHandle; + nmsServer = nmsServerObject; + } + + public static boolean isStopping() { + boolean stopping = false; + if (isStopping != null) { + try { + stopping = (boolean) isStopping.invoke(); + } catch (Throwable t) { + t.printStackTrace(); + } + } else if (nmsServer != null) { + if (nmsHasStopped != null) { + try { + stopping = (boolean) nmsHasStopped.invokeExact(nmsServer); + } catch (Throwable t) { + t.printStackTrace(); + } + } else if (nmsIsRunning != null) { + try { + stopping = (boolean) nmsIsRunning.invokeExact(nmsServer); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + return stopping; + } +}