[Experimental] Attempt to implement compatibility for 1.7 servers

This commit is contained in:
vemacs 2016-01-18 21:01:05 -07:00
parent b17f5d32c9
commit a4871cac36
2 changed files with 76 additions and 16 deletions

View file

@ -154,15 +154,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
Console.setInstance(this); Console.setInstance(this);
File file = new File(getDataFolder(), ".skipversion");
if (!file.exists()) {
String serverString = Bukkit.getServer().getClass().getName();
for (int i = 1; i <= 7; i++) {
if (serverString.contains(".v1_" + i + "_R")) {
throw new Error("Outdated server. This version of Essentials will only work on Bukkit 1.8 or higher.");
}
}
}
final PluginManager pm = getServer().getPluginManager(); final PluginManager pm = getServer().getPluginManager();
for (Plugin plugin : pm.getPlugins()) { for (Plugin plugin : pm.getPlugins()) {
if (plugin.getDescription().getName().startsWith("Essentials") && !plugin.getDescription().getVersion().equals(this.getDescription().getVersion()) && !plugin.getDescription().getName().equals("EssentialsAntiCheat")) { if (plugin.getDescription().getName().startsWith("Essentials") && !plugin.getDescription().getVersion().equals(this.getDescription().getVersion()) && !plugin.getDescription().getName().equals("EssentialsAntiCheat")) {

View file

@ -2,15 +2,17 @@ package com.earth2me.essentials;
import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.UncheckedExecutionException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.io.File; import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.ConcurrentSkipListSet;
@ -20,19 +22,34 @@ import java.util.regex.Pattern;
public class UserMap extends CacheLoader<String, User> implements IConf { public class UserMap extends CacheLoader<String, User> implements IConf {
private final transient IEssentials ess; private final transient IEssentials ess;
private final transient LoadingCache<String, User> users; private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<>();
private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<UUID>(); private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<>();
private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<String, UUID>(); private final transient ConcurrentSkipListMap<UUID, ArrayList<String>> history = new ConcurrentSkipListMap<>();
private final transient ConcurrentSkipListMap<UUID, ArrayList<String>> history = new ConcurrentSkipListMap<UUID, ArrayList<String>>();
private UUIDMap uuidMap; private UUIDMap uuidMap;
private final transient Cache<String, User> users;
public UserMap(final IEssentials ess) { public UserMap(final IEssentials ess) {
super(); super();
this.ess = ess; this.ess = ess;
uuidMap = new UUIDMap(ess); uuidMap = new UUIDMap(ess);
//RemovalListener<UUID, User> remListener = new UserMapRemovalListener(); //RemovalListener<UUID, User> remListener = new UserMapRemovalListener();
//users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().removalListener(remListener).build(this); //users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().removalListener(remListener).build(this);
users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().build(this); CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
int maxCount = ess.getSettings().getMaxUserCacheCount();
boolean legacy = false;
try {
cacheBuilder.maximumSize(maxCount);
} catch (NoSuchMethodError nsme) {
legacy = true;
legacyMaximumSize(cacheBuilder, maxCount);
}
cacheBuilder.softValues();
if (!legacy) {
users = cacheBuilder.build(this);
} else {
users = legacyBuild(cacheBuilder);
}
} }
private void loadAllUsersAsync(final IEssentials ess) { private void loadAllUsersAsync(final IEssentials ess) {
@ -90,7 +107,11 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
public User getUser(final UUID uuid) { public User getUser(final UUID uuid) {
try { try {
return users.get(uuid.toString()); try {
return ((LoadingCache<String, User>) users).get(uuid.toString());
} catch (SecurityException | ClassCastException e) {
return legacyCacheGet(uuid);
}
} catch (ExecutionException ex) { } catch (ExecutionException ex) {
return null; return null;
} catch (UncheckedExecutionException ex) { } catch (UncheckedExecutionException ex) {
@ -244,4 +265,52 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
return getUser(uuid); return getUser(uuid);
} }
} }
private static Method getLegacy;
private User legacyCacheGet(UUID uuid) {
if (getLegacy == null) {
Class<?> usersClass = users.getClass();
for (Method m : usersClass.getDeclaredMethods()) {
if (m.getName().equals("get")) {
getLegacy = m;
getLegacy.setAccessible(true);
break;
}
}
}
try {
return (User) getLegacy.invoke(users, uuid.toString());
} catch (IllegalAccessException | InvocationTargetException e) {
return null;
}
}
private void legacyMaximumSize(CacheBuilder builder, int maxCount) {
try {
Method maxSizeLegacy = builder.getClass().getDeclaredMethod("maximumSize", Integer.TYPE);
maxSizeLegacy.invoke(builder, maxCount);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
private Cache<String, User> legacyBuild(CacheBuilder builder) {
Method build = null;
for (Method method : builder.getClass().getDeclaredMethods()) {
if (method.getName().equals("build")) {
build = method;
break;
}
}
Cache<String, User> legacyUsers;
try {
assert build != null;
legacyUsers = (Cache<String, User>) build.invoke(builder, this);
} catch (IllegalAccessException | InvocationTargetException e) {
legacyUsers = null;
}
return legacyUsers;
}
} }