Resolve user system for offline servers

This commit is contained in:
Sotr
2019-04-01 17:33:38 +08:00
parent e616f1b1ed
commit fc19a9cfce
9 changed files with 200 additions and 23 deletions

View File

@@ -33,9 +33,6 @@ import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import io.akarin.server.core.AkarinAsyncExecutor;
import io.akarin.server.core.AkarinGlobalConfig;
import net.minecraft.server.UserCache.UserCacheEntry;
@@ -58,7 +55,7 @@ public class AkarinUserCache {
protected final Gson gson;
private final File userCacheFile;
private static boolean isOnlineMode() {
protected static boolean isOnlineMode() {
return UserCache.isOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode);
}
@@ -79,19 +76,12 @@ public class AkarinUserCache {
private static boolean isExpired(UserCacheEntry entry) {
return System.currentTimeMillis() >= entry.getExpireDate().getTime();
}
private static UserCacheEntry refreshExpireDate(UserCacheEntry entry) {
return new UserCacheEntry(entry.getProfile(), createExpireDate(true));
}
private static GameProfile lookup(GameProfileRepository profileRepo, String username, ProfileLookupCallback callback, boolean async) {
if (!isOnlineMode()) {
String usernameKey = username.toLowerCase(Locale.ROOT);
GameProfile offlineProfile = new GameProfile(EntityHuman.getOfflineUUID(usernameKey), usernameKey);
if (async) callback.onProfileLookupSucceeded(offlineProfile);
return offlineProfile;
}
GameProfile[] gameProfile = new GameProfile[1];
ProfileLookupCallback callbackHandler = new ProfileLookupCallback() {
@Override
@@ -167,14 +157,20 @@ public class AkarinUserCache {
public GameProfile acquire(String username, ProfileLookupCallback callback, boolean async) {
if (StringUtils.isBlank(username))
return null;
String usernameKey = isOnlineMode() ? username : username.toLowerCase(Locale.ROOT);
UserCacheEntry entry = profiles.getIfPresent(usernameKey);
throw new UnsupportedOperationException("Blank username");
if (!isOnlineMode()) {
String usernameOffline = username.toLowerCase(Locale.ROOT);
GameProfile offlineProfile = new GameProfile(EntityHuman.getOfflineUUID(usernameOffline), username);
if (async) callback.onProfileLookupSucceeded(offlineProfile);
return offlineProfile;
}
UserCacheEntry entry = profiles.getIfPresent(username);
if (entry != null) {
if (isExpired(entry)) {
profiles.invalidate(usernameKey);
profiles.invalidate(username);
return lookupAndCache(username, callback, async);
} else {
if (async) {

View File

@@ -0,0 +1,57 @@
package net.minecraft.server;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import javax.annotation.Nullable;
public class CommandBan {
private static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("commands.ban.failed", new Object[0]));
public static void a(com.mojang.brigadier.CommandDispatcher<CommandListenerWrapper> com_mojang_brigadier_commanddispatcher) {
com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("ban").requires((commandlistenerwrapper) -> {
return commandlistenerwrapper.getServer().getPlayerList().getProfileBans().isEnabled() && commandlistenerwrapper.hasPermission(3);
})).then(((RequiredArgumentBuilder) CommandDispatcher.a("targets", (ArgumentType) ArgumentProfile.a()).executes((commandcontext) -> {
return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentProfile.a(commandcontext, "targets"), (IChatBaseComponent) null);
})).then(CommandDispatcher.a("reason", (ArgumentType) ArgumentChat.a()).executes((commandcontext) -> {
return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentProfile.a(commandcontext, "targets"), ArgumentChat.a(commandcontext, "reason"));
}))));
}
private static int a(CommandListenerWrapper commandlistenerwrapper, Collection<GameProfile> collection, @Nullable IChatBaseComponent ichatbasecomponent) throws CommandSyntaxException {
GameProfileBanList gameprofilebanlist = commandlistenerwrapper.getServer().getPlayerList().getProfileBans();
int i = 0;
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
GameProfile gameprofile = (GameProfile) iterator.next();
if (!gameprofilebanlist.isBanned(gameprofile)) {
GameProfileBanEntry gameprofilebanentry = new GameProfileBanEntry(gameprofile, (Date) null, commandlistenerwrapper.getName(), (Date) null, ichatbasecomponent == null ? null : ichatbasecomponent.getString());
gameprofilebanlist.add(gameprofilebanentry);
++i;
commandlistenerwrapper.sendMessage(new ChatMessage("commands.ban.success", new Object[] { ChatComponentUtils.a(gameprofile), gameprofilebanentry.getReason()}), true);
EntityPlayer entityplayer = commandlistenerwrapper.getServer().getPlayerList().getPlayer(gameprofile.getName()); // Akarin
if (entityplayer != null) {
entityplayer.playerConnection.disconnect(new ChatMessage("multiplayer.disconnect.banned", new Object[0]));
}
}
}
if (i == 0) {
throw CommandBan.a.create();
} else {
return i;
}
}
}

View File

@@ -0,0 +1,38 @@
package net.minecraft.server;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import java.io.File;
import java.util.Iterator;
public class GameProfileBanList extends JsonList<GameProfile, GameProfileBanEntry> {
public GameProfileBanList(File file) {
super(file);
}
protected JsonListEntry<GameProfile> a(JsonObject jsonobject) {
return new GameProfileBanEntry(jsonobject);
}
public boolean isBanned(GameProfile gameprofile) {
return this.d(gameprofile);
}
public String[] getEntries() {
String[] astring = new String[this.e().size()];
int i = 0;
JsonListEntry jsonlistentry;
for (Iterator iterator = this.e().iterator(); iterator.hasNext(); astring[i++] = ((GameProfile) jsonlistentry.getKey()).getName()) {
jsonlistentry = (JsonListEntry) iterator.next();
}
return astring;
}
protected String a(GameProfile gameprofile) {
return AkarinUserCache.isOnlineMode() ? gameprofile.getId().toString() : gameprofile.getName(); // Akarin
}
}

View File

@@ -12,6 +12,8 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.mojang.authlib.GameProfile;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
@@ -24,9 +26,11 @@ import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

View File

@@ -269,7 +269,7 @@ public class NameReferencingFileConverter {
public static String a(final MinecraftServer minecraftserver, String s) {
if (!UtilColor.b(s) && s.length() <= 16) {
GameProfile gameprofile = minecraftserver.getUserCache().getProfile(s);
GameProfile gameprofile = minecraftserver.getModernUserCache().acquire(s); // Akarin
if (gameprofile != null && gameprofile.getId() != null) {
return gameprofile.getId().toString();

View File

@@ -28,6 +28,7 @@ import java.nio.channels.Channels;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.annotation.Nullable;
import javax.crypto.SecretKey;
@@ -66,7 +67,7 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
private PacketListener packetListener;
private IChatBaseComponent n;
private boolean o;
private volatile boolean p; // Akarin - add volatile
private AtomicBoolean p = new AtomicBoolean(false); // Akarin - atomic
private int q;
private int r;
private float s;
@@ -437,10 +438,10 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
public void handleDisconnection() {
if (this.channel != null && !this.channel.isOpen()) {
if (this.p) {
NetworkManager.g.warn("handleDisconnection() called twice");
if (!this.p.compareAndSet(false, true)) { // Akarin
//NetworkManager.g.warn("handleDisconnection() called twice"); // Akarin
} else {
this.p = true;
//this.p = true; // Akarin
if (this.j() != null) {
this.i().a(this.j());
} else if (this.i() != null) {

View File

@@ -0,0 +1,40 @@
package net.minecraft.server;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import java.io.File;
import java.util.Iterator;
public class OpList extends JsonList<GameProfile, OpListEntry> {
public OpList(File file) {
super(file);
}
protected JsonListEntry<GameProfile> a(JsonObject jsonobject) {
return new OpListEntry(jsonobject);
}
public String[] getEntries() {
String[] astring = new String[this.e().size()];
int i = 0;
JsonListEntry jsonlistentry;
for (Iterator iterator = this.e().iterator(); iterator.hasNext(); astring[i++] = ((GameProfile) jsonlistentry.getKey()).getName()) {
jsonlistentry = (JsonListEntry) iterator.next();
}
return astring;
}
public boolean b(GameProfile gameprofile) {
OpListEntry oplistentry = (OpListEntry) this.get(gameprofile);
return oplistentry != null ? oplistentry.b() : false;
}
protected String a(GameProfile gameprofile) {
return AkarinUserCache.isOnlineMode() ? gameprofile.getId().toString() : gameprofile.getName(); // Akarin
}
}

View File

@@ -533,7 +533,7 @@ public abstract class PlayerList {
for (int i = 0; i < this.players.size(); ++i) {
entityplayer = (EntityPlayer) this.players.get(i);
if (entityplayer.getUniqueID().equals(uuid)) {
if (AkarinUserCache.isOnlineMode() ? entityplayer.getUniqueID().equals(uuid) : entityplayer.getName().equals(gameprofile.getName())) { // Akarin - resolve offline servers
list.add(entityplayer);
}
}

View File

@@ -0,0 +1,41 @@
package net.minecraft.server;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import java.io.File;
import java.util.Iterator;
import java.util.Locale;
import org.apache.commons.lang3.builder.ToStringBuilder;
public class WhiteList extends JsonList<GameProfile, WhiteListEntry> {
public WhiteList(File file) {
super(file);
}
protected JsonListEntry<GameProfile> a(JsonObject jsonobject) {
return new WhiteListEntry(jsonobject);
}
public boolean isWhitelisted(GameProfile gameprofile) {
return this.d(gameprofile);
}
public String[] getEntries() {
String[] astring = new String[this.e().size()];
int i = 0;
JsonListEntry jsonlistentry;
for (Iterator iterator = this.e().iterator(); iterator.hasNext(); astring[i++] = ((GameProfile) jsonlistentry.getKey()).getName()) {
jsonlistentry = (JsonListEntry) iterator.next();
}
return astring;
}
protected String a(GameProfile gameprofile) {
return AkarinUserCache.isOnlineMode() ? gameprofile.getId().toString() : gameprofile.getName(); // Akarin
}
}