Save player logout times on shutdown (#3157)

Properly save userdata and mark the player's last logout time when the server is shutting down.

Fixes #2764.
This commit is contained in:
Josh Roy 2020-05-11 09:53:05 -04:00 committed by GitHub
parent 96590a3389
commit fc2b7b63a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 1 deletions

View File

@ -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) {

View File

@ -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;
}
}