Проверка Лицензии(Нужна помощь_)

lxtopxm

Выдающийся
Местный
Сообщения
379
Розыгрыши
0
Репутация
239
Реакции
45
Баллы
1 375
Помогите снять проверку лицензии, знаю ток путь к файлу
atavism/server/plugins/proxyplugin
 

Вложения

  • dist.rar
    4,6 МБ · Просмотры: 22

Сделал декомпил, но не знаю ровный он и как удалить привязку

Java:
package atavism.server.plugins;

import atavism.agis.database.AccountDatabase;
import atavism.agis.database.ContentDatabase;
import atavism.agis.events.AbilityStatusEvent;
import atavism.agis.events.AbilityStatusMessage;
import atavism.agis.events.ConcludeQuest;
import atavism.agis.events.QuestResponse;
import atavism.agis.events.RequestQuestInfo;
import atavism.agis.plugins.AnimationClient;
import atavism.agis.plugins.ChatClient;
import atavism.agis.plugins.CombatClient;
import atavism.agis.plugins.DataLoggerClient;
import atavism.agis.plugins.QuestClient;
import atavism.agis.plugins.SocialClient;
import atavism.agis.plugins.AnimationClient.InvokeEffectMessage;
import atavism.agis.plugins.ChatClient.ComMessage;
import atavism.agis.plugins.ChatClient.SysChatMessage;
import atavism.agis.plugins.ChatClient.TargetedComMessage;
import atavism.agis.plugins.CombatClient.AbilityUpdateMessage;
import atavism.agis.plugins.CombatClient.DamageMessage;
import atavism.agis.plugins.QuestClient.QuestResponseMessage;
import atavism.agis.plugins.SocialClient.BlockListMessage;
import atavism.agis.util.EventMessageHelper;
import atavism.agis.util.HelperFunctions;
import atavism.management.Management;
import atavism.msgsys.FilterUpdate;
import atavism.msgsys.GenericMessage;
import atavism.msgsys.Message;
import atavism.msgsys.MessageTrigger;
import atavism.msgsys.MessageType;
import atavism.msgsys.MessageTypeFilter;
import atavism.msgsys.NoRecipientsException;
import atavism.msgsys.RPCTimeoutException;
import atavism.msgsys.ResponseCallback;
import atavism.msgsys.ResponseMessage;
import atavism.msgsys.SubjectMessage;
import atavism.msgsys.TargetMessage;
import atavism.server.engine.BasicWorldNode;
import atavism.server.engine.Database;
import atavism.server.engine.Engine;
import atavism.server.engine.EnginePlugin;
import atavism.server.engine.Event;
import atavism.server.engine.Hook;
import atavism.server.engine.Namespace;
import atavism.server.engine.OID;
import atavism.server.events.ActivateItemEvent;
import atavism.server.events.AmbientLightEvent;
import atavism.server.events.AttachEvent;
import atavism.server.events.AuthorizedLoginEvent;
import atavism.server.events.AuthorizedLoginResponseEvent;
import atavism.server.events.AutoAttackEvent;
import atavism.server.events.ComEvent;
import atavism.server.events.CommandEvent;
import atavism.server.events.DetachEvent;
import atavism.server.events.DirLocOrientEvent;
import atavism.server.events.ExtensionMessageEvent;
import atavism.server.events.FreeTerrainDecalEvent;
import atavism.server.events.LoadingStateEvent;
import atavism.server.events.LogoutEvent;
import atavism.server.events.ModelInfoEvent;
import atavism.server.events.NewLightEvent;
import atavism.server.events.NewTerrainDecalEvent;
import atavism.server.events.NotifyFreeObjectEvent;
import atavism.server.events.NotifyPlayAnimationEvent;
import atavism.server.events.PlayerHaEvent;
import atavism.server.events.SceneLoadedEvent;
import atavism.server.events.WorldFileEvent;
import atavism.server.math.AOVector;
import atavism.server.math.Point;
import atavism.server.math.Quaternion;
import atavism.server.messages.LoginMessage;
import atavism.server.messages.LogoutMessage;
import atavism.server.messages.PerceptionFilter;
import atavism.server.messages.PerceptionMessage;
import atavism.server.messages.PerceptionTrigger;
import atavism.server.messages.PropertyMessage;
import atavism.server.network.AOByteBuffer;
import atavism.server.network.ClientConnection;
import atavism.server.network.ClientTCPMessageIO;
import atavism.server.network.PacketAggregator;
import atavism.server.network.rdp.RDPConnection;
import atavism.server.network.rdp.RDPServer;
import atavism.server.network.rdp.RDPServerSocket;
import atavism.server.objects.Color;
import atavism.server.objects.DisplayContext;
import atavism.server.objects.FogRegionConfig;
import atavism.server.objects.InstanceEntryCallback;
import atavism.server.objects.InstanceRestorePoint;
import atavism.server.objects.InstanceTemplate;
import atavism.server.objects.Light;
import atavism.server.objects.LightData;
import atavism.server.objects.ObjectType;
import atavism.server.objects.ObjectTypes;
import atavism.server.objects.OceanData;
import atavism.server.objects.Player;
import atavism.server.objects.PlayerManager;
import atavism.server.objects.ProxyExtensionHook;
import atavism.server.objects.ProxyLoginCallback;
import atavism.server.objects.Road;
import atavism.server.objects.SoundData;
import atavism.server.objects.Template;
import atavism.server.objects.TerrainDecalData;
import atavism.server.objects.World;
import atavism.server.telemetry.Prometheus;
import atavism.server.util.AOMeter;
import atavism.server.util.AORuntimeException;
import atavism.server.util.AnimationCommand;
import atavism.server.util.Base64;
import atavism.server.util.CountLogger;
import atavism.server.util.DebugUtils;
import atavism.server.util.EncryptionHelper;
import atavism.server.util.LockFactory;
import atavism.server.util.Log;
import atavism.server.util.Logger;
import atavism.server.util.SQCallback;
import atavism.server.util.SQThreadPool;
import atavism.server.util.SecureToken;
import atavism.server.util.SecureTokenManager;
import atavism.server.util.SecureTokenSpec;
import atavism.server.util.ServerVersion;
import atavism.server.util.SquareQueue;
import atavism.server.util.TimeHistogram;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Timer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.function.Supplier;

public class ProxyPlugin extends EnginePlugin implements ClientConnection.AcceptCallback, ClientConnection.MessageCallback {
   private static int MESSAGE_QUEUE_THREADS = 16;
   private static int EVENT_QUEUE_THREADS = 16;
   private static int SLOW_EVENT_QUEUE_THREADS = 8;
   private static final int RDP_CHANNELS_COUNT = 128;
   public static final int PERCEPTION_GAIN_THRESHOLD = 20;
   CountLogger countLogger = new CountLogger("ProxyMsg", 5000, 2);
   CountLogger.Counter countMsgPerception;
   CountLogger.Counter countMsgPerceptionGain;
   CountLogger.Counter countMsgPerceptionLost;
   CountLogger.Counter countMsgUpdateWNodeIn;
   CountLogger.Counter countMsgUpdateWNodeOut;
   CountLogger.Counter countMsgPropertyIn;
   CountLogger.Counter countMsgPropertyOut;
   CountLogger.Counter countMsgTargetedProperty;
   CountLogger.Counter countMsgWNodeCorrectIn;
   CountLogger.Counter countMsgWNodeCorrectOut;
   CountLogger.Counter countMsgMobPathIn;
   CountLogger.Counter countMsgMobPathOut;
   public static boolean debugLic = false;
   protected Lock commandMapLock = LockFactory.makeLock("CommandMapLock");
   Map<String, ProxyPlugin.RegisteredCommand> commandMap = new HashMap();
   ProxyPlugin.CommandAccessCheck defaultCommandAccess = new ProxyPlugin.DefaultCommandAccess();
   SquareQueue<Player, Message> messageQQ = new SquareQueue("Message");
   SQThreadPool messageThreadPool = null;
   private final SquareQueue<Player, Event> eventQQ = new SquareQueue("Event");
   private SQThreadPool<Player, Event> eventThreadPool = null;
   private final SquareQueue<Player, Event> slowEventQQ = new SquareQueue("SlowEvent");
   private SQThreadPool<Player, Event> slowEventThreadPool = null;
   AOMeter clientMsgMeter = new AOMeter("ClientEventProcessorMeter");
   protected ConcurrentHashMap<OID, Long> playerLastClientTime = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, Long> playerLastServerTime = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, Long> playerFirstSpeedHackTime = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, Long> playerSpeedHackCount = new ConcurrentHashMap();
   public boolean defaultAllowClientToClientMessage = false;
   protected HashMap<String, MessageType> extensionMessageRegistry = new HashMap();
   private final ExecutorService logoutExecutor = Executors.newCachedThreadPool();
   protected AccountDatabase aDB;
   protected PerceptionFilter perceptionFilter;
   protected long perceptionSubId;
   protected PerceptionFilter responderFilter;
   protected PerceptionFilter responderFilter2;
   protected long responderSubId;
   protected long responderSubId2;
   protected int clientPort;
   protected static final Logger log = new Logger("ProxyPlugin");
   ProxyPlugin.PlayerMessageCallback playerMessageCallback = new ProxyPlugin.PlayerMessageCallback();
   protected PlayerManager playerManager = new PlayerManager();
   protected ConcurrentHashMap<OID, String> playersOnlineList = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, String> playersOnlineOnProxy = new ConcurrentHashMap();
   protected TimeHistogram proxyQueueHistogram = null;
   protected TimeHistogram proxyCallbackHistogram = null;
   protected List<MessageType> extraPlayerMessageTypes = null;
   private ProxyLoginCallback proxyLoginCallback = new ProxyPlugin.DefaultProxyLoginCallback();
   private InstanceEntryCallback instanceEntryCallback = new ProxyPlugin.DefaultInstanceEntryCallback();
   private int instanceEntryCount = 0;
   private int chatSentCount = 0;
   private int privateChatSentCount = 0;
   public static final MessageType MSG_TYPE_VOICE_PARMS = MessageType.intern("ao.VOICE_PARMS");
   public static final MessageType MSG_TYPE_PLAYER_PATH_REQ = MessageType.intern("ao.PLAYER_PATH_REQ");
   public static final MessageType MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST = MessageType.intern("ao.UPDATE_PLAYER_IGNORE_LIST");
   public static final MessageType MSG_TYPE_GET_MATCHING_PLAYERS = MessageType.intern("ao.GET_MATCHING_PLAYERS");
   public static final MessageType MSG_TYPE_PLAYER_IGNORE_LIST = MessageType.intern("ao.PLAYER_IGNORE_LIST");
   public static final MessageType MSG_TYPE_PLAYER_IGNORE_LIST_REQ = MessageType.intern("ao.PLAYER_IGNORE_LIST_REQ");
   public static final MessageType MSG_TYPE_RELAY_UPDATE_PLAYER_IGNORE_LIST = MessageType.intern("ao.RELAY_UPDATE_PLAYER_IGNORE_LIST");
   public static final MessageType MSG_TYPE_GET_PLAYER_LOGIN_STATUS = MessageType.intern("ao.GET_PLAYER_LOGIN_STATUS");
   public static final MessageType MSG_TYPE_LOGOUT_PLAYER = MessageType.intern("ao.LOGOUT_PLAYER");
   public static final MessageType MSG_TYPE_ADD_STATIC_PERCEPTION = MessageType.intern("ao.ADD_STATIC_PERCEPTION");
   public static final MessageType MSG_TYPE_REMOVE_STATIC_PERCEPTION = MessageType.intern("ao.REMOVE_STATIC_PERCEPTION");
   public static final MessageType MSG_TYPE_LOGIN_SPAWNED = MessageType.intern("ao.LOGIN_SPAWNED");
   public static final MessageType MSG_TYPE_ACCOUNT_LOGIN = MessageType.intern("ao.ACCOUNT_LOGIN");
   public static final MessageType MSG_TYPE_SERVER_SHUTDOWN_MESSAGE = MessageType.intern("server.Shutdown_Message");
   public static final MessageType MSG_TYPE_SERVER_SHUTDOWN = MessageType.intern("server.Shutdown");
   public static final MessageType MSG_TYPE_SERVER_RELOAD = MessageType.intern("server.Reload");
   protected static String voiceServerHost = "";
   protected static Integer voiceServerPort = null;
   public String serverCapabilitiesSentToClient = "DirLocOrient";
   public static int DiffTimeToSkipDirLocOrientMessage = 500;
   static int serverSocketReceiveBufferSize = 8388608;
   public static int MaxConcurrentUsers = 2000;
   public static int LOGIN_QUEUE_MAX_USERS = 2000;
   public static int restriction_level = 0;
   public static int idleTimeout = 900;
   public static int silenceTimeout = 30;
   public static int silenceLoadingTimeout = 900;
   public static int maxMessagesBeforeConnectionReset = 2000;
   public static int maxByteCountBeforeConnectionReset = 1000000;
   public String capacityError = "Login Failed: Servers at capacity, please try again later.";
   public String tokenError = "Login Failed: Secure token invalid.";
   public static String SpeedhackChatMsg = "Detected Speedhack";
   public static int SpeedhackCountToDisconect = 10;
   public static int SpeedhackMinDiff = 8000;
   private ClientTCPMessageIO clientTCPMessageIO = null;
   Set<OID> adminSet = new HashSet();
   Map<OID, ClientConnection> clientConnections = new ConcurrentHashMap();
   Set<String> filteredProps = null;
   Set<String> playerSpecificProps = null;
   Set<String> cachedPlayerSpecificFilterProps = null;
   String serverVersion = null;
   protected Map<String, List<ProxyExtensionHook>> extensionHooks = new HashMap();
   private int connectionLimit = 0;
   boolean devMode = true;

   public ProxyPlugin() {
      super(getPluginName(), (atavism.msgsys.MessageCallback)null);
      this.setPluginType("Proxy");
      this.serverVersion = "10.9.0 " + ServerVersion.getBuildNumber();
      String MessageQueueThreadPoolSize = Engine.properties.getProperty("atavism.proxy.MessageQueueThreadPoolSize");
      if (MessageQueueThreadPoolSize != null) {
         try {
            int v = Integer.parseInt(MessageQueueThreadPoolSize);
            MESSAGE_QUEUE_THREADS = v;
         } catch (NumberFormatException var9) {
            var9.printStackTrace();
            Log.exception(var9);
         }
      }

      String EventQueueThreadPoolSize = Engine.properties.getProperty("atavism.proxy.EventQueueThreadPoolSize");
      if (EventQueueThreadPoolSize != null) {
         try {
            int v = Integer.parseInt(EventQueueThreadPoolSize);
            EVENT_QUEUE_THREADS = v;
         } catch (NumberFormatException var8) {
            var8.printStackTrace();
            Log.exception(var8);
         }
      }

      String proxy_concurrent_logins = Engine.properties.getProperty("atavism.proxy.ConcurrentLogins");
      if (proxy_concurrent_logins != null) {
         try {
            int v = Integer.parseInt(proxy_concurrent_logins);
            SLOW_EVENT_QUEUE_THREADS = v;
         } catch (NumberFormatException var7) {
            var7.printStackTrace();
            Log.exception(var7);
         }
      }

      this.messageThreadPool = new SQThreadPool(this.messageQQ, new ProxyPlugin.MessageCallback(this), MESSAGE_QUEUE_THREADS);
      this.eventThreadPool = new SQThreadPool(this.eventQQ, new ProxyPlugin.EventCallback(), EVENT_QUEUE_THREADS);
      this.slowEventThreadPool = new SQThreadPool(this.slowEventQQ, new ProxyPlugin.EventCallback(), SLOW_EVENT_QUEUE_THREADS);
      this.countMsgPerception = this.countLogger.addCounter("ao.PERCEPTION_INFO");
      this.countMsgPerceptionGain = this.countLogger.addCounter("Perception.gain");
      this.countMsgPerceptionLost = this.countLogger.addCounter("Perception.lost");
      this.countMsgUpdateWNodeIn = this.countLogger.addCounter("ao.UPDATEWNODE.in");
      this.countMsgUpdateWNodeOut = this.countLogger.addCounter("ao.UPDATEWNODE.out");
      this.countMsgPropertyIn = this.countLogger.addCounter("ao.PROPERTY.in");
      this.countMsgPropertyOut = this.countLogger.addCounter("ao.PROPERTY.out");
      this.countMsgTargetedProperty = this.countLogger.addCounter("ao.TARGETED_PROPERTY");
      this.countMsgWNodeCorrectIn = this.countLogger.addCounter("ao.WNODECORRECT.in");
      this.countMsgWNodeCorrectOut = this.countLogger.addCounter("ao.WNODECORRECT.out");
      this.countMsgMobPathIn = this.countLogger.addCounter("ao.MOB_PATH.in");
      this.countMsgMobPathOut = this.countLogger.addCounter("ao.MOB_PATH.out");
      ContentDatabase ctDB = new ContentDatabase(false);
      String _silenceTimeout = ctDB.loadGameSetting("PLAYER_SILENCE_TIMEOUT");
      if (_silenceTimeout != null) {
         silenceTimeout = Integer.parseInt(_silenceTimeout);
      }

      String loginQueueMaxUsers = ctDB.loadGameSetting("LOGIN_QUEUE_MAX_USERS");
      if (loginQueueMaxUsers != null) {
         LOGIN_QUEUE_MAX_USERS = Integer.parseInt(loginQueueMaxUsers);
         Log.info("Game Settings LOGIN_QUEUE_MAX_USERS set to " + LOGIN_QUEUE_MAX_USERS);
      }

      this.aDB = new AccountDatabase(true);
      this.addProxyExtensionHook("ao.heartbeat", new ProxyPlugin.PlayerHeartbeat());
      (new Thread(new ProxyPlugin.PlayerTimeout(), "PlayerTimeout")).start();
   }

   private static String getPluginName() {
      try {
         String proxyPluginName = Engine.getAgent().getDomainClient().allocName("PLUGIN", "Proxy#");
         return proxyPluginName;
      } catch (IOException var2) {
         throw new AORuntimeException("Could not allocate proxy plugin name", var2);
      }
   }

   public static boolean isOnBlockList(OID subject, OID target) {
      WorldManagerClient.ExtensionMessage message = new WorldManagerClient.ExtensionMessage(SocialClient.MSG_TYPE_IS_ON_BLOCK_LIST, "ao.IS_ON_BLOCK_LIST", subject);
      message.setProperty("targetOid", target);
      return Engine.getAgent().sendRPCReturnBoolean(message);
   }

   public boolean isDevMode() {
      return this.devMode;
   }

   public void setDevMode(boolean mode) {
      this.devMode = mode;
   }

   public List<MessageType> getExtraPlayerMessageTypes() {
      return this.extraPlayerMessageTypes;
   }

   public void setExtraPlayerMessageTypes(List<MessageType> extraPlayerMessageTypes) {
      this.extraPlayerMessageTypes = extraPlayerMessageTypes;
   }

   public void addExtraPlayerMessageType(MessageType messageType) {
      if (this.extraPlayerMessageTypes == null) {
         this.extraPlayerMessageTypes = new LinkedList();
      }

      this.extraPlayerMessageTypes.add(messageType);
   }

   public void addExtraPlayerExtensionMessageType(MessageType messageType) {
      this.addExtraPlayerMessageType(messageType);
      this.getHookManager().addHook(messageType, new ProxyPlugin.ExtensionHook());
   }

   public void addProxyExtensionHook(String subType, ProxyExtensionHook hook) {
      synchronized(this.extensionHooks) {
         List<ProxyExtensionHook> hookList = (List)this.extensionHooks.get(subType);
         if (hookList == null) {
            hookList = new ArrayList();
            this.extensionHooks.put(subType, hookList);
         }

         ((List)hookList).add(hook);
      }
   }

   public Map<String, List<ProxyExtensionHook>> getProxyExtensionHooks(String subType) {
      return this.extensionHooks;
   }

   public void onActivate() {
      try {
         PacketAggregator.initializeAggregation(Engine.getProperties());
         String logProxyHistograms = Engine.properties.getProperty("atavism.log_proxy_histograms");
         if (logProxyHistograms != null && logProxyHistograms.equals("true")) {
            int interval = 5000;
            String intervalString = Engine.properties.getProperty("atavism.log_proxy_histograms_interval");
            if (intervalString != null) {
               int newInterval = Integer.parseInt(intervalString);
               if (newInterval > 0) {
                  interval = newInterval;
               }
            }

            this.proxyQueueHistogram = new TimeHistogram("TimeInQ", interval);
            this.proxyCallbackHistogram = new TimeHistogram("TimeInCallback", interval);
            this.countLogger.start();
         }

         this.filteredProps = new HashSet();
         this.playerSpecificProps = new HashSet();
         this.cachedPlayerSpecificFilterProps = new HashSet();
         this.addFilteredProperty("inv.bag");
         this.addFilteredProperty(":loc");
         this.addFilteredProperty("masterOid");
         this.addFilteredProperty("agisobj.basedc");
         this.addFilteredProperty("aoobj.dc");
         this.addFilteredProperty("aoobj.followsterrainflag");
         this.addFilteredProperty("aoobj.perceiver");
         this.addFilteredProperty("aoobj.scale");
         this.addFilteredProperty("aoobj.mobflag");
         this.addFilteredProperty("aoobj.structflag");
         this.addFilteredProperty("aoobj.userflag");
         this.addFilteredProperty("aoobj.itemflag");
         this.addFilteredProperty("aoobj.lightflag");
         this.addFilteredProperty("namespace");
         this.addFilteredProperty("regenEffectMap");
         this.addFilteredProperty(WorldManagerClient.MOB_PATH_PROPERTY);
         this.addFilteredProperty(WorldManagerClient.TEMPL_SOUND_DATA_LIST);
         this.addFilteredProperty(WorldManagerClient.TEMPL_TERRAIN_DECAL_DATA);
         this.addFilteredProperty("instanceStack");
         this.addFilteredProperty("currentInstanceName");
         this.addFilteredProperty("ignored_oids");
         this.registerHooks();
         ProxyPlugin.PluginMessageCallback pluginMessageCallback = new ProxyPlugin.PluginMessageCallback();
         MessageTypeFilter filter = new MessageTypeFilter();
         filter.addType(WorldManagerClient.MSG_TYPE_SYS_CHAT);
         Engine.getAgent().createSubscription(filter, pluginMessageCallback);
         LinkedList<MessageType> types = new LinkedList();
         types.add(WorldManagerClient.MSG_TYPE_PERCEPTION_INFO);
         types.add(WorldManagerClient.MSG_TYPE_ANIMATION);
         types.add(WorldManagerClient.MSG_TYPE_DISPLAY_CONTEXT);
         types.add(WorldManagerClient.MSG_TYPE_DETACH);
         types.add(PropertyMessage.MSG_TYPE_PROPERTY);
         types.add(ChatClient.MSG_TYPE_COM);
         types.add(SocialClient.MSG_TYPE_BLOCK_LIST);
         types.add(CombatClient.MSG_TYPE_DAMAGE);
         types.add(WorldManagerClient.MSG_TYPE_UPDATEWNODE);
         types.add(WorldManagerClient.MSG_TYPE_MOB_PATH);
         types.add(WorldManagerClient.MSG_TYPE_WNODECORRECT);
         types.add(WorldManagerClient.MSG_TYPE_ORIENT);
         types.add(WorldManagerClient.MSG_TYPE_SOUND);
         types.add(AnimationClient.MSG_TYPE_INVOKE_EFFECT);
         types.add(WorldManagerClient.MSG_TYPE_EXTENSION);
         types.add(WorldManagerClient.MSG_TYPE_P2P_EXTENSION);
         types.add(InventoryClient.MSG_TYPE_INV_UPDATE);
         types.add(CombatClient.MSG_TYPE_ABILITY_STATUS);
         types.add(CombatClient.MSG_TYPE_ABILITY_UPDATE);
         types.add(WorldManagerClient.MSG_TYPE_FOG);
         types.add(WorldManagerClient.MSG_TYPE_ROAD);
         types.add(WorldManagerClient.MSG_TYPE_NEW_DIRLIGHT);
         types.add(WorldManagerClient.MSG_TYPE_SET_AMBIENT);
         types.add(WorldManagerClient.MSG_TYPE_TARGETED_PROPERTY);
         types.add(WorldManagerClient.MSG_TYPE_FREE_OBJECT);
         types.add(MSG_TYPE_VOICE_PARMS);
         types.add(MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST);
         types.add(MSG_TYPE_GET_MATCHING_PLAYERS);
         types.add(MSG_TYPE_ADD_STATIC_PERCEPTION);
         types.add(MSG_TYPE_REMOVE_STATIC_PERCEPTION);
         if (this.extraPlayerMessageTypes != null) {
            types.addAll(this.extraPlayerMessageTypes);
         }

         this.perceptionFilter = new PerceptionFilter(types, true);
         PerceptionTrigger perceptionTrigger = new PerceptionTrigger();
         this.perceptionSubId = Engine.getAgent().createSubscription(this.perceptionFilter, this.playerMessageCallback, 0, (MessageTrigger)perceptionTrigger);
         types.clear();
         types.add(InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ);
         types.add(MSG_TYPE_PLAYER_IGNORE_LIST_REQ);
         types.add(MSG_TYPE_GET_PLAYER_LOGIN_STATUS);
         types.add(MSG_TYPE_LOGOUT_PLAYER);
         this.responderFilter = new PerceptionFilter(types);
         this.responderSubId = Engine.getAgent().createSubscription(this.responderFilter, this.playerMessageCallback, 8);
         this.responderFilter2 = new PerceptionFilter();
         this.responderSubId2 = Engine.getAgent().createSubscription(this.responderFilter2, this, 8);
         types.clear();
         types.add(Management.MSG_TYPE_GET_PLUGIN_STATUS);
         Engine.getAgent().createSubscription(new MessageTypeFilter(types), pluginMessageCallback, 8);
         MessageTypeFilter filter3 = new MessageTypeFilter();
         filter3.addType(MSG_TYPE_ACCOUNT_LOGIN);
         Engine.getAgent().createSubscription(filter3, this);
         String log_rdp_counters = Engine.getProperty("atavism.log_rdp_counters");
         if (log_rdp_counters == null || log_rdp_counters.equals("false")) {
            RDPServer.setCounterLogging(false);
         }

         RDPServer.startRDPServer();
         this.initializeVoiceServerInformation();
         this.registerExtensionSubtype("voice_parms", MSG_TYPE_VOICE_PARMS);
         this.registerExtensionSubtype("player_path_req", MSG_TYPE_PLAYER_PATH_REQ);
         this.registerExtensionSubtype("player_path_req", MSG_TYPE_PLAYER_PATH_REQ);
         this.registerExtensionSubtype("ao.UPDATE_PLAYER_IGNORE_LIST", MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST);
         this.registerExtensionSubtype("ao.GET_MATCHING_PLAYERS", MSG_TYPE_GET_MATCHING_PLAYERS);
         this.registerExtensionSubtype("ao.PLAYER_IGNORE_LIST_REQ", MSG_TYPE_PLAYER_IGNORE_LIST_REQ);
         Log.debug("ProxyPlugin before bindAddress");
         InetSocketAddress bindAddress = this.getBindAddress();
         Log.debug("ProxyPlugin after bindAddress " + bindAddress.getHostName() + " " + bindAddress.getAddress() + " " + bindAddress.getPort());
         Log.debug("ProxyPlugin before server socket");
         int port = Integer.parseInt(Engine.getProperty("atavism.proxy.bindport").trim());
         Log.debug("Proxy: getBindAddress port=" + port);
         String agent_name = Engine.getAgent().getName();
         String[] an = agent_name.split("_");
         int agentId = Integer.parseInt(an[1]);
         port += agentId - 1;
         int rdpChannels = Integer.parseInt(Engine.properties.getProperty("atavism.proxy.rdp_channels", String.valueOf(128)));

         for(int i = 0; i < rdpChannels; ++i) {
            RDPServerSocket serverSocket = new RDPServerSocket();
            serverSocket.registerAcceptCallback(this);
            serverSocket.bind(port, serverSocketReceiveBufferSize);
            if (Log.loggingDebug) {
               Log.debug("BIND: binding for client tcp and rdp packets on port " + bindAddress.getPort() + " with rdpsocket: " + serverSocket.toString());
            }
         }

         Log.debug("BIND: bound server socket");
         this.clientTCPMessageIO = ClientTCPMessageIO.setup((InetSocketAddress)bindAddress, this, this);
         Log.debug("BIND: setup clientTCPMessage");
         this.clientTCPMessageIO.start("ClientIO");
         Log.debug("BIND: started clientTCPMessage");
         InetSocketAddress externalAddress = this.getExternalAddress(bindAddress);
         Log.debug("BIND: got external Address " + externalAddress.getHostName() + " " + externalAddress.getAddress() + " " + externalAddress.getPort());
         this.setPluginInfo("host=" + Engine.getProperty("atavism.proxy.externaladdress") + ",port=" + externalAddress.getPort());
         Log.debug("Registering proxy plugin");
         Engine.registerStatusReportingPlugin(this);
         Log.debug("Proxy: activation done");
         this.runCheck();
         Gauge.builder("event_qq_size", new Supplier<Number>() {
            public Number get() {
               return ProxyPlugin.this.eventQQ.getSQSize();
            }
         }).register(Prometheus.registry());
         Gauge.builder("message_qq_size", new Supplier<Number>() {
            public Number get() {
               return ProxyPlugin.this.messageQQ.getSQSize();
            }
         }).register(Prometheus.registry());
         Gauge.builder("message_qq_unqueued_size", new Supplier<Number>() {
            public Number get() {
               return ProxyPlugin.this.messageQQ.getSQUnqueuedSize();
            }
         }).register(Prometheus.registry());
      } catch (Exception var16) {
         throw new AORuntimeException("activate failed", var16);
      }
   }

   private InetSocketAddress getBindAddress() throws IOException {
      String propStr = Engine.getProperty("atavism.proxy.bindport");
      Log.debug("Proxy: getBindAddress propStr=" + propStr);
      int port;
      if (propStr != null) {
         port = Integer.parseInt(propStr.trim());
         Log.debug("Proxy: getBindAddress port=" + port);
         String agent_name = Engine.getAgent().getName();
         String[] an = agent_name.split("_");
         int agentId = Integer.parseInt(an[1]);
         port += agentId - 1;
         Log.debug("Proxy: getBindAddress port=" + port);
      } else {
         port = Integer.parseInt(Engine.getProperty("atavism.proxyport").trim());
      }

      Log.debug("Proxy: getBindAddress port=" + port);
      propStr = Engine.getProperty("atavism.proxy.bindaddress");
      Log.debug("Proxy: getBindAddress propStr=" + propStr + " " + Character.digit(propStr.charAt(0), 16) + " " + Character.digit(propStr.charAt(1), 16) + " " + Character.digit(propStr.charAt(2), 16) + " c=");
      int count = 0;
      if (propStr.contains(".")) {
         for(int i = 0; i < propStr.length(); ++i) {
            if (propStr.charAt(i) == '.') {
               ++count;
            }
         }
      }

      InetAddress address = null;
      InetAddress[] address2 = null;
      if (count == 3 && Character.digit(propStr.charAt(0), 10) != -1) {
      }

      if (propStr != null) {
         try {
            address = InetAddress.getByName(propStr.trim());
            address2 = InetAddress.getAllByName(propStr.trim());
            InetAddress[] var6 = address2;
            int var7 = address2.length;

            for(int var8 = 0; var8 < var7; ++var8) {
               InetAddress ai = var6[var8];
               Log.debug("Proxy: getBindAddress address2=" + ai + " " + ai.getHostName() + " " + ai.getHostAddress());
            }

            Log.debug("Proxy: getBindAddress address=" + address + " " + address.getHostName() + " " + address.getHostAddress());
         } catch (UnknownHostException var10) {
            log.error("getBindAddress " + var10.getMessage() + " " + var10.getLocalizedMessage());
         }
      }

      Log.debug("Proxy: getBindAddress address=" + address + " " + address.getHostName() + " " + address.getAddress());
      return new InetSocketAddress(address, port);
   }

   private InetSocketAddress getExternalAddress(InetSocketAddress bindAddress) throws IOException {
      String propStr = Engine.getProperty("atavism.proxy.externalport");
      Log.debug("Proxy: getExternalAddress ext port propStr=" + propStr);
      int port;
      if (propStr != null) {
         port = Integer.parseInt(propStr.trim());
      } else {
         port = bindAddress.getPort();
      }

      Log.debug("Proxy: getExternalAddress port=" + port);
      propStr = Engine.getProperty("atavism.proxy.externaladdress");
      Log.debug("Proxy: getExternalAddress ext addr propStr=" + propStr);
      InetAddress address;
      if (propStr != null) {
         address = InetAddress.getByName(propStr.trim());
      } else {
         address = bindAddress.getAddress();
         Log.debug("Proxy: getExternalAddress else address=" + address);
         if (address.isAnyLocalAddress()) {
            address = InetAddress.getLocalHost();
            Log.debug("Proxy: getExternalAddress get local host address=" + address + " " + address.getHostName() + " " + address.getHostAddress());
         }
      }

      Log.debug("Proxy: getExternalAddress address=" + address + " " + address.getHostName() + " " + address.getAddress());
      return new InetSocketAddress(address, port);
   }

   private String howla() {
      String characters = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnoprstquwxyz123456789";
      String k = "";

      for(int i = 0; i < 14; ++i) {
         Random random = new Random();
         k = k + characters.charAt(random.nextInt(characters.length() - 1));
      }

      return k;
   }

   private void runCheck() {
      String email = Engine.getProperty("atavism.licence.email");
      String licencekey = Engine.getProperty("atavism.licence.key");
      String proxy_id = Engine.getProperty("atavism.proxy.id");
      int num = 0;
      int proxyId = 0;

      try {
         if (proxy_id != null && proxy_id != "") {
            proxyId = Integer.parseInt(proxy_id);
         }
      } catch (NumberFormatException var18) {
      }

      String[] url = new String[]{"https://apanel.atavismonline.com/login/verifyserver.php", "https://licensing2.dragonsan.com:2443/login/verifyserver.php", "https://licensing1.atavismonline.com/login/verifyserver.php", "https://licensing.dragonsan.com/login/verifyserver.php", "https://licensing1.dragonsan.com/login/verifyserver.php", "https://licensing.atavismonline.com/login/verifyserver.php", "https://licensing2.atavismonline.com/login/verifyserver.php"};
      String resSor = this.howla();
      ProxyPlugin.rck reCheck = new ProxyPlugin.rck(resSor);
      Engine.getExecutor().scheduleAtFixedRate(reCheck, 300L, 300L, TimeUnit.SECONDS);

      while(num < url.length) {
         boolean failed = false;

         try {
            String res = "";
            URL urlObj = new URL(url[num]);
            URLConnection lu = urlObj.openConnection();
            lu.setConnectTimeout(10000);
            String data = "email=" + URLEncoder.encode(email, "UTF-8") + "&licence=" + URLEncoder.encode(licencekey, "UTF-8") + "&ver=" + URLEncoder.encode("10.9.0", "UTF-8") + "&addr=" + URLEncoder.encode(Engine.getProperty("atavism.proxy.bindaddress"), "UTF-8") + "&sor=" + URLEncoder.encode(resSor, "UTF-8") + "&c=" + URLEncoder.encode("0", "UTF-8") + "&cp=" + this.playerManager.getPlayerCount() + " &pi=" + proxyId + "&build=" + URLEncoder.encode(ServerVersion.getBuildDate(), "UTF-8") + "&m=" + MaxConcurrentUsers;
            lu.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(lu.getOutputStream());
            wr.write(data);
            wr.flush();
            BufferedReader rd = new BufferedReader(new InputStreamReader(lu.getInputStream()));

            for(String line = ""; (line = rd.readLine()) != null; res = res + line) {
            }

            wr.flush();
            wr.close();
            if (debugLic) {
               System.out.println("\n" + url[num] + "\n" + res + "\n");
            }

            res = HelperFunctions.readEncodedString(Base64.decode(res));
            String[] output = res.split(":");
            if (debugLic) {
               System.out.println("\nsec: " + resSor + "\n s: " + HelperFunctions.readEncodedString(Base64.decode(output[2])) + "\n");
            }

            if (EncryptionHelper.passwordMD5Check(output[0], this.getTemp()) && resSor.equals(HelperFunctions.readEncodedString(Base64.decode(output[2])))) {
               this.connectionLimit = Integer.parseInt(HelperFunctions.readEncodedString(Base64.decode(output[1])));
            } else {
               System.out.println("\nLicense verification failed");
               Log.error("License verification failed");
            }

            Log.debug("CONNECTOR: connections set to: " + this.connectionLimit);
         } catch (Exception var19) {
            Log.error("CONNECTOR: failed verifying " + var19);
            if (debugLic) {
               System.out.println("\n" + url[num] + "\n" + var19);
            }

            ++num;
            failed = true;
         }

         if (!failed) {
            return;
         }
      }

      System.out.println("\nLicense verification failed");
      Log.error("License verification failed");
      this.connectionLimit = 0;
   }

   public Map<String, String> getStatusMap() {
      Map<String, String> status = new HashMap();
      status.put("players", Integer.toString(this.playerManager.getPlayerCount()));
      return status;
   }

   public void registerCommand(String command, ProxyPlugin.CommandParser parser) {
      this.commandMapLock.lock();

      try {
         this.commandMap.put(command, new ProxyPlugin.RegisteredCommand(parser, this.defaultCommandAccess));
      } finally {
         this.commandMapLock.unlock();
      }

   }

   public void registerCommand(String command, ProxyPlugin.CommandParser parser, ProxyPlugin.CommandAccessCheck access) {
      this.commandMapLock.lock();

      try {
         this.commandMap.put(command, new ProxyPlugin.RegisteredCommand(parser, access));
      } finally {
         this.commandMapLock.unlock();
      }

   }

   void registerHooks() {
      log.debug("registering hooks");
      this.getHookManager().addHook(SocialClient.MSG_TYPE_BLOCK_LIST, new ProxyPlugin.BlockListHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_DISPLAY_CONTEXT, new ProxyPlugin.DisplayContextHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_DETACH, new ProxyPlugin.DetachHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_ANIMATION, new ProxyPlugin.AnimationHook());
      this.getHookManager().addHook(AnimationClient.MSG_TYPE_INVOKE_EFFECT, new ProxyPlugin.InvokeEffectHook());
      this.getHookManager().addHook(PropertyMessage.MSG_TYPE_PROPERTY, new ProxyPlugin.PropertyHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_EXTENSION, new ProxyPlugin.ExtensionHook());
      this.getHookManager().addHook(CombatClient.MSG_TYPE_ABILITY_STATUS, new ProxyPlugin.AbilityStatusHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_TARGETED_PROPERTY, new ProxyPlugin.TargetedPropertyHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_PERCEPTION_INFO, new ProxyPlugin.PerceptionHook());
      this.getHookManager().addHook(ChatClient.MSG_TYPE_COM, new ProxyPlugin.ComHook());
      this.getHookManager().addHook(CombatClient.MSG_TYPE_DAMAGE, new ProxyPlugin.DamageHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_SYS_CHAT, new ProxyPlugin.SysChatHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_UPDATEWNODE, new ProxyPlugin.UpdateWNodeHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_MOB_PATH, new ProxyPlugin.UpdateMobPathHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_WNODECORRECT, new ProxyPlugin.WNodeCorrectHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_ORIENT, new ProxyPlugin.OrientHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_SOUND, new ProxyPlugin.SoundHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_FOG, new ProxyPlugin.FogHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_ROAD, new ProxyPlugin.RoadHook());
      this.getHookManager().addHook(InventoryClient.MSG_TYPE_INV_UPDATE, new ProxyPlugin.InvUpdateHook());
      this.getHookManager().addHook(CombatClient.MSG_TYPE_ABILITY_UPDATE, new ProxyPlugin.AbilityUpdateHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_NEW_DIRLIGHT, new ProxyPlugin.NewDirLightHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_FREE_OBJECT, new ProxyPlugin.FreeObjectHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_SET_AMBIENT, new ProxyPlugin.SetAmbientHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_P2P_EXTENSION, new ProxyPlugin.P2PExtensionHook());
      this.getHookManager().addHook(MSG_TYPE_VOICE_PARMS, new ProxyPlugin.VoiceParmsHook());
      this.getHookManager().addHook(MSG_TYPE_PLAYER_PATH_REQ, new ProxyPlugin.PlayerPathReqHook());
      this.getHookManager().addHook(InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ, new ProxyPlugin.InstanceEntryReqHook());
      this.getHookManager().addHook(Management.MSG_TYPE_GET_PLUGIN_STATUS, new ProxyPlugin.GetPluginStatusHook());
      this.getHookManager().addHook(MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST, new ProxyPlugin.UpdatePlayerIgnoreListHook());
      this.getHookManager().addHook(MSG_TYPE_GET_MATCHING_PLAYERS, new ProxyPlugin.GetMatchingPlayersHook());
      this.getHookManager().addHook(MSG_TYPE_PLAYER_IGNORE_LIST_REQ, new ProxyPlugin.PlayerIgnoreListReqHook());
      this.getHookManager().addHook(MSG_TYPE_GET_PLAYER_LOGIN_STATUS, new ProxyPlugin.GetPlayerLoginStatusHook());
      this.getHookManager().addHook(MSG_TYPE_LOGOUT_PLAYER, new ProxyPlugin.LogoutPlayerHook());
      this.getHookManager().addHook(MSG_TYPE_ADD_STATIC_PERCEPTION, new ProxyPlugin.AddStaticPerceptionHook());
      this.getHookManager().addHook(MSG_TYPE_REMOVE_STATIC_PERCEPTION, new ProxyPlugin.RemoveStaticPerceptionHook());
      this.getHookManager().addHook(MSG_TYPE_ACCOUNT_LOGIN, new ProxyPlugin.AccountLoginHook());
   }

   void callEngineOnMessage(Message message, int flags) {
      super.handleMessage(message, flags);
   }

   protected void initializeVoiceServerInformation() {
      voiceServerHost = Engine.properties.getProperty("atavism.voiceserver");
      String s = Engine.properties.getProperty("atavism.voiceport");
      if (s != null) {
         voiceServerPort = Integer.parseInt(s);
      }

      if (Log.loggingDebug) {
         log.debug("initializeVoiceServerInformation: voiceServerHost " + voiceServerHost + ", voiceServerPort " + voiceServerPort);
      }

   }

   public void acceptConnection(ClientConnection con) {
      Log.info("ProxyPlugin: CONNECTION remote=" + con);
      con.registerMessageCallback(this);
   }

   public void processPacket(ClientConnection con, AOByteBuffer buf) {
      try {
         long time1 = System.nanoTime();
         if (Log.loggingNet) {
            if (ClientConnection.getLogMessageContents()) {
               Log.net("ProxyPlugin.processPacket: con " + con + ", length " + buf.limit() + ", packet " + DebugUtils.byteArrayToHexString(buf));
            } else {
               Log.net("ProxyPlugin.processPacket: con " + con + ", buf " + buf);
            }
         }

         Event event = Engine.getEventServer().parseBytes(buf, con);
         if (event == null) {
            Log.error("Engine: could not parse packet data, remote=" + con);
            return;
         }

         SquareQueue<Player, Event> qq = this.eventQQ;
         if (event instanceof AuthorizedLoginEvent) {
            qq = this.slowEventQQ;
         }

         Player player = (Player)con.getAssociation();
         if (player == null) {
            if (!(event instanceof AuthorizedLoginEvent)) {
               Log.error("Cannot process event for connection with no player: " + con);
               return;
            }

            Log.info("ProxyPlugin: LOGIN_RECV remote=" + con + " playerOid=" + ((AuthorizedLoginEvent)event).getOid());
            player = new Player(((AuthorizedLoginEvent)event).getOid(), con);
         }

         this.playerManager.processEvent(player, event, qq);
         long time2 = System.nanoTime();
         Timer.builder("process_packet_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(time2 - time1));
      } catch (AORuntimeException var10) {
         Log.exception("ProxyPlugin.processPacket caught exception", var10);
      }

   }

   public Set<OID> getPlayerOids() {
      List<Player> players = new ArrayList(this.playerManager.getPlayerCount());
      this.playerManager.getPlayers(players);
      Set<OID> result = new HashSet(players.size());
      Iterator var3 = players.iterator();

      while(var3.hasNext()) {
         Player player = (Player)var3.next();
         result.add(player.getOid());
      }

      return result;
   }

   public List<String> getPlayerNames() {
      List<Player> players = new ArrayList(this.playerManager.getPlayerCount());
      Log.debug("ProxyPlugin.getPlayerNames: count is " + this.playerManager.getPlayerCount());
      this.playerManager.getPlayers(players);
      List<String> result = new ArrayList(players.size());
      Iterator var3 = players.iterator();

      while(var3.hasNext()) {
         Player player = (Player)var3.next();
         result.add(player.getName() + " " + player.getOid() + " " + this.getName());
      }

      Collections.sort(result);
      return result;
   }

   public List<String> getAllPlayerNames() {
      Log.debug("ProxyPlugin.getAllPlayerNames: count is " + this.playersOnlineList.size());
      List<String> result = new ArrayList(this.playersOnlineList.size());
      HashMap<OID, String> plays = new HashMap();
      plays.putAll(this.playersOnlineList);
      Iterator var3 = plays.keySet().iterator();

      while(var3.hasNext()) {
         OID player = (OID)var3.next();
         result.add((String)plays.get(player) + " " + player + " " + (String)this.playersOnlineOnProxy.get(player));
      }

      Collections.sort(result);
      return result;
   }

   public List<Player> getPlayers() {
      List<Player> players = new ArrayList(this.playerManager.getPlayerCount());
      this.playerManager.getPlayers(players);
      return players;
   }

   public Player getPlayer(OID oid) {
      return this.playerManager.getPlayer(oid);
   }

   public void addPlayerMessage(Message message, Player player) {
      long start = System.nanoTime();
      message.setEnqueueTime();
      this.messageQQ.insert((Object)player, message);
      long microseconds = System.nanoTime() - start;
   }

   public void addFilteredProperty(String filteredProperty) {
      this.filteredProps.add(filteredProperty);
      this.cachedPlayerSpecificFilterProps.add(filteredProperty);
   }

   public void addPlayerSpecificProperty(String filteredProperty) {
      this.playerSpecificProps.add(filteredProperty);
      this.cachedPlayerSpecificFilterProps.add(filteredProperty);
   }

   protected void recreatePlayerSpecificCache() {
      this.cachedPlayerSpecificFilterProps = new HashSet();
      this.cachedPlayerSpecificFilterProps.addAll(this.filteredProps);
      this.cachedPlayerSpecificFilterProps.addAll(this.playerSpecificProps);
   }

   protected boolean processLogin(ClientConnection con, AuthorizedLoginEvent loginEvent) {
      Prometheus.registry().counter("player_login_request", new String[0]).increment();
      OID playerOid = loginEvent.getOid();
      String version = loginEvent.getVersion();
      int nPlayers = this.playerManager.getPlayerCount();
      String[] clientVersionCapabilities = null;
      if (version != null && version.length() > 0) {
         clientVersionCapabilities = version.split(",");
      }

      LinkedList<String> clientCapabilities = new LinkedList();
      String clientVersion = "";
      int i;
      if (clientVersionCapabilities != null && clientVersionCapabilities.length > 0) {
         clientVersion = clientVersionCapabilities[0];

         for(i = 1; i < clientVersionCapabilities.length; ++i) {
            clientCapabilities.add(clientVersionCapabilities[i].trim());
         }
      }

      i = ServerVersion.compareVersionStrings(clientVersion, "10.9.0");
      AuthorizedLoginResponseEvent loginResponse;
      if (i != 0) {
         Log.warn("processLogin: unsupported version " + clientVersion + " from player: " + playerOid);
         loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed: Unsupported client version", this.serverVersion);
         con.send(loginResponse.toBytes());
         Prometheus.registry().counter("player_login_result", new String[]{"status", "unsupported_version"}).increment();
         return false;
      } else {
         if (this.isAdmin(playerOid) && nPlayers < this.connectionLimit) {
            Log.debug("processLogin: player is admin, bypassing max check");
         } else {
            Log.debug("processLogin: player is not admin");
            if (nPlayers >= MaxConcurrentUsers || nPlayers >= this.connectionLimit) {
               Log.warn("processLogin: too many users, failed for player: " + playerOid);
               loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, this.capacityError, this.serverVersion);
               con.send(loginResponse.toBytes());
               Prometheus.registry().counter("player_login_result", new String[]{"status", "too_many_users_" + String.valueOf(this.connectionLimit)}).increment();
               return false;
            }
         }

         SecureToken token = SecureTokenManager.getInstance().importToken(loginEvent.getWorldToken());
         boolean validToken = true;
         if (!token.getValid()) {
            Log.debug("token is not valid");
            validToken = false;
         }

         OID characterOid = (OID)token.getProperty("character_oid");
         if (Log.loggingDebug) {
            Log.debug("PlayerOID: " + playerOid);
         }

         if (Log.loggingDebug) {
            Log.debug("CharacterOID: " + characterOid);
         }

         if (!playerOid.equals(characterOid)) {
            Log.debug("playerOid does not match character_oid");
            validToken = false;
         }

         if (!token.getProperty("proxy_server").equals(Engine.getAgent().getName())) {
            Log.debug("proxy_server does not match engine agent name");
            validToken = false;
         }

         if (!validToken) {
            Log.error("processLogin: invalid proxy token");
            Event loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, this.tokenError, this.serverVersion);
            con.send(loginResponse.toBytes());
            Prometheus.registry().counter("player_login_result", new String[]{"status", "invalid_token"}).increment();
            return false;
         } else {
            try {
               TargetMessage getPlayerLoginStatus = new TargetMessage(MSG_TYPE_GET_PLAYER_LOGIN_STATUS, playerOid);
               ProxyPlugin.PlayerLoginStatus loginStatus = (ProxyPlugin.PlayerLoginStatus)Engine.getAgent().sendRPCReturnObject(getPlayerLoginStatus);
               if (this.proxyLoginCallback.duplicateLogin(loginStatus, con)) {
                  if (loginStatus != null) {
                     if (Log.loggingInfo) {
                        Log.info("processLogin: LOGIN_DUPLICATE remote=" + con + " playerOid=" + playerOid + " name=" + loginStatus.name + " existingCon=" + loginStatus.clientCon + " existingProxy=" + loginStatus.proxyPluginName);
                     }
                  } else if (Log.loggingInfo) {
                     Log.info("processLogin: LOGIN_DUPLICATE remote=" + con + " playerOid=" + playerOid + " loginStatus is null");
                  }

                  log.debug("processLogin: Send logout");
                  Prometheus.registry().counter("player_logout", new String[]{"reason", "duplicate"}).increment();
                  TargetMessage logoutPly = new TargetMessage(MSG_TYPE_LOGOUT_PLAYER, playerOid);
                  Engine.getAgent().sendRPCReturnObject(logoutPly);
                  log.debug("processLogin: Send logout | ");
                  AuthorizedLoginResponseEvent loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed: Already connected", this.serverVersion);
                  con.send(loginResponse.toBytes());
                  Prometheus.registry().counter("player_login_result", new String[]{"status", "duplicate"}).increment();
                  return false;
               }
            } catch (NoRecipientsException var20) {
               if (Log.loggingDebug) {
                  log.debug("processLogin: OK! player is not logged " + var20);
               }
            }

            Player player = new Player(playerOid, con);
            player.setStatus(1);
            if (!this.playerManager.addPlayer(player)) {
               player = this.playerManager.getPlayer(playerOid);
               Log.info("processLogin: LOGIN_DUPLICATE remote=" + con + " playerOid=" + playerOid + " existing=" + player.getConnection());
               AuthorizedLoginResponseEvent loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed: Already connected", this.serverVersion);
               con.send(loginResponse.toBytes());
               Prometheus.registry().counter("player_login_result", new String[]{"status", "duplicate_add"}).increment();
               return false;
            } else {
               con.setAssociation(player);
               player.setVersion(clientVersion);
               player.setCapabilities(clientCapabilities);
               String errorMessage = this.proxyLoginCallback.preLoad(player, con);
               AuthorizedLoginResponseEvent loginResponse;
               if (errorMessage != null) {
                  this.playerManager.removePlayer(playerOid);
                  loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, errorMessage, this.serverVersion);
                  con.send(loginResponse.toBytes());
                  Prometheus.registry().counter("player_login_result", new String[]{"status", "pre_load_error"}).increment();
                  return false;
               } else {
                  if (Log.loggingDebug) {
                     Log.debug("processLogin: loading object: " + playerOid + ", con=" + con);
                  }

                  if (!this.loadPlayerObject(player)) {
                     Log.error("processLogin: could not load object " + playerOid);
                     this.playerManager.removePlayer(playerOid);
                     loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed", this.serverVersion);
                     con.send(loginResponse.toBytes());
                     Prometheus.registry().counter("player_login_result", new String[]{"status", "not_loaded"}).increment();
                     return false;
                  } else {
                     if (Log.loggingDebug) {
                        Log.debug("processLogin: loaded player object: " + playerOid);
                     }

                     errorMessage = this.proxyLoginCallback.postLoad(player, con);
                     if (errorMessage != null) {
                        this.playerManager.removePlayer(playerOid);
                        loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, errorMessage, this.serverVersion);
                        con.send(loginResponse.toBytes());
                        Prometheus.registry().counter("player_login_result", new String[]{"status", "error"}).increment();
                        return false;
                     } else {
                        loginResponse = new AuthorizedLoginResponseEvent(playerOid, true, "Login Succeeded", this.serverVersion + ", " + this.serverCapabilitiesSentToClient);
                        con.send(loginResponse.toBytes());
                        if (Log.loggingDebug) {
                           Log.debug("Login response sent for playerOid=" + playerOid + " the authorized login response message is : " + loginResponse.getMessage());
                        }

                        this.playerManager.addStaticPerception(player, playerOid);
                        boolean loginOK = this.processLoginHelper(con, player);
                        if (Log.loggingDebug) {
                           log.debug("processLogin: loginOK?:" + loginOK + "  | player=" + player);
                        }

                        if (!loginOK) {
                           if (Log.loggingDebug) {
                              Log.debug("processLogin: loading object: " + playerOid + ", con=" + con + " login failed disconect player");
                           }

                           con.setAssociation((Object)null);
                           if (this.perceptionFilter.removeTarget(playerOid)) {
                              FilterUpdate filterUpdate = new FilterUpdate(1);
                              filterUpdate.removeFieldValue(1, playerOid);
                              Engine.getAgent().applyFilterUpdate(this.perceptionSubId, filterUpdate);
                              this.responderFilter.removeTarget(playerOid);
                              this.responderFilter2.removeTarget(playerOid);
                              Engine.getAgent().applyFilterUpdate(this.responderSubId, filterUpdate);
                              Engine.getAgent().applyFilterUpdate(this.responderSubId2, filterUpdate);
                           }

                           this.playerManager.removeStaticPerception(player, playerOid);
                           this.playerManager.removePlayer(playerOid);
                           Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "bad_login"}).increment();
                           con.close();
                        } else {
                           this.proxyLoginCallback.postSpawn(player, con);
                           this.playerManager.loginComplete(player, this.eventQQ);
                           SubjectMessage loginSpawned = new SubjectMessage(MSG_TYPE_LOGIN_SPAWNED);
                           loginSpawned.setSubject(playerOid);
                           Engine.getAgent().sendBroadcast(loginSpawned);
                           this.processPlayerIgnoreList(player);
                           OID accountID = (OID)EnginePlugin.getObjectProperty(playerOid, WorldManagerClient.NAMESPACE, "accountId");
                           this.clientConnections.put(accountID, con);
                           if (player.getStatus() == 3) {
                              ProxyPlugin.ConnectionResetMessage message = new ProxyPlugin.ConnectionResetMessage(con, player);
                              message.setEnqueueTime();
                              this.messageQQ.insert((Object)player, message);
                           }
                        }

                        Prometheus.registry().counter("player_login_result", new String[]{"status", loginOK ? "ok" : "failed"}).increment();
                        if (Log.loggingDebug) {
                           log.debug("processLogin: loginOK?:" + loginOK + " || player=" + player);
                           log.debug("processLogin: loginOK:" + loginOK + " end");
                        }

                        return loginOK;
                     }
                  }
               }
            }
         }
      }
   }

   protected boolean loadPlayerObject(Player player) {
      if (Log.loggingDebug) {
         log.debug("loadPlayerObject player " + player);
      }

      InstanceRestorePoint restorePoint = null;
      LinkedList restoreStack = null;
      boolean first = true;
      OID playerOid = player.getOid();
      List<Namespace> namespaces = new ArrayList();
      OID oidResult = ObjectManagerClient.loadSubObject(playerOid, namespaces);
      if (Log.loggingDebug) {
         log.debug("loadPlayerObject player " + player + " oidResult=" + oidResult);
      }

      if (oidResult == null) {
         return false;
      } else {
         Point location = new Point();
         OID instanceOid = Engine.getDatabase().getLocation(playerOid, WorldManagerClient.NAMESPACE, location);
         if (Log.loggingDebug) {
            log.debug("loadPlayerObject instanceOid " + instanceOid + " instanceEntryAllowed:" + this.instanceEntryAllowed(playerOid, instanceOid, location));
         }

         if (Log.loggingDebug) {
            log.debug("loadPlayerObject: trying to load player into instance: " + instanceOid);
         }

         int guildID = this.aDB.GetGuildId(playerOid);
         if (Log.loggingDebug) {
            log.debug("loadPlayerObject: load player guildID: " + guildID);
         }

         while(true) {
            try {
               OID result = null;
               if (this.instanceEntryAllowed(playerOid, instanceOid, location)) {
                  InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145);
                  if (Log.loggingDebug) {
                     log.debug("loadPlayerObject InstanceInfo " + instanceInfo + " plyOid=" + instanceInfo.playerOid + " tempId" + instanceInfo.templateID + " groupId" + instanceInfo.groupOid + " guildId" + instanceInfo.guildId + " start do ");
                  }

                  if (instanceInfo.oid != null && (instanceInfo.populationLimit < 1 || instanceInfo.playerPopulation < instanceInfo.populationLimit)) {
                     result = ObjectManagerClient.loadObject(playerOid);
                     if (Log.loggingDebug) {
                        Log.debug("loadPlayerObject: loading player into instance: " + instanceInfo.oid + " of ID: " + instanceInfo.templateID);
                     }
                  }
               }

               if (restoreStack != null && !restorePoint.getFallbackFlag()) {
                  EnginePlugin.setObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack", restoreStack);
               }

               if (result == null) {
                  if (first) {
                     Integer instanceID = (Integer)EnginePlugin.getObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "currentInstanceName");
                     if (Log.loggingDebug) {
                        log.debug("Failed initial load, retrying with current instanceID=" + instanceID);
                     }

                     if (Log.loggingDebug) {
                        log.debug(" loadPlayerObject instanceID=" + instanceID + "  playerOid=" + playerOid + " guildID=" + guildID);
                     }

                     if (instanceID > 0) {
                        instanceOid = this.instanceEntryCallback.selectInstance(player, instanceID, playerOid, guildID);
                        if (Log.loggingDebug) {
                           log.debug("loadPlayerObject instanceOid:" + instanceOid);
                        }

                        if (instanceOid != null) {
                           InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145, false);
                           if (Log.loggingDebug) {
                              log.debug(" loadPlayerObject InstanceInfo " + instanceInfo + " plyOid=" + instanceInfo.playerOid + " tempId=" + instanceInfo.templateID + " groupId=" + instanceInfo.groupOid + " guildId=" + instanceInfo.guildId);
                           }

                           if (instanceInfo.oid != null) {
                              if (instanceInfo.populationLimit > 0 && instanceInfo.playerPopulation >= instanceInfo.populationLimit) {
                                 if (Log.loggingDebug) {
                                    Log.debug("POP: got population: " + instanceInfo.playerPopulation + " and limit: " + instanceInfo.populationLimit);
                                 }

                                 instanceOid = handleFullInstance(instanceInfo.templateID, instanceInfo);
                                 instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145);
                                 log.debug(" loadPlayerObject 2 InstanceInfo " + instanceInfo + " plyOid" + instanceInfo.playerOid + " tempId=" + instanceInfo.templateID + " groupId=" + instanceInfo.groupOid + " guildId=" + instanceInfo.guildId);
                              }

                              if (Log.loggingDebug) {
                                 log.debug("Failed initial load, retrying with instanceOid=" + instanceOid + " and instanceName: " + instanceInfo.name);
                              }

                              BasicWorldNode wnode = new BasicWorldNode();
                              wnode.setInstanceOid(instanceOid);
                              ObjectManagerClient.fixWorldNode(playerOid, wnode);
                              first = false;
                              continue;
                           }
                        }
                     }
                  }

                  if (restorePoint != null && restorePoint.getFallbackFlag()) {
                     if (Log.loggingDebug) {
                        log.debug("loadPlayerObject instanceOid " + instanceOid + " restorePoint:" + restorePoint + " restorePoint.getFallbackFlag():" + restorePoint.getFallbackFlag() + " return false");
                     }

                     return false;
                  }

                  restoreStack = (LinkedList)EnginePlugin.getObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack");
                  if (restoreStack != null && restoreStack.size() != 0) {
                     int size = restoreStack.size();
                     restorePoint = (InstanceRestorePoint)restoreStack.get(size - 1);
                     instanceOid = restorePoint.getInstanceOid();
                     if (restorePoint.getInstanceID() > 0) {
                        instanceOid = this.instanceEntryCallback.selectInstance(player, restorePoint.getInstanceID());
                        if (Log.loggingDebug) {
                           Log.debug("Failed finding matching instance, retrying with restore point instanceID=" + restorePoint.getInstanceID() + " result: " + instanceOid);
                        }
                     }

                     if (instanceOid != null) {
                        BasicWorldNode wnode = new BasicWorldNode();
                        wnode.setInstanceOid(instanceOid);
                        wnode.setLoc(restorePoint.getLoc());
                        wnode.setOrientation(restorePoint.getOrientation());
                        wnode.setDir(new AOVector(0.0F, 0.0F, 0.0F));
                        boolean rc = ObjectManagerClient.fixWorldNode(playerOid, wnode);
                        if (!rc) {
                           if (Log.loggingDebug) {
                              log.debug("loadPlayerObject instanceOid " + instanceOid + " rc:" + rc + " return false");
                           }

                           return false;
                        }

                        location = restorePoint.getLoc();
                     }

                     first = false;
                     if (!restorePoint.getFallbackFlag()) {
                        restoreStack.remove(size - 1);
                     }
                     continue;
                  }

                  Log.error("Failed finding matching instance, and restore stack is null or empty?" + restoreStack + " return false");
                  return false;
               }

               if (restorePoint != null) {
                  EnginePlugin.setObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "currentInstanceName", restorePoint.getInstanceID());
                  if (Log.loggingDebug) {
                     log.debug("INSTANCE: setting current instance prop: " + restorePoint.getInstanceID());
                  }
               }
            } catch (Exception var15) {
               log.error("loadPlayerObject instanceOid " + instanceOid + " Exception: " + var15.getMessage() + " " + var15.getLocalizedMessage());
            }

            if (Log.loggingDebug) {
               log.debug("loadPlayerObject instanceOid " + instanceOid + " END return true");
            }

            return true;
         }
      }
   }

   protected boolean processLoginHelper(ClientConnection con, Player player) {
      OID playerOid = player.getOid();
      WorldManagerClient.ObjectInfo objInfo = WorldManagerClient.getObjectInfo(playerOid);
      if (objInfo == null) {
         Log.error("processLogin: Could not get player ObjectInfo oid=" + playerOid);
         return false;
      } else {
         if (Log.loggingDebug) {
            log.debug("processLoginHelper objInfo " + objInfo.instanceOid);
         }

         if (World.FollowsTerrainOverride != null) {
            Log.debug("using follows terrain override");
            objInfo.followsTerrain = World.FollowsTerrainOverride;
         }

         if (Log.loggingDebug) {
            Log.debug("processLogin: got object info: " + objInfo);
         }

         player.setName(objInfo.name);
         InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(objInfo.instanceOid, -262145);
         if (Log.loggingDebug) {
            log.debug("InstanceInfo " + instanceInfo + " " + instanceInfo.playerOid + " " + instanceInfo.templateID + " " + instanceInfo.groupOid + " " + instanceInfo.guildId);
         }

         if (instanceInfo == null) {
            Log.error("processLogin: unknown instanceOid=" + objInfo.instanceOid);
            return false;
         } else {
            if (Log.loggingDebug) {
               Log.debug("processLogin: sending template (scene) name: " + instanceInfo.templateName);
            }

            Event worldFileEvent = new WorldFileEvent(instanceInfo.templateName);
            con.send(worldFileEvent.toBytes());
            player.sceneLoading(true);
            Log.debug("INFO: process login helper");
            con.send(objInfo.toBuffer(playerOid));
            DisplayContext dc = WorldManagerClient.getDisplayContext(playerOid);
            ModelInfoEvent modelInfoEvent = new ModelInfoEvent(playerOid);
            modelInfoEvent.setDisplayContext(dc);
            if (Log.loggingDebug) {
               Log.debug("processLogin: got dc: " + dc);
            }

            con.send(modelInfoEvent.toBytes());
            Map<String, DisplayContext> childMap = dc.getChildDCMap();
            if (childMap != null && !childMap.isEmpty()) {
               Iterator var10 = childMap.keySet().iterator();

               while(var10.hasNext()) {
                  String slot = (String)var10.next();
                  DisplayContext attachDC = (DisplayContext)childMap.get(slot);
                  if (attachDC == null) {
                     throw new AORuntimeException("attach DC is null for obj: " + playerOid);
                  }

                  OID attacheeOID = attachDC.getObjRef();
                  if (attacheeOID == null) {
                     throw new AORuntimeException("attachee oid is null for obj: " + playerOid);
                  }

                  if (Log.loggingDebug) {
                     Log.debug("processLogin: sending attach message to " + playerOid + " attaching to obj " + playerOid + ", object being attached=" + attacheeOID + " to slot " + slot + ", attachmentDC=" + attachDC);
                  }

                  AttachEvent event = new AttachEvent(playerOid, attacheeOID, slot, attachDC);
                  con.send(event.toBytes());
               }

               Log.debug("processLogin: done with processing attachments");
            }

            if (this.perceptionFilter.addTarget(playerOid)) {
               FilterUpdate filterUpdate = new FilterUpdate(1);
               filterUpdate.addFieldValue(1, playerOid);
               Engine.getAgent().applyFilterUpdate(this.perceptionSubId, filterUpdate);
               this.responderFilter.addTarget(playerOid);
               this.responderFilter2.addTarget(playerOid);
               Engine.getAgent().applyFilterUpdate(this.responderSubId, filterUpdate);
               Engine.getAgent().applyFilterUpdate(this.responderSubId2, filterUpdate);
            }

            LoginMessage loginMessage = new LoginMessage(playerOid, objInfo.name);
            loginMessage.setInstanceOid(objInfo.instanceOid);
            loginMessage.setProxy(this.getName());
            ProxyPlugin.AsyncRPCCallback asyncRPCCallback = new ProxyPlugin.AsyncRPCCallback(player, "processLogin: got LoginMessage response");
            int expectedResponses = Engine.getAgent().sendBroadcastRPC(loginMessage, asyncRPCCallback);
            asyncRPCCallback.waitForResponses(expectedResponses);
            WorldManagerClient.updateObject(playerOid, playerOid);
            WorldManagerClient.TargetedExtensionMessage spawnBegin = new WorldManagerClient.TargetedExtensionMessage(playerOid, playerOid);
            spawnBegin.setExtensionType("ao.SCENE_BEGIN");
            spawnBegin.setProperty("action", "login");
            spawnBegin.setProperty("name", instanceInfo.name);
            spawnBegin.setProperty("templateName", instanceInfo.templateName);
            WorldManagerClient.TargetedExtensionMessage spawnEnd = new WorldManagerClient.TargetedExtensionMessage(playerOid, playerOid);
            spawnEnd.setExtensionType("ao.SCENE_END");
            spawnEnd.setProperty("action", "login");
            spawnEnd.setProperty("name", instanceInfo.name);
            spawnEnd.setProperty("templateName", instanceInfo.templateName);
            Integer perceptionCount = WorldManagerClient.spawn(playerOid, spawnBegin, spawnEnd);
            if (perceptionCount < 0) {
               Log.error("processLogin: spawn failed error=" + perceptionCount + " playerOid=" + playerOid);
               return perceptionCount == -2 ? false : false;
            } else {
               if (perceptionCount == 0 && player.supportsLoadingState()) {
                  player.setLoadingState(1);
                  con.send((new LoadingStateEvent(false)).toBytes());
               }

               if (Log.loggingDebug) {
                  Log.debug("processLogin: During login, perceptionCount is " + perceptionCount);
                  Log.debug("processLogin: spawned player, master playerOid=" + playerOid);
               }

               if (Log.loggingDebug) {
                  Log.debug("processLogin: sending over instance information for player " + playerOid + ", instance=" + instanceInfo.name + ", instanceOid=" + instanceInfo.oid);
               }

               this.updateInstancePerception(player.getOid(), (OID)null, instanceInfo.oid, instanceInfo.name);
               return true;
            }
         }
      }
   }

   public ProxyLoginCallback getProxyLoginCallback() {
      return this.proxyLoginCallback;
   }

   public void setProxyLoginCallback(ProxyLoginCallback callback) {
      this.proxyLoginCallback = callback;
   }

   private boolean instanceEntryAllowed(OID playerOid, OID instanceOid, Point location) {
      return instanceOid == null ? false : this.instanceEntryCallback.instanceEntryAllowed(playerOid, instanceOid, location);
   }

   public InstanceEntryCallback getInstanceEntryCallback() {
      return this.instanceEntryCallback;
   }

   public void setInstanceEntryCallback(InstanceEntryCallback callback) {
      this.instanceEntryCallback = callback;
   }

   public void processRequestQuestInfo(ClientConnection con, RequestQuestInfo event) {
      OID npcOid = event.getQuestNpcOid();
      Player player = this.verifyPlayer("processRequestQuestInfo", event, con);
      if (Log.loggingDebug) {
         Log.debug("processRequestQuestInfo: player=" + player + ", npc=" + npcOid);
      }

      QuestClient.requestQuestInfo(npcOid, player.getOid());
   }

   public void processQuestResponse(ClientConnection con, QuestResponse event) {
      Player player = this.verifyPlayer("processQuestResponse", event, con);
      boolean acceptStatus = event.getResponse();
      OID npcOid = event.getQuestNpcOid();
      OID questOid = event.getQuestId();
      if (Log.loggingDebug) {
         Log.debug("processQuestResponse: player=" + player + ", npcOid=" + npcOid + ", acceptStatus=" + acceptStatus);
      }

      QuestResponseMessage msg = new QuestResponseMessage(npcOid, player.getOid(), questOid, acceptStatus);
      Engine.getAgent().sendBroadcast(msg);
   }

   public void processReqConcludeQuest(ClientConnection con, ConcludeQuest event) {
      Player player = this.verifyPlayer("processReqConcludeQuest", event, con);
      OID mobOid = event.getQuestNpcOid();
      if (Log.loggingDebug) {
         Log.debug("processReqConclude: player=" + player + ", mobOid=" + mobOid);
      }

      QuestClient.requestConclude(mobOid, player.getOid());
   }

   public void connectionReset(ClientConnection con) {
      Player player = (Player)con.getAssociation();
      if (player == null) {
         Log.info("ProxyPlugin: DISCONNECT remote=" + con);
      } else {
         if (Log.loggingInfo) {
            Log.info("ProxyPlugin: DISCONNECT remote=" + con + " playerOid=" + player.getOid() + " name=" + player.getName() + " player=" + player);
            Log.info("ProxyPlugin: DISCONNECT remote=" + con + " player=" + player);
         }

         this.playerManager.logout(player);
         ProxyPlugin.ConnectionResetMessage message = new ProxyPlugin.ConnectionResetMessage(con, player);
         message.setEnqueueTime();
         this.messageQQ.insert((Object)player, message);
      }
   }

   protected void processConnectionResetInternal(ProxyPlugin.ConnectionResetMessage message) {
      long startTime = System.currentTimeMillis();
      ClientConnection con = message.getConnection();
      Player player = message.getPlayer();
      OID playerOid = player.getOid();
      if (Log.loggingInfo) {
         Log.info("ProxyPlugin: LOGOUT_BEGIN remote=" + con + " playerOid=" + player.getOid() + " name=" + player.getName());
      }

      if (player.getStatus() != 3) {
         log.error("processConnectionReset: player status is " + Player.statusToString(player.getStatus()) + " should be " + Player.statusToString(3));
         player.setStatus(3);
      }

      try {
         try {
            if (!WorldManagerClient.despawn(playerOid)) {
               log.warn("processConnectionReset: despawn player failed for " + playerOid);
            }
         } catch (Exception var13) {
            log.warn("processConnectionReset: despawn player failed for " + playerOid + " " + var13);
         }

         if (Log.loggingDebug) {
            Log.debug("processConnectionResetInternal Removing perceptionFilter for palyer: " + playerOid);
         }

         if (this.perceptionFilter.removeTarget(playerOid)) {
            FilterUpdate filterUpdate = new FilterUpdate(1);
            filterUpdate.removeFieldValue(1, playerOid);
            if (Log.loggingDebug) {
               Log.debug("processConnectionResetInternal Removing perceptionFilter applyFilterUpdate for palyer: " + playerOid);
            }

            Engine.getAgent().applyFilterUpdate(this.perceptionSubId, filterUpdate);
            if (Log.loggingDebug) {
               Log.debug("processConnectionResetInternal Removing responderFilter for palyer: " + playerOid);
            }

            this.responderFilter.removeTarget(playerOid);
            this.responderFilter2.removeTarget(playerOid);
            if (Log.loggingDebug) {
               Log.debug("processConnectionResetInternal Removing perceptionFilter applyFilterUpdate for palyer: " + playerOid);
            }

            Engine.getAgent().applyFilterUpdate(this.responderSubId, filterUpdate);
            Engine.getAgent().applyFilterUpdate(this.responderSubId2, filterUpdate);
         }

         LogoutMessage logoutMessage = new LogoutMessage(playerOid, player.getName());
         if (Log.loggingDebug) {
            Log.debug("processConnectionResetInternal: Send LogoutMessage for player: " + playerOid + "  and wait for response");
         }

         ProxyPlugin.AsyncRPCCallback asyncRPCCallback = new ProxyPlugin.AsyncRPCCallback(player, "processLogout: got LogoutMessage response");
         int expectedResponses = Engine.getAgent().sendBroadcastRPC(logoutMessage, asyncRPCCallback);
         if (Log.loggingDebug) {
            Log.debug("processConnectionResetInternal: Send LogoutMessage for player: " + playerOid + "  and wait for response expectedResponses=" + expectedResponses);
         }

         asyncRPCCallback.waitForResponses(expectedResponses);
         OID accountID = this.aDB.getAccountForCharacter(playerOid);
         if (Log.loggingDebug) {
            Log.debug("Removing connection from client connection map for account: " + accountID);
         }

         if (this.clientConnections.containsKey(accountID) && ((ClientConnection)this.clientConnections.get(accountID)).isOpen()) {
            Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "internal_reset"}).increment();
            ((ClientConnection)this.clientConnections.get(accountID)).close();
         }

         this.clientConnections.remove(accountID);
         if (!ObjectManagerClient.unloadObject(playerOid)) {
            log.warn("processConnectionReset: unloadObject failed oid=" + playerOid);
         }
      } catch (NoRecipientsException var14) {
         log.exception("ProxyPlugin.processConnectionResetInternal(): NoRecipientsException ", var14);
      } catch (RPCTimeoutException var15) {
         log.exception("ProxyPlugin.processConnectionResetInternal(): RPCTimeoutException ", var15);
      } catch (Exception var16) {
         log.exception("ProxyPlugin.processConnectionResetInternal(): Exception ", var16);
      }

      this.messageQQ.removeKey(player);
      this.eventQQ.removeKey(player);
      this.slowEventQQ.removeKey(player);
      con.closeAggregator();
      this.playerManager.removeStaticPerception(player, playerOid);
      this.playerManager.removePlayer(playerOid);
      if (Log.loggingInfo) {
         Log.info("ProxyPlugin: LOGOUT_END remote=" + con + " playerOid=" + player.getOid() + " name=" + player.getName() + " in-queue=" + (startTime - message.getEnqueueTime()) + " processing=" + (System.currentTimeMillis() - startTime) + " nPlayers=" + this.playerManager.getPlayerCount());
      }

      synchronized(player) {
         player.clearConnection();
         player.notifyAll();
      }
   }

   protected void processPlayerHa(ClientConnection con, PlayerHaEvent event) {
      if (Log.loggingDebug) {
         Log.debug("processPlayerHa: got dir loc orient event: " + event);
      }

      Player player = this.verifyPlayer("processPlayerHa", event, con);
      long stime = System.currentTimeMillis();
      long ctime = event.getTime();
      long lctime = 0L;
      long lstime = 0L;

      try {
         lctime = (Long)this.playerLastClientTime.get(player.getOid());
      } catch (Exception var20) {
      }

      try {
         lstime = (Long)this.playerLastServerTime.get(player.getOid());
      } catch (Exception var19) {
      }

      this.playerLastClientTime.put(player.getOid(), event.getTime());
      this.playerLastServerTime.put(player.getOid(), stime);
      if (lctime > 0L && lstime > 0L && stime - lstime < (long)SpeedhackMinDiff) {
         log.error("SPEEDHACK detected plyOid=" + player.getOid() + " Ct=" + ctime + " LCT=" + lctime + " ST=" + stime + " LST=" + lstime + " dst=" + (stime - lstime) + " dct=" + (ctime - lctime));
         long count = 0L;

         try {
            count = (Long)this.playerSpeedHackCount.get(player.getOid());
         } catch (Exception var18) {
         }

         ++count;
         this.playerSpeedHackCount.put(player.getOid(), count);
         long fdtime = 0L;

         try {
            fdtime = (Long)this.playerFirstSpeedHackTime.get(player.getOid());
         } catch (Exception var17) {
         }

         if (fdtime == 0L) {
            fdtime = stime;
            this.playerFirstSpeedHackTime.put(player.getOid(), stime);
         }

         if (SpeedhackChatMsg.length() > 1) {
            TargetedComMessage comMsg = new TargetedComMessage();
            comMsg.setString(SpeedhackChatMsg);
            comMsg.setChannel(0);
            comMsg.setChatterName("Admin");
            comMsg.setTarget(player.getOid());
            Engine.getAgent().sendBroadcast(comMsg);
         }

         HashMap<String, Serializable> logData = new HashMap();
         logData.put("serverDeltaTime", stime - lstime);
         logData.put("clientDeltaTime", ctime - lctime);
         logData.put("firstDetection", fdtime);
         logData.put("count", count);
         DataLoggerClient.logData("SPEEDHACK", player.getOid(), (OID)null, (OID)null, logData);
         if (count > (long)SpeedhackCountToDisconect) {
            Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "speed_hack"}).increment();
            con.close();
            this.playerLastClientTime.remove(player.getOid());
            this.playerLastServerTime.remove(player.getOid());
            this.playerFirstSpeedHackTime.remove(player.getOid());
            this.playerSpeedHackCount.remove(player.getOid());
         }
      }

   }

   protected void processDirLocOrient(ClientConnection con, DirLocOrientEvent event) {
      if (Log.loggingDebug) {
         Log.debug("processDirLocOrient: got dir loc orient event: " + event);
      }

      Player player = this.verifyPlayer("processDirLoc", event, con);
      BasicWorldNode wnode = new BasicWorldNode();
      wnode.setDir(event.getDir());
      wnode.setLoc(event.getLoc());
      wnode.setOrientation(event.getQuaternion());
      wnode.time = event.getTime();
      wnode.mid = event.getId();
      wnode.cid = event.getUId();
      WorldManagerClient.updateWorldNode(player.getOid(), wnode);
   }

   protected void processCom(ClientConnection con, ComEvent event) {
      Player player = this.verifyPlayer("processCom", event, con);
      if (Log.loggingInfo) {
         Log.info("ProxyPlugin: CHAT_SENT player=" + player + " channel=" + event.getChannelId() + " msg=[" + event.getMessage() + "]");
      }

      log.debug("processCom: CHAT_SENT");
      if (!this.aDB.isOnBlackList(player.getOid(), event.getObjectOid())) {
         this.incrementChatCount();
         ChatClient.sendChatMsg(player.getOid(), player.getName(), event.getChannelId(), event.getMessage());
      }
   }

   protected void processCommand(ClientConnection con, CommandEvent event) {
      Player player = this.verifyPlayer("processCommand", event, con);
      String cmd = event.getCommand().split(" ")[0];
      if (Log.loggingDebug) {
         log.debug("processCommand: cmd=" + cmd + ", fullCmd=" + event.getCommand());
      }

      this.commandMapLock.lock();

      ProxyPlugin.RegisteredCommand command;
      try {
         command = (ProxyPlugin.RegisteredCommand)this.commandMap.get(cmd);
      } finally {
         this.commandMapLock.unlock();
      }

      if (command == null) {
         Log.warn("processCommand: no parser for command: " + event.getCommand());
         command = (ProxyPlugin.RegisteredCommand)this.commandMap.get("/unknowncmd");
         if (command != null) {
            Engine.setCurrentPlugin(this);
            command.parser.parse(event);
            Engine.setCurrentPlugin((EnginePlugin)null);
         }

      } else {
         Engine.setCurrentPlugin(this);
         if (command.access.allowed(event, this)) {
            command.parser.parse(event);
         } else {
            Log.warn("Player " + player + " not allowed to run command '" + event.getCommand() + "'");
         }

         Engine.setCurrentPlugin((EnginePlugin)null);
      }
   }

   protected void processAutoAttack(ClientConnection con, AutoAttackEvent event) {
      CombatClient.autoAttack(event.getAttackerOid(), event.getTargetOid(), event.getAttackStatus());
   }

   protected void processActivateItem(ClientConnection con, ActivateItemEvent event) {
      InventoryClient.activateObject(event.getItemOid(), event.getObjectOid(), event.getTargetOid());
   }

   protected void processAbilityStatusEvent(ClientConnection con, AbilityStatusEvent event) {
      Player player = (Player)con.getAssociation();
      AbilityStatusMessage msg = new AbilityStatusMessage(CombatClient.MSG_TYPE_ABILITY_STATUS, player.getOid(), event.getPropertyMap());
      Engine.getAgent().sendBroadcast(msg);
   }

   protected void processLogout(ClientConnection con, LogoutEvent event) {
   }

   protected void processSceneLoaded(ClientConnection con, SceneLoadedEvent event) {
      Player player = (Player)con.getAssociation();
      player.sceneLoading(false);
      if (Log.loggingDebug) {
         Log.debug("SCENE: sceneLoading set to false for player: " + player.getOid());
      }

   }

   protected void processExtensionMessageEvent(ClientConnection con, ExtensionMessageEvent event) {
      String key = (String)event.getPropertyMap().get("ext_msg_subtype");
      OID target = event.getTargetOid();
      Player player = (Player)con.getAssociation();
      if (Log.loggingDebug) {
         Log.debug("processExtensionMessageEvent: " + player + " subType=" + key + " target=" + target);
      }

      List<ProxyExtensionHook> proxyHookList = (List)this.extensionHooks.get(key);
      if (proxyHookList == null) {
         if (target != null) {
            WorldManagerClient.TargetedExtensionMessage msg = new WorldManagerClient.TargetedExtensionMessage(WorldManagerClient.MSG_TYPE_EXTENSION, target, player.getOid(), event.getClientTargeted(), event.getPropertyMap());
            if (event.getClientTargeted()) {
               msg.setMsgType(WorldManagerClient.MSG_TYPE_P2P_EXTENSION);
               if (this.allowClientToClientMessage(player, target, msg)) {
                  Engine.getAgent().sendBroadcast(msg);
               }
            } else {
               MessageType msgType = this.getExtensionMessageType(key);
               if (msgType == null) {
                  Log.error("processExtensionMessageEvent: key '" + key + "' has no corresponding MessageType");
                  return;
               }

               msg.setMsgType(msgType);
               Engine.getAgent().sendBroadcast(msg);
            }
         } else {
            MessageType msgType = this.getExtensionMessageType(key);
            if (msgType == null) {
               Log.error("processExtensionMessageEvent: key '" + key + "' has no corresponding MessageType");
               return;
            }

            WorldManagerClient.ExtensionMessage msg = new WorldManagerClient.ExtensionMessage(msgType, player.getOid(), event.getPropertyMap());
            Engine.getAgent().sendBroadcast(msg);
         }

      } else {
         Iterator var7 = proxyHookList.iterator();

         while(var7.hasNext()) {
            ProxyExtensionHook hook = (ProxyExtensionHook)var7.next();
            hook.processExtensionEvent(event, player, this);
         }

      }
   }

   public void registerExtensionSubtype(String subtype, MessageType type) {
      this.extensionMessageRegistry.put(subtype, type);
   }

   public MessageType unregisterExtensionSubtype(String subtype) {
      return (MessageType)this.extensionMessageRegistry.remove(subtype);
   }

   public MessageType getExtensionMessageType(String subtype) {
      return (MessageType)this.extensionMessageRegistry.get(subtype);
   }

   public boolean allowClientToClientMessage(Player sender, OID targetOid, WorldManagerClient.TargetedExtensionMessage message) {
      return this.defaultAllowClientToClientMessage;
   }

   protected boolean specialCaseNewProcessing(PerceptionMessage.ObjectNote objectNote, Player player) {
      long start = System.currentTimeMillis();
      ClientConnection con = player.getConnection();
      OID objOid = objectNote.getSubject();
      ObjectType objType = objectNote.getObjectType();
      if (objType == ObjectTypes.light) {
         Log.debug("specialCaseNewProcessing: got a light object");
         LightData lightData = (LightData)EnginePlugin.getObjectProperty(objOid, Namespace.WORLD_MANAGER, Light.LightDataPropertyKey);
         if (Log.loggingDebug) {
            Log.debug("specialCaseNewProcessing: light data=" + lightData);
         }

         NewLightEvent lightEvent = new NewLightEvent(player.getOid(), objOid, lightData);
         con.send(lightEvent.toBytes());
         return true;
      } else if (objType.equals(WorldManagerClient.TEMPL_OBJECT_TYPE_TERRAIN_DECAL)) {
         Log.debug("specialCaseNewProcessing: got a terrain decal object");
         TerrainDecalData decalData = (TerrainDecalData)EnginePlugin.getObjectProperty(objOid, Namespace.WORLD_MANAGER, WorldManagerClient.TEMPL_TERRAIN_DECAL_DATA);
         if (Log.loggingDebug) {
            Log.debug("specialCaseNewProcessing: terrain decal data=" + decalData);
         }

         NewTerrainDecalEvent decalEvent = new NewTerrainDecalEvent(objOid, decalData);
         con.send(decalEvent.toBytes());
         return true;
      } else if (objType.equals(WorldManagerClient.TEMPL_OBJECT_TYPE_POINT_SOUND)) {
         Log.debug("specialCaseNewProcessing: got a point sound object");
         List<SoundData> soundData = (List)EnginePlugin.getObjectProperty(objOid, Namespace.WORLD_MANAGER, WorldManagerClient.TEMPL_SOUND_DATA_LIST);
         if (Log.loggingDebug) {
            Log.debug("specialCaseNewProcessing: sound data=" + soundData);
         }

         WorldManagerClient.SoundMessage soundMsg = new WorldManagerClient.SoundMessage(objOid);
         soundMsg.setSoundData(soundData);
         con.send(soundMsg.toBuffer());
         return true;
      } else {
         WorldManagerClient.PerceptionInfo perceptionInfo = (WorldManagerClient.PerceptionInfo)objectNote.getObjectInfo();
         if (perceptionInfo.objectInfo == null) {
            return true;
         } else {
            WorldManagerClient.MobPathMessage pathMsg = (WorldManagerClient.MobPathMessage)perceptionInfo.objectInfo.getProperty(WorldManagerClient.MOB_PATH_PROPERTY);
            if (Log.loggingDebug) {
               Log.debug("INFO: MobPathMessage special case with player/npc: " + perceptionInfo.objectInfo.name);
            }

            con.send(perceptionInfo.objectInfo.toBuffer(player.getOid()));
            if (Log.loggingDebug) {
               Log.debug("INFO: specialCaseNewProcessing " + perceptionInfo.displayContext);
            }

            if (perceptionInfo.displayContext != null) {
               ModelInfoEvent modelInfoEvent = new ModelInfoEvent(objOid);
               modelInfoEvent.setDisplayContext(perceptionInfo.displayContext);
               con.send(modelInfoEvent.toBytes());
            } else if (Log.loggingDebug) {
               Log.debug("No display context for " + objOid + " " + perceptionInfo.objectInfo);
            }

            if (pathMsg != null) {
               if (pathMsg.pathExpired()) {
                  if (Log.loggingDebug) {
                     Log.debug("specialCaseNewProcessing: for mob " + objOid + ", last mob path expired " + pathMsg.toString());
                  }
               } else {
                  if (Log.loggingDebug) {
                     Log.debug("specialCaseNewProcessing: for mob " + objOid + ", sending last mob path " + pathMsg.toString());
                  }

                  AOByteBuffer pathBuf = pathMsg.toBuffer();
                  con.send(pathBuf);
               }
            }

            Map<String, DisplayContext> childMap = null;
            if (perceptionInfo.displayContext != null) {
               childMap = perceptionInfo.displayContext.getChildDCMap();
            }

            if (childMap != null && !childMap.isEmpty()) {
               Iterator var11 = childMap.keySet().iterator();

               while(var11.hasNext()) {
                  String slot = (String)var11.next();
                  DisplayContext attachDC = (DisplayContext)childMap.get(slot);
                  if (attachDC == null) {
                     throw new AORuntimeException("attach DC is null for obj: " + objOid);
                  }

                  OID attacheeOID = attachDC.getObjRef();
                  if (attacheeOID == null) {
                     throw new AORuntimeException("attachee oid is null for obj: " + objOid);
                  }

                  if (Log.loggingDebug) {
                     Log.debug("specialCaseNewProcessing: sending attach message to " + player.getOid() + " attaching to obj " + objOid + ", object being attached=" + attacheeOID + " to slot " + slot + ", attachmentDC=" + attachDC);
                  }

                  AttachEvent event = new AttachEvent(objOid, attacheeOID, slot, attachDC);
                  con.send(event.toBytes());
               }

               if (Log.loggingDebug) {
                  Log.debug("specialCaseNewProcessing: done with processing attachments");
               }
            }

            long finish = System.currentTimeMillis();
            if (Log.loggingDebug) {
               Log.debug("specialCaseNewProcessing: finished.\tplayerOid=" + player.getOid() + ", oid=" + objOid + " in " + (finish - start) + " ms");
            }

            return false;
         }
      }
   }

   protected boolean specialCaseFreeProcessing(PerceptionMessage.ObjectNote objectNote, Player player) {
      if (player.getOid().equals(objectNote.getSubject())) {
         Log.debug("ignoring free object message to self");
         return true;
      } else {
         ClientConnection con = player.getConnection();
         if (!con.isOpen()) {
            con = null;
         }

         OID objOid = objectNote.getSubject();
         if (objectNote.getObjectType() == ObjectTypes.road) {
            if (Log.loggingDebug) {
               Log.debug("specialCaseFreeProcessing: playerOid=" + player.getOid() + ", roadSegmentOid=" + objOid);
            }

            this.handleFreeRoad(con, objOid);
            return true;
         } else if (objectNote.getObjectType().equals(WorldManagerClient.TEMPL_OBJECT_TYPE_TERRAIN_DECAL)) {
            if (Log.loggingDebug) {
               Log.debug("specialCaseFreeProcessing: playerOid=" + player.getOid() + ", decalOid=" + objOid);
            }

            FreeTerrainDecalEvent decalEvent = new FreeTerrainDecalEvent(objOid);
            if (con != null) {
               con.send(decalEvent.toBytes());
            }

            return true;
         } else {
            if (Log.loggingDebug) {
               Log.debug("specialCaseFreeProcessing: playerOid=" + player.getOid() + ", objOid=" + objOid);
            }

            NotifyFreeObjectEvent freeEvent = new NotifyFreeObjectEvent(player.getOid(), objOid);
            if (con != null) {
               con.send(freeEvent.toBytes());
            }

            return false;
         }
      }
   }

   protected void handleFreeRoad(ClientConnection con, OID objOid) {
      WorldManagerClient.FreeRoadMessage freeRoadMsg = new WorldManagerClient.FreeRoadMessage(objOid);
      AOByteBuffer buf = freeRoadMsg.toBuffer();
      if (con != null) {
         con.send(buf);
      }

   }

   public static void addStaticPerception(OID playerOid, OID oid) {
      addStaticPerception(playerOid, oid, (String)null, (ObjectType)null, false);
   }

   public static void addStaticPerception(OID oid, OID oid2, String name, ObjectType type) {
      addStaticPerception(oid, oid2, name, type, true);
   }

   private static void addStaticPerception(OID playerOid, OID oid, String name, ObjectType type, boolean hasObjectInfo) {
      ProxyPlugin.AddStaticPerceptionMessage message = new ProxyPlugin.AddStaticPerceptionMessage(MSG_TYPE_ADD_STATIC_PERCEPTION);
      message.setTarget(playerOid);
      message.setSubject(oid);
      message.setName(name);
      message.setType(type);
      message.setHasObjectInfo(hasObjectInfo);
      Engine.getAgent().sendBroadcast(message);
   }

   public static void removeStaticPerception(OID playerOid, OID oid) {
      TargetMessage message = new TargetMessage(MSG_TYPE_REMOVE_STATIC_PERCEPTION);
      message.setTarget(playerOid);
      message.setSubject(oid);
      Engine.getAgent().sendBroadcast(message);
   }

   protected void processPlayerIgnoreList(Player player) {
      if (player.getStatus() == 3) {
         Log.error("ProxyPlugin.processPlayerIgnoreList: Aborting... player.getStatus() is STATUS_LOGOUT");
      } else {
         this.sendPlayerIgnoreList(player);
      }
   }

   protected void sendPlayerIgnoreList(Player player) {
      String missing = " Missing ";
   }

   public void updateIgnoredOids(Player player, List<OID> nowIgnored, List<OID> noLongerIgnored) {
   }

   public List<Object> matchingPlayers(Player player, String playerName, Boolean exactMatch) {
      boolean match = exactMatch == null ? true : exactMatch;
      List<Object> matchLists = Engine.getDatabase().getOidsAndNamesMatchingName(playerName, match);
      List<OID> oids = (List)matchLists.get(0);
      List<String> names = (List)matchLists.get(1);
      if (Log.loggingDebug) {
         log.debug("ProxyPlugin.matchingPlayers: For player " + player.getOid() + ", found " + (oids == null ? 0 : oids.size()) + " players: " + Database.makeOidCollectionString(oids) + " " + (match ? "exactly matching" : "starting with") + " name '" + playerName + "':" + Database.makeNameCollectionString(names));
      }

      return matchLists;
   }

   public boolean isOnBlockList2(OID playerOid, OID targetOid) {
      if (Log.loggingDebug) {
         log.debug("IsOnBlockList: SocialPlugin  started for: " + playerOid);
      }

      boolean isOnBlockList = this.aDB.isOnBlackList(playerOid, targetOid);
      String targetName;
      if (isOnBlockList) {
         targetName = WorldManagerClient.getObjectInfo(targetOid).name;
         EventMessageHelper.SendErrorEvent(playerOid, "ErrorPlayerOnBlockList", 0, targetName);
      } else {
         isOnBlockList = this.aDB.isOnBlackList(targetOid, playerOid);
         if (isOnBlockList) {
            targetName = WorldManagerClient.getObjectInfo(targetOid).name;
            EventMessageHelper.SendErrorEvent(playerOid, "ErrorPlayerYourOnBlockList", 0, targetName);
         }
      }

      if (Log.loggingDebug) {
         log.debug("IsOnBlockList: SocialPlugin  finished for: " + playerOid);
      }

      return isOnBlockList;
   }

   private boolean isPlayerConnectionValid(Player player) {
      ClientConnection con = player.getConnection();
      return con != null && con.isOpen();
   }

   public static OID handleFullInstance(int instanceTemplateID, InstanceClient.InstanceInfo instanceInfo) {
      if (Log.loggingDebug) {
         Log.debug("POP: instance full with template: " + instanceTemplateID);
      }

      int instanceNum = 1;
      String instanceName = "";
      InstanceTemplate island = InstanceClient.getInstanceTemplate(instanceTemplateID);

      OID instanceOid;
      while(true) {
         instanceName = island.getName() + "_" + instanceNum;
         instanceOid = InstanceClient.getInstanceOid(instanceName);
         if (instanceOid != null) {
            instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145);
            if (instanceInfo.populationLimit < 1 || instanceInfo.playerPopulation < instanceInfo.populationLimit) {
               break;
            }
         } else {
            Template overrideTemplate = new Template();
            overrideTemplate.put((Namespace)Namespace.INSTANCE, "name", instanceName);
            overrideTemplate.setName(instanceName);
            instanceOid = InstanceClient.createInstance(instanceTemplateID, overrideTemplate);
            if (instanceOid != null) {
               break;
            }
         }

         ++instanceNum;
      }

      return instanceOid;
   }

   private void updateInstancePerception(OID playerOid, OID prevInstanceOid, OID destInstanceOid, String destInstanceName) {
      if (prevInstanceOid != null) {
         removeStaticPerception(playerOid, prevInstanceOid);
      }

      addStaticPerception(playerOid, destInstanceOid, destInstanceName, ObjectTypes.instance);
   }

   protected void pushInstanceRestorePoint(Player player, BasicWorldNode loc) {
      OID playerOid = player.getOid();
      if (Log.loggingDebug) {
         log.debug("pushInstanceRestorePoint " + playerOid);
      }

      InstanceRestorePoint restorePoint = new InstanceRestorePoint();
      restorePoint.setInstanceOid(loc.getInstanceOid());
      restorePoint.setLoc(loc.getLoc());
      restorePoint.setOrientation(loc.getOrientation());
      InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(loc.getInstanceOid(), 8);
      restorePoint.setInstanceID(instanceInfo.templateID);
      LinkedList<Object> restoreStack = (LinkedList)EnginePlugin.getObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack");
      if (restoreStack == null) {
         restoreStack = new LinkedList();
      }

      restoreStack.add(restorePoint);
      EnginePlugin.setObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack", restoreStack);
   }

   protected void sendOceanData(OceanData oceanData, Player player) {
      WorldManagerClient.TargetedExtensionMessage oceanMsg = new ClientParameter.ClientParameterMessage(player.getOid());
      oceanMsg.setProperty("Ocean.DisplayOcean", oceanData.displayOcean.toString());
      if (oceanData.useParams != null) {
         oceanMsg.setProperty("Ocean.UseParams", oceanData.useParams.toString());
      }

      if (oceanData.waveHeight != null) {
         oceanMsg.setProperty("Ocean.WaveHeight", oceanData.waveHeight.toString());
      }

      if (oceanData.seaLevel != null) {
         oceanMsg.setProperty("Ocean.SeaLevel", oceanData.seaLevel.toString());
      }

      if (oceanData.bumpScale != null) {
         oceanMsg.setProperty("Ocean.BumpScale", oceanData.bumpScale.toString());
      }

      if (oceanData.bumpSpeedX != null) {
         oceanMsg.setProperty("Ocean.BumpSpeedX", oceanData.bumpSpeedX.toString());
      }

      if (oceanData.bumpSpeedZ != null) {
         oceanMsg.setProperty("Ocean.BumpSpeedZ", oceanData.bumpSpeedZ.toString());
      }

      if (oceanData.textureScaleX != null) {
         oceanMsg.setProperty("Ocean.TextureScaleX", oceanData.textureScaleX.toString());
      }

      if (oceanData.textureScaleZ != null) {
         oceanMsg.setProperty("Ocean.TextureScaleZ", oceanData.textureScaleZ.toString());
      }

      if (oceanData.deepColor != null) {
         oceanMsg.setProperty("Ocean.DeepColor", oceanData.deepColor.toString());
      }

      if (oceanData.shallowColor != null) {
         oceanMsg.setProperty("Ocean.ShallowColor", oceanData.shallowColor.toString());
      }

      player.getConnection().send(oceanMsg.toBuffer(player.getVersion()));
   }

   protected Player verifyPlayer(String context, Event event, ClientConnection con) {
      Player player = (Player)con.getAssociation();
      if (!player.getOid().equals(event.getObjectOid())) {
         throw new AORuntimeException(context + ": con doesn't match player " + player + " against eventOid " + event.getObjectOid());
      } else {
         return player;
      }
   }

   public void incrementChatCount() {
      ++this.chatSentCount;
   }

   public void incrementPrivateChatCount() {
      ++this.privateChatSentCount;
   }

   public void addAdmin(OID oid) {
      if (Log.loggingDebug) {
         log.debug("ProxyPlugin.addAdmin: adding oid " + oid);
      }

      this.lock.lock();

      try {
         this.adminSet.add(oid);
      } finally {
         this.lock.unlock();
      }

   }

   public Set<OID> getAdmins() {
      this.lock.lock();

      HashSet var1;
      try {
         var1 = new HashSet(this.adminSet);
      } finally {
         this.lock.unlock();
      }

      return var1;
   }

   public boolean isAdmin(OID playerOid) {
      this.lock.lock();

      boolean var2;
      try {
         if (playerOid != null) {
            AccountDatabase aDB = new AccountDatabase(false);
            int status = aDB.getCharacterAccountStatus(playerOid);
            boolean var4 = status == 5;
            return var4;
         }

         var2 = false;
      } finally {
         this.lock.unlock();
      }

      return var2;
   }

   public int GetConnectionLimit() {
      return this.connectionLimit;
   }

   protected Object createMBeanInstance() {
      return new ProxyPlugin.ProxyJMX();
   }

   private String getTemp() {
      return "47bedc488b0106b2219dd2e2ff5524fd";
   }

   protected class ProxyJMX implements ProxyPlugin.ProxyJMXMBean {
      public int getMaxConcurrentUsers() {
         return ProxyPlugin.MaxConcurrentUsers;
      }

      public void setMaxConcurrentUsers(int users) {
         if (users >= 0) {
            ProxyPlugin.MaxConcurrentUsers = users;
         }

      }

      public int getIdleTimeout() {
         return ProxyPlugin.idleTimeout;
      }

      public void setIdleTimeout(int timeout) {
         if (timeout > 0) {
            ProxyPlugin.idleTimeout = timeout;
         }

      }

      public int getSilenceTimeout() {
         return ProxyPlugin.silenceTimeout;
      }

      public void setSilenceTimeout(int timeout) {
         if (timeout > 0) {
            ProxyPlugin.silenceTimeout = timeout;
         }

      }

      public int getCurrentUsers() {
         return ProxyPlugin.this.playerManager.getPlayerCount();
      }

      public int getPeakUsers() {
         return ProxyPlugin.this.playerManager.getPeakPlayerCount();
      }

      public int getLoginCount() {
         return ProxyPlugin.this.playerManager.getLoginCount();
      }

      public int getLogoutCount() {
         return ProxyPlugin.this.playerManager.getLogoutCount();
      }

      public int getClientPort() {
         return ProxyPlugin.this.clientPort;
      }

      public int getMaxMessagesBeforeConnectionReset() {
         return ProxyPlugin.maxMessagesBeforeConnectionReset;
      }

      public void setMaxMessagesBeforeConnectionReset(int count) {
         if (count > 0) {
            ProxyPlugin.maxMessagesBeforeConnectionReset = count;
         }

      }

      public int getMaxByteCountBeforeConnectionReset() {
         return ProxyPlugin.maxByteCountBeforeConnectionReset;
      }

      public void setMaxByteCountBeforeConnectionReset(int bytes) {
         if (bytes > 0) {
            ProxyPlugin.maxByteCountBeforeConnectionReset = bytes;
         }

      }

      public String getCapacityErrorMessage() {
         return ProxyPlugin.this.capacityError;
      }

      public void setCapacityErrorMessage(String errorMessage) {
         if (errorMessage != null) {
            ProxyPlugin.this.capacityError = errorMessage;
         }

      }
   }

   public interface ProxyJMXMBean {
      int getMaxConcurrentUsers();

      void setMaxConcurrentUsers(int var1);

      int getIdleTimeout();

      void setIdleTimeout(int var1);

      int getSilenceTimeout();

      void setSilenceTimeout(int var1);

      int getCurrentUsers();

      int getPeakUsers();

      int getLoginCount();

      int getLogoutCount();

      int getClientPort();

      int getMaxMessagesBeforeConnectionReset();

      void setMaxMessagesBeforeConnectionReset(int var1);

      int getMaxByteCountBeforeConnectionReset();

      void setMaxByteCountBeforeConnectionReset(int var1);

      String getCapacityErrorMessage();

      void setCapacityErrorMessage(String var1);
   }

   static class AsyncRPCCallback implements ResponseCallback {
      Player player;
      String debugPrefix;
      int responders = 0;

      AsyncRPCCallback(Player player, String debugPrefix) {
         this.player = player;
         this.debugPrefix = debugPrefix;
      }

      public synchronized void handleResponse(ResponseMessage response) {
         --this.responders;
         if (Log.loggingDebug) {
            Log.debug(this.debugPrefix + ", fromAgent=" + response.getSenderName() + " playerOid=" + this.player.getOid() + " responders=" + this.responders);
         }

         if (this.responders < 1) {
            this.notify();
         }

      }

      public synchronized void waitForResponses(int expectedResponses) {
         if (Log.loggingDebug) {
            Log.debug(this.debugPrefix + ", playerOid=" + this.player.getOid() + " responders=" + this.responders + " expectedResponses=" + expectedResponses);
         }

         this.responders += expectedResponses;
         if (Log.loggingDebug) {
            Log.debug(this.debugPrefix + ", playerOid=" + this.player.getOid() + " responders=" + this.responders + " expectedResponses=" + expectedResponses + " after");
         }

         while(this.responders > 0) {
            try {
               this.wait();
            } catch (InterruptedException var3) {
               ProxyPlugin.log.error("waitForResponses wait InterruptedException: " + var3.getMessage() + " " + var3.getLocalizedMessage());
            } catch (Exception var4) {
               ProxyPlugin.log.error("waitForResponses wait InterruptedException: " + var4.getMessage() + " " + var4.getLocalizedMessage());
            }
         }

      }
   }

   private static class PlayerHeartbeat implements ProxyExtensionHook {
      private PlayerHeartbeat() {
      }

      public void processExtensionEvent(ExtensionMessageEvent event, Player player, ProxyPlugin proxy) {
         Serializable time = null;
         Map<String, Serializable> props = new HashMap();
         if (event.getPropertyMap().containsKey("time")) {
            time = (Serializable)event.getPropertyMap().get("time");
         }

         props.put("ext_msg_subtype", "ao.heartbeat");
         props.put("time", time);
         WorldManagerClient.TargetedExtensionMessage msg = new WorldManagerClient.TargetedExtensionMessage(WorldManagerClient.MSG_TYPE_EXTENSION, player.getOid(), player.getOid(), false, props);
         Engine.getAgent().sendBroadcast(msg);
      }

      // $FF: synthetic method
      PlayerHeartbeat(Object x0) {
         this();
      }
   }

   private class PlayerTimeout implements Runnable {
      private PlayerTimeout() {
      }

      public void run() {
         while(true) {
            try {
               Log.debug("PlayerTimeout thread running..");
               this.timeoutPlayers();
            } catch (Exception var3) {
               Log.exception("PlayerTimeout", var3);
            }

            try {
               Thread.sleep(10000L);
            } catch (InterruptedException var2) {
            }
         }
      }

      private void timeoutPlayers() {
         List<Player> timedoutPlayers = ProxyPlugin.this.playerManager.getTimedoutPlayers((long)(ProxyPlugin.idleTimeout * 1000), (long)(ProxyPlugin.silenceTimeout * 1000), (long)(ProxyPlugin.silenceLoadingTimeout * 1000));
         Iterator var2 = timedoutPlayers.iterator();

         while(var2.hasNext()) {
            Player player = (Player)var2.next();
            if (!ProxyPlugin.this.isAdmin(player.getOid())) {
               Log.info("ProxyPlugin: IDLE_TIMEOUT remote=" + player.getConnection() + " player=" + player);
               Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "timeout"}).increment();
               player.setStatus(4);
               player.getConnection().close();
            }
         }

      }

      // $FF: synthetic method
      PlayerTimeout(Object x1) {
         this();
      }
   }

   class InstanceEntryReqHook extends ProxyPlugin.BasicProxyHook {
      InstanceEntryReqHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         InstanceClient.InstanceEntryReqMessage entryMessage = (InstanceClient.InstanceEntryReqMessage)msg;
         ProxyPlugin.log.debug("InstanceEntryReqHook ");
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("InstanceEntryReqHook Oid=" + entryMessage.getSubject() + " instOid=" + entryMessage.getMsgInstanceOid() + " WorldNode=" + entryMessage.getWorldNode() + " RestoreNode=" + entryMessage.getRestoreNode() + " flags=" + entryMessage.getFlags() + " player=" + player);
         }

         ProxyPlugin.InstanceEntryState state = (ProxyPlugin.InstanceEntryState)entryMessage.getProcessingState();
         if (state == null) {
            state = new ProxyPlugin.InstanceEntryState();
            entryMessage.setProcessingState(state);
         }

         if (state.step == 1) {
            this.entryStep1(entryMessage, state, player);
         } else if (state.step == 2) {
            this.entryStep2(entryMessage, state, player);
         }

      }

      protected void entryStep1(InstanceClient.InstanceEntryReqMessage entryMessage, ProxyPlugin.InstanceEntryState state, Player player) {
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("entryStep1 " + player);
         }

         BasicWorldNode destination = entryMessage.getWorldNode();
         int entryFlags = entryMessage.getFlags();
         String flagStr = "";
         if ((entryFlags & 1) != 0) {
            flagStr = flagStr + "push,";
         }

         if ((entryFlags & 2) != 0) {
            flagStr = flagStr + "pop,";
         }

         Log.info("ProxyPlugin: INSTANCE_BEGIN player=" + player + " destination=" + destination + " flags=" + flagStr);
         if ((entryFlags & 1) != 0 && (entryFlags & 2) != 0) {
            Log.debug("InstanceEntryReqHook: push and pop flags cannot be combined oid=" + player.getOid());
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else if ((entryFlags & 1) != 0 && destination == null) {
            Log.debug("InstanceEntryReqHook: push without destination oid=" + player.getOid());
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else if ((entryFlags & 2) != 0 && destination != null) {
            Log.debug("InstanceEntryReqHook: pop with destination oid=" + player.getOid());
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else if (player.getStatus() != 2) {
            Log.debug("InstanceEntryReqHook: invalid player status " + player);
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else {
            if ((entryFlags & 2) != 0) {
               LinkedList restoreStack = (LinkedList)EnginePlugin.getObjectProperty(player.getOid(), Namespace.OBJECT_MANAGER, "instanceStack");
               if (restoreStack == null || restoreStack.size() == 0) {
                  Log.debug("InstanceEntryReqHook: player has no stack to pop " + player);
                  Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
                  return;
               }

               state.restoreStack = restoreStack;
               InstanceRestorePoint restorePoint = (InstanceRestorePoint)restoreStack.get(restoreStack.size() - 1);
               if (restoreStack.size() == 1) {
                  if (restorePoint.getFallbackFlag()) {
                     Log.warn("InstanceEntryReqHook: popping to fallback restore point " + player);
                  } else {
                     Log.warn("InstanceEntryReqHook: popping last instance restore point " + player);
                  }
               }

               destination = new BasicWorldNode();
               OID instanceOid = restorePoint.getInstanceOid();
               if (restorePoint.getInstanceID() > 0) {
                  instanceOid = ProxyPlugin.this.instanceEntryCallback.selectInstance(player, restorePoint.getInstanceID());
               }

               if (instanceOid != null) {
                  destination.setInstanceOid(instanceOid);
                  destination.setLoc(restorePoint.getLoc());
                  destination.setOrientation(restorePoint.getOrientation());
                  destination.setDir(new AOVector(0.0F, 0.0F, 0.0F));
               }

               entryMessage.setWorldNode(destination);
            }

            if (!ProxyPlugin.this.instanceEntryAllowed(player.getOid(), destination.getInstanceOid(), destination.getLoc())) {
               Log.info("ProxyPlugin: INSTANCE_REJECT player=" + player + " current=" + state.previousLoc + " destination=" + destination);
               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
            } else {
               state.instanceInfo = InstanceClient.getInstanceInfo(destination.getInstanceOid(), -262145);
               if (state.instanceInfo.oid == null) {
                  Log.error("InstanceEntryReqHook: unknown instanceOid=" + destination.getInstanceOid());
                  Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
               } else {
                  Log.debug("POP: got population: " + state.instanceInfo.playerPopulation + " and limit: " + state.instanceInfo.populationLimit);
                  if (state.instanceInfo.populationLimit > 0 && state.instanceInfo.playerPopulation >= state.instanceInfo.populationLimit) {
                     OID instanceOidx = ProxyPlugin.handleFullInstance(state.instanceInfo.templateID, state.instanceInfo);
                     destination.setInstanceOid(instanceOidx);
                     state.instanceInfo = InstanceClient.getInstanceInfo(destination.getInstanceOid(), -262145);
                  }

                  if (Log.loggingDebug) {
                     Log.debug("InstanceEntryReqHook: instance terrain config: " + state.instanceInfo.terrainConfig);
                  }

                  WorldManagerClient.TargetedExtensionMessage instanceBegin = new WorldManagerClient.TargetedExtensionMessage(player.getOid(), player.getOid());
                  instanceBegin.setExtensionType("ao.SCENE_BEGIN");
                  instanceBegin.setProperty("action", "instance");
                  instanceBegin.setProperty("name", state.instanceInfo.name);
                  instanceBegin.setProperty("templateName", state.instanceInfo.templateName);
                  boolean rc = WorldManagerClient.despawn(player.getOid(), instanceBegin, (Message)null);
                  if (!rc) {
                     Log.error("InstanceEntryReqHook: despawn failed " + player);
                     Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
                  } else {
                     state.previousLoc = WorldManagerClient.getWorldNode(player.getOid());
                     Log.info("ProxyPlugin: INSTANCE_STEP1 player=" + player + " current=" + state.previousLoc + " destination=" + destination + " destName=" + state.instanceInfo.name);
                     ArrayList<Namespace> unloadWM = new ArrayList(1);
                     unloadWM.add(WorldManagerClient.NAMESPACE);
                     rc = ObjectManagerClient.unloadSubObject(player.getOid(), unloadWM);
                     if (!rc) {
                        Log.error("InstanceEntryReqHook: unload wm sub-object failed " + player);
                        Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
                     } else {
                        state.step = 2;
                        ProxyPlugin.this.messageQQ.insert((Object)player, entryMessage);
                     }
                  }
               }
            }
         }
      }

      protected void entryStep2(InstanceClient.InstanceEntryReqMessage entryMessage, ProxyPlugin.InstanceEntryState state, Player player) {
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug(" entryStep2 " + player);
         }

         int entryFlags = entryMessage.getFlags();
         ClientConnection con = player.getConnection();
         BasicWorldNode destination = entryMessage.getWorldNode();
         BasicWorldNode previousLoc = state.previousLoc;
         BasicWorldNode restoreLoc = null;
         if ((entryFlags & 1) != 0) {
            restoreLoc = entryMessage.getRestoreNode();
            if (restoreLoc == null) {
               restoreLoc = previousLoc;
            }
         }

         while(true) {
            boolean rc = ObjectManagerClient.fixWorldNode(player.getOid(), destination);
            if (!rc) {
               if (Log.loggingDebug) {
                  Log.debug("InstanceEntryReqHook: fixWorldNode failed " + player + " node=" + destination);
               }

               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
               return;
            }

            InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(destination.getInstanceOid(), 8);
            EnginePlugin.setObjectProperty(player.getOid(), Namespace.OBJECT_MANAGER, "currentInstanceName", instanceInfo.templateID);
            if (Log.loggingDebug) {
               Log.debug("INSTANCE: storing current instance prop: " + instanceInfo.templateID);
            }

            if (Log.loggingDebug) {
               Log.debug("instanceReq: sending template (scene) name: " + state.instanceInfo.templateName);
            }

            Event worldFileEvent = new WorldFileEvent(state.instanceInfo.templateName, destination.getLoc());
            con.send(worldFileEvent.toBytes());
            player.sceneLoading(true);
            WorldManagerClient.WorldNodeCorrectMessage correctMsg = new WorldManagerClient.WorldNodeCorrectMessage(player.getOid(), destination);
            con.send(correctMsg.toBuffer());
            if ((entryFlags & 1) != 0) {
               ProxyPlugin.this.pushInstanceRestorePoint(player, restoreLoc);
            }

            WorldManagerClient.TargetedExtensionMessage instanceEnd = new WorldManagerClient.TargetedExtensionMessage(player.getOid(), player.getOid());
            instanceEnd.setExtensionType("ao.SCENE_END");
            instanceEnd.setProperty("action", "instance");
            instanceEnd.setProperty("name", state.instanceInfo.name);
            instanceEnd.setProperty("templateName", state.instanceInfo.templateName);
            ArrayList<Namespace> loadWM = new ArrayList(1);
            loadWM.add(WorldManagerClient.NAMESPACE);
            OID oid = ObjectManagerClient.loadSubObject(player.getOid(), loadWM);
            if (oid == null) {
               Log.error("InstanceEntryReqHook: load wm sub-object failed " + player);
               if (previousLoc != null && destination != previousLoc) {
                  Log.error("InstanceEntryReqHook: attempting to restore previous location " + player + " previous=" + previousLoc);
                  destination = previousLoc;
                  entryFlags &= -3;
                  continue;
               }
            }

            Integer result = WorldManagerClient.spawn(player.getOid(), (Message)null, instanceEnd);
            if (result >= 0) {
               WorldManagerClient.updateWorldNode(player.getOid(), destination, true);
               WorldManagerClient.correctWorldNode(player.getOid(), destination);
               ProxyPlugin.this.updateInstancePerception(player.getOid(), previousLoc.getInstanceOid(), destination.getInstanceOid(), instanceInfo.name);
               if (Log.loggingInfo) {
                  Log.info("ProxyPlugin: entryStep2 INSTANCE_END player=" + player + " destination=" + destination);
               }

               if ((entryFlags & 2) != 0) {
                  LinkedList restoreStack = state.restoreStack;
                  InstanceRestorePoint top = (InstanceRestorePoint)restoreStack.get(restoreStack.size() - 1);
                  if (!top.getFallbackFlag()) {
                     restoreStack.remove(restoreStack.size() - 1);
                     EnginePlugin.setObjectProperty(player.getOid(), Namespace.OBJECT_MANAGER, "instanceStack", restoreStack);
                  }
               }

               ProxyPlugin.this.instanceEntryCount++;
               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.TRUE);
               return;
            }

            Log.error("InstanceEntryReqHook: spawn failed " + player);
            if (result != -2 || previousLoc == null || destination == previousLoc) {
               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
               Log.error("InstanceEntryReqHook: spawn failed " + player + " return");
               return;
            }

            Log.error("InstanceEntryReqHook: attempting to restore previous location " + player + " previous=" + previousLoc);
            destination = previousLoc;
            entryFlags &= -3;
         }
      }
   }

   static class InstanceEntryState {
      int step = 1;
      InstanceClient.InstanceInfo instanceInfo;
      LinkedList restoreStack;
      BasicWorldNode previousLoc;
   }

   private class AccountLoginHook implements Hook {
      private AccountLoginHook() {
      }

      public boolean processMessage(Message msg, int flags) {
         Log.debug("AccountLoginHook hit");
         GenericMessage tMsg = (GenericMessage)msg;
         OID accountId = (OID)tMsg.getProperty("accountId");
         if (Log.loggingDebug) {
            Log.debug("AccountLoginHook accountId=" + accountId + "; map=" + ProxyPlugin.this.clientConnections);
         }

         RDPConnection c = (RDPConnection)ProxyPlugin.this.clientConnections.get(accountId);
         if (c != null) {
            Log.debug("Closing client connection");
            Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "duplicate", "status", String.valueOf(c.getState())}).increment();
            ((ClientConnection)ProxyPlugin.this.clientConnections.get(accountId)).close();
            ProxyPlugin.this.clientConnections.remove(accountId);
         }

         return true;
      }

      // $FF: synthetic method
      AccountLoginHook(Object x1) {
         this();
      }
   }

   private class LogoutPlayerRPCThread implements Runnable {
      private Player player;
      private Message message;

      public LogoutPlayerRPCThread(Message message, Player player) {
         this.player = player;
         this.message = message;
      }

      public void run() {
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.run(): start");
         long tStart = System.nanoTime();

         try {
            Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.run(): try { logoutPlayer(); }");
            this.logoutPlayer();
         } catch (Exception var4) {
            Log.exception("LogoutPlayer", var4);
            Engine.getAgent().sendObjectResponse(this.message, (Object)null);
         }

         Timer.builder("logout_thread").publishPercentiles(new double[]{0.95D}).register(Prometheus.registry()).record(Duration.ofNanos(System.nanoTime() - tStart));
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.run(): done");
      }

      public void logoutPlayer() {
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): start");
         ProxyPlugin.PlayerLoginStatus loginStatus = new ProxyPlugin.PlayerLoginStatus();
         loginStatus.oid = this.player.getOid();
         loginStatus.status = this.player.getStatus();
         loginStatus.name = this.player.getName();
         loginStatus.clientCon = this.player.getConnection().toString();
         loginStatus.proxyPluginName = ProxyPlugin.this.getName();
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): about send chat msg");
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): send");

         try {
            Thread.sleep(20L);
         } catch (InterruptedException var6) {
            Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): sleep error " + var6);
         }

         Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "logout"}).increment();
         this.player.getConnection().close();
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): close");
         synchronized(this.player) {
            while(ProxyPlugin.this.isPlayerConnectionValid(this.player)) {
               try {
                  this.player.wait();
               } catch (InterruptedException var5) {
                  Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): wait error " + var5);
               }
            }
         }

         if (Log.loggingDebug) {
            Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): Engine.getAgent().sendObjectResponse() message=" + this.message + ", loginStatus=" + loginStatus);
         }

         Engine.getAgent().sendObjectResponse(this.message, loginStatus);
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): done");
      }
   }

   private class LogoutPlayerHook extends ProxyPlugin.BasicProxyHook {
      private LogoutPlayerHook() {
         super();
      }

      public void processMessage(Message message, int flags, Player player) {
         Prometheus.registry().counter("logout_hook", new String[0]).increment();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("LogoutPlayerHook " + player);
         }

         Engine.getAgent().sendObjectResponse(message, true);
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("LogoutPlayerHook Send " + player);
         }

         if (player.getStatus() != 3 && player.getStatus() != 4) {
            player.setStatus(4);
            ProxyPlugin.this.logoutExecutor.execute(ProxyPlugin.this.new LogoutPlayerRPCThread(message, player));
         }

         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("LogoutPlayerHook End " + player);
         }

      }

      // $FF: synthetic method
      LogoutPlayerHook(Object x1) {
         this();
      }
   }

   private class GetPlayerLoginStatusHook extends ProxyPlugin.BasicProxyHook {
      private GetPlayerLoginStatusHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         if (Log.loggingDebug) {
            Log.debug("GetPlayerLoginStatusHook: player=" + player);
         }

         ProxyPlugin.PlayerLoginStatus loginStatus = new ProxyPlugin.PlayerLoginStatus();
         loginStatus.oid = player.getOid();
         loginStatus.status = player.getStatus();
         loginStatus.name = player.getName();
         loginStatus.clientCon = player.getConnection().toString();
         loginStatus.proxyPluginName = ProxyPlugin.this.getName();
         if (Log.loggingDebug) {
            Log.debug("GetPlayerLoginStatusHook: response=" + loginStatus);
         }

         Engine.getAgent().sendObjectResponse(msg, loginStatus);
      }

      // $FF: synthetic method
      GetPlayerLoginStatusHook(Object x1) {
         this();
      }
   }

   public static class PlayerLoginStatus {
      public OID oid;
      public int status;
      public String name;
      public String clientCon;
      public String proxyPluginName;

      public String toString() {
         return "[PlayerLoginStatus: oid=" + this.oid + ", status=" + this.status + ", name=" + this.name + ", proxyPluginName=" + this.proxyPluginName + "]";
      }
   }

   class GetPluginStatusHook implements Hook {
      public boolean processMessage(Message msg, int flags) {
         LinkedHashMap<String, Serializable> status = new LinkedHashMap();
         status.put("plugin", ProxyPlugin.this.getName());
         status.put("user", ProxyPlugin.this.playerManager.getPlayerCount());
         status.put("login", ProxyPlugin.this.playerManager.getLoginCount());
         status.put("login_sec", ProxyPlugin.this.playerManager.getLoginSeconds());
         status.put("instance_entry", ProxyPlugin.this.instanceEntryCount);
         status.put("chat", ProxyPlugin.this.chatSentCount);
         status.put("private_chat", ProxyPlugin.this.privateChatSentCount);
         Engine.getAgent().sendObjectResponse(msg, status);
         return true;
      }
   }

   class AbilityUpdateHook extends ProxyPlugin.BasicProxyHook {
      AbilityUpdateHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AbilityUpdateMessage pMsg = (AbilityUpdateMessage)msg;
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("AbilityUpdateHook: got AbilityUpdate message: " + msg);
         }

         ClientConnection con = player.getConnection();
         con.send(pMsg.toBuffer());
      }
   }

   class RoadHook extends ProxyPlugin.BasicProxyHook {
      RoadHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.RoadMessage roadMsg = (WorldManagerClient.RoadMessage)msg;
         Set<Road> roads = roadMsg.getRoads();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("RoadHook: got " + roads.size() + " roads");
         }

         OID targetOid = roadMsg.getTarget();
         ClientConnection con = player.getConnection();
         List<AOByteBuffer> bufList = roadMsg.toBuffer();
         Iterator var9 = bufList.iterator();

         while(var9.hasNext()) {
            AOByteBuffer buf = (AOByteBuffer)var9.next();
            con.send(buf);
         }

         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("RoadHook: sent new roads to targetOid " + targetOid);
         }

      }
   }

   class FogHook extends ProxyPlugin.BasicProxyHook {
      FogHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.FogMessage fogMsg = (WorldManagerClient.FogMessage)msg;
         FogRegionConfig fogConfig = fogMsg.getFogConfig();
         OID targetOid = fogMsg.getTarget();
         ClientConnection con = player.getConnection();
         WorldManagerClient.FogMessage fogMessage = new WorldManagerClient.FogMessage((OID)null, fogConfig);
         con.send(fogMessage.toBuffer());
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("FogHook: sending new fog to targetOid " + targetOid + " " + fogConfig);
         }

      }
   }

   class InvUpdateHook extends ProxyPlugin.BasicProxyHook {
      InvUpdateHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         InventoryClient.InvUpdateMessage uMsg = (InventoryClient.InvUpdateMessage)msg;
         if (player.getOid().equals(uMsg.getSubject())) {
            ClientConnection con = player.getConnection();
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("InvUpdateHook: sending update to player " + player.getOid() + " msgOid=" + uMsg.getSubject());
            }

            con.send(uMsg.toBuffer());
         }
      }
   }

   class SoundHook extends ProxyPlugin.BasicProxyHook {
      SoundHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.SoundMessage sMsg = (WorldManagerClient.SoundMessage)msg;
         OID target = sMsg.getTarget();
         if (target == null || target.equals(player.getOid())) {
            ClientConnection con = player.getConnection();
            con.send(sMsg.toBuffer());
         }
      }
   }

   class OrientHook extends ProxyPlugin.BasicProxyHook {
      OrientHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.OrientMessage oMsg = (WorldManagerClient.OrientMessage)msg;
         AOByteBuffer buf = oMsg.toBuffer();
         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class WNodeCorrectHook extends ProxyPlugin.BasicProxyHook {
      WNodeCorrectHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.WorldNodeCorrectMessage wMsg = (WorldManagerClient.WorldNodeCorrectMessage)msg;
         OID oid = wMsg.getSubject();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("WNodeCorrectHook.processMessage: oid=" + oid + ", msg=" + msg);
         }

         AOByteBuffer buf = wMsg.toBuffer();
         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class UpdateMobPathHook extends ProxyPlugin.BasicProxyHook {
      UpdateMobPathHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.MobPathMessage pathMsg = (WorldManagerClient.MobPathMessage)msg;
         OID subjectOid = pathMsg.getSubject();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("UpdateMobPathHook.processMessage: MobPathMessage MSG_TYPE_MOB_PATH subjectOid=" + subjectOid + ", msg=" + msg);
         }

         AOByteBuffer buf = pathMsg.toBuffer();
         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class UpdateWNodeHook extends ProxyPlugin.BasicProxyHook {
      UpdateWNodeHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.UpdateWorldNodeMessage wMsg = (WorldManagerClient.UpdateWorldNodeMessage)msg;
         OID subjectOid = wMsg.getSubject();
         OID playerOid = player.getOid();
         if (Log.loggingDebug) {
            Log.debug("UpdateWNodeHook.processMessage: subjectOid=" + subjectOid + ", playerOid=" + playerOid + " msg=" + msg);
         }

         if (playerOid.equals(subjectOid)) {
            if (Log.loggingDebug) {
               Log.debug("UpdateWNodeHook.processMessage: subjectOid=" + subjectOid + ", ignoring msg since playerOid matches subjectOid");
            }

         } else {
            if (Log.loggingDebug) {
               Log.debug("UpdateWNodeHook.processMessage: subjectOid=" + subjectOid + ", playerOid " + playerOid + " " + wMsg.getMsgId() + " " + wMsg.getSenderName() + " " + wMsg.getMsgType() + " " + wMsg.getWorldNode().getDir());
            }

            player.getConnection().send(wMsg.getEventBuf());
         }
      }
   }

   class SysChatHook implements Hook {
      public boolean processMessage(Message msg, int flags) {
         SysChatMessage sysMsg = (SysChatMessage)msg;
         AOByteBuffer buf = sysMsg.toBuffer();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("syschathook:\t " + sysMsg.getString());
         }

         Collection<Player> players = new ArrayList(ProxyPlugin.this.playerManager.getPlayerCount());
         ProxyPlugin.this.playerManager.getPlayers(players);
         Iterator var6 = players.iterator();

         while(var6.hasNext()) {
            Player pp = (Player)var6.next();
            pp.getConnection().send(buf);
         }

         return true;
      }
   }

   class DamageHook extends ProxyPlugin.BasicProxyHook {
      DamageHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         DamageMessage dmgMsg = (DamageMessage)msg;
         OID attackerOid = dmgMsg.getAttackerOid();
         OID targetOid = dmgMsg.getTargetOid();
         AOByteBuffer buf = dmgMsg.toBuffer();
         ClientConnection con = player.getConnection();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("DamageHook: attackerOid= " + attackerOid + ", attacks targetOid=" + targetOid + " for " + dmgMsg.getDmg() + " damage");
         }

         con.send(buf);
      }
   }

   class ComHook extends ProxyPlugin.BasicProxyHook {
      ComHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AOByteBuffer buf = null;
         OID oid;
         if (msg instanceof ComMessage) {
            ComMessage comMsgx = (ComMessage)msg;
            oid = comMsgx.getSubject();
            if (Log.loggingDebug) {
               Log.debug("ComHook.processMessage: ComMessage player:" + player + " plyOid:" + player.getOid() + " getSubject:" + oid + " comMsg:" + comMsgx);
            }

            if (ProxyPlugin.this.isOnBlockList2(player.getOid(), oid)) {
               if (Log.loggingDebug) {
                  Log.debug("ComHook.processMessage: Ignoring chat from player " + oid + " to player " + player.getOid() + " because originator is in the player's ignored list");
               }

               return;
            }

            buf = comMsgx.toBuffer();
            Log.info("ProxyPlugin: CHAT_RECV player=" + player + " from=" + comMsgx.getSubject() + " private=false msg=[" + comMsgx.getString() + "]");
         } else {
            if (!(msg instanceof TargetedComMessage)) {
               if (Log.loggingDebug) {
                  Log.debug("ComHook.processMessage: else player:" + player + " plyOid:" + player.getOid() + " msg " + msg);
               }

               return;
            }

            TargetedComMessage comMsg = (TargetedComMessage)msg;
            oid = comMsg.getSubject();
            if (Log.loggingDebug) {
               Log.debug("ComHook.processMessage: TargetedComMessage player:" + player + " plyOid:" + player.getOid() + " getSubject:" + oid + " comMsg:" + comMsg);
            }

            if (ProxyPlugin.this.isOnBlockList2(player.getOid(), oid)) {
               if (Log.loggingDebug) {
                  Log.debug("ComHook.processMessage: Ignoring chat from player " + oid + " to player " + player.getOid() + " because originator is in the player's ignored list");
               }

               return;
            }

            buf = comMsg.toBuffer();
            Log.info("ProxyPlugin: CHAT_RECV player=" + player + " from=" + comMsg.getSubject() + " private=true msg=[" + comMsg.getString() + "]");
         }

         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class BlockListHook extends ProxyPlugin.BasicProxyHook {
      BlockListHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         BlockListMessage dmgMsg = (BlockListMessage)msg;
         player.setIgnoredOids(dmgMsg.getBlockList());
      }
   }

   class PlayerPathReqHook extends ProxyPlugin.BasicProxyHook {
      PlayerPathReqHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         OID playerOid = player.getOid();
         BasicWorldNode wnode = WorldManagerClient.getWorldNode(playerOid);
         WorldManagerClient.ExtensionMessage extMsg = (WorldManagerClient.ExtensionMessage)msg;
         WorldManagerClient.PlayerPathWMReqMessage reqMsg = new WorldManagerClient.PlayerPathWMReqMessage(playerOid, wnode.getInstanceOid(), (String)extMsg.getProperty("room_id"), (AOVector)extMsg.getProperty("start"), (Float)extMsg.getProperty("speed"), (Quaternion)extMsg.getProperty("start_orient"), (AOVector)extMsg.getProperty("dest"), (Quaternion)extMsg.getProperty("dest_orient"), (List)extMsg.getProperty("boundary"), (List)extMsg.getProperty("obstacles"), (Float)extMsg.getProperty("avatar_width"));
         Engine.getAgent().sendBroadcast(reqMsg);
      }
   }

   class PlayerIgnoreListReqHook extends ProxyPlugin.BasicProxyHook {
      PlayerIgnoreListReqHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
      }
   }

   class GetMatchingPlayersHook extends ProxyPlugin.BasicProxyHook {
      GetMatchingPlayersHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = (WorldManagerClient.TargetedExtensionMessage)msg;
         String playerName = (String)extMsg.getProperty("player_name");
         Boolean exactMatch = (Boolean)extMsg.getProperty("exact_match");
         boolean match = exactMatch == null ? true : exactMatch;
         List<Object> matchLists = Engine.getDatabase().getOidsAndNamesMatchingName(playerName, match);
         WorldManagerClient.TargetedExtensionMessage response = new WorldManagerClient.TargetedExtensionMessage("player_ignore_list", player.getOid());
         response.setSubject(player.getOid());
         List<OID> oids = (List)matchLists.get(0);
         List<String> names = (List)matchLists.get(1);
         response.setProperty("ignored_oids", (Serializable)oids);
         response.setProperty("ignored_player_names", (Serializable)names);
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("ProxyPlugin.GetMatchingPlayersHook: For player " + player.getOid() + ", found " + (oids == null ? 0 : oids.size()) + " players: " + Database.makeOidCollectionString(oids) + " " + (match ? "exactly matching" : "starting with") + " name '" + playerName + "':" + Database.makeNameCollectionString(names));
         }

         player.getConnection().send(response.toBuffer(player.getVersion()));
      }
   }

   class UpdatePlayerIgnoreListHook extends ProxyPlugin.BasicProxyHook {
      UpdatePlayerIgnoreListHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = (WorldManagerClient.TargetedExtensionMessage)msg;
         LinkedList<OID> nowIgnored = (LinkedList)extMsg.getProperty("now_ignored");
         LinkedList<OID> noLongerIgnored = (LinkedList)extMsg.getProperty("no_longer_ignored");
         ProxyPlugin.this.updateIgnoredOids(player, nowIgnored, noLongerIgnored);
      }
   }

   class VoiceParmsHook extends ProxyPlugin.BasicProxyHook {
      VoiceParmsHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = new WorldManagerClient.TargetedExtensionMessage("voice_parms_response", player.getOid());
         extMsg.setProperty("host", ProxyPlugin.voiceServerHost);
         extMsg.setProperty("port", ProxyPlugin.voiceServerPort);
         SecureTokenSpec tokenSpec = new SecureTokenSpec((byte)2, Engine.getAgent().getName(), System.currentTimeMillis() + 30000L);
         tokenSpec.setProperty("player_oid", player.getOid());
         byte[] authToken = SecureTokenManager.getInstance().generateToken(tokenSpec);
         extMsg.setProperty("auth_token", Base64.encodeBytes(authToken));
         ClientConnection con = player.getConnection();
         AOByteBuffer buf = extMsg.toBuffer(player.getVersion());
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("VoiceParmsHook: sent voice_parm_response ext msg for player " + player.getOid());
            }
         }

      }
   }

   private class RemoveStaticPerceptionHook extends ProxyPlugin.BasicProxyHook {
      private RemoveStaticPerceptionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         TargetMessage message = (TargetMessage)msg;
         boolean proxyPerceptionLoss = ProxyPlugin.this.playerManager.removeStaticPerception(player, message.getSubject());
         Log.debug("ProxyPlugin.RemoveStaticPerceptionHook(): proxyPerceptionLoss = " + proxyPerceptionLoss + ", playerOid=" + player.getOid() + ", oid=" + message.getSubject());
         if (proxyPerceptionLoss) {
            FilterUpdate proxyPerceptionUpdate = new FilterUpdate(1);
            proxyPerceptionUpdate.removeFieldValue(2, message.getSubject());
            Engine.getAgent().applyFilterUpdate(ProxyPlugin.this.perceptionSubId, proxyPerceptionUpdate, 0);
         }

         NotifyFreeObjectEvent freeEvent = new NotifyFreeObjectEvent(player.getOid(), message.getSubject());
         player.getConnection().send(freeEvent.toBytes());
      }

      // $FF: synthetic method
      RemoveStaticPerceptionHook(Object x1) {
         this();
      }
   }

   private class AddStaticPerceptionHook extends ProxyPlugin.BasicProxyHook {
      private AddStaticPerceptionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         ProxyPlugin.AddStaticPerceptionMessage message = (ProxyPlugin.AddStaticPerceptionMessage)msg;
         if (Log.loggingDebug) {
            Log.debug("AddStaticPerceptionHook: player=" + player.getOid() + ", subject=" + message.getSubject());
         }

         if (!message.hasObjectInfo()) {
            ObjectManagerClient.ObjectStatus objectStatus = ObjectManagerClient.getObjectStatus(message.getSubject());
            if (objectStatus == null || objectStatus.namespaces == null) {
               Log.error("AddStaticPerceptionHook: ignoring unknown subject=" + message.getSubject() + " added to " + player);
               return;
            }

            message.setName(objectStatus.name);
            message.setType(objectStatus.type);
         }

         boolean perceptionGain = ProxyPlugin.this.playerManager.addStaticPerception(player, message.getSubject());
         if (perceptionGain) {
            FilterUpdate perceptionUpdate = new FilterUpdate(1);
            perceptionUpdate.addFieldValue(2, message.getSubject());
            Engine.getAgent().applyFilterUpdate(ProxyPlugin.this.perceptionSubId, perceptionUpdate, 0);
            WorldManagerClient.ObjectInfo info = new WorldManagerClient.ObjectInfo();
            info.oid = message.getSubject();
            info.name = message.getName();
            info.objType = message.getType();
            info.dir = new AOVector(0.0F, 0.0F, 0.0F);
            Log.debug("INFO: add static perception hook");
            player.getConnection().send(info.toBuffer(player.getOid()));
            WorldManagerClient.updateObject(player.getOid(), message.getSubject());
         }

      }

      // $FF: synthetic method
      AddStaticPerceptionHook(Object x1) {
         this();
      }
   }

   public static class AddStaticPerceptionMessage extends TargetMessage {
      private String name;
      private ObjectType type;
      private boolean objectInfoProvided;

      public AddStaticPerceptionMessage() {
      }

      public AddStaticPerceptionMessage(MessageType type) {
         super(type);
      }

      public String getName() {
         return this.name;
      }

      public void setName(String name) {
         this.name = name;
      }

      public ObjectType getType() {
         return this.type;
      }

      public void setType(ObjectType type) {
         this.type = type;
      }

      public boolean hasObjectInfo() {
         return this.objectInfoProvided;
      }

      public void setHasObjectInfo(boolean flag) {
         this.objectInfoProvided = flag;
      }
   }

   class PerceptionHook extends ProxyPlugin.BasicProxyHook {
      PerceptionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         PerceptionMessage perceptionMessage = (PerceptionMessage)msg;
         List<PerceptionMessage.ObjectNote> gain = perceptionMessage.getGainObjects();
         List<PerceptionMessage.ObjectNote> lost = perceptionMessage.getLostObjects();
         List<PerceptionMessage.ObjectNote> sGain = perceptionMessage.getStealthedGainObjects();
         List<PerceptionMessage.ObjectNote> sLost = perceptionMessage.getStealthedLostObjects();
         List<OID> stealthed = perceptionMessage.getSteathedObjects();
         if (Log.loggingDebug) {
            Log.debug("PerceptionHook.processMessage: start " + (gain == null ? 0 : gain.size()) + " gain and " + (lost == null ? 0 : lost.size()) + " lost and " + (sGain == null ? 0 : sGain.size()) + " sGain and" + (sLost == null ? 0 : sLost.size()) + " sLost ");
         }

         if (player.getOid().equals(World.DEBUG_OID)) {
            Log.info("PerceptionHook: oid=" + World.DEBUG_OID + " start " + (gain == null ? 0 : gain.size()) + " gain and " + (lost == null ? 0 : lost.size()) + " lost and " + (sGain == null ? 0 : sGain.size()) + " sGain and" + (sLost == null ? 0 : sLost.size()) + " sLost ");
         }

         ClientConnection con = player.getConnection();
         List<OID> newSubjects = new LinkedList();
         List<OID> deleteSubjects = new LinkedList();
         if (lost != null) {
            ProxyPlugin.this.playerManager.removeWorldPerception(player, lost, deleteSubjects);
         }

         if (gain != null) {
            ProxyPlugin.this.playerManager.addWorldPerception(player, gain, newSubjects);
         }

         Iterator var14;
         if (deleteSubjects.size() > 0 || newSubjects.size() > 0) {
            FilterUpdate perceptionUpdate = new FilterUpdate(deleteSubjects.size() + newSubjects.size());
            var14 = newSubjects.iterator();

            while(var14.hasNext()) {
               OID oid = (OID)var14.next();
               perceptionUpdate.addFieldValue(2, oid);
            }

            if (player.getOid().equals(World.DEBUG_OID) && Log.loggingInfo) {
               Log.info("subject changes: " + newSubjects.size() + " gained " + deleteSubjects.size() + " lost");
            }

            Engine.getAgent().applyFilterUpdate(ProxyPlugin.this.perceptionSubId, perceptionUpdate, 0, (Message)perceptionMessage);
         }

         boolean loadingState = false;
         if (player.supportsLoadingState() && (player.getLoadingState() == 0 || gain != null && gain.size() > 20 || lost != null && lost.size() > 20)) {
            con.send((new LoadingStateEvent(true)).toBytes());
            loadingState = true;
         }

         PerceptionMessage.ObjectNote objectNote;
         if (lost != null) {
            var14 = lost.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();
               ProxyPlugin.this.specialCaseFreeProcessing(objectNote, player);
            }
         }

         if (gain != null) {
            var14 = gain.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();

               try {
                  if (stealthed != null && stealthed.contains(objectNote.getSubject())) {
                     ProxyPlugin.this.specialCaseFreeProcessing(objectNote, player);
                  } else {
                     ProxyPlugin.this.specialCaseNewProcessing(objectNote, player);
                  }

                  WorldManagerClient.updateObject(player.getOid(), objectNote.getSubject());
               } catch (Exception var19) {
                  Log.exception("specialCaseNewProcessing: player=" + player + " oid=" + objectNote.getSubject(), var19);
               }
            }
         }

         if (sGain != null) {
            var14 = sGain.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();

               try {
                  ProxyPlugin.this.specialCaseNewProcessing(objectNote, player);
                  WorldManagerClient.updateObject(player.getOid(), objectNote.getSubject());
               } catch (Exception var18) {
                  Log.exception("specialCaseNewProcessing: player=" + player + " stealthed oid=" + objectNote.getSubject(), var18);
               }
            }
         }

         if (sLost != null) {
            var14 = sLost.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();

               try {
                  ProxyPlugin.this.specialCaseFreeProcessing(objectNote, player);
                  WorldManagerClient.updateObject(player.getOid(), objectNote.getSubject());
               } catch (Exception var17) {
                  Log.exception("specialCaseFreeProcessing: player=" + player + " stealthed oid=" + objectNote.getSubject(), var17);
               }
            }
         }

         if (loadingState) {
            player.setLoadingState(1);
            con.send((new LoadingStateEvent(false)).toBytes());
         }

      }
   }

   class TargetedPropertyHook extends ProxyPlugin.BasicProxyHook {
      TargetedPropertyHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedPropertyMessage propMsg = (WorldManagerClient.TargetedPropertyMessage)msg;
         OID targetOid = propMsg.getTarget();
         OID subjectOid = propMsg.getSubject();
         if (Log.loggingDebug) {
            Set<String> keySet = propMsg.keySet();
            Iterator var8 = keySet.iterator();

            while(var8.hasNext()) {
               String key = (String)var8.next();
               ProxyPlugin.log.debug("handleTargetedPropertyMsg: playerOid=" + player.getOid() + ", targetOid=" + targetOid + ", oid = " + subjectOid + ", got key " + key + ", value=" + propMsg.getProperty(key));
            }
         }

         ClientConnection con = player.getConnection();
         Set<String> filter = ProxyPlugin.this.playerSpecificProps.size() > 0 && !player.getOid().equals(subjectOid) ? ProxyPlugin.this.cachedPlayerSpecificFilterProps : ProxyPlugin.this.filteredProps;
         AOByteBuffer buf = propMsg.toBuffer(player.getVersion(), filter);
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("sent targeted prop msg for targetOid " + targetOid + ", subjectOid=" + subjectOid);
            }
         } else if (Log.loggingDebug) {
            ProxyPlugin.log.debug("filtered out targeted prop msg for targetOid " + targetOid + ", subjectOid=" + subjectOid + " because all props were filtered");
         }

      }
   }

   class PropertyHook extends ProxyPlugin.BasicProxyHook {
      PropertyHook() {
         super();
      }

      public boolean processMessage(Message msg, int flags) {
         return true;
      }

      public void processMessage(Message msg, int flags, Player player) {
         PropertyMessage propMsg = (PropertyMessage)msg;
         OID subjectOid = propMsg.getSubject();
         Iterator buf;
         if (Log.loggingDebug) {
            Set<String> keySet = propMsg.keySet();
            buf = keySet.iterator();

            while(buf.hasNext()) {
               String key = (String)buf.next();
               ProxyPlugin.log.debug("handlePropertyMsg: player=" + player + ", oid=" + subjectOid + ", got key " + key + ", value=" + propMsg.getProperty(key));
            }
         }

         ClientConnection con = player.getConnection();
         buf = null;
         AOByteBuffer bufx;
         if (ProxyPlugin.this.playerSpecificProps.size() > 0 && subjectOid != player.getOid()) {
            bufx = propMsg.toBuffer(player.getVersion(), ProxyPlugin.this.cachedPlayerSpecificFilterProps);
         } else {
            bufx = propMsg.toBuffer(player.getVersion(), ProxyPlugin.this.filteredProps);
         }

         if (bufx != null) {
            con.send(bufx);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("sent prop msg for player " + player + ", subjectId=" + subjectOid);
            }
         } else if (Log.loggingDebug) {
            ProxyPlugin.log.debug("filtered out prop msg for player " + player + ", subjectId=" + subjectOid + " because all props were filtered");
         }

      }
   }

   class P2PExtensionHook extends ProxyPlugin.BasicProxyHook {
      P2PExtensionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = (WorldManagerClient.TargetedExtensionMessage)msg;
         OID objOid = extMsg.getSubject();
         Set<String> keySet = extMsg.keySet();
         Iterator var7 = keySet.iterator();

         while(var7.hasNext()) {
            String key = (String)var7.next();
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("P2PExtensionHook: playerOid=" + player.getOid() + ", oid = " + objOid + ", got key " + key + ", value=" + extMsg.getProperty(key));
            }
         }

         ClientConnection con = player.getConnection();
         AOByteBuffer buf = extMsg.toBuffer(player.getVersion());
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("P2PExtensionHook: sent ext msg for notifyOid " + objOid);
            }
         }

      }
   }

   class ExtensionHook extends ProxyPlugin.BasicProxyHook {
      ExtensionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AOByteBuffer buf = null;
         ClientConnection con = player.getConnection();
         OID subject = null;
         OID target = null;
         String subType = null;
         Set keySet;
         Iterator var11;
         String key;
         if (msg instanceof WorldManagerClient.TargetedExtensionMessage) {
            WorldManagerClient.TargetedExtensionMessage extMsgx = (WorldManagerClient.TargetedExtensionMessage)msg;
            subject = extMsgx.getSubject();
            target = extMsgx.getTarget();
            subType = extMsgx.getExtensionType();
            if (Log.loggingDebug) {
               keySet = extMsgx.keySet();
               var11 = keySet.iterator();

               while(var11.hasNext()) {
                  key = (String)var11.next();
                  ProxyPlugin.log.debug("ExtensionHook: playerOid=" + player.getOid() + ", oid=" + subject + ", key " + key + ", value=" + extMsgx.getProperty(key));
               }
            }

            buf = extMsgx.toBuffer(player.getVersion());
         } else {
            WorldManagerClient.ExtensionMessage extMsg = (WorldManagerClient.ExtensionMessage)msg;
            subject = extMsg.getSubject();
            subType = extMsg.getExtensionType();
            if (Log.loggingDebug) {
               keySet = extMsg.keySet();
               var11 = keySet.iterator();

               while(var11.hasNext()) {
                  key = (String)var11.next();
                  ProxyPlugin.log.debug("ExtensionHook: playerOid=" + player.getOid() + ", oid=" + subject + ", key " + key + ", value=" + extMsg.getProperty(key));
               }
            }

            buf = extMsg.toBuffer(player.getVersion());
         }

         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("ExtensionHook: sent subType " + subType + " for playerOid=" + player.getOid() + ", target=" + target + ", subject=" + subject);
            }
         }

      }
   }

   class AbilityStatusHook extends ProxyPlugin.BasicProxyHook {
      AbilityStatusHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AOByteBuffer buf = null;
         ClientConnection con = player.getConnection();
         AbilityStatusMessage asMsg = (AbilityStatusMessage)msg;
         buf = asMsg.toBuffer();
         if (buf != null) {
            con.send(buf);
         }

      }
   }

   class InvokeEffectHook extends ProxyPlugin.BasicProxyHook {
      InvokeEffectHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         InvokeEffectMessage effectMsg = (InvokeEffectMessage)msg;
         OID objOid = effectMsg.getSubject();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("InvokeEffectHook: got msg=" + effectMsg.toString());
         }

         ClientConnection con = player.getConnection();
         AOByteBuffer buf = effectMsg.toBuffer(player.getVersion());
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("InvokeEffectHook: sent ext msg for notifyOid " + objOid);
            }
         }

      }
   }

   class AnimationHook extends ProxyPlugin.BasicProxyHook {
      AnimationHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.AnimationMessage animMsg = (WorldManagerClient.AnimationMessage)msg;
         OID playerOid = player.getOid();
         ClientConnection con = player.getConnection();
         OID objOid = animMsg.getSubject();
         List<AnimationCommand> animList = animMsg.getAnimationList();
         NotifyPlayAnimationEvent animEvent = new NotifyPlayAnimationEvent(objOid);
         animEvent.setAnimList(animList);
         con.send(animEvent.toBytes());
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("AnimationHook: send anim msg for playerOid " + playerOid + ", objId=" + objOid + ", animEvent=" + animEvent);
         }

      }
   }

   class DetachHook extends ProxyPlugin.BasicProxyHook {
      DetachHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.DetachMessage dMsg = (WorldManagerClient.DetachMessage)msg;
         OID dcObjOid = dMsg.getSubject();
         OID objBeingDetached = dMsg.getObjBeingDetached();
         String socket = dMsg.getSocketName();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("DetachHook: dcObjOid=" + dcObjOid + ", objBeingDetached=" + objBeingDetached + ", socket=" + socket);
         }

         ClientConnection con = player.getConnection();
         DetachEvent detachEvent = new DetachEvent(dcObjOid, objBeingDetached, socket);
         con.send(detachEvent.toBytes());
      }
   }

   class SetAmbientHook extends ProxyPlugin.BasicProxyHook {
      SetAmbientHook() {
         super();
      }

      public void processMessage(Message m, int flags, Player player) {
         WorldManagerClient.SetAmbientLightMessage msg = (WorldManagerClient.SetAmbientLightMessage)m;
         Color ambientLight = msg.getColor();
         OID playerOid = msg.getTarget();
         if (!playerOid.equals(player.getOid())) {
            Log.error("Message target and perceiver mismatch");
         }

         ClientConnection con = player.getConnection();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("SetAmbientHook: targetOid=" + playerOid + ", ambient=" + ambientLight);
         }

         Event ambientLightEvent = new AmbientLightEvent(ambientLight);
         con.send(ambientLightEvent.toBytes());
      }
   }

   class FreeObjectHook extends ProxyPlugin.BasicProxyHook {
      FreeObjectHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.FreeObjectMessage message = (WorldManagerClient.FreeObjectMessage)msg;
         if (Log.loggingDebug) {
            Log.debug("FreeObjectHook: " + msg + " " + message);
         }

         player.getConnection().send(message.toBuffer());
      }
   }

   class NewDirLightHook extends ProxyPlugin.BasicProxyHook {
      NewDirLightHook() {
         super();
      }

      public void processMessage(Message m, int flags, Player player) {
         WorldManagerClient.NewDirLightMessage msg = (WorldManagerClient.NewDirLightMessage)m;
         OID playerOid = msg.getTarget();
         OID lightOid = msg.getSubject();
         LightData lightData = msg.getLightData();
         if (!playerOid.equals(player.getOid())) {
            Log.error("Message target and perceiver mismatch");
         }

         ClientConnection con = player.getConnection();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("NewDirLightHook: notifyOid=" + playerOid + ", lightOid=" + lightOid + ", light=" + lightData);
         }

         NewLightEvent lightEvent = new NewLightEvent(playerOid, lightOid, lightData);
         con.send(lightEvent.toBytes());
      }
   }

   class DisplayContextHook extends ProxyPlugin.BasicProxyHook {
      DisplayContextHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.DisplayContextMessage dcMsg = (WorldManagerClient.DisplayContextMessage)msg;
         OID dcObjOid = dcMsg.getSubject();
         DisplayContext dc = dcMsg.getDisplayContext();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("handleDC: oid=" + dcObjOid + " dc=" + dc);
         }

         ClientConnection con = player.getConnection();
         if (dc != null) {
            ModelInfoEvent eventx = new ModelInfoEvent(dcObjOid);
            eventx.setDisplayContext(dc);
            eventx.setForceInstantLoad(dcMsg.getForceInstantLoad());
            con.send(eventx.toBytes());
         }

         Map<String, DisplayContext> childMap = dc.getChildDCMap();
         if (childMap != null && !childMap.isEmpty()) {
            Iterator var9 = childMap.keySet().iterator();

            while(var9.hasNext()) {
               String slot = (String)var9.next();
               DisplayContext attachDC = (DisplayContext)childMap.get(slot);
               if (attachDC == null) {
                  throw new AORuntimeException("attach DC is null for obj: " + dcObjOid);
               }

               OID attacheeOID = attachDC.getObjRef();
               if (attacheeOID == null) {
                  throw new AORuntimeException("attachee oid is null for obj: " + dcObjOid);
               }

               if (Log.loggingDebug) {
                  ProxyPlugin.log.debug("DisplayContextHook: sending attach message to " + player.getOid() + " attaching to obj " + dcObjOid + ", object being attached=" + attacheeOID + " to slot " + slot + ", attachmentDC=" + attachDC);
               }

               AttachEvent event = new AttachEvent(dcObjOid, attacheeOID, slot, attachDC);
               con.send(event.toBytes());
            }

            ProxyPlugin.log.debug("DisplayContextHook: done with processing attachments");
         }

      }
   }

   abstract class BasicProxyHook implements ProxyHook {
      public boolean processMessage(Message msg, int flags) {
         return true;
      }

      public abstract void processMessage(Message var1, int var2, Player var3);
   }

   class ConnectionResetMessage extends Message {
      ClientConnection con;
      Player player;
      public static final long serialVersionUID = 1L;

      ConnectionResetMessage(ClientConnection con, Player player) {
         this.con = con;
         this.player = player;
      }

      public Player getPlayer() {
         return this.player;
      }

      public ClientConnection getConnection() {
         return this.con;
      }
   }

   private static class DefaultInstanceEntryCallback implements InstanceEntryCallback {
      private DefaultInstanceEntryCallback() {
      }

      public boolean instanceEntryAllowed(OID playerOid, OID instanceOid, Point location) {
         return true;
      }

      public OID selectInstance(Player player, int instanceID) {
         return InstanceClient.getInstanceOid(instanceID, player.getOid(), (OID)null, -1, false);
      }

      public OID selectInstance(Player player, int instanceID, OID playerOid) {
         return InstanceClient.getInstanceOid(instanceID, player.getOid(), playerOid, -1, false);
      }

      public OID selectInstance(Player player, int instanceID, OID playerOid, int guildId) {
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("selectInstance player=" + player + " instanceID=" + instanceID + " OID=" + player.getOid() + " playerOid=" + playerOid + " guildId=" + guildId);
         }

         return InstanceClient.getInstanceOid(instanceID, player.getOid(), playerOid, guildId, false);
      }

      // $FF: synthetic method
      DefaultInstanceEntryCallback(Object x0) {
         this();
      }
   }

   private static class DefaultProxyLoginCallback implements ProxyLoginCallback {
      private DefaultProxyLoginCallback() {
      }

      public boolean duplicateLogin(ProxyPlugin.PlayerLoginStatus existingLogin, ClientConnection con) {
         return existingLogin != null;
      }

      public String preLoad(Player player, ClientConnection con) {
         return null;
      }

      public String postLoad(Player player, ClientConnection con) {
         return null;
      }

      public void postSpawn(Player player, ClientConnection con) {
      }

      // $FF: synthetic method
      DefaultProxyLoginCallback(Object x0) {
         this();
      }
   }

   public class EventCallback implements SQCallback<Player, Event> {
      public void doWork(Event event, Player player) {
         if (event == null) {
            Log.dumpStack("EventCallback.doWork: event object is null, for key " + player);
         } else {
            try {
               ClientConnection con = event.getConnection();
               long startTime = System.currentTimeMillis();
               long inQueue = startTime - event.getEnqueueTime();
               Timer.builder("event_queue_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofMillis(inQueue));
               if (Log.loggingInfo) {
                  Log.info("ProxyPlugin: EventCallback doWork  value" + event + " key=" + player + " in-queue=" + inQueue + " ms");
               }

               if (event instanceof AuthorizedLoginEvent) {
                  int timeout = Integer.parseInt(Engine.properties.getProperty("atavism.proxy_login_event_timeout_seconds", "10"));
                  if (inQueue > (long)(timeout * 1000)) {
                     Prometheus.registry().counter("skipped_login_events", new String[0]).increment();
                     return;
                  }

                  AuthorizedLoginEvent loginEvent = (AuthorizedLoginEvent)event;
                  OID playerOid = loginEvent.getOid();
                  Log.info("ProxyPlugin: LOGIN_BEGIN remote=" + con + " playerOid=" + playerOid + " in-queue=" + inQueue + " ms");
                  boolean loginOK = ProxyPlugin.this.processLogin(con, loginEvent);
                  Player newPlayer = ProxyPlugin.this.playerManager.getPlayer(playerOid);
                  String playerName = null;
                  if (newPlayer != null) {
                     playerName = newPlayer.getName();
                  }

                  if (Log.loggingInfo) {
                     Log.info("ProxyPlugin: LOGIN_END remote=" + con + (loginOK ? " SUCCESS " : " FAILURE ") + " playerOid=" + playerOid + " name=" + playerName + " in-queue=" + inQueue + " ms processing=" + (System.currentTimeMillis() - startTime) + " ms nPlayers=" + ProxyPlugin.this.playerManager.getPlayerCount());
                  }

                  Timer.builder("event_process_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofMillis(System.currentTimeMillis() - startTime));
                  return;
               }

               if (Log.loggingDebug) {
                  Log.debug("ClientEvent: player=" + player + ", in-queue=" + inQueue + " ms: " + event.getName());
               }

               if (Log.loggingInfo && inQueue > 2000L) {
                  Log.info("LONG IN-QUEUE: " + inQueue + " ms: player=" + player + " " + event.getName());
               }

               Lock objLock = ProxyPlugin.this.getObjectLockManager().getLock(player.getOid());
               objLock.lock();

               try {
                  if (Log.loggingDebug) {
                     Log.debug("ClientEvent: event detail: " + event);
                  }

                  if (event instanceof ComEvent) {
                     ProxyPlugin.this.processCom(con, (ComEvent)event);
                  } else if (event instanceof DirLocOrientEvent) {
                     ProxyPlugin.this.processDirLocOrient(con, (DirLocOrientEvent)event);
                  } else if (event instanceof CommandEvent) {
                     ProxyPlugin.this.processCommand(con, (CommandEvent)event);
                  } else if (event instanceof AutoAttackEvent) {
                     ProxyPlugin.this.processAutoAttack(con, (AutoAttackEvent)event);
                  } else if (event instanceof ExtensionMessageEvent) {
                     ProxyPlugin.this.processExtensionMessageEvent(con, (ExtensionMessageEvent)event);
                  } else if (event instanceof AbilityStatusEvent) {
                     ProxyPlugin.this.processAbilityStatusEvent(con, (AbilityStatusEvent)event);
                  } else if (event instanceof RequestQuestInfo) {
                     ProxyPlugin.this.processRequestQuestInfo(con, (RequestQuestInfo)event);
                  } else if (event instanceof QuestResponse) {
                     ProxyPlugin.this.processQuestResponse(con, (QuestResponse)event);
                  } else if (event instanceof ConcludeQuest) {
                     ProxyPlugin.this.processReqConcludeQuest(con, (ConcludeQuest)event);
                  } else if (event instanceof ActivateItemEvent) {
                     ProxyPlugin.this.processActivateItem(con, (ActivateItemEvent)event);
                  } else if (event instanceof LogoutEvent) {
                     ProxyPlugin.this.processLogout(con, (LogoutEvent)event);
                  } else if (event instanceof SceneLoadedEvent) {
                     ProxyPlugin.this.processSceneLoaded(con, (SceneLoadedEvent)event);
                  } else {
                     if (!(event instanceof PlayerHaEvent)) {
                        throw new RuntimeException("Unknown event: " + event);
                     }

                     ProxyPlugin.this.processPlayerHa(con, (PlayerHaEvent)event);
                  }

                  long elapsed = System.currentTimeMillis() - startTime;
                  if (Log.loggingDebug) {
                     Log.debug("ClientEvent: processed event " + event + ", player=" + player + ", processing=" + elapsed + " ms");
                     ProxyPlugin.this.clientMsgMeter.add(elapsed);
                  }

                  if (elapsed > 2000L) {
                     Log.info("LONG PROCESS: " + elapsed + " ms: player=" + player + " " + (event != null ? event.getName() : ""));
                  }

                  Timer.builder("event_process_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofMillis(elapsed));
               } catch (Exception var18) {
                  throw new RuntimeException("ProxyPlugin.EventCallback " + event + " processing error ", var18);
               } finally {
                  objLock.unlock();
               }
            } catch (Exception var20) {
               throw new RuntimeException("ProxyPlugin.EventCallback " + event + " ", var20);
            }

            ProxyPlugin.log.debug("ProxyPlugin.EventCallback " + event + " doWork End");
         }
      }
   }

   class MessageCallback implements SQCallback<Player, Message> {
      protected ProxyPlugin proxyPlugin;

      public MessageCallback(ProxyPlugin proxyPlugin) {
         this.proxyPlugin = proxyPlugin;
      }

      public void doWork(Message message, Player player) {
         long tStart = System.nanoTime();
         if (message == null) {
            Log.dumpStack("DOMESSAGE: Message for oid=" + player.getOid() + " is not a Message: " + message);
         } else if (message instanceof ProxyPlugin.ConnectionResetMessage) {
            ProxyPlugin.this.processConnectionResetInternal((ProxyPlugin.ConnectionResetMessage)message);
            long tEnd = System.nanoTime();
            Timer.builder("message_qq_callback").tag("message", message.getClass().getSimpleName()).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(tEnd - tStart));
         } else {
            int status = player.getStatus();
            if (status != 3 && status != 0) {
               long inQueue;
               try {
                  inQueue = 0L;
                  if (Log.loggingDebug) {
                     inQueue = System.nanoTime() - message.getEnqueueTime();
                     Log.debug("DOINGSVRMESSAGE: Message for oid=" + player.getOid() + ",msgId=" + message.getMsgId() + ",in-queue=" + inQueue / 1000L + " usec: " + message.getMsgType());
                  }

                  if (Log.loggingInfo && ProxyPlugin.this.proxyQueueHistogram != null) {
                     ProxyPlugin.this.proxyQueueHistogram.addTime(inQueue);
                  }

                  Timer.builder("message_qq_lag").publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(tStart - message.getEnqueueTime()));
                  List<Hook> hooks = ProxyPlugin.this.getHookManager().getHooks(message.getMsgType());
                  long callbackStart = System.nanoTime();
                  Iterator var11 = hooks.iterator();

                  while(var11.hasNext()) {
                     Hook hook = (Hook)var11.next();
                     ((ProxyHook)hook).processMessage(message, 0, player);
                  }

                  long callbackTime = 0L;
                  if (Log.loggingDebug || Log.loggingInfo) {
                     callbackTime = System.nanoTime() - callbackStart;
                  }

                  if (Log.loggingDebug) {
                     Log.debug("DONESVRMESSAGE: Message for oid=" + player.getOid() + ",msgId=" + message.getMsgId() + ",in-queue=" + inQueue / 1000L + " usec: ,execute=" + callbackTime / 1000L + " usec: " + message.getMsgType());
                  }

                  if (Log.loggingInfo && ProxyPlugin.this.proxyCallbackHistogram != null) {
                     ProxyPlugin.this.proxyCallbackHistogram.addTime(callbackTime);
                  }
               } catch (Exception var13) {
                  Prometheus.registry().counter("message_qq_errors", new String[0]).increment();
                  Log.exception("SQ MessageCallback", var13);
               }

               inQueue = System.nanoTime();
               Timer.builder("message_qq_callback").tag("message", message.getClass().getSimpleName()).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(inQueue - tStart));
            } else {
               Log.debug("Ignoring message: id=" + message.getMsgId() + " type=" + message.getMsgType() + " for " + player);
               if (message.isRPC()) {
                  if (message.getMsgType() == InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ) {
                     Engine.getAgent().sendBooleanResponse(message, false);
                  } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_PLAYER_IGNORE_LIST_REQ) {
                     Engine.getAgent().sendObjectResponse(message, (Object)null);
                  } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_GET_PLAYER_LOGIN_STATUS) {
                     Engine.getAgent().sendObjectResponse(message, (Object)null);
                  } else {
                     if (message.getMsgType() != ProxyPlugin.MSG_TYPE_LOGOUT_PLAYER) {
                        throw new RuntimeException("Unexpected RPC message " + message + " for player " + player);
                     }

                     ProxyPlugin.log.error("handleMessage MSG_TYPE_LOGOUT_PLAYER");
                     Engine.getAgent().sendObjectResponse(message, (Object)null);
                  }
               }

            }
         }
      }
   }

   private static class DefaultCommandAccess implements ProxyPlugin.CommandAccessCheck {
      private DefaultCommandAccess() {
      }

      public boolean allowed(CommandEvent event, ProxyPlugin proxy) {
         return true;
      }

      // $FF: synthetic method
      DefaultCommandAccess(Object x0) {
         this();
      }
   }

   private static class RegisteredCommand {
      public ProxyPlugin.CommandParser parser;
      public ProxyPlugin.CommandAccessCheck access;

      public RegisteredCommand(ProxyPlugin.CommandParser p, ProxyPlugin.CommandAccessCheck a) {
         this.parser = p;
         this.access = a;
      }
   }

   public interface CommandAccessCheck {
      boolean allowed(CommandEvent var1, ProxyPlugin var2);
   }

   public interface CommandParser {
      void parse(CommandEvent var1);
   }

   public class PlayerMessageCallback implements atavism.msgsys.MessageCallback {
      public void handleMessage(Message message, int flags) {
         Prometheus.registry().counter("handled_messages", new String[]{"message", message.getClass().getSimpleName()}).increment();
         Object perceivers = new ArrayList();

         try {
            if (message instanceof TargetMessage) {
               if (message.getMsgType() == WorldManagerClient.MSG_TYPE_TARGETED_PROPERTY) {
                  ProxyPlugin.this.countMsgTargetedProperty.add();
               }

               OID playerOid = ((TargetMessage)message).getTarget();
               Player player = ProxyPlugin.this.playerManager.getPlayer(playerOid);
               if (player == null) {
                  Log.debug("TargetMessage: player " + playerOid + " not found");
                  if (message.isRPC()) {
                     if (message.getMsgType() == InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ) {
                        Engine.getAgent().sendBooleanResponse(message, false);
                     } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_PLAYER_IGNORE_LIST_REQ) {
                        Engine.getAgent().sendObjectResponse(message, (Object)null);
                     } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_GET_PLAYER_LOGIN_STATUS) {
                        Engine.getAgent().sendObjectResponse(message, (Object)null);
                     } else {
                        if (message.getMsgType() != ProxyPlugin.MSG_TYPE_LOGOUT_PLAYER) {
                           throw new RuntimeException("Unexpected RPC message " + message + " for player " + player);
                        }

                        ProxyPlugin.log.error("handleMessage MSG_TYPE_LOGOUT_PLAYER");
                        Engine.getAgent().sendObjectResponse(message, (Object)null);
                     }
                  }
               } else {
                  long start = System.nanoTime();
                  message.setEnqueueTime();
                  if (Log.loggingTrace) {
                     Log.trace("PlayerMessageCallback.handleMessage " + message.getMsgId() + " TargetMessage " + message.getMsgType() + " add to messageQQ player:" + player);
                  }

                  ProxyPlugin.this.messageQQ.insert((Object)player, message);
                  if (Log.loggingTrace) {
                     Log.trace("ProxyPlugin.handleMessage messageQQ.insert key=" + player + " nanoseconds: " + (System.nanoTime() - start));
                  }
               }

               return;
            }

            if (!(message instanceof SubjectMessage)) {
               if (message instanceof PerceptionMessage) {
                  PerceptionMessage pMsg = (PerceptionMessage)message;
                  ProxyPlugin.this.countMsgPerception.add();
                  ProxyPlugin.this.countMsgPerceptionGain.add((long)pMsg.getGainObjectCount());
                  ProxyPlugin.this.countMsgPerceptionLost.add((long)pMsg.getLostObjectCount());
                  OID playerOidx = pMsg.getTarget();
                  if (Log.loggingTrace) {
                     Log.debug("PERCEP: got perception message with player: " + playerOidx);
                  }

                  Player playerx = ProxyPlugin.this.playerManager.getPlayer(playerOidx);
                  if (playerx == null) {
                     Log.debug("PerceptionMessage: player " + playerOidx + " not found");
                  } else {
                     long startx = System.nanoTime();
                     message.setEnqueueTime();
                     ProxyPlugin.this.messageQQ.insert((Object)playerx, message);
                     if (Log.loggingTrace) {
                        Log.trace("ProxyPlugin.handleMessage2 messageQQ.insert key=" + playerx + "  nanoseconds: " + (System.nanoTime() - startx));
                     }

                     if (Log.loggingTrace) {
                        Log.debug("PERCEP: added perception message to messageQQ: ");
                     }
                  }

                  return;
               }

               Log.error("PlayerMessageCallback unknown type=" + message.getMsgType());
               return;
            }

            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("PlayerMessageCallback.handleMessage: " + message);
            }

            try {
               perceivers = ProxyPlugin.this.playerManager.getPerceivers(((SubjectMessage)message).getSubject());
            } catch (Exception var9) {
               Log.exception("PlayerMessageCallback message=" + message + " " + var9.getMessage() + " " + var9.getLocalizedMessage() + " getPerceivers ", var9);
            }

            if (perceivers == null) {
               Log.warn("No perceivers for " + message);
               return;
            }

            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("PlayerMessageCallback.handleMessage: | " + message + " perceivers=" + perceivers + " " + ((List)perceivers).size());
            }

            if (message instanceof WorldManagerClient.UpdateWorldNodeMessage) {
               WorldManagerClient.UpdateWorldNodeMessage wMsg = (WorldManagerClient.UpdateWorldNodeMessage)message;
               if (Log.loggingTrace) {
                  ProxyPlugin.log.trace("PlayerMessageCallback.handleMessage: UpdateWorldNodeMessage " + wMsg.getMsgId() + " " + wMsg.getSenderName() + " " + wMsg.getSubject() + " " + wMsg.getWorldNode() + " " + message.getMsgType());
               }

               DirLocOrientEvent dloEvent = new DirLocOrientEvent(wMsg.getSubject(), wMsg.getWorldNode());
               wMsg.setEventBuf(dloEvent.toBytes());
            }

            if (message.getMsgType() == WorldManagerClient.MSG_TYPE_UPDATEWNODE) {
               ProxyPlugin.this.countMsgUpdateWNodeIn.add();
               ProxyPlugin.this.countMsgUpdateWNodeOut.add((long)((List)perceivers).size());
            } else if (message.getMsgType() == PropertyMessage.MSG_TYPE_PROPERTY) {
               ProxyPlugin.this.countMsgPropertyIn.add();
               ProxyPlugin.this.countMsgPropertyOut.add((long)((List)perceivers).size());
            } else if (message.getMsgType() == WorldManagerClient.MSG_TYPE_WNODECORRECT) {
               ProxyPlugin.this.countMsgWNodeCorrectIn.add();
               ProxyPlugin.this.countMsgWNodeCorrectOut.add((long)((List)perceivers).size());
            } else if (message.getMsgType() == WorldManagerClient.MSG_TYPE_MOB_PATH) {
               ProxyPlugin.this.countMsgMobPathIn.add();
               ProxyPlugin.this.countMsgMobPathOut.add((long)((List)perceivers).size());
            }
         } catch (Exception var10) {
            Log.exception("PlayerMessageCallback message=" + message + " " + var10.getMessage() + " " + var10.getLocalizedMessage(), var10);
            return;
         }

         message.setEnqueueTime();
         if (Log.loggingTrace) {
            Log.trace("PlayerMessageCallback.handleMessage " + message.getMsgId() + " TargetMessage " + message.getMsgType() + " add to messageQQ ");
         }

         ProxyPlugin.this.messageQQ.insert((List)perceivers, message);
      }
   }

   public class PluginMessageCallback implements atavism.msgsys.MessageCallback {
      ExecutorService executor = Executors.newSingleThreadExecutor();

      public void handleMessage(Message message, int flags) {
         this.executor.execute(ProxyPlugin.this.new ReceivedMessage(message, flags));
      }
   }

   class ReceivedMessage implements Runnable {
      Message message;
      int flags;

      ReceivedMessage(Message message, int flags) {
         this.message = message;
         this.flags = flags;
      }

      public void run() {
         ProxyPlugin.this.callEngineOnMessage(this.message, this.flags);
      }
   }

   class rck implements Runnable {
      protected String sec = "";

      public rck(String sec) {
         this.sec = sec;
      }

      public void run() {
         Log.debug("CONNECTOR: ");
         String email = Engine.getProperty("atavism.licence.email");
         String licencekey = Engine.getProperty("atavism.licence.key");
         String[] url = new String[]{"https://apanel.atavismonline.com/login/verifyserver.php", "https://licensing2.dragonsan.com:2443/login/verifyserver.php", "https://licensing.dragonsan.com/login/verifyserver.php", "https://licensing1.dragonsan.com/login/verifyserver.php", "https://licensing.atavismonline.com/login/verifyserver.php", "https://licensing1.atavismonline.com/login/verifyserver.php", "https://licensing2.atavismonline.com/login/verifyserver.php"};
         String proxy_id = Engine.getProperty("atavism.proxy.id");
         int num = 0;
         int proxyId = 0;

         try {
            if (proxy_id != null && proxy_id != "") {
               proxyId = Integer.parseInt(proxy_id);
            }
         } catch (NumberFormatException var16) {
         }

         while(num < url.length) {
            boolean failed = false;

            try {
               String res = "";
               URL urlObj = new URL(url[num]);
               URLConnection lu = urlObj.openConnection();
               lu.setConnectTimeout(10000);
               String data = "email=" + URLEncoder.encode(email, "UTF-8") + "&licence=" + URLEncoder.encode(licencekey, "UTF-8") + "&ver=" + URLEncoder.encode("10.9.0", "UTF-8") + "&addr=" + URLEncoder.encode(Engine.getProperty("atavism.proxy.bindaddress"), "UTF-8") + "&sor=" + URLEncoder.encode(this.sec, "UTF-8") + "&c=" + URLEncoder.encode("0", "UTF-8") + "&cp=" + ProxyPlugin.this.playerManager.getPlayerCount() + " &pi=" + proxyId + "&build=" + URLEncoder.encode(ServerVersion.getBuildDate(), "UTF-8") + "&m=" + ProxyPlugin.MaxConcurrentUsers;
               lu.setDoOutput(true);
               OutputStreamWriter wr = new OutputStreamWriter(lu.getOutputStream());
               wr.write(data);
               wr.flush();
               BufferedReader rd = new BufferedReader(new InputStreamReader(lu.getInputStream()));

               for(String line = ""; (line = rd.readLine()) != null; res = res + line) {
               }

               wr.flush();
               wr.close();
               if (ProxyPlugin.debugLic) {
                  System.out.println("\nKeepAlive " + url[num] + "\nEncoded:" + res + "\n");
               }

               res = HelperFunctions.readEncodedString(Base64.decode(res));
               String[] output = res.split(":");
               if (EncryptionHelper.passwordMD5Check(output[0], ProxyPlugin.this.getTemp()) && this.sec.equals(HelperFunctions.readEncodedString(Base64.decode(output[2])))) {
                  ProxyPlugin.this.connectionLimit = Integer.parseInt(HelperFunctions.readEncodedString(Base64.decode(output[1])));
               } else {
                  System.out.println("\nLicense verification failed");
                  Log.error("License verification failed");
                  ProxyPlugin.this.connectionLimit = 0;
               }

               Log.info("CONNECTOR: connections set to: " + ProxyPlugin.this.connectionLimit);
            } catch (Exception var17) {
               Log.error("CONNECTOR: failed verifying " + var17);
               if (ProxyPlugin.debugLic) {
                  System.out.println("\n" + url[num] + "\n" + var17);
               }

               ++num;
               failed = true;
            }

            if (!failed) {
               return;
            }
         }

         System.out.println("\nLicense verification failed");
         Log.error("License verification failed");
         ProxyPlugin.this.connectionLimit = 0;
      }
   }
}

Вроде тут привязка.
Код:
 private void runCheck() {
      String email = Engine.getProperty("atavism.licence.email");
      String licencekey = Engine.getProperty("atavism.licence.key");
      String proxy_id = Engine.getProperty("atavism.proxy.id");
      int num = 0;
      int proxyId = 0;

      try {
         if (proxy_id != null && proxy_id != "") {
            proxyId = Integer.parseInt(proxy_id);
         }
      } catch (NumberFormatException var18) {
      }

      String[] url = new String[]{"https://apanel.atavismonline.com/login/verifyserver.php", "https://licensing2.dragonsan.com:2443/login/verifyserver.php", "https://licensing1.atavismonline.com/login/verifyserver.php", "https://licensing.dragonsan.com/login/verifyserver.php", "https://licensing1.dragonsan.com/login/verifyserver.php", "https://licensing.atavismonline.com/login/verifyserver.php", "https://licensing2.atavismonline.com/login/verifyserver.php"};
      String resSor = this.howla();
      ProxyPlugin.rck reCheck = new ProxyPlugin.rck(resSor);
      Engine.getExecutor().scheduleAtFixedRate(reCheck, 300L, 300L, TimeUnit.SECONDS);

      while(num < url.length) {
         boolean failed = false;

         try {
            String res = "";
            URL urlObj = new URL(url[num]);
            URLConnection lu = urlObj.openConnection();
            lu.setConnectTimeout(10000);
            String data = "email=" + URLEncoder.encode(email, "UTF-8") + "&licence=" + URLEncoder.encode(licencekey, "UTF-8") + "&ver=" + URLEncoder.encode("10.9.0", "UTF-8") + "&addr=" + URLEncoder.encode(Engine.getProperty("atavism.proxy.bindaddress"), "UTF-8") + "&sor=" + URLEncoder.encode(resSor, "UTF-8") + "&c=" + URLEncoder.encode("0", "UTF-8") + "&cp=" + this.playerManager.getPlayerCount() + " &pi=" + proxyId + "&build=" + URLEncoder.encode(ServerVersion.getBuildDate(), "UTF-8") + "&m=" + MaxConcurrentUsers;
            lu.setDoOutput(true);
            OutputStreamWriter wr = new OutputStreamWriter(lu.getOutputStream());
            wr.write(data);
            wr.flush();
            BufferedReader rd = new BufferedReader(new InputStreamReader(lu.getInputStream()));

            for(String line = ""; (line = rd.readLine()) != null; res = res + line) {
            }

            wr.flush();
            wr.close();
            if (debugLic) {
               System.out.println("\n" + url[num] + "\n" + res + "\n");
            }

            res = HelperFunctions.readEncodedString(Base64.decode(res));
            String[] output = res.split(":");
            if (debugLic) {
               System.out.println("\nsec: " + resSor + "\n s: " + HelperFunctions.readEncodedString(Base64.decode(output[2])) + "\n");
            }

            if (EncryptionHelper.passwordMD5Check(output[0], this.getTemp()) && resSor.equals(HelperFunctions.readEncodedString(Base64.decode(output[2])))) {
               this.connectionLimit = Integer.parseInt(HelperFunctions.readEncodedString(Base64.decode(output[1])));
            } else {
               System.out.println("\nLicense verification failed");
               Log.error("License verification failed");
            }

            Log.debug("CONNECTOR: connections set to: " + this.connectionLimit);
         } catch (Exception var19) {
            Log.error("CONNECTOR: failed verifying " + var19);
            if (debugLic) {
               System.out.println("\n" + url[num] + "\n" + var19);
            }

            ++num;
            failed = true;
         }

         if (!failed) {
            return;
         }
      }

      System.out.println("\nLicense verification failed");
      Log.error("License verification failed");
      this.connectionLimit = 0;
   }
 
Последнее редактирование модератором:
Java:
private void runCheck()
{
    if (true)
    {
        this.connectionLimit = 10;
        return;
    }
    ...
}
 
connectionLimit = 10000;
так же можно изменить через "конфиг" (или что там):
Engine.getProperty("proxy.connectionLimit")

компилил как есть, только ерроры исправил.
 

Вложения

  • archive.rar
    1,7 МБ · Просмотры: 7
connectionLimit = 10000;
так же можно изменить через "конфиг" (или что там):
Engine.getProperty("proxy.connectionLimit")

компилил как есть, только ерроры исправил.
конфига нету, а
connectionLimit = 10000; не помогу не пускает
 
ну тогда править/отлаживать дальше:
Java:
package atavism.server.plugins;

import atavism.agis.database.AccountDatabase;
import atavism.agis.database.ContentDatabase;
import atavism.agis.events.AbilityStatusEvent;
import atavism.agis.events.AbilityStatusMessage;
import atavism.agis.events.ConcludeQuest;
import atavism.agis.events.QuestResponse;
import atavism.agis.events.RequestQuestInfo;
import atavism.agis.plugins.AnimationClient;
import atavism.agis.plugins.ChatClient;
import atavism.agis.plugins.CombatClient;
import atavism.agis.plugins.DataLoggerClient;
import atavism.agis.plugins.QuestClient;
import atavism.agis.plugins.SocialClient;
import atavism.agis.plugins.AnimationClient.InvokeEffectMessage;
import atavism.agis.plugins.ChatClient.ComMessage;
import atavism.agis.plugins.ChatClient.SysChatMessage;
import atavism.agis.plugins.ChatClient.TargetedComMessage;
import atavism.agis.plugins.CombatClient.AbilityUpdateMessage;
import atavism.agis.plugins.CombatClient.DamageMessage;
import atavism.agis.plugins.QuestClient.QuestResponseMessage;
import atavism.agis.plugins.SocialClient.BlockListMessage;
import atavism.agis.util.EventMessageHelper;
import atavism.agis.util.HelperFunctions;
import atavism.management.Management;
import atavism.msgsys.FilterUpdate;
import atavism.msgsys.GenericMessage;
import atavism.msgsys.Message;
import atavism.msgsys.MessageTrigger;
import atavism.msgsys.MessageType;
import atavism.msgsys.MessageTypeFilter;
import atavism.msgsys.NoRecipientsException;
import atavism.msgsys.RPCTimeoutException;
import atavism.msgsys.ResponseCallback;
import atavism.msgsys.ResponseMessage;
import atavism.msgsys.SubjectMessage;
import atavism.msgsys.TargetMessage;
import atavism.server.engine.BasicWorldNode;
import atavism.server.engine.Database;
import atavism.server.engine.Engine;
import atavism.server.engine.EnginePlugin;
import atavism.server.engine.Event;
import atavism.server.engine.Hook;
import atavism.server.engine.Namespace;
import atavism.server.engine.OID;
import atavism.server.events.ActivateItemEvent;
import atavism.server.events.AmbientLightEvent;
import atavism.server.events.AttachEvent;
import atavism.server.events.AuthorizedLoginEvent;
import atavism.server.events.AuthorizedLoginResponseEvent;
import atavism.server.events.AutoAttackEvent;
import atavism.server.events.ComEvent;
import atavism.server.events.CommandEvent;
import atavism.server.events.DetachEvent;
import atavism.server.events.DirLocOrientEvent;
import atavism.server.events.ExtensionMessageEvent;
import atavism.server.events.FreeTerrainDecalEvent;
import atavism.server.events.LoadingStateEvent;
import atavism.server.events.LogoutEvent;
import atavism.server.events.ModelInfoEvent;
import atavism.server.events.NewLightEvent;
import atavism.server.events.NewTerrainDecalEvent;
import atavism.server.events.NotifyFreeObjectEvent;
import atavism.server.events.NotifyPlayAnimationEvent;
import atavism.server.events.PlayerHaEvent;
import atavism.server.events.SceneLoadedEvent;
import atavism.server.events.WorldFileEvent;
import atavism.server.math.AOVector;
import atavism.server.math.Point;
import atavism.server.math.Quaternion;
import atavism.server.messages.LoginMessage;
import atavism.server.messages.LogoutMessage;
import atavism.server.messages.PerceptionFilter;
import atavism.server.messages.PerceptionMessage;
import atavism.server.messages.PerceptionTrigger;
import atavism.server.messages.PropertyMessage;
import atavism.server.network.AOByteBuffer;
import atavism.server.network.ClientConnection;
import atavism.server.network.ClientTCPMessageIO;
import atavism.server.network.PacketAggregator;
import atavism.server.network.rdp.RDPConnection;
import atavism.server.network.rdp.RDPServer;
import atavism.server.network.rdp.RDPServerSocket;
import atavism.server.objects.Color;
import atavism.server.objects.DisplayContext;
import atavism.server.objects.FogRegionConfig;
import atavism.server.objects.InstanceEntryCallback;
import atavism.server.objects.InstanceRestorePoint;
import atavism.server.objects.InstanceTemplate;
import atavism.server.objects.Light;
import atavism.server.objects.LightData;
import atavism.server.objects.ObjectType;
import atavism.server.objects.ObjectTypes;
import atavism.server.objects.OceanData;
import atavism.server.objects.Player;
import atavism.server.objects.PlayerManager;
import atavism.server.objects.ProxyExtensionHook;
import atavism.server.objects.ProxyLoginCallback;
import atavism.server.objects.Road;
import atavism.server.objects.SoundData;
import atavism.server.objects.Template;
import atavism.server.objects.TerrainDecalData;
import atavism.server.objects.World;
import atavism.server.telemetry.Prometheus;
import atavism.server.util.AOMeter;
import atavism.server.util.AORuntimeException;
import atavism.server.util.AnimationCommand;
import atavism.server.util.Base64;
import atavism.server.util.CountLogger;
import atavism.server.util.DebugUtils;
import atavism.server.util.EncryptionHelper;
import atavism.server.util.LockFactory;
import atavism.server.util.Log;
import atavism.server.util.Logger;
import atavism.server.util.SQCallback;
import atavism.server.util.SQThreadPool;
import atavism.server.util.SecureToken;
import atavism.server.util.SecureTokenManager;
import atavism.server.util.SecureTokenSpec;
import atavism.server.util.ServerVersion;
import atavism.server.util.SquareQueue;
import atavism.server.util.TimeHistogram;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.Timer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.function.Supplier;

public class ProxyPlugin extends EnginePlugin implements ClientConnection.AcceptCallback, ClientConnection.MessageCallback {
   private static int MESSAGE_QUEUE_THREADS = 16;
   private static int EVENT_QUEUE_THREADS = 16;
   private static int SLOW_EVENT_QUEUE_THREADS = 8;
   private static final int RDP_CHANNELS_COUNT = 128;
   public static final int PERCEPTION_GAIN_THRESHOLD = 20;
   CountLogger countLogger = new CountLogger("ProxyMsg", 5000, 2);
   CountLogger.Counter countMsgPerception;
   CountLogger.Counter countMsgPerceptionGain;
   CountLogger.Counter countMsgPerceptionLost;
   CountLogger.Counter countMsgUpdateWNodeIn;
   CountLogger.Counter countMsgUpdateWNodeOut;
   CountLogger.Counter countMsgPropertyIn;
   CountLogger.Counter countMsgPropertyOut;
   CountLogger.Counter countMsgTargetedProperty;
   CountLogger.Counter countMsgWNodeCorrectIn;
   CountLogger.Counter countMsgWNodeCorrectOut;
   CountLogger.Counter countMsgMobPathIn;
   CountLogger.Counter countMsgMobPathOut;
   public static boolean debugLic = false;
   protected Lock commandMapLock = LockFactory.makeLock("CommandMapLock");
   Map<String, ProxyPlugin.RegisteredCommand> commandMap = new HashMap<String, ProxyPlugin.RegisteredCommand>();
   ProxyPlugin.CommandAccessCheck defaultCommandAccess = new ProxyPlugin.DefaultCommandAccess();
   SquareQueue<Player, Message> messageQQ = new SquareQueue("Message");
   SQThreadPool messageThreadPool = null;
   private final SquareQueue<Player, Event> eventQQ = new SquareQueue("Event");
   private SQThreadPool<Player, Event> eventThreadPool = null;
   private final SquareQueue<Player, Event> slowEventQQ = new SquareQueue("SlowEvent");
   private SQThreadPool<Player, Event> slowEventThreadPool = null;
   AOMeter clientMsgMeter = new AOMeter("ClientEventProcessorMeter");
   protected ConcurrentHashMap<OID, Long> playerLastClientTime = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, Long> playerLastServerTime = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, Long> playerFirstSpeedHackTime = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, Long> playerSpeedHackCount = new ConcurrentHashMap();
   public boolean defaultAllowClientToClientMessage = false;
   protected HashMap<String, MessageType> extensionMessageRegistry = new HashMap();
   private final ExecutorService logoutExecutor = Executors.newCachedThreadPool();
   protected AccountDatabase aDB;
   protected PerceptionFilter perceptionFilter;
   protected long perceptionSubId;
   protected PerceptionFilter responderFilter;
   protected PerceptionFilter responderFilter2;
   protected long responderSubId;
   protected long responderSubId2;
   protected int clientPort;
   protected static final Logger log = new Logger("ProxyPlugin");
   ProxyPlugin.PlayerMessageCallback playerMessageCallback = new ProxyPlugin.PlayerMessageCallback();
   protected PlayerManager playerManager = new PlayerManager();
   protected ConcurrentHashMap<OID, String> playersOnlineList = new ConcurrentHashMap();
   protected ConcurrentHashMap<OID, String> playersOnlineOnProxy = new ConcurrentHashMap();
   protected TimeHistogram proxyQueueHistogram = null;
   protected TimeHistogram proxyCallbackHistogram = null;
   protected List<MessageType> extraPlayerMessageTypes = null;
   private ProxyLoginCallback proxyLoginCallback = new ProxyPlugin.DefaultProxyLoginCallback();
   private InstanceEntryCallback instanceEntryCallback = new ProxyPlugin.DefaultInstanceEntryCallback();
   private int instanceEntryCount = 0;
   private int chatSentCount = 0;
   private int privateChatSentCount = 0;
   public static final MessageType MSG_TYPE_VOICE_PARMS = MessageType.intern("ao.VOICE_PARMS");
   public static final MessageType MSG_TYPE_PLAYER_PATH_REQ = MessageType.intern("ao.PLAYER_PATH_REQ");
   public static final MessageType MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST = MessageType.intern("ao.UPDATE_PLAYER_IGNORE_LIST");
   public static final MessageType MSG_TYPE_GET_MATCHING_PLAYERS = MessageType.intern("ao.GET_MATCHING_PLAYERS");
   public static final MessageType MSG_TYPE_PLAYER_IGNORE_LIST = MessageType.intern("ao.PLAYER_IGNORE_LIST");
   public static final MessageType MSG_TYPE_PLAYER_IGNORE_LIST_REQ = MessageType.intern("ao.PLAYER_IGNORE_LIST_REQ");
   public static final MessageType MSG_TYPE_RELAY_UPDATE_PLAYER_IGNORE_LIST = MessageType.intern("ao.RELAY_UPDATE_PLAYER_IGNORE_LIST");
   public static final MessageType MSG_TYPE_GET_PLAYER_LOGIN_STATUS = MessageType.intern("ao.GET_PLAYER_LOGIN_STATUS");
   public static final MessageType MSG_TYPE_LOGOUT_PLAYER = MessageType.intern("ao.LOGOUT_PLAYER");
   public static final MessageType MSG_TYPE_ADD_STATIC_PERCEPTION = MessageType.intern("ao.ADD_STATIC_PERCEPTION");
   public static final MessageType MSG_TYPE_REMOVE_STATIC_PERCEPTION = MessageType.intern("ao.REMOVE_STATIC_PERCEPTION");
   public static final MessageType MSG_TYPE_LOGIN_SPAWNED = MessageType.intern("ao.LOGIN_SPAWNED");
   public static final MessageType MSG_TYPE_ACCOUNT_LOGIN = MessageType.intern("ao.ACCOUNT_LOGIN");
   public static final MessageType MSG_TYPE_SERVER_SHUTDOWN_MESSAGE = MessageType.intern("server.Shutdown_Message");
   public static final MessageType MSG_TYPE_SERVER_SHUTDOWN = MessageType.intern("server.Shutdown");
   public static final MessageType MSG_TYPE_SERVER_RELOAD = MessageType.intern("server.Reload");
   protected static String voiceServerHost = "";
   protected static Integer voiceServerPort = null;
   public String serverCapabilitiesSentToClient = "DirLocOrient";
   public static int DiffTimeToSkipDirLocOrientMessage = 500;
   static int serverSocketReceiveBufferSize = 8388608;
   public static int MaxConcurrentUsers = 2000;
   public static int LOGIN_QUEUE_MAX_USERS = 2000;
   public static int restriction_level = 0;
   public static int idleTimeout = 900;
   public static int silenceTimeout = 30;
   public static int silenceLoadingTimeout = 900;
   public static int maxMessagesBeforeConnectionReset = 2000;
   public static int maxByteCountBeforeConnectionReset = 1000000;
   public String capacityError = "Login Failed: Servers at capacity, please try again later.";
   public String tokenError = "Login Failed: Secure token invalid.";
   public static String SpeedhackChatMsg = "Detected Speedhack";
   public static int SpeedhackCountToDisconect = 10;
   public static int SpeedhackMinDiff = 8000;
   private ClientTCPMessageIO clientTCPMessageIO = null;
   Set<OID> adminSet = new HashSet();
   Map<OID, ClientConnection> clientConnections = new ConcurrentHashMap();
   Set<String> filteredProps = null;
   Set<String> playerSpecificProps = null;
   Set<String> cachedPlayerSpecificFilterProps = null;
   String serverVersion = null;
   protected Map<String, List<ProxyExtensionHook>> extensionHooks = new HashMap();
   private int connectionLimit = 10000;
   boolean devMode = true;

   public ProxyPlugin() {
      super(getPluginName(), (atavism.msgsys.MessageCallback)null);
      this.setPluginType("Proxy");
      this.serverVersion = "10.9.0 " + ServerVersion.getBuildNumber();
      String MessageQueueThreadPoolSize = Engine.properties.getProperty("atavism.proxy.MessageQueueThreadPoolSize");
      if (MessageQueueThreadPoolSize != null) {
         try {
            int v = Integer.parseInt(MessageQueueThreadPoolSize);
            MESSAGE_QUEUE_THREADS = v;
         } catch (NumberFormatException var9) {
            var9.printStackTrace();
            Log.exception(var9);
         }
      }

      String EventQueueThreadPoolSize = Engine.properties.getProperty("atavism.proxy.EventQueueThreadPoolSize");
      if (EventQueueThreadPoolSize != null) {
         try {
            int v = Integer.parseInt(EventQueueThreadPoolSize);
            EVENT_QUEUE_THREADS = v;
         } catch (NumberFormatException var8) {
            var8.printStackTrace();
            Log.exception(var8);
         }
      }

      String proxy_concurrent_logins = Engine.properties.getProperty("atavism.proxy.ConcurrentLogins");
      if (proxy_concurrent_logins != null) {
         try {
            int v = Integer.parseInt(proxy_concurrent_logins);
            SLOW_EVENT_QUEUE_THREADS = v;
         } catch (NumberFormatException var7) {
            var7.printStackTrace();
            Log.exception(var7);
         }
      }

      this.messageThreadPool = new SQThreadPool(this.messageQQ, new ProxyPlugin.MessageCallback(this), MESSAGE_QUEUE_THREADS);
      this.eventThreadPool = new SQThreadPool(this.eventQQ, new ProxyPlugin.EventCallback(), EVENT_QUEUE_THREADS);
      this.slowEventThreadPool = new SQThreadPool(this.slowEventQQ, new ProxyPlugin.EventCallback(), SLOW_EVENT_QUEUE_THREADS);
      this.countMsgPerception = this.countLogger.addCounter("ao.PERCEPTION_INFO");
      this.countMsgPerceptionGain = this.countLogger.addCounter("Perception.gain");
      this.countMsgPerceptionLost = this.countLogger.addCounter("Perception.lost");
      this.countMsgUpdateWNodeIn = this.countLogger.addCounter("ao.UPDATEWNODE.in");
      this.countMsgUpdateWNodeOut = this.countLogger.addCounter("ao.UPDATEWNODE.out");
      this.countMsgPropertyIn = this.countLogger.addCounter("ao.PROPERTY.in");
      this.countMsgPropertyOut = this.countLogger.addCounter("ao.PROPERTY.out");
      this.countMsgTargetedProperty = this.countLogger.addCounter("ao.TARGETED_PROPERTY");
      this.countMsgWNodeCorrectIn = this.countLogger.addCounter("ao.WNODECORRECT.in");
      this.countMsgWNodeCorrectOut = this.countLogger.addCounter("ao.WNODECORRECT.out");
      this.countMsgMobPathIn = this.countLogger.addCounter("ao.MOB_PATH.in");
      this.countMsgMobPathOut = this.countLogger.addCounter("ao.MOB_PATH.out");
      ContentDatabase ctDB = new ContentDatabase(false);
      String _silenceTimeout = ctDB.loadGameSetting("PLAYER_SILENCE_TIMEOUT");
      if (_silenceTimeout != null) {
         silenceTimeout = Integer.parseInt(_silenceTimeout);
      }

      String loginQueueMaxUsers = ctDB.loadGameSetting("LOGIN_QUEUE_MAX_USERS");
      if (loginQueueMaxUsers != null) {
         LOGIN_QUEUE_MAX_USERS = Integer.parseInt(loginQueueMaxUsers);
         Log.info("Game Settings LOGIN_QUEUE_MAX_USERS set to " + LOGIN_QUEUE_MAX_USERS);
      }

      this.aDB = new AccountDatabase(true);
      this.addProxyExtensionHook("ao.heartbeat", new ProxyPlugin.PlayerHeartbeat());
      (new Thread(new ProxyPlugin.PlayerTimeout(), "PlayerTimeout")).start();
   }

   private static String getPluginName() {
      try {
         String proxyPluginName = Engine.getAgent().getDomainClient().allocName("PLUGIN", "Proxy#");
         return proxyPluginName;
      } catch (IOException var2) {
         throw new AORuntimeException("Could not allocate proxy plugin name", var2);
      }
   }

   public static boolean isOnBlockList(OID subject, OID target) {
      WorldManagerClient.ExtensionMessage message = new WorldManagerClient.ExtensionMessage(SocialClient.MSG_TYPE_IS_ON_BLOCK_LIST, "ao.IS_ON_BLOCK_LIST", subject);
      message.setProperty("targetOid", target);
      return Engine.getAgent().sendRPCReturnBoolean(message);
   }

   public boolean isDevMode() {
      return this.devMode;
   }

   public void setDevMode(boolean mode) {
      this.devMode = mode;
   }

   public List<MessageType> getExtraPlayerMessageTypes() {
      return this.extraPlayerMessageTypes;
   }

   public void setExtraPlayerMessageTypes(List<MessageType> extraPlayerMessageTypes) {
      this.extraPlayerMessageTypes = extraPlayerMessageTypes;
   }

   public void addExtraPlayerMessageType(MessageType messageType) {
      if (this.extraPlayerMessageTypes == null) {
         this.extraPlayerMessageTypes = new LinkedList();
      }

      this.extraPlayerMessageTypes.add(messageType);
   }

   public void addExtraPlayerExtensionMessageType(MessageType messageType) {
      this.addExtraPlayerMessageType(messageType);
      this.getHookManager().addHook(messageType, new ProxyPlugin.ExtensionHook());
   }

   public void addProxyExtensionHook(String subType, ProxyExtensionHook hook) {
      synchronized(this.extensionHooks) {
         List<ProxyExtensionHook> hookList = (List)this.extensionHooks.get(subType);
         if (hookList == null) {
            hookList = new ArrayList();
            this.extensionHooks.put(subType, hookList);
         }

         ((List)hookList).add(hook);
      }
   }

   public Map<String, List<ProxyExtensionHook>> getProxyExtensionHooks(String subType) {
      return this.extensionHooks;
   }

   public void onActivate() {
      try {
         PacketAggregator.initializeAggregation(Engine.getProperties());
         String logProxyHistograms = Engine.properties.getProperty("atavism.log_proxy_histograms");
         if (logProxyHistograms != null && logProxyHistograms.equals("true")) {
            int interval = 5000;
            String intervalString = Engine.properties.getProperty("atavism.log_proxy_histograms_interval");
            if (intervalString != null) {
               int newInterval = Integer.parseInt(intervalString);
               if (newInterval > 0) {
                  interval = newInterval;
               }
            }

            this.proxyQueueHistogram = new TimeHistogram("TimeInQ", interval);
            this.proxyCallbackHistogram = new TimeHistogram("TimeInCallback", interval);
            this.countLogger.start();
         }

         this.filteredProps = new HashSet();
         this.playerSpecificProps = new HashSet();
         this.cachedPlayerSpecificFilterProps = new HashSet();
         this.addFilteredProperty("inv.bag");
         this.addFilteredProperty(":loc");
         this.addFilteredProperty("masterOid");
         this.addFilteredProperty("agisobj.basedc");
         this.addFilteredProperty("aoobj.dc");
         this.addFilteredProperty("aoobj.followsterrainflag");
         this.addFilteredProperty("aoobj.perceiver");
         this.addFilteredProperty("aoobj.scale");
         this.addFilteredProperty("aoobj.mobflag");
         this.addFilteredProperty("aoobj.structflag");
         this.addFilteredProperty("aoobj.userflag");
         this.addFilteredProperty("aoobj.itemflag");
         this.addFilteredProperty("aoobj.lightflag");
         this.addFilteredProperty("namespace");
         this.addFilteredProperty("regenEffectMap");
         this.addFilteredProperty(WorldManagerClient.MOB_PATH_PROPERTY);
         this.addFilteredProperty(WorldManagerClient.TEMPL_SOUND_DATA_LIST);
         this.addFilteredProperty(WorldManagerClient.TEMPL_TERRAIN_DECAL_DATA);
         this.addFilteredProperty("instanceStack");
         this.addFilteredProperty("currentInstanceName");
         this.addFilteredProperty("ignored_oids");
         this.registerHooks();
         ProxyPlugin.PluginMessageCallback pluginMessageCallback = new ProxyPlugin.PluginMessageCallback();
         MessageTypeFilter filter = new MessageTypeFilter();
         filter.addType(WorldManagerClient.MSG_TYPE_SYS_CHAT);
         Engine.getAgent().createSubscription(filter, pluginMessageCallback);
         LinkedList<MessageType> types = new LinkedList();
         types.add(WorldManagerClient.MSG_TYPE_PERCEPTION_INFO);
         types.add(WorldManagerClient.MSG_TYPE_ANIMATION);
         types.add(WorldManagerClient.MSG_TYPE_DISPLAY_CONTEXT);
         types.add(WorldManagerClient.MSG_TYPE_DETACH);
         types.add(PropertyMessage.MSG_TYPE_PROPERTY);
         types.add(ChatClient.MSG_TYPE_COM);
         types.add(SocialClient.MSG_TYPE_BLOCK_LIST);
         types.add(CombatClient.MSG_TYPE_DAMAGE);
         types.add(WorldManagerClient.MSG_TYPE_UPDATEWNODE);
         types.add(WorldManagerClient.MSG_TYPE_MOB_PATH);
         types.add(WorldManagerClient.MSG_TYPE_WNODECORRECT);
         types.add(WorldManagerClient.MSG_TYPE_ORIENT);
         types.add(WorldManagerClient.MSG_TYPE_SOUND);
         types.add(AnimationClient.MSG_TYPE_INVOKE_EFFECT);
         types.add(WorldManagerClient.MSG_TYPE_EXTENSION);
         types.add(WorldManagerClient.MSG_TYPE_P2P_EXTENSION);
         types.add(InventoryClient.MSG_TYPE_INV_UPDATE);
         types.add(CombatClient.MSG_TYPE_ABILITY_STATUS);
         types.add(CombatClient.MSG_TYPE_ABILITY_UPDATE);
         types.add(WorldManagerClient.MSG_TYPE_FOG);
         types.add(WorldManagerClient.MSG_TYPE_ROAD);
         types.add(WorldManagerClient.MSG_TYPE_NEW_DIRLIGHT);
         types.add(WorldManagerClient.MSG_TYPE_SET_AMBIENT);
         types.add(WorldManagerClient.MSG_TYPE_TARGETED_PROPERTY);
         types.add(WorldManagerClient.MSG_TYPE_FREE_OBJECT);
         types.add(MSG_TYPE_VOICE_PARMS);
         types.add(MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST);
         types.add(MSG_TYPE_GET_MATCHING_PLAYERS);
         types.add(MSG_TYPE_ADD_STATIC_PERCEPTION);
         types.add(MSG_TYPE_REMOVE_STATIC_PERCEPTION);
         if (this.extraPlayerMessageTypes != null) {
            types.addAll(this.extraPlayerMessageTypes);
         }

         this.perceptionFilter = new PerceptionFilter(types, true);
         PerceptionTrigger perceptionTrigger = new PerceptionTrigger();
         this.perceptionSubId = Engine.getAgent().createSubscription(this.perceptionFilter, this.playerMessageCallback, 0, (MessageTrigger)perceptionTrigger);
         types.clear();
         types.add(InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ);
         types.add(MSG_TYPE_PLAYER_IGNORE_LIST_REQ);
         types.add(MSG_TYPE_GET_PLAYER_LOGIN_STATUS);
         types.add(MSG_TYPE_LOGOUT_PLAYER);
         this.responderFilter = new PerceptionFilter(types);
         this.responderSubId = Engine.getAgent().createSubscription(this.responderFilter, this.playerMessageCallback, 8);
         this.responderFilter2 = new PerceptionFilter();
         this.responderSubId2 = Engine.getAgent().createSubscription(this.responderFilter2, this, 8);
         types.clear();
         types.add(Management.MSG_TYPE_GET_PLUGIN_STATUS);
         Engine.getAgent().createSubscription(new MessageTypeFilter(types), pluginMessageCallback, 8);
         MessageTypeFilter filter3 = new MessageTypeFilter();
         filter3.addType(MSG_TYPE_ACCOUNT_LOGIN);
         Engine.getAgent().createSubscription(filter3, this);
         String log_rdp_counters = Engine.getProperty("atavism.log_rdp_counters");
         if (log_rdp_counters == null || log_rdp_counters.equals("false")) {
            RDPServer.setCounterLogging(false);
         }

         RDPServer.startRDPServer();
         this.initializeVoiceServerInformation();
         this.registerExtensionSubtype("voice_parms", MSG_TYPE_VOICE_PARMS);
         this.registerExtensionSubtype("player_path_req", MSG_TYPE_PLAYER_PATH_REQ);
         this.registerExtensionSubtype("player_path_req", MSG_TYPE_PLAYER_PATH_REQ);
         this.registerExtensionSubtype("ao.UPDATE_PLAYER_IGNORE_LIST", MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST);
         this.registerExtensionSubtype("ao.GET_MATCHING_PLAYERS", MSG_TYPE_GET_MATCHING_PLAYERS);
         this.registerExtensionSubtype("ao.PLAYER_IGNORE_LIST_REQ", MSG_TYPE_PLAYER_IGNORE_LIST_REQ);
         Log.debug("ProxyPlugin before bindAddress");
         InetSocketAddress bindAddress = this.getBindAddress();
         Log.debug("ProxyPlugin after bindAddress " + bindAddress.getHostName() + " " + bindAddress.getAddress() + " " + bindAddress.getPort());
         Log.debug("ProxyPlugin before server socket");
         int port = Integer.parseInt(Engine.getProperty("atavism.proxy.bindport").trim());
         Log.debug("Proxy: getBindAddress port=" + port);
         String agent_name = Engine.getAgent().getName();
         String[] an = agent_name.split("_");
         int agentId = Integer.parseInt(an[1]);
         port += agentId - 1;
         int rdpChannels = Integer.parseInt(Engine.properties.getProperty("atavism.proxy.rdp_channels", String.valueOf(RDP_CHANNELS_COUNT)));

         for(int i = 0; i < rdpChannels; ++i) {
            RDPServerSocket serverSocket = new RDPServerSocket();
            serverSocket.registerAcceptCallback(this);
            serverSocket.bind(port, serverSocketReceiveBufferSize);
            if (Log.loggingDebug) {
               Log.debug("BIND: binding for client tcp and rdp packets on port " + bindAddress.getPort() + " with rdpsocket: " + serverSocket.toString());
            }
         }

         Log.debug("BIND: bound server socket");
         this.clientTCPMessageIO = ClientTCPMessageIO.setup((InetSocketAddress)bindAddress, this, this);
         Log.debug("BIND: setup clientTCPMessage");
         this.clientTCPMessageIO.start("ClientIO");
         Log.debug("BIND: started clientTCPMessage");
         InetSocketAddress externalAddress = this.getExternalAddress(bindAddress);
         Log.debug("BIND: got external Address " + externalAddress.getHostName() + " " + externalAddress.getAddress() + " " + externalAddress.getPort());
         this.setPluginInfo("host=" + Engine.getProperty("atavism.proxy.externaladdress") + ",port=" + externalAddress.getPort());
         Log.debug("Registering proxy plugin");
         Engine.registerStatusReportingPlugin(this);
         Log.debug("Proxy: activation done");
         String cfg = Engine.getProperty("proxy.connectionLimit");
         if(cfg != null) {
             int count = Integer.parseInt(cfg);
             if(count > 0)
                 connectionLimit = count;
         }
         Log.debug("Proxy: connection limit is " + connectionLimit);
         Gauge.builder("event_qq_size", new Supplier<Number>() {
            public Number get() {
               return ProxyPlugin.this.eventQQ.getSQSize();
            }
         }).register(Prometheus.registry());
         Gauge.builder("message_qq_size", new Supplier<Number>() {
            public Number get() {
               return ProxyPlugin.this.messageQQ.getSQSize();
            }
         }).register(Prometheus.registry());
         Gauge.builder("message_qq_unqueued_size", new Supplier<Number>() {
            public Number get() {
               return ProxyPlugin.this.messageQQ.getSQUnqueuedSize();
            }
         }).register(Prometheus.registry());
      } catch (Exception var16) {
         throw new AORuntimeException("activate failed", var16);
      }
   }

   private InetSocketAddress getBindAddress() throws IOException {
      String propStr = Engine.getProperty("atavism.proxy.bindport");
      Log.debug("Proxy: getBindAddress propStr=" + propStr);
      int port;
      if (propStr != null) {
         port = Integer.parseInt(propStr.trim());
         Log.debug("Proxy: getBindAddress port=" + port);
         String agent_name = Engine.getAgent().getName();
         String[] an = agent_name.split("_");
         int agentId = Integer.parseInt(an[1]);
         port += agentId - 1;
         Log.debug("Proxy: getBindAddress port=" + port);
      } else {
         port = Integer.parseInt(Engine.getProperty("atavism.proxyport").trim());
      }

      Log.debug("Proxy: getBindAddress port=" + port);
      propStr = Engine.getProperty("atavism.proxy.bindaddress");
      Log.debug("Proxy: getBindAddress propStr=" + propStr + " " + Character.digit(propStr.charAt(0), 16) + " " + Character.digit(propStr.charAt(1), 16) + " " + Character.digit(propStr.charAt(2), 16) + " c=");
      int count = 0;
      if (propStr.contains(".")) {
         for(int i = 0; i < propStr.length(); ++i) {
            if (propStr.charAt(i) == '.') {
               ++count;
            }
         }
      }

      InetAddress address = null;
      InetAddress[] address2 = null;
      if (count == 3 && Character.digit(propStr.charAt(0), 10) != -1) {
      }

      if (propStr != null) {
         try {
            address = InetAddress.getByName(propStr.trim());
            address2 = InetAddress.getAllByName(propStr.trim());
            InetAddress[] var6 = address2;
            int var7 = address2.length;

            for(int var8 = 0; var8 < var7; ++var8) {
               InetAddress ai = var6[var8];
               Log.debug("Proxy: getBindAddress address2=" + ai + " " + ai.getHostName() + " " + ai.getHostAddress());
            }

            Log.debug("Proxy: getBindAddress address=" + address + " " + address.getHostName() + " " + address.getHostAddress());
         } catch (UnknownHostException var10) {
            log.error("getBindAddress " + var10.getMessage() + " " + var10.getLocalizedMessage());
         }
      }

      Log.debug("Proxy: getBindAddress address=" + address + " " + address.getHostName() + " " + address.getAddress());
      return new InetSocketAddress(address, port);
   }

   private InetSocketAddress getExternalAddress(InetSocketAddress bindAddress) throws IOException {
      String propStr = Engine.getProperty("atavism.proxy.externalport");
      Log.debug("Proxy: getExternalAddress ext port propStr=" + propStr);
      int port;
      if (propStr != null) {
         port = Integer.parseInt(propStr.trim());
      } else {
         port = bindAddress.getPort();
      }

      Log.debug("Proxy: getExternalAddress port=" + port);
      propStr = Engine.getProperty("atavism.proxy.externaladdress");
      Log.debug("Proxy: getExternalAddress ext addr propStr=" + propStr);
      InetAddress address;
      if (propStr != null) {
         address = InetAddress.getByName(propStr.trim());
      } else {
         address = bindAddress.getAddress();
         Log.debug("Proxy: getExternalAddress else address=" + address);
         if (address.isAnyLocalAddress()) {
            address = InetAddress.getLocalHost();
            Log.debug("Proxy: getExternalAddress get local host address=" + address + " " + address.getHostName() + " " + address.getHostAddress());
         }
      }

      Log.debug("Proxy: getExternalAddress address=" + address + " " + address.getHostName() + " " + address.getAddress());
      return new InetSocketAddress(address, port);
   }

   private String howla() {
      String characters = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnoprstquwxyz123456789";
      String k = "";

      for(int i = 0; i < 14; ++i) {
         Random random = new Random();
         k = k + characters.charAt(random.nextInt(characters.length() - 1));
      }

      return k;
   }

   public Map<String, String> getStatusMap() {
      Map<String, String> status = new HashMap();
      status.put("players", Integer.toString(this.playerManager.getPlayerCount()));
      return status;
   }

   public void registerCommand(String command, ProxyPlugin.CommandParser parser) {
      this.commandMapLock.lock();

      try {
         this.commandMap.put(command, new ProxyPlugin.RegisteredCommand(parser, this.defaultCommandAccess));
      } finally {
         this.commandMapLock.unlock();
      }

   }

   public void registerCommand(String command, ProxyPlugin.CommandParser parser, ProxyPlugin.CommandAccessCheck access) {
      this.commandMapLock.lock();

      try {
         this.commandMap.put(command, new ProxyPlugin.RegisteredCommand(parser, access));
      } finally {
         this.commandMapLock.unlock();
      }

   }

   void registerHooks() {
      log.debug("registering hooks");
      this.getHookManager().addHook(SocialClient.MSG_TYPE_BLOCK_LIST, new ProxyPlugin.BlockListHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_DISPLAY_CONTEXT, new ProxyPlugin.DisplayContextHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_DETACH, new ProxyPlugin.DetachHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_ANIMATION, new ProxyPlugin.AnimationHook());
      this.getHookManager().addHook(AnimationClient.MSG_TYPE_INVOKE_EFFECT, new ProxyPlugin.InvokeEffectHook());
      this.getHookManager().addHook(PropertyMessage.MSG_TYPE_PROPERTY, new ProxyPlugin.PropertyHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_EXTENSION, new ProxyPlugin.ExtensionHook());
      this.getHookManager().addHook(CombatClient.MSG_TYPE_ABILITY_STATUS, new ProxyPlugin.AbilityStatusHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_TARGETED_PROPERTY, new ProxyPlugin.TargetedPropertyHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_PERCEPTION_INFO, new ProxyPlugin.PerceptionHook());
      this.getHookManager().addHook(ChatClient.MSG_TYPE_COM, new ProxyPlugin.ComHook());
      this.getHookManager().addHook(CombatClient.MSG_TYPE_DAMAGE, new ProxyPlugin.DamageHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_SYS_CHAT, new ProxyPlugin.SysChatHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_UPDATEWNODE, new ProxyPlugin.UpdateWNodeHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_MOB_PATH, new ProxyPlugin.UpdateMobPathHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_WNODECORRECT, new ProxyPlugin.WNodeCorrectHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_ORIENT, new ProxyPlugin.OrientHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_SOUND, new ProxyPlugin.SoundHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_FOG, new ProxyPlugin.FogHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_ROAD, new ProxyPlugin.RoadHook());
      this.getHookManager().addHook(InventoryClient.MSG_TYPE_INV_UPDATE, new ProxyPlugin.InvUpdateHook());
      this.getHookManager().addHook(CombatClient.MSG_TYPE_ABILITY_UPDATE, new ProxyPlugin.AbilityUpdateHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_NEW_DIRLIGHT, new ProxyPlugin.NewDirLightHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_FREE_OBJECT, new ProxyPlugin.FreeObjectHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_SET_AMBIENT, new ProxyPlugin.SetAmbientHook());
      this.getHookManager().addHook(WorldManagerClient.MSG_TYPE_P2P_EXTENSION, new ProxyPlugin.P2PExtensionHook());
      this.getHookManager().addHook(MSG_TYPE_VOICE_PARMS, new ProxyPlugin.VoiceParmsHook());
      this.getHookManager().addHook(MSG_TYPE_PLAYER_PATH_REQ, new ProxyPlugin.PlayerPathReqHook());
      this.getHookManager().addHook(InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ, new ProxyPlugin.InstanceEntryReqHook());
      this.getHookManager().addHook(Management.MSG_TYPE_GET_PLUGIN_STATUS, new ProxyPlugin.GetPluginStatusHook());
      this.getHookManager().addHook(MSG_TYPE_UPDATE_PLAYER_IGNORE_LIST, new ProxyPlugin.UpdatePlayerIgnoreListHook());
      this.getHookManager().addHook(MSG_TYPE_GET_MATCHING_PLAYERS, new ProxyPlugin.GetMatchingPlayersHook());
      this.getHookManager().addHook(MSG_TYPE_PLAYER_IGNORE_LIST_REQ, new ProxyPlugin.PlayerIgnoreListReqHook());
      this.getHookManager().addHook(MSG_TYPE_GET_PLAYER_LOGIN_STATUS, new ProxyPlugin.GetPlayerLoginStatusHook());
      this.getHookManager().addHook(MSG_TYPE_LOGOUT_PLAYER, new ProxyPlugin.LogoutPlayerHook());
      this.getHookManager().addHook(MSG_TYPE_ADD_STATIC_PERCEPTION, new ProxyPlugin.AddStaticPerceptionHook());
      this.getHookManager().addHook(MSG_TYPE_REMOVE_STATIC_PERCEPTION, new ProxyPlugin.RemoveStaticPerceptionHook());
      this.getHookManager().addHook(MSG_TYPE_ACCOUNT_LOGIN, new ProxyPlugin.AccountLoginHook());
   }

   void callEngineOnMessage(Message message, int flags) {
      super.handleMessage(message, flags);
   }

   protected void initializeVoiceServerInformation() {
      voiceServerHost = Engine.properties.getProperty("atavism.voiceserver");
      String s = Engine.properties.getProperty("atavism.voiceport");
      if (s != null) {
         voiceServerPort = Integer.parseInt(s);
      }

      if (Log.loggingDebug) {
         log.debug("initializeVoiceServerInformation: voiceServerHost " + voiceServerHost + ", voiceServerPort " + voiceServerPort);
      }

   }

   public void acceptConnection(ClientConnection con) {
      Log.info("ProxyPlugin: CONNECTION remote=" + con);
      con.registerMessageCallback(this);
   }

   public void processPacket(ClientConnection con, AOByteBuffer buf) {
      try {
         long time1 = System.nanoTime();
         if (Log.loggingNet) {
            if (ClientConnection.getLogMessageContents()) {
               Log.net("ProxyPlugin.processPacket: con " + con + ", length " + buf.limit() + ", packet " + DebugUtils.byteArrayToHexString(buf));
            } else {
               Log.net("ProxyPlugin.processPacket: con " + con + ", buf " + buf);
            }
         }

         Event event = Engine.getEventServer().parseBytes(buf, con);
         if (event == null) {
            Log.error("Engine: could not parse packet data, remote=" + con);
            return;
         }

         SquareQueue<Player, Event> qq = this.eventQQ;
         if (event instanceof AuthorizedLoginEvent) {
            qq = this.slowEventQQ;
         }

         Player player = (Player)con.getAssociation();
         if (player == null) {
            if (!(event instanceof AuthorizedLoginEvent)) {
               Log.error("Cannot process event for connection with no player: " + con);
               return;
            }

            Log.info("ProxyPlugin: LOGIN_RECV remote=" + con + " playerOid=" + ((AuthorizedLoginEvent)event).getOid());
            player = new Player(((AuthorizedLoginEvent)event).getOid(), con);
         }

         this.playerManager.processEvent(player, event, qq);
         long time2 = System.nanoTime();
         Timer.builder("process_packet_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(time2 - time1));
      } catch (AORuntimeException var10) {
         Log.exception("ProxyPlugin.processPacket caught exception", var10);
      }

   }

   public Set<OID> getPlayerOids() {
      List<Player> players = new ArrayList<Player>(this.playerManager.getPlayerCount());
      this.playerManager.getPlayers(players);
      Set<OID> result = new HashSet<OID>(players.size());
      Iterator<Player> var3 = players.iterator();

      while(var3.hasNext()) {
         Player player = (Player)var3.next();
         result.add(player.getOid());
      }

      return result;
   }

   public List<String> getPlayerNames() {
      List<Player> players = new ArrayList(this.playerManager.getPlayerCount());
      Log.debug("ProxyPlugin.getPlayerNames: count is " + this.playerManager.getPlayerCount());
      this.playerManager.getPlayers(players);
      List<String> result = new ArrayList(players.size());
      Iterator var3 = players.iterator();

      while(var3.hasNext()) {
         Player player = (Player)var3.next();
         result.add(player.getName() + " " + player.getOid() + " " + this.getName());
      }

      Collections.sort(result);
      return result;
   }

   public List<String> getAllPlayerNames() {
      Log.debug("ProxyPlugin.getAllPlayerNames: count is " + this.playersOnlineList.size());
      List<String> result = new ArrayList(this.playersOnlineList.size());
      HashMap<OID, String> plays = new HashMap();
      plays.putAll(this.playersOnlineList);
      Iterator var3 = plays.keySet().iterator();

      while(var3.hasNext()) {
         OID player = (OID)var3.next();
         result.add((String)plays.get(player) + " " + player + " " + (String)this.playersOnlineOnProxy.get(player));
      }

      Collections.sort(result);
      return result;
   }

   public List<Player> getPlayers() {
      List<Player> players = new ArrayList(this.playerManager.getPlayerCount());
      this.playerManager.getPlayers(players);
      return players;
   }

   public Player getPlayer(OID oid) {
      return this.playerManager.getPlayer(oid);
   }

   public void addPlayerMessage(Message message, Player player) {
      long start = System.nanoTime();
      message.setEnqueueTime();
      this.messageQQ.insert(player, message);
      long microseconds = System.nanoTime() - start;
   }

   public void addFilteredProperty(String filteredProperty) {
      this.filteredProps.add(filteredProperty);
      this.cachedPlayerSpecificFilterProps.add(filteredProperty);
   }

   public void addPlayerSpecificProperty(String filteredProperty) {
      this.playerSpecificProps.add(filteredProperty);
      this.cachedPlayerSpecificFilterProps.add(filteredProperty);
   }

   protected void recreatePlayerSpecificCache() {
      this.cachedPlayerSpecificFilterProps = new HashSet();
      this.cachedPlayerSpecificFilterProps.addAll(this.filteredProps);
      this.cachedPlayerSpecificFilterProps.addAll(this.playerSpecificProps);
   }

   protected boolean processLogin(ClientConnection con, AuthorizedLoginEvent loginEvent) {
      Prometheus.registry().counter("player_login_request", new String[0]).increment();
      OID playerOid = loginEvent.getOid();
      String version = loginEvent.getVersion();
      int nPlayers = this.playerManager.getPlayerCount();
      String[] clientVersionCapabilities = null;
      if (version != null && version.length() > 0) {
         clientVersionCapabilities = version.split(",");
      }

      LinkedList<String> clientCapabilities = new LinkedList();
      String clientVersion = "";
      int i;
      if (clientVersionCapabilities != null && clientVersionCapabilities.length > 0) {
         clientVersion = clientVersionCapabilities[0];

         for(i = 1; i < clientVersionCapabilities.length; ++i) {
            clientCapabilities.add(clientVersionCapabilities[i].trim());
         }
      }

      i = ServerVersion.compareVersionStrings(clientVersion, "10.9.0");
      AuthorizedLoginResponseEvent loginResponse;
      if (i != 0) {
         Log.warn("processLogin: unsupported version " + clientVersion + " from player: " + playerOid);
         loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed: Unsupported client version", this.serverVersion);
         con.send(loginResponse.toBytes());
         Prometheus.registry().counter("player_login_result", new String[]{"status", "unsupported_version"}).increment();
         return false;
      } else {
         if (this.isAdmin(playerOid) && nPlayers < this.connectionLimit) {
            Log.debug("processLogin: player is admin, bypassing max check");
         } else {
            Log.debug("processLogin: player is not admin");
            if (nPlayers >= MaxConcurrentUsers || nPlayers >= this.connectionLimit) {
               Log.warn("processLogin: too many users, failed for player: " + playerOid);
               loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, this.capacityError, this.serverVersion);
               con.send(loginResponse.toBytes());
               Prometheus.registry().counter("player_login_result", new String[]{"status", "too_many_users_" + String.valueOf(this.connectionLimit)}).increment();
               return false;
            }
         }

         SecureToken token = SecureTokenManager.getInstance().importToken(loginEvent.getWorldToken());
         boolean validToken = true;
         if (!token.getValid()) {
            Log.debug("token is not valid");
            validToken = false;
         }

         OID characterOid = (OID)token.getProperty("character_oid");
         if (Log.loggingDebug) {
            Log.debug("PlayerOID: " + playerOid);
         }

         if (Log.loggingDebug) {
            Log.debug("CharacterOID: " + characterOid);
         }

         if (!playerOid.equals(characterOid)) {
            Log.debug("playerOid does not match character_oid");
            validToken = false;
         }

         if (!token.getProperty("proxy_server").equals(Engine.getAgent().getName())) {
            Log.debug("proxy_server does not match engine agent name");
            validToken = false;
         }

         if (!validToken) {
            Log.error("processLogin: invalid proxy token");
            loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, this.tokenError, this.serverVersion);
            con.send(loginResponse.toBytes());
            Prometheus.registry().counter("player_login_result", new String[]{"status", "invalid_token"}).increment();
            return false;
         } else {
            try {
               TargetMessage getPlayerLoginStatus = new TargetMessage(MSG_TYPE_GET_PLAYER_LOGIN_STATUS, playerOid);
               ProxyPlugin.PlayerLoginStatus loginStatus = (ProxyPlugin.PlayerLoginStatus)Engine.getAgent().sendRPCReturnObject(getPlayerLoginStatus);
               if (this.proxyLoginCallback.duplicateLogin(loginStatus, con)) {
                  if (loginStatus != null) {
                     if (Log.loggingInfo) {
                        Log.info("processLogin: LOGIN_DUPLICATE remote=" + con + " playerOid=" + playerOid + " name=" + loginStatus.name + " existingCon=" + loginStatus.clientCon + " existingProxy=" + loginStatus.proxyPluginName);
                     }
                  } else if (Log.loggingInfo) {
                     Log.info("processLogin: LOGIN_DUPLICATE remote=" + con + " playerOid=" + playerOid + " loginStatus is null");
                  }

                  log.debug("processLogin: Send logout");
                  Prometheus.registry().counter("player_logout", new String[]{"reason", "duplicate"}).increment();
                  TargetMessage logoutPly = new TargetMessage(MSG_TYPE_LOGOUT_PLAYER, playerOid);
                  Engine.getAgent().sendRPCReturnObject(logoutPly);
                  log.debug("processLogin: Send logout | ");
                  loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed: Already connected", this.serverVersion);
                  con.send(loginResponse.toBytes());
                  Prometheus.registry().counter("player_login_result", new String[]{"status", "duplicate"}).increment();
                  return false;
               }
            } catch (NoRecipientsException var20) {
               if (Log.loggingDebug) {
                  log.debug("processLogin: OK! player is not logged " + var20);
               }
            }

            Player player = new Player(playerOid, con);
            player.setStatus(1);
            if (!this.playerManager.addPlayer(player)) {
               player = this.playerManager.getPlayer(playerOid);
               Log.info("processLogin: LOGIN_DUPLICATE remote=" + con + " playerOid=" + playerOid + " existing=" + player.getConnection());
               loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed: Already connected", this.serverVersion);
               con.send(loginResponse.toBytes());
               Prometheus.registry().counter("player_login_result", new String[]{"status", "duplicate_add"}).increment();
               return false;
            } else {
               con.setAssociation(player);
               player.setVersion(clientVersion);
               player.setCapabilities(clientCapabilities);
               String errorMessage = this.proxyLoginCallback.preLoad(player, con);
               if (errorMessage != null) {
                  this.playerManager.removePlayer(playerOid);
                  loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, errorMessage, this.serverVersion);
                  con.send(loginResponse.toBytes());
                  Prometheus.registry().counter("player_login_result", new String[]{"status", "pre_load_error"}).increment();
                  return false;
               } else {
                  if (Log.loggingDebug) {
                     Log.debug("processLogin: loading object: " + playerOid + ", con=" + con);
                  }

                  if (!this.loadPlayerObject(player)) {
                     Log.error("processLogin: could not load object " + playerOid);
                     this.playerManager.removePlayer(playerOid);
                     loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, "Login Failed", this.serverVersion);
                     con.send(loginResponse.toBytes());
                     Prometheus.registry().counter("player_login_result", new String[]{"status", "not_loaded"}).increment();
                     return false;
                  } else {
                     if (Log.loggingDebug) {
                        Log.debug("processLogin: loaded player object: " + playerOid);
                     }

                     errorMessage = this.proxyLoginCallback.postLoad(player, con);
                     if (errorMessage != null) {
                        this.playerManager.removePlayer(playerOid);
                        loginResponse = new AuthorizedLoginResponseEvent(playerOid, false, errorMessage, this.serverVersion);
                        con.send(loginResponse.toBytes());
                        Prometheus.registry().counter("player_login_result", new String[]{"status", "error"}).increment();
                        return false;
                     } else {
                        loginResponse = new AuthorizedLoginResponseEvent(playerOid, true, "Login Succeeded", this.serverVersion + ", " + this.serverCapabilitiesSentToClient);
                        con.send(loginResponse.toBytes());
                        if (Log.loggingDebug) {
                           Log.debug("Login response sent for playerOid=" + playerOid + " the authorized login response message is : " + loginResponse.getMessage());
                        }

                        this.playerManager.addStaticPerception(player, playerOid);
                        boolean loginOK = this.processLoginHelper(con, player);
                        if (Log.loggingDebug) {
                           log.debug("processLogin: loginOK?:" + loginOK + "  | player=" + player);
                        }

                        if (!loginOK) {
                           if (Log.loggingDebug) {
                              Log.debug("processLogin: loading object: " + playerOid + ", con=" + con + " login failed disconect player");
                           }

                           con.setAssociation((Object)null);
                           if (this.perceptionFilter.removeTarget(playerOid)) {
                              FilterUpdate filterUpdate = new FilterUpdate(1);
                              filterUpdate.removeFieldValue(1, playerOid);
                              Engine.getAgent().applyFilterUpdate(this.perceptionSubId, filterUpdate);
                              this.responderFilter.removeTarget(playerOid);
                              this.responderFilter2.removeTarget(playerOid);
                              Engine.getAgent().applyFilterUpdate(this.responderSubId, filterUpdate);
                              Engine.getAgent().applyFilterUpdate(this.responderSubId2, filterUpdate);
                           }

                           this.playerManager.removeStaticPerception(player, playerOid);
                           this.playerManager.removePlayer(playerOid);
                           Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "bad_login"}).increment();
                           con.close();
                        } else {
                           this.proxyLoginCallback.postSpawn(player, con);
                           this.playerManager.loginComplete(player, this.eventQQ);
                           SubjectMessage loginSpawned = new SubjectMessage(MSG_TYPE_LOGIN_SPAWNED);
                           loginSpawned.setSubject(playerOid);
                           Engine.getAgent().sendBroadcast(loginSpawned);
                           this.processPlayerIgnoreList(player);
                           OID accountID = (OID)EnginePlugin.getObjectProperty(playerOid, WorldManagerClient.NAMESPACE, "accountId");
                           this.clientConnections.put(accountID, con);
                           if (player.getStatus() == 3) {
                              ProxyPlugin.ConnectionResetMessage message = new ProxyPlugin.ConnectionResetMessage(con, player);
                              message.setEnqueueTime();
                              this.messageQQ.insert(player, message);
                           }
                        }

                        Prometheus.registry().counter("player_login_result", new String[]{"status", loginOK ? "ok" : "failed"}).increment();
                        if (Log.loggingDebug) {
                           log.debug("processLogin: loginOK?:" + loginOK + " || player=" + player);
                           log.debug("processLogin: loginOK:" + loginOK + " end");
                        }

                        return loginOK;
                     }
                  }
               }
            }
         }
      }
   }

   protected boolean loadPlayerObject(Player player) {
      if (Log.loggingDebug) {
         log.debug("loadPlayerObject player " + player);
      }

      InstanceRestorePoint restorePoint = null;
      LinkedList restoreStack = null;
      boolean first = true;
      OID playerOid = player.getOid();
      List<Namespace> namespaces = new ArrayList();
      OID oidResult = ObjectManagerClient.loadSubObject(playerOid, namespaces);
      if (Log.loggingDebug) {
         log.debug("loadPlayerObject player " + player + " oidResult=" + oidResult);
      }

      if (oidResult == null) {
         return false;
      } else {
         Point location = new Point();
         OID instanceOid = Engine.getDatabase().getLocation(playerOid, WorldManagerClient.NAMESPACE, location);
         if (Log.loggingDebug) {
            log.debug("loadPlayerObject instanceOid " + instanceOid + " instanceEntryAllowed:" + this.instanceEntryAllowed(playerOid, instanceOid, location));
         }

         if (Log.loggingDebug) {
            log.debug("loadPlayerObject: trying to load player into instance: " + instanceOid);
         }

         int guildID = this.aDB.GetGuildId(playerOid);
         if (Log.loggingDebug) {
            log.debug("loadPlayerObject: load player guildID: " + guildID);
         }

         while(true) {
            try {
               OID result = null;
               if (this.instanceEntryAllowed(playerOid, instanceOid, location)) {
                  InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145);
                  if (Log.loggingDebug) {
                     log.debug("loadPlayerObject InstanceInfo " + instanceInfo + " plyOid=" + instanceInfo.playerOid + " tempId" + instanceInfo.templateID + " groupId" + instanceInfo.groupOid + " guildId" + instanceInfo.guildId + " start do ");
                  }

                  if (instanceInfo.oid != null && (instanceInfo.populationLimit < 1 || instanceInfo.playerPopulation < instanceInfo.populationLimit)) {
                     result = ObjectManagerClient.loadObject(playerOid);
                     if (Log.loggingDebug) {
                        Log.debug("loadPlayerObject: loading player into instance: " + instanceInfo.oid + " of ID: " + instanceInfo.templateID);
                     }
                  }
               }

               if (restoreStack != null && !restorePoint.getFallbackFlag()) {
                  EnginePlugin.setObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack", restoreStack);
               }

               if (result == null) {
                  if (first) {
                     Integer instanceID = (Integer)EnginePlugin.getObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "currentInstanceName");
                     if (Log.loggingDebug) {
                        log.debug("Failed initial load, retrying with current instanceID=" + instanceID);
                     }

                     if (Log.loggingDebug) {
                        log.debug(" loadPlayerObject instanceID=" + instanceID + "  playerOid=" + playerOid + " guildID=" + guildID);
                     }

                     if (instanceID > 0) {
                        instanceOid = this.instanceEntryCallback.selectInstance(player, instanceID, playerOid, guildID);
                        if (Log.loggingDebug) {
                           log.debug("loadPlayerObject instanceOid:" + instanceOid);
                        }

                        if (instanceOid != null) {
                           InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145, false);
                           if (Log.loggingDebug) {
                              log.debug(" loadPlayerObject InstanceInfo " + instanceInfo + " plyOid=" + instanceInfo.playerOid + " tempId=" + instanceInfo.templateID + " groupId=" + instanceInfo.groupOid + " guildId=" + instanceInfo.guildId);
                           }

                           if (instanceInfo.oid != null) {
                              if (instanceInfo.populationLimit > 0 && instanceInfo.playerPopulation >= instanceInfo.populationLimit) {
                                 if (Log.loggingDebug) {
                                    Log.debug("POP: got population: " + instanceInfo.playerPopulation + " and limit: " + instanceInfo.populationLimit);
                                 }

                                 instanceOid = handleFullInstance(instanceInfo.templateID, instanceInfo);
                                 instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145);
                                 log.debug(" loadPlayerObject 2 InstanceInfo " + instanceInfo + " plyOid" + instanceInfo.playerOid + " tempId=" + instanceInfo.templateID + " groupId=" + instanceInfo.groupOid + " guildId=" + instanceInfo.guildId);
                              }

                              if (Log.loggingDebug) {
                                 log.debug("Failed initial load, retrying with instanceOid=" + instanceOid + " and instanceName: " + instanceInfo.name);
                              }

                              BasicWorldNode wnode = new BasicWorldNode();
                              wnode.setInstanceOid(instanceOid);
                              ObjectManagerClient.fixWorldNode(playerOid, wnode);
                              first = false;
                              continue;
                           }
                        }
                     }
                  }

                  if (restorePoint != null && restorePoint.getFallbackFlag()) {
                     if (Log.loggingDebug) {
                        log.debug("loadPlayerObject instanceOid " + instanceOid + " restorePoint:" + restorePoint + " restorePoint.getFallbackFlag():" + restorePoint.getFallbackFlag() + " return false");
                     }

                     return false;
                  }

                  restoreStack = (LinkedList)EnginePlugin.getObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack");
                  if (restoreStack != null && restoreStack.size() != 0) {
                     int size = restoreStack.size();
                     restorePoint = (InstanceRestorePoint)restoreStack.get(size - 1);
                     instanceOid = restorePoint.getInstanceOid();
                     if (restorePoint.getInstanceID() > 0) {
                        instanceOid = this.instanceEntryCallback.selectInstance(player, restorePoint.getInstanceID());
                        if (Log.loggingDebug) {
                           Log.debug("Failed finding matching instance, retrying with restore point instanceID=" + restorePoint.getInstanceID() + " result: " + instanceOid);
                        }
                     }

                     if (instanceOid != null) {
                        BasicWorldNode wnode = new BasicWorldNode();
                        wnode.setInstanceOid(instanceOid);
                        wnode.setLoc(restorePoint.getLoc());
                        wnode.setOrientation(restorePoint.getOrientation());
                        wnode.setDir(new AOVector(0.0F, 0.0F, 0.0F));
                        boolean rc = ObjectManagerClient.fixWorldNode(playerOid, wnode);
                        if (!rc) {
                           if (Log.loggingDebug) {
                              log.debug("loadPlayerObject instanceOid " + instanceOid + " rc:" + rc + " return false");
                           }

                           return false;
                        }

                        location = restorePoint.getLoc();
                     }

                     first = false;
                     if (!restorePoint.getFallbackFlag()) {
                        restoreStack.remove(size - 1);
                     }
                     continue;
                  }

                  Log.error("Failed finding matching instance, and restore stack is null or empty?" + restoreStack + " return false");
                  return false;
               }

               if (restorePoint != null) {
                  EnginePlugin.setObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "currentInstanceName", restorePoint.getInstanceID());
                  if (Log.loggingDebug) {
                     log.debug("INSTANCE: setting current instance prop: " + restorePoint.getInstanceID());
                  }
               }
            } catch (Exception var15) {
               log.error("loadPlayerObject instanceOid " + instanceOid + " Exception: " + var15.getMessage() + " " + var15.getLocalizedMessage());
            }

            if (Log.loggingDebug) {
               log.debug("loadPlayerObject instanceOid " + instanceOid + " END return true");
            }

            return true;
         }
      }
   }

   protected boolean processLoginHelper(ClientConnection con, Player player) {
      OID playerOid = player.getOid();
      WorldManagerClient.ObjectInfo objInfo = WorldManagerClient.getObjectInfo(playerOid);
      if (objInfo == null) {
         Log.error("processLogin: Could not get player ObjectInfo oid=" + playerOid);
         return false;
      } else {
         if (Log.loggingDebug) {
            log.debug("processLoginHelper objInfo " + objInfo.instanceOid);
         }

         if (World.FollowsTerrainOverride != null) {
            Log.debug("using follows terrain override");
            objInfo.followsTerrain = World.FollowsTerrainOverride;
         }

         if (Log.loggingDebug) {
            Log.debug("processLogin: got object info: " + objInfo);
         }

         player.setName(objInfo.name);
         InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(objInfo.instanceOid, -262145);
         if (Log.loggingDebug) {
            log.debug("InstanceInfo " + instanceInfo + " " + instanceInfo.playerOid + " " + instanceInfo.templateID + " " + instanceInfo.groupOid + " " + instanceInfo.guildId);
         }

         if (instanceInfo == null) {
            Log.error("processLogin: unknown instanceOid=" + objInfo.instanceOid);
            return false;
         } else {
            if (Log.loggingDebug) {
               Log.debug("processLogin: sending template (scene) name: " + instanceInfo.templateName);
            }

            Event worldFileEvent = new WorldFileEvent(instanceInfo.templateName);
            con.send(worldFileEvent.toBytes());
            player.sceneLoading(true);
            Log.debug("INFO: process login helper");
            con.send(objInfo.toBuffer(playerOid));
            DisplayContext dc = WorldManagerClient.getDisplayContext(playerOid);
            ModelInfoEvent modelInfoEvent = new ModelInfoEvent(playerOid);
            modelInfoEvent.setDisplayContext(dc);
            if (Log.loggingDebug) {
               Log.debug("processLogin: got dc: " + dc);
            }

            con.send(modelInfoEvent.toBytes());
            Map<String, DisplayContext> childMap = dc.getChildDCMap();
            if (childMap != null && !childMap.isEmpty()) {
               Iterator var10 = childMap.keySet().iterator();

               while(var10.hasNext()) {
                  String slot = (String)var10.next();
                  DisplayContext attachDC = (DisplayContext)childMap.get(slot);
                  if (attachDC == null) {
                     throw new AORuntimeException("attach DC is null for obj: " + playerOid);
                  }

                  OID attacheeOID = attachDC.getObjRef();
                  if (attacheeOID == null) {
                     throw new AORuntimeException("attachee oid is null for obj: " + playerOid);
                  }

                  if (Log.loggingDebug) {
                     Log.debug("processLogin: sending attach message to " + playerOid + " attaching to obj " + playerOid + ", object being attached=" + attacheeOID + " to slot " + slot + ", attachmentDC=" + attachDC);
                  }

                  AttachEvent event = new AttachEvent(playerOid, attacheeOID, slot, attachDC);
                  con.send(event.toBytes());
               }

               Log.debug("processLogin: done with processing attachments");
            }

            if (this.perceptionFilter.addTarget(playerOid)) {
               FilterUpdate filterUpdate = new FilterUpdate(1);
               filterUpdate.addFieldValue(1, playerOid);
               Engine.getAgent().applyFilterUpdate(this.perceptionSubId, filterUpdate);
               this.responderFilter.addTarget(playerOid);
               this.responderFilter2.addTarget(playerOid);
               Engine.getAgent().applyFilterUpdate(this.responderSubId, filterUpdate);
               Engine.getAgent().applyFilterUpdate(this.responderSubId2, filterUpdate);
            }

            LoginMessage loginMessage = new LoginMessage(playerOid, objInfo.name);
            loginMessage.setInstanceOid(objInfo.instanceOid);
            loginMessage.setProxy(this.getName());
            ProxyPlugin.AsyncRPCCallback asyncRPCCallback = new ProxyPlugin.AsyncRPCCallback(player, "processLogin: got LoginMessage response");
            int expectedResponses = Engine.getAgent().sendBroadcastRPC(loginMessage, asyncRPCCallback);
            asyncRPCCallback.waitForResponses(expectedResponses);
            WorldManagerClient.updateObject(playerOid, playerOid);
            WorldManagerClient.TargetedExtensionMessage spawnBegin = new WorldManagerClient.TargetedExtensionMessage(playerOid, playerOid);
            spawnBegin.setExtensionType("ao.SCENE_BEGIN");
            spawnBegin.setProperty("action", "login");
            spawnBegin.setProperty("name", instanceInfo.name);
            spawnBegin.setProperty("templateName", instanceInfo.templateName);
            WorldManagerClient.TargetedExtensionMessage spawnEnd = new WorldManagerClient.TargetedExtensionMessage(playerOid, playerOid);
            spawnEnd.setExtensionType("ao.SCENE_END");
            spawnEnd.setProperty("action", "login");
            spawnEnd.setProperty("name", instanceInfo.name);
            spawnEnd.setProperty("templateName", instanceInfo.templateName);
            Integer perceptionCount = WorldManagerClient.spawn(playerOid, spawnBegin, spawnEnd);
            if (perceptionCount < 0) {
               Log.error("processLogin: spawn failed error=" + perceptionCount + " playerOid=" + playerOid);
               return perceptionCount == -2 ? false : false;
            } else {
               if (perceptionCount == 0 && player.supportsLoadingState()) {
                  player.setLoadingState(1);
                  con.send((new LoadingStateEvent(false)).toBytes());
               }

               if (Log.loggingDebug) {
                  Log.debug("processLogin: During login, perceptionCount is " + perceptionCount);
                  Log.debug("processLogin: spawned player, master playerOid=" + playerOid);
               }

               if (Log.loggingDebug) {
                  Log.debug("processLogin: sending over instance information for player " + playerOid + ", instance=" + instanceInfo.name + ", instanceOid=" + instanceInfo.oid);
               }

               this.updateInstancePerception(player.getOid(), (OID)null, instanceInfo.oid, instanceInfo.name);
               return true;
            }
         }
      }
   }

   public ProxyLoginCallback getProxyLoginCallback() {
      return this.proxyLoginCallback;
   }

   public void setProxyLoginCallback(ProxyLoginCallback callback) {
      this.proxyLoginCallback = callback;
   }

   private boolean instanceEntryAllowed(OID playerOid, OID instanceOid, Point location) {
      return instanceOid == null ? false : this.instanceEntryCallback.instanceEntryAllowed(playerOid, instanceOid, location);
   }

   public InstanceEntryCallback getInstanceEntryCallback() {
      return this.instanceEntryCallback;
   }

   public void setInstanceEntryCallback(InstanceEntryCallback callback) {
      this.instanceEntryCallback = callback;
   }

   public void processRequestQuestInfo(ClientConnection con, RequestQuestInfo event) {
      OID npcOid = event.getQuestNpcOid();
      Player player = this.verifyPlayer("processRequestQuestInfo", event, con);
      if (Log.loggingDebug) {
         Log.debug("processRequestQuestInfo: player=" + player + ", npc=" + npcOid);
      }

      QuestClient.requestQuestInfo(npcOid, player.getOid());
   }

   public void processQuestResponse(ClientConnection con, QuestResponse event) {
      Player player = this.verifyPlayer("processQuestResponse", event, con);
      boolean acceptStatus = event.getResponse();
      OID npcOid = event.getQuestNpcOid();
      OID questOid = event.getQuestId();
      if (Log.loggingDebug) {
         Log.debug("processQuestResponse: player=" + player + ", npcOid=" + npcOid + ", acceptStatus=" + acceptStatus);
      }

      QuestResponseMessage msg = new QuestResponseMessage(npcOid, player.getOid(), questOid, acceptStatus);
      Engine.getAgent().sendBroadcast(msg);
   }

   public void processReqConcludeQuest(ClientConnection con, ConcludeQuest event) {
      Player player = this.verifyPlayer("processReqConcludeQuest", event, con);
      OID mobOid = event.getQuestNpcOid();
      if (Log.loggingDebug) {
         Log.debug("processReqConclude: player=" + player + ", mobOid=" + mobOid);
      }

      QuestClient.requestConclude(mobOid, player.getOid());
   }

   public void connectionReset(ClientConnection con) {
      Player player = (Player)con.getAssociation();
      if (player == null) {
         Log.info("ProxyPlugin: DISCONNECT remote=" + con);
      } else {
         if (Log.loggingInfo) {
            Log.info("ProxyPlugin: DISCONNECT remote=" + con + " playerOid=" + player.getOid() + " name=" + player.getName() + " player=" + player);
            Log.info("ProxyPlugin: DISCONNECT remote=" + con + " player=" + player);
         }

         this.playerManager.logout(player);
         ProxyPlugin.ConnectionResetMessage message = new ProxyPlugin.ConnectionResetMessage(con, player);
         message.setEnqueueTime();
         this.messageQQ.insert(player, message);
      }
   }

   protected void processConnectionResetInternal(ProxyPlugin.ConnectionResetMessage message) {
      long startTime = System.currentTimeMillis();
      ClientConnection con = message.getConnection();
      Player player = message.getPlayer();
      OID playerOid = player.getOid();
      if (Log.loggingInfo) {
         Log.info("ProxyPlugin: LOGOUT_BEGIN remote=" + con + " playerOid=" + player.getOid() + " name=" + player.getName());
      }

      if (player.getStatus() != 3) {
         log.error("processConnectionReset: player status is " + Player.statusToString(player.getStatus()) + " should be " + Player.statusToString(3));
         player.setStatus(3);
      }

      try {
         try {
            if (!WorldManagerClient.despawn(playerOid)) {
               log.warn("processConnectionReset: despawn player failed for " + playerOid);
            }
         } catch (Exception var13) {
            log.warn("processConnectionReset: despawn player failed for " + playerOid + " " + var13);
         }

         if (Log.loggingDebug) {
            Log.debug("processConnectionResetInternal Removing perceptionFilter for palyer: " + playerOid);
         }

         if (this.perceptionFilter.removeTarget(playerOid)) {
            FilterUpdate filterUpdate = new FilterUpdate(1);
            filterUpdate.removeFieldValue(1, playerOid);
            if (Log.loggingDebug) {
               Log.debug("processConnectionResetInternal Removing perceptionFilter applyFilterUpdate for palyer: " + playerOid);
            }

            Engine.getAgent().applyFilterUpdate(this.perceptionSubId, filterUpdate);
            if (Log.loggingDebug) {
               Log.debug("processConnectionResetInternal Removing responderFilter for palyer: " + playerOid);
            }

            this.responderFilter.removeTarget(playerOid);
            this.responderFilter2.removeTarget(playerOid);
            if (Log.loggingDebug) {
               Log.debug("processConnectionResetInternal Removing perceptionFilter applyFilterUpdate for palyer: " + playerOid);
            }

            Engine.getAgent().applyFilterUpdate(this.responderSubId, filterUpdate);
            Engine.getAgent().applyFilterUpdate(this.responderSubId2, filterUpdate);
         }

         LogoutMessage logoutMessage = new LogoutMessage(playerOid, player.getName());
         if (Log.loggingDebug) {
            Log.debug("processConnectionResetInternal: Send LogoutMessage for player: " + playerOid + "  and wait for response");
         }

         ProxyPlugin.AsyncRPCCallback asyncRPCCallback = new ProxyPlugin.AsyncRPCCallback(player, "processLogout: got LogoutMessage response");
         int expectedResponses = Engine.getAgent().sendBroadcastRPC(logoutMessage, asyncRPCCallback);
         if (Log.loggingDebug) {
            Log.debug("processConnectionResetInternal: Send LogoutMessage for player: " + playerOid + "  and wait for response expectedResponses=" + expectedResponses);
         }

         asyncRPCCallback.waitForResponses(expectedResponses);
         OID accountID = this.aDB.getAccountForCharacter(playerOid);
         if (Log.loggingDebug) {
            Log.debug("Removing connection from client connection map for account: " + accountID);
         }

         if (this.clientConnections.containsKey(accountID) && ((ClientConnection)this.clientConnections.get(accountID)).isOpen()) {
            Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "internal_reset"}).increment();
            ((ClientConnection)this.clientConnections.get(accountID)).close();
         }

         this.clientConnections.remove(accountID);
         if (!ObjectManagerClient.unloadObject(playerOid)) {
            log.warn("processConnectionReset: unloadObject failed oid=" + playerOid);
         }
      } catch (NoRecipientsException var14) {
         log.exception("ProxyPlugin.processConnectionResetInternal(): NoRecipientsException ", var14);
      } catch (RPCTimeoutException var15) {
         log.exception("ProxyPlugin.processConnectionResetInternal(): RPCTimeoutException ", var15);
      } catch (Exception var16) {
         log.exception("ProxyPlugin.processConnectionResetInternal(): Exception ", var16);
      }

      this.messageQQ.removeKey(player);
      this.eventQQ.removeKey(player);
      this.slowEventQQ.removeKey(player);
      con.closeAggregator();
      this.playerManager.removeStaticPerception(player, playerOid);
      this.playerManager.removePlayer(playerOid);
      if (Log.loggingInfo) {
         Log.info("ProxyPlugin: LOGOUT_END remote=" + con + " playerOid=" + player.getOid() + " name=" + player.getName() + " in-queue=" + (startTime - message.getEnqueueTime()) + " processing=" + (System.currentTimeMillis() - startTime) + " nPlayers=" + this.playerManager.getPlayerCount());
      }

      synchronized(player) {
         player.clearConnection();
         player.notifyAll();
      }
   }

   protected void processPlayerHa(ClientConnection con, PlayerHaEvent event) {
      if (Log.loggingDebug) {
         Log.debug("processPlayerHa: got dir loc orient event: " + event);
      }

      Player player = this.verifyPlayer("processPlayerHa", event, con);
      long stime = System.currentTimeMillis();
      long ctime = event.getTime();
      long lctime = 0L;
      long lstime = 0L;

      try {
         lctime = (Long)this.playerLastClientTime.get(player.getOid());
      } catch (Exception var20) {
      }

      try {
         lstime = (Long)this.playerLastServerTime.get(player.getOid());
      } catch (Exception var19) {
      }

      this.playerLastClientTime.put(player.getOid(), event.getTime());
      this.playerLastServerTime.put(player.getOid(), stime);
      if (lctime > 0L && lstime > 0L && stime - lstime < (long)SpeedhackMinDiff) {
         log.error("SPEEDHACK detected plyOid=" + player.getOid() + " Ct=" + ctime + " LCT=" + lctime + " ST=" + stime + " LST=" + lstime + " dst=" + (stime - lstime) + " dct=" + (ctime - lctime));
         long count = 0L;

         try {
            count = (Long)this.playerSpeedHackCount.get(player.getOid());
         } catch (Exception var18) {
         }

         ++count;
         this.playerSpeedHackCount.put(player.getOid(), count);
         long fdtime = 0L;

         try {
            fdtime = (Long)this.playerFirstSpeedHackTime.get(player.getOid());
         } catch (Exception var17) {
         }

         if (fdtime == 0L) {
            fdtime = stime;
            this.playerFirstSpeedHackTime.put(player.getOid(), stime);
         }

         if (SpeedhackChatMsg.length() > 1) {
            TargetedComMessage comMsg = new TargetedComMessage();
            comMsg.setString(SpeedhackChatMsg);
            comMsg.setChannel(0);
            comMsg.setChatterName("Admin");
            comMsg.setTarget(player.getOid());
            Engine.getAgent().sendBroadcast(comMsg);
         }

         HashMap<String, Serializable> logData = new HashMap();
         logData.put("serverDeltaTime", stime - lstime);
         logData.put("clientDeltaTime", ctime - lctime);
         logData.put("firstDetection", fdtime);
         logData.put("count", count);
         DataLoggerClient.logData("SPEEDHACK", player.getOid(), (OID)null, (OID)null, logData);
         if (count > (long)SpeedhackCountToDisconect) {
            Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "speed_hack"}).increment();
            con.close();
            this.playerLastClientTime.remove(player.getOid());
            this.playerLastServerTime.remove(player.getOid());
            this.playerFirstSpeedHackTime.remove(player.getOid());
            this.playerSpeedHackCount.remove(player.getOid());
         }
      }

   }

   protected void processDirLocOrient(ClientConnection con, DirLocOrientEvent event) {
      if (Log.loggingDebug) {
         Log.debug("processDirLocOrient: got dir loc orient event: " + event);
      }

      Player player = this.verifyPlayer("processDirLoc", event, con);
      BasicWorldNode wnode = new BasicWorldNode();
      wnode.setDir(event.getDir());
      wnode.setLoc(event.getLoc());
      wnode.setOrientation(event.getQuaternion());
      wnode.time = event.getTime();
      wnode.mid = event.getId();
      wnode.cid = event.getUId();
      WorldManagerClient.updateWorldNode(player.getOid(), wnode);
   }

   protected void processCom(ClientConnection con, ComEvent event) {
      Player player = this.verifyPlayer("processCom", event, con);
      if (Log.loggingInfo) {
         Log.info("ProxyPlugin: CHAT_SENT player=" + player + " channel=" + event.getChannelId() + " msg=[" + event.getMessage() + "]");
      }

      log.debug("processCom: CHAT_SENT");
      if (!this.aDB.isOnBlackList(player.getOid(), event.getObjectOid())) {
         this.incrementChatCount();
         ChatClient.sendChatMsg(player.getOid(), player.getName(), event.getChannelId(), event.getMessage());
      }
   }

   protected void processCommand(ClientConnection con, CommandEvent event) {
      Player player = this.verifyPlayer("processCommand", event, con);
      String cmd = event.getCommand().split(" ")[0];
      if (Log.loggingDebug) {
         log.debug("processCommand: cmd=" + cmd + ", fullCmd=" + event.getCommand());
      }

      this.commandMapLock.lock();

      ProxyPlugin.RegisteredCommand command;
      try {
         command = (ProxyPlugin.RegisteredCommand)this.commandMap.get(cmd);
      } finally {
         this.commandMapLock.unlock();
      }

      if (command == null) {
         Log.warn("processCommand: no parser for command: " + event.getCommand());
         command = (ProxyPlugin.RegisteredCommand)this.commandMap.get("/unknowncmd");
         if (command != null) {
            Engine.setCurrentPlugin(this);
            command.parser.parse(event);
            Engine.setCurrentPlugin((EnginePlugin)null);
         }

      } else {
         Engine.setCurrentPlugin(this);
         if (command.access.allowed(event, this)) {
            command.parser.parse(event);
         } else {
            Log.warn("Player " + player + " not allowed to run command '" + event.getCommand() + "'");
         }

         Engine.setCurrentPlugin((EnginePlugin)null);
      }
   }

   protected void processAutoAttack(ClientConnection con, AutoAttackEvent event) {
      CombatClient.autoAttack(event.getAttackerOid(), event.getTargetOid(), event.getAttackStatus());
   }

   protected void processActivateItem(ClientConnection con, ActivateItemEvent event) {
      InventoryClient.activateObject(event.getItemOid(), event.getObjectOid(), event.getTargetOid());
   }

   protected void processAbilityStatusEvent(ClientConnection con, AbilityStatusEvent event) {
      Player player = (Player)con.getAssociation();
      AbilityStatusMessage msg = new AbilityStatusMessage(CombatClient.MSG_TYPE_ABILITY_STATUS, player.getOid(), event.getPropertyMap());
      Engine.getAgent().sendBroadcast(msg);
   }

   protected void processLogout(ClientConnection con, LogoutEvent event) {
   }

   protected void processSceneLoaded(ClientConnection con, SceneLoadedEvent event) {
      Player player = (Player)con.getAssociation();
      player.sceneLoading(false);
      if (Log.loggingDebug) {
         Log.debug("SCENE: sceneLoading set to false for player: " + player.getOid());
      }

   }

   protected void processExtensionMessageEvent(ClientConnection con, ExtensionMessageEvent event) {
      String key = (String)event.getPropertyMap().get("ext_msg_subtype");
      OID target = event.getTargetOid();
      Player player = (Player)con.getAssociation();
      if (Log.loggingDebug) {
         Log.debug("processExtensionMessageEvent: " + player + " subType=" + key + " target=" + target);
      }

      List<ProxyExtensionHook> proxyHookList = (List)this.extensionHooks.get(key);
      if (proxyHookList == null) {
         if (target != null) {
            WorldManagerClient.TargetedExtensionMessage msg = new WorldManagerClient.TargetedExtensionMessage(WorldManagerClient.MSG_TYPE_EXTENSION, target, player.getOid(), event.getClientTargeted(), event.getPropertyMap());
            if (event.getClientTargeted()) {
               msg.setMsgType(WorldManagerClient.MSG_TYPE_P2P_EXTENSION);
               if (this.allowClientToClientMessage(player, target, msg)) {
                  Engine.getAgent().sendBroadcast(msg);
               }
            } else {
               MessageType msgType = this.getExtensionMessageType(key);
               if (msgType == null) {
                  Log.error("processExtensionMessageEvent: key '" + key + "' has no corresponding MessageType");
                  return;
               }

               msg.setMsgType(msgType);
               Engine.getAgent().sendBroadcast(msg);
            }
         } else {
            MessageType msgType = this.getExtensionMessageType(key);
            if (msgType == null) {
               Log.error("processExtensionMessageEvent: key '" + key + "' has no corresponding MessageType");
               return;
            }

            WorldManagerClient.ExtensionMessage msg = new WorldManagerClient.ExtensionMessage(msgType, player.getOid(), event.getPropertyMap());
            Engine.getAgent().sendBroadcast(msg);
         }

      } else {
         Iterator var7 = proxyHookList.iterator();

         while(var7.hasNext()) {
            ProxyExtensionHook hook = (ProxyExtensionHook)var7.next();
            hook.processExtensionEvent(event, player, this);
         }

      }
   }

   public void registerExtensionSubtype(String subtype, MessageType type) {
      this.extensionMessageRegistry.put(subtype, type);
   }

   public MessageType unregisterExtensionSubtype(String subtype) {
      return (MessageType)this.extensionMessageRegistry.remove(subtype);
   }

   public MessageType getExtensionMessageType(String subtype) {
      return (MessageType)this.extensionMessageRegistry.get(subtype);
   }

   public boolean allowClientToClientMessage(Player sender, OID targetOid, WorldManagerClient.TargetedExtensionMessage message) {
      return this.defaultAllowClientToClientMessage;
   }

   protected boolean specialCaseNewProcessing(PerceptionMessage.ObjectNote objectNote, Player player) {
      long start = System.currentTimeMillis();
      ClientConnection con = player.getConnection();
      OID objOid = objectNote.getSubject();
      ObjectType objType = objectNote.getObjectType();
      if (objType == ObjectTypes.light) {
         Log.debug("specialCaseNewProcessing: got a light object");
         LightData lightData = (LightData)EnginePlugin.getObjectProperty(objOid, Namespace.WORLD_MANAGER, Light.LightDataPropertyKey);
         if (Log.loggingDebug) {
            Log.debug("specialCaseNewProcessing: light data=" + lightData);
         }

         NewLightEvent lightEvent = new NewLightEvent(player.getOid(), objOid, lightData);
         con.send(lightEvent.toBytes());
         return true;
      } else if (objType.equals(WorldManagerClient.TEMPL_OBJECT_TYPE_TERRAIN_DECAL)) {
         Log.debug("specialCaseNewProcessing: got a terrain decal object");
         TerrainDecalData decalData = (TerrainDecalData)EnginePlugin.getObjectProperty(objOid, Namespace.WORLD_MANAGER, WorldManagerClient.TEMPL_TERRAIN_DECAL_DATA);
         if (Log.loggingDebug) {
            Log.debug("specialCaseNewProcessing: terrain decal data=" + decalData);
         }

         NewTerrainDecalEvent decalEvent = new NewTerrainDecalEvent(objOid, decalData);
         con.send(decalEvent.toBytes());
         return true;
      } else if (objType.equals(WorldManagerClient.TEMPL_OBJECT_TYPE_POINT_SOUND)) {
         Log.debug("specialCaseNewProcessing: got a point sound object");
         List<SoundData> soundData = (List)EnginePlugin.getObjectProperty(objOid, Namespace.WORLD_MANAGER, WorldManagerClient.TEMPL_SOUND_DATA_LIST);
         if (Log.loggingDebug) {
            Log.debug("specialCaseNewProcessing: sound data=" + soundData);
         }

         WorldManagerClient.SoundMessage soundMsg = new WorldManagerClient.SoundMessage(objOid);
         soundMsg.setSoundData(soundData);
         con.send(soundMsg.toBuffer());
         return true;
      } else {
         WorldManagerClient.PerceptionInfo perceptionInfo = (WorldManagerClient.PerceptionInfo)objectNote.getObjectInfo();
         if (perceptionInfo.objectInfo == null) {
            return true;
         } else {
            WorldManagerClient.MobPathMessage pathMsg = (WorldManagerClient.MobPathMessage)perceptionInfo.objectInfo.getProperty(WorldManagerClient.MOB_PATH_PROPERTY);
            if (Log.loggingDebug) {
               Log.debug("INFO: MobPathMessage special case with player/npc: " + perceptionInfo.objectInfo.name);
            }

            con.send(perceptionInfo.objectInfo.toBuffer(player.getOid()));
            if (Log.loggingDebug) {
               Log.debug("INFO: specialCaseNewProcessing " + perceptionInfo.displayContext);
            }

            if (perceptionInfo.displayContext != null) {
               ModelInfoEvent modelInfoEvent = new ModelInfoEvent(objOid);
               modelInfoEvent.setDisplayContext(perceptionInfo.displayContext);
               con.send(modelInfoEvent.toBytes());
            } else if (Log.loggingDebug) {
               Log.debug("No display context for " + objOid + " " + perceptionInfo.objectInfo);
            }

            if (pathMsg != null) {
               if (pathMsg.pathExpired()) {
                  if (Log.loggingDebug) {
                     Log.debug("specialCaseNewProcessing: for mob " + objOid + ", last mob path expired " + pathMsg.toString());
                  }
               } else {
                  if (Log.loggingDebug) {
                     Log.debug("specialCaseNewProcessing: for mob " + objOid + ", sending last mob path " + pathMsg.toString());
                  }

                  AOByteBuffer pathBuf = pathMsg.toBuffer();
                  con.send(pathBuf);
               }
            }

            Map<String, DisplayContext> childMap = null;
            if (perceptionInfo.displayContext != null) {
               childMap = perceptionInfo.displayContext.getChildDCMap();
            }

            if (childMap != null && !childMap.isEmpty()) {
               Iterator var11 = childMap.keySet().iterator();

               while(var11.hasNext()) {
                  String slot = (String)var11.next();
                  DisplayContext attachDC = (DisplayContext)childMap.get(slot);
                  if (attachDC == null) {
                     throw new AORuntimeException("attach DC is null for obj: " + objOid);
                  }

                  OID attacheeOID = attachDC.getObjRef();
                  if (attacheeOID == null) {
                     throw new AORuntimeException("attachee oid is null for obj: " + objOid);
                  }

                  if (Log.loggingDebug) {
                     Log.debug("specialCaseNewProcessing: sending attach message to " + player.getOid() + " attaching to obj " + objOid + ", object being attached=" + attacheeOID + " to slot " + slot + ", attachmentDC=" + attachDC);
                  }

                  AttachEvent event = new AttachEvent(objOid, attacheeOID, slot, attachDC);
                  con.send(event.toBytes());
               }

               if (Log.loggingDebug) {
                  Log.debug("specialCaseNewProcessing: done with processing attachments");
               }
            }

            long finish = System.currentTimeMillis();
            if (Log.loggingDebug) {
               Log.debug("specialCaseNewProcessing: finished.\tplayerOid=" + player.getOid() + ", oid=" + objOid + " in " + (finish - start) + " ms");
            }

            return false;
         }
      }
   }

   protected boolean specialCaseFreeProcessing(PerceptionMessage.ObjectNote objectNote, Player player) {
      if (player.getOid().equals(objectNote.getSubject())) {
         Log.debug("ignoring free object message to self");
         return true;
      } else {
         ClientConnection con = player.getConnection();
         if (!con.isOpen()) {
            con = null;
         }

         OID objOid = objectNote.getSubject();
         if (objectNote.getObjectType() == ObjectTypes.road) {
            if (Log.loggingDebug) {
               Log.debug("specialCaseFreeProcessing: playerOid=" + player.getOid() + ", roadSegmentOid=" + objOid);
            }

            this.handleFreeRoad(con, objOid);
            return true;
         } else if (objectNote.getObjectType().equals(WorldManagerClient.TEMPL_OBJECT_TYPE_TERRAIN_DECAL)) {
            if (Log.loggingDebug) {
               Log.debug("specialCaseFreeProcessing: playerOid=" + player.getOid() + ", decalOid=" + objOid);
            }

            FreeTerrainDecalEvent decalEvent = new FreeTerrainDecalEvent(objOid);
            if (con != null) {
               con.send(decalEvent.toBytes());
            }

            return true;
         } else {
            if (Log.loggingDebug) {
               Log.debug("specialCaseFreeProcessing: playerOid=" + player.getOid() + ", objOid=" + objOid);
            }

            NotifyFreeObjectEvent freeEvent = new NotifyFreeObjectEvent(player.getOid(), objOid);
            if (con != null) {
               con.send(freeEvent.toBytes());
            }

            return false;
         }
      }
   }

   protected void handleFreeRoad(ClientConnection con, OID objOid) {
      WorldManagerClient.FreeRoadMessage freeRoadMsg = new WorldManagerClient.FreeRoadMessage(objOid);
      AOByteBuffer buf = freeRoadMsg.toBuffer();
      if (con != null) {
         con.send(buf);
      }

   }

   public static void addStaticPerception(OID playerOid, OID oid) {
      addStaticPerception(playerOid, oid, (String)null, (ObjectType)null, false);
   }

   public static void addStaticPerception(OID oid, OID oid2, String name, ObjectType type) {
      addStaticPerception(oid, oid2, name, type, true);
   }

   private static void addStaticPerception(OID playerOid, OID oid, String name, ObjectType type, boolean hasObjectInfo) {
      ProxyPlugin.AddStaticPerceptionMessage message = new ProxyPlugin.AddStaticPerceptionMessage(MSG_TYPE_ADD_STATIC_PERCEPTION);
      message.setTarget(playerOid);
      message.setSubject(oid);
      message.setName(name);
      message.setType(type);
      message.setHasObjectInfo(hasObjectInfo);
      Engine.getAgent().sendBroadcast(message);
   }

   public static void removeStaticPerception(OID playerOid, OID oid) {
      TargetMessage message = new TargetMessage(MSG_TYPE_REMOVE_STATIC_PERCEPTION);
      message.setTarget(playerOid);
      message.setSubject(oid);
      Engine.getAgent().sendBroadcast(message);
   }

   protected void processPlayerIgnoreList(Player player) {
      if (player.getStatus() == 3) {
         Log.error("ProxyPlugin.processPlayerIgnoreList: Aborting... player.getStatus() is STATUS_LOGOUT");
      } else {
         this.sendPlayerIgnoreList(player);
      }
   }

   protected void sendPlayerIgnoreList(Player player) {
      String missing = " Missing ";
   }

   public void updateIgnoredOids(Player player, List<OID> nowIgnored, List<OID> noLongerIgnored) {
   }

   public List<Object> matchingPlayers(Player player, String playerName, Boolean exactMatch) {
      boolean match = exactMatch == null ? true : exactMatch;
      List<Object> matchLists = Engine.getDatabase().getOidsAndNamesMatchingName(playerName, match);
      List<OID> oids = (List)matchLists.get(0);
      List<String> names = (List)matchLists.get(1);
      if (Log.loggingDebug) {
         log.debug("ProxyPlugin.matchingPlayers: For player " + player.getOid() + ", found " + (oids == null ? 0 : oids.size()) + " players: " + Database.makeOidCollectionString(oids) + " " + (match ? "exactly matching" : "starting with") + " name '" + playerName + "':" + Database.makeNameCollectionString(names));
      }

      return matchLists;
   }

   public boolean isOnBlockList2(OID playerOid, OID targetOid) {
      if (Log.loggingDebug) {
         log.debug("IsOnBlockList: SocialPlugin  started for: " + playerOid);
      }

      boolean isOnBlockList = this.aDB.isOnBlackList(playerOid, targetOid);
      String targetName;
      if (isOnBlockList) {
         targetName = WorldManagerClient.getObjectInfo(targetOid).name;
         EventMessageHelper.SendErrorEvent(playerOid, "ErrorPlayerOnBlockList", 0, targetName);
      } else {
         isOnBlockList = this.aDB.isOnBlackList(targetOid, playerOid);
         if (isOnBlockList) {
            targetName = WorldManagerClient.getObjectInfo(targetOid).name;
            EventMessageHelper.SendErrorEvent(playerOid, "ErrorPlayerYourOnBlockList", 0, targetName);
         }
      }

      if (Log.loggingDebug) {
         log.debug("IsOnBlockList: SocialPlugin  finished for: " + playerOid);
      }

      return isOnBlockList;
   }

   private boolean isPlayerConnectionValid(Player player) {
      ClientConnection con = player.getConnection();
      return con != null && con.isOpen();
   }

   public static OID handleFullInstance(int instanceTemplateID, InstanceClient.InstanceInfo instanceInfo) {
      if (Log.loggingDebug) {
         Log.debug("POP: instance full with template: " + instanceTemplateID);
      }

      int instanceNum = 1;
      String instanceName = "";
      InstanceTemplate island = InstanceClient.getInstanceTemplate(instanceTemplateID);

      OID instanceOid;
      while(true) {
         instanceName = island.getName() + "_" + instanceNum;
         instanceOid = InstanceClient.getInstanceOid(instanceName);
         if (instanceOid != null) {
            instanceInfo = InstanceClient.getInstanceInfo(instanceOid, -262145);
            if (instanceInfo.populationLimit < 1 || instanceInfo.playerPopulation < instanceInfo.populationLimit) {
               break;
            }
         } else {
            Template overrideTemplate = new Template();
            overrideTemplate.put((Namespace)Namespace.INSTANCE, "name", instanceName);
            overrideTemplate.setName(instanceName);
            instanceOid = InstanceClient.createInstance(instanceTemplateID, overrideTemplate);
            if (instanceOid != null) {
               break;
            }
         }

         ++instanceNum;
      }

      return instanceOid;
   }

   private void updateInstancePerception(OID playerOid, OID prevInstanceOid, OID destInstanceOid, String destInstanceName) {
      if (prevInstanceOid != null) {
         removeStaticPerception(playerOid, prevInstanceOid);
      }

      addStaticPerception(playerOid, destInstanceOid, destInstanceName, ObjectTypes.instance);
   }

   protected void pushInstanceRestorePoint(Player player, BasicWorldNode loc) {
      OID playerOid = player.getOid();
      if (Log.loggingDebug) {
         log.debug("pushInstanceRestorePoint " + playerOid);
      }

      InstanceRestorePoint restorePoint = new InstanceRestorePoint();
      restorePoint.setInstanceOid(loc.getInstanceOid());
      restorePoint.setLoc(loc.getLoc());
      restorePoint.setOrientation(loc.getOrientation());
      InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(loc.getInstanceOid(), 8);
      restorePoint.setInstanceID(instanceInfo.templateID);
      LinkedList<Object> restoreStack = (LinkedList)EnginePlugin.getObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack");
      if (restoreStack == null) {
         restoreStack = new LinkedList();
      }

      restoreStack.add(restorePoint);
      EnginePlugin.setObjectProperty(playerOid, Namespace.OBJECT_MANAGER, "instanceStack", restoreStack);
   }

   protected void sendOceanData(OceanData oceanData, Player player) {
      WorldManagerClient.TargetedExtensionMessage oceanMsg = new ClientParameter.ClientParameterMessage(player.getOid());
      oceanMsg.setProperty("Ocean.DisplayOcean", oceanData.displayOcean.toString());
      if (oceanData.useParams != null) {
         oceanMsg.setProperty("Ocean.UseParams", oceanData.useParams.toString());
      }

      if (oceanData.waveHeight != null) {
         oceanMsg.setProperty("Ocean.WaveHeight", oceanData.waveHeight.toString());
      }

      if (oceanData.seaLevel != null) {
         oceanMsg.setProperty("Ocean.SeaLevel", oceanData.seaLevel.toString());
      }

      if (oceanData.bumpScale != null) {
         oceanMsg.setProperty("Ocean.BumpScale", oceanData.bumpScale.toString());
      }

      if (oceanData.bumpSpeedX != null) {
         oceanMsg.setProperty("Ocean.BumpSpeedX", oceanData.bumpSpeedX.toString());
      }

      if (oceanData.bumpSpeedZ != null) {
         oceanMsg.setProperty("Ocean.BumpSpeedZ", oceanData.bumpSpeedZ.toString());
      }

      if (oceanData.textureScaleX != null) {
         oceanMsg.setProperty("Ocean.TextureScaleX", oceanData.textureScaleX.toString());
      }

      if (oceanData.textureScaleZ != null) {
         oceanMsg.setProperty("Ocean.TextureScaleZ", oceanData.textureScaleZ.toString());
      }

      if (oceanData.deepColor != null) {
         oceanMsg.setProperty("Ocean.DeepColor", oceanData.deepColor.toString());
      }

      if (oceanData.shallowColor != null) {
         oceanMsg.setProperty("Ocean.ShallowColor", oceanData.shallowColor.toString());
      }

      player.getConnection().send(oceanMsg.toBuffer(player.getVersion()));
   }

   protected Player verifyPlayer(String context, Event event, ClientConnection con) {
      Player player = (Player)con.getAssociation();
      if (!player.getOid().equals(event.getObjectOid())) {
         throw new AORuntimeException(context + ": con doesn't match player " + player + " against eventOid " + event.getObjectOid());
      } else {
         return player;
      }
   }

   public void incrementChatCount() {
      ++this.chatSentCount;
   }

   public void incrementPrivateChatCount() {
      ++this.privateChatSentCount;
   }

   public void addAdmin(OID oid) {
      if (Log.loggingDebug) {
         log.debug("ProxyPlugin.addAdmin: adding oid " + oid);
      }

      this.lock.lock();

      try {
         this.adminSet.add(oid);
      } finally {
         this.lock.unlock();
      }

   }

   public Set<OID> getAdmins() {
      this.lock.lock();

      HashSet var1;
      try {
         var1 = new HashSet(this.adminSet);
      } finally {
         this.lock.unlock();
      }

      return var1;
   }

   public boolean isAdmin(OID playerOid) {
      this.lock.lock();

      boolean var2;
      try {
         if (playerOid != null) {
            AccountDatabase aDB = new AccountDatabase(false);
            int status = aDB.getCharacterAccountStatus(playerOid);
            boolean var4 = status == 5;
            return var4;
         }

         var2 = false;
      } finally {
         this.lock.unlock();
      }

      return var2;
   }

   public int GetConnectionLimit() {
      return this.connectionLimit;
   }

   protected Object createMBeanInstance() {
      return new ProxyPlugin.ProxyJMX();
   }

   private String getTemp() {
      return "47bedc488b0106b2219dd2e2ff5524fd";
   }

   protected class ProxyJMX implements ProxyPlugin.ProxyJMXMBean {
      public int getMaxConcurrentUsers() {
         return ProxyPlugin.MaxConcurrentUsers;
      }

      public void setMaxConcurrentUsers(int users) {
         if (users >= 0) {
            ProxyPlugin.MaxConcurrentUsers = users;
         }

      }

      public int getIdleTimeout() {
         return ProxyPlugin.idleTimeout;
      }

      public void setIdleTimeout(int timeout) {
         if (timeout > 0) {
            ProxyPlugin.idleTimeout = timeout;
         }

      }

      public int getSilenceTimeout() {
         return ProxyPlugin.silenceTimeout;
      }

      public void setSilenceTimeout(int timeout) {
         if (timeout > 0) {
            ProxyPlugin.silenceTimeout = timeout;
         }

      }

      public int getCurrentUsers() {
         return ProxyPlugin.this.playerManager.getPlayerCount();
      }

      public int getPeakUsers() {
         return ProxyPlugin.this.playerManager.getPeakPlayerCount();
      }

      public int getLoginCount() {
         return ProxyPlugin.this.playerManager.getLoginCount();
      }

      public int getLogoutCount() {
         return ProxyPlugin.this.playerManager.getLogoutCount();
      }

      public int getClientPort() {
         return ProxyPlugin.this.clientPort;
      }

      public int getMaxMessagesBeforeConnectionReset() {
         return ProxyPlugin.maxMessagesBeforeConnectionReset;
      }

      public void setMaxMessagesBeforeConnectionReset(int count) {
         if (count > 0) {
            ProxyPlugin.maxMessagesBeforeConnectionReset = count;
         }

      }

      public int getMaxByteCountBeforeConnectionReset() {
         return ProxyPlugin.maxByteCountBeforeConnectionReset;
      }

      public void setMaxByteCountBeforeConnectionReset(int bytes) {
         if (bytes > 0) {
            ProxyPlugin.maxByteCountBeforeConnectionReset = bytes;
         }

      }

      public String getCapacityErrorMessage() {
         return ProxyPlugin.this.capacityError;
      }

      public void setCapacityErrorMessage(String errorMessage) {
         if (errorMessage != null) {
            ProxyPlugin.this.capacityError = errorMessage;
         }

      }
   }

   public interface ProxyJMXMBean {
      int getMaxConcurrentUsers();

      void setMaxConcurrentUsers(int var1);

      int getIdleTimeout();

      void setIdleTimeout(int var1);

      int getSilenceTimeout();

      void setSilenceTimeout(int var1);

      int getCurrentUsers();

      int getPeakUsers();

      int getLoginCount();

      int getLogoutCount();

      int getClientPort();

      int getMaxMessagesBeforeConnectionReset();

      void setMaxMessagesBeforeConnectionReset(int var1);

      int getMaxByteCountBeforeConnectionReset();

      void setMaxByteCountBeforeConnectionReset(int var1);

      String getCapacityErrorMessage();

      void setCapacityErrorMessage(String var1);
   }

   static class AsyncRPCCallback implements ResponseCallback {
      Player player;
      String debugPrefix;
      int responders = 0;

      AsyncRPCCallback(Player player, String debugPrefix) {
         this.player = player;
         this.debugPrefix = debugPrefix;
      }

      public synchronized void handleResponse(ResponseMessage response) {
         --this.responders;
         if (Log.loggingDebug) {
            Log.debug(this.debugPrefix + ", fromAgent=" + response.getSenderName() + " playerOid=" + this.player.getOid() + " responders=" + this.responders);
         }

         if (this.responders < 1) {
            this.notify();
         }

      }

      public synchronized void waitForResponses(int expectedResponses) {
         if (Log.loggingDebug) {
            Log.debug(this.debugPrefix + ", playerOid=" + this.player.getOid() + " responders=" + this.responders + " expectedResponses=" + expectedResponses);
         }

         this.responders += expectedResponses;
         if (Log.loggingDebug) {
            Log.debug(this.debugPrefix + ", playerOid=" + this.player.getOid() + " responders=" + this.responders + " expectedResponses=" + expectedResponses + " after");
         }

         while(this.responders > 0) {
            try {
               this.wait();
            } catch (InterruptedException var3) {
               ProxyPlugin.log.error("waitForResponses wait InterruptedException: " + var3.getMessage() + " " + var3.getLocalizedMessage());
            } catch (Exception var4) {
               ProxyPlugin.log.error("waitForResponses wait InterruptedException: " + var4.getMessage() + " " + var4.getLocalizedMessage());
            }
         }

      }
   }

   private static class PlayerHeartbeat implements ProxyExtensionHook {
      private PlayerHeartbeat() {
      }

      public void processExtensionEvent(ExtensionMessageEvent event, Player player, ProxyPlugin proxy) {
         Serializable time = null;
         Map<String, Serializable> props = new HashMap();
         if (event.getPropertyMap().containsKey("time")) {
            time = (Serializable)event.getPropertyMap().get("time");
         }

         props.put("ext_msg_subtype", "ao.heartbeat");
         props.put("time", time);
         WorldManagerClient.TargetedExtensionMessage msg = new WorldManagerClient.TargetedExtensionMessage(WorldManagerClient.MSG_TYPE_EXTENSION, player.getOid(), player.getOid(), false, props);
         Engine.getAgent().sendBroadcast(msg);
      }

      // $FF: synthetic method
      PlayerHeartbeat(Object x0) {
         this();
      }
   }

   private class PlayerTimeout implements Runnable {
      private PlayerTimeout() {
      }

      public void run() {
         while(true) {
            try {
               Log.debug("PlayerTimeout thread running..");
               this.timeoutPlayers();
            } catch (Exception var3) {
               Log.exception("PlayerTimeout", var3);
            }

            try {
               Thread.sleep(10000L);
            } catch (InterruptedException var2) {
            }
         }
      }

      private void timeoutPlayers() {
         List<Player> timedoutPlayers = ProxyPlugin.this.playerManager.getTimedoutPlayers((long)(ProxyPlugin.idleTimeout * 1000), (long)(ProxyPlugin.silenceTimeout * 1000), (long)(ProxyPlugin.silenceLoadingTimeout * 1000));
         Iterator var2 = timedoutPlayers.iterator();

         while(var2.hasNext()) {
            Player player = (Player)var2.next();
            if (!ProxyPlugin.this.isAdmin(player.getOid())) {
               Log.info("ProxyPlugin: IDLE_TIMEOUT remote=" + player.getConnection() + " player=" + player);
               Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "timeout"}).increment();
               player.setStatus(4);
               player.getConnection().close();
            }
         }

      }

      // $FF: synthetic method
      PlayerTimeout(Object x1) {
         this();
      }
   }

   class InstanceEntryReqHook extends ProxyPlugin.BasicProxyHook {
      InstanceEntryReqHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         InstanceClient.InstanceEntryReqMessage entryMessage = (InstanceClient.InstanceEntryReqMessage)msg;
         ProxyPlugin.log.debug("InstanceEntryReqHook ");
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("InstanceEntryReqHook Oid=" + entryMessage.getSubject() + " instOid=" + entryMessage.getMsgInstanceOid() + " WorldNode=" + entryMessage.getWorldNode() + " RestoreNode=" + entryMessage.getRestoreNode() + " flags=" + entryMessage.getFlags() + " player=" + player);
         }

         ProxyPlugin.InstanceEntryState state = (ProxyPlugin.InstanceEntryState)entryMessage.getProcessingState();
         if (state == null) {
            state = new ProxyPlugin.InstanceEntryState();
            entryMessage.setProcessingState(state);
         }

         if (state.step == 1) {
            this.entryStep1(entryMessage, state, player);
         } else if (state.step == 2) {
            this.entryStep2(entryMessage, state, player);
         }

      }

      protected void entryStep1(InstanceClient.InstanceEntryReqMessage entryMessage, ProxyPlugin.InstanceEntryState state, Player player) {
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("entryStep1 " + player);
         }

         BasicWorldNode destination = entryMessage.getWorldNode();
         int entryFlags = entryMessage.getFlags();
         String flagStr = "";
         if ((entryFlags & 1) != 0) {
            flagStr = flagStr + "push,";
         }

         if ((entryFlags & 2) != 0) {
            flagStr = flagStr + "pop,";
         }

         Log.info("ProxyPlugin: INSTANCE_BEGIN player=" + player + " destination=" + destination + " flags=" + flagStr);
         if ((entryFlags & 1) != 0 && (entryFlags & 2) != 0) {
            Log.debug("InstanceEntryReqHook: push and pop flags cannot be combined oid=" + player.getOid());
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else if ((entryFlags & 1) != 0 && destination == null) {
            Log.debug("InstanceEntryReqHook: push without destination oid=" + player.getOid());
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else if ((entryFlags & 2) != 0 && destination != null) {
            Log.debug("InstanceEntryReqHook: pop with destination oid=" + player.getOid());
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else if (player.getStatus() != 2) {
            Log.debug("InstanceEntryReqHook: invalid player status " + player);
            Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
         } else {
            if ((entryFlags & 2) != 0) {
               LinkedList restoreStack = (LinkedList)EnginePlugin.getObjectProperty(player.getOid(), Namespace.OBJECT_MANAGER, "instanceStack");
               if (restoreStack == null || restoreStack.size() == 0) {
                  Log.debug("InstanceEntryReqHook: player has no stack to pop " + player);
                  Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
                  return;
               }

               state.restoreStack = restoreStack;
               InstanceRestorePoint restorePoint = (InstanceRestorePoint)restoreStack.get(restoreStack.size() - 1);
               if (restoreStack.size() == 1) {
                  if (restorePoint.getFallbackFlag()) {
                     Log.warn("InstanceEntryReqHook: popping to fallback restore point " + player);
                  } else {
                     Log.warn("InstanceEntryReqHook: popping last instance restore point " + player);
                  }
               }

               destination = new BasicWorldNode();
               OID instanceOid = restorePoint.getInstanceOid();
               if (restorePoint.getInstanceID() > 0) {
                  instanceOid = ProxyPlugin.this.instanceEntryCallback.selectInstance(player, restorePoint.getInstanceID());
               }

               if (instanceOid != null) {
                  destination.setInstanceOid(instanceOid);
                  destination.setLoc(restorePoint.getLoc());
                  destination.setOrientation(restorePoint.getOrientation());
                  destination.setDir(new AOVector(0.0F, 0.0F, 0.0F));
               }

               entryMessage.setWorldNode(destination);
            }

            if (!ProxyPlugin.this.instanceEntryAllowed(player.getOid(), destination.getInstanceOid(), destination.getLoc())) {
               Log.info("ProxyPlugin: INSTANCE_REJECT player=" + player + " current=" + state.previousLoc + " destination=" + destination);
               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
            } else {
               state.instanceInfo = InstanceClient.getInstanceInfo(destination.getInstanceOid(), -262145);
               if (state.instanceInfo.oid == null) {
                  Log.error("InstanceEntryReqHook: unknown instanceOid=" + destination.getInstanceOid());
                  Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
               } else {
                  Log.debug("POP: got population: " + state.instanceInfo.playerPopulation + " and limit: " + state.instanceInfo.populationLimit);
                  if (state.instanceInfo.populationLimit > 0 && state.instanceInfo.playerPopulation >= state.instanceInfo.populationLimit) {
                     OID instanceOidx = ProxyPlugin.handleFullInstance(state.instanceInfo.templateID, state.instanceInfo);
                     destination.setInstanceOid(instanceOidx);
                     state.instanceInfo = InstanceClient.getInstanceInfo(destination.getInstanceOid(), -262145);
                  }

                  if (Log.loggingDebug) {
                     Log.debug("InstanceEntryReqHook: instance terrain config: " + state.instanceInfo.terrainConfig);
                  }

                  WorldManagerClient.TargetedExtensionMessage instanceBegin = new WorldManagerClient.TargetedExtensionMessage(player.getOid(), player.getOid());
                  instanceBegin.setExtensionType("ao.SCENE_BEGIN");
                  instanceBegin.setProperty("action", "instance");
                  instanceBegin.setProperty("name", state.instanceInfo.name);
                  instanceBegin.setProperty("templateName", state.instanceInfo.templateName);
                  boolean rc = WorldManagerClient.despawn(player.getOid(), instanceBegin, (Message)null);
                  if (!rc) {
                     Log.error("InstanceEntryReqHook: despawn failed " + player);
                     Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
                  } else {
                     state.previousLoc = WorldManagerClient.getWorldNode(player.getOid());
                     Log.info("ProxyPlugin: INSTANCE_STEP1 player=" + player + " current=" + state.previousLoc + " destination=" + destination + " destName=" + state.instanceInfo.name);
                     ArrayList<Namespace> unloadWM = new ArrayList(1);
                     unloadWM.add(WorldManagerClient.NAMESPACE);
                     rc = ObjectManagerClient.unloadSubObject(player.getOid(), unloadWM);
                     if (!rc) {
                        Log.error("InstanceEntryReqHook: unload wm sub-object failed " + player);
                        Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
                     } else {
                        state.step = 2;
                        ProxyPlugin.this.messageQQ.insert(player, entryMessage);
                     }
                  }
               }
            }
         }
      }

      protected void entryStep2(InstanceClient.InstanceEntryReqMessage entryMessage, ProxyPlugin.InstanceEntryState state, Player player) {
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug(" entryStep2 " + player);
         }

         int entryFlags = entryMessage.getFlags();
         ClientConnection con = player.getConnection();
         BasicWorldNode destination = entryMessage.getWorldNode();
         BasicWorldNode previousLoc = state.previousLoc;
         BasicWorldNode restoreLoc = null;
         if ((entryFlags & 1) != 0) {
            restoreLoc = entryMessage.getRestoreNode();
            if (restoreLoc == null) {
               restoreLoc = previousLoc;
            }
         }

         while(true) {
            boolean rc = ObjectManagerClient.fixWorldNode(player.getOid(), destination);
            if (!rc) {
               if (Log.loggingDebug) {
                  Log.debug("InstanceEntryReqHook: fixWorldNode failed " + player + " node=" + destination);
               }

               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
               return;
            }

            InstanceClient.InstanceInfo instanceInfo = InstanceClient.getInstanceInfo(destination.getInstanceOid(), 8);
            EnginePlugin.setObjectProperty(player.getOid(), Namespace.OBJECT_MANAGER, "currentInstanceName", instanceInfo.templateID);
            if (Log.loggingDebug) {
               Log.debug("INSTANCE: storing current instance prop: " + instanceInfo.templateID);
            }

            if (Log.loggingDebug) {
               Log.debug("instanceReq: sending template (scene) name: " + state.instanceInfo.templateName);
            }

            Event worldFileEvent = new WorldFileEvent(state.instanceInfo.templateName, destination.getLoc());
            con.send(worldFileEvent.toBytes());
            player.sceneLoading(true);
            WorldManagerClient.WorldNodeCorrectMessage correctMsg = new WorldManagerClient.WorldNodeCorrectMessage(player.getOid(), destination);
            con.send(correctMsg.toBuffer());
            if ((entryFlags & 1) != 0) {
               ProxyPlugin.this.pushInstanceRestorePoint(player, restoreLoc);
            }

            WorldManagerClient.TargetedExtensionMessage instanceEnd = new WorldManagerClient.TargetedExtensionMessage(player.getOid(), player.getOid());
            instanceEnd.setExtensionType("ao.SCENE_END");
            instanceEnd.setProperty("action", "instance");
            instanceEnd.setProperty("name", state.instanceInfo.name);
            instanceEnd.setProperty("templateName", state.instanceInfo.templateName);
            ArrayList<Namespace> loadWM = new ArrayList(1);
            loadWM.add(WorldManagerClient.NAMESPACE);
            OID oid = ObjectManagerClient.loadSubObject(player.getOid(), loadWM);
            if (oid == null) {
               Log.error("InstanceEntryReqHook: load wm sub-object failed " + player);
               if (previousLoc != null && destination != previousLoc) {
                  Log.error("InstanceEntryReqHook: attempting to restore previous location " + player + " previous=" + previousLoc);
                  destination = previousLoc;
                  entryFlags &= -3;
                  continue;
               }
            }

            Integer result = WorldManagerClient.spawn(player.getOid(), (Message)null, instanceEnd);
            if (result >= 0) {
               WorldManagerClient.updateWorldNode(player.getOid(), destination, true);
               WorldManagerClient.correctWorldNode(player.getOid(), destination);
               ProxyPlugin.this.updateInstancePerception(player.getOid(), previousLoc.getInstanceOid(), destination.getInstanceOid(), instanceInfo.name);
               if (Log.loggingInfo) {
                  Log.info("ProxyPlugin: entryStep2 INSTANCE_END player=" + player + " destination=" + destination);
               }

               if ((entryFlags & 2) != 0) {
                  LinkedList restoreStack = state.restoreStack;
                  InstanceRestorePoint top = (InstanceRestorePoint)restoreStack.get(restoreStack.size() - 1);
                  if (!top.getFallbackFlag()) {
                     restoreStack.remove(restoreStack.size() - 1);
                     EnginePlugin.setObjectProperty(player.getOid(), Namespace.OBJECT_MANAGER, "instanceStack", restoreStack);
                  }
               }

               ProxyPlugin.this.instanceEntryCount++;
               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.TRUE);
               return;
            }

            Log.error("InstanceEntryReqHook: spawn failed " + player);
            if (result != -2 || previousLoc == null || destination == previousLoc) {
               Engine.getAgent().sendBooleanResponse(entryMessage, Boolean.FALSE);
               Log.error("InstanceEntryReqHook: spawn failed " + player + " return");
               return;
            }

            Log.error("InstanceEntryReqHook: attempting to restore previous location " + player + " previous=" + previousLoc);
            destination = previousLoc;
            entryFlags &= -3;
         }
      }
   }

   static class InstanceEntryState {
      int step = 1;
      InstanceClient.InstanceInfo instanceInfo;
      LinkedList restoreStack;
      BasicWorldNode previousLoc;
   }

   private class AccountLoginHook implements Hook {
      private AccountLoginHook() {
      }

      public boolean processMessage(Message msg, int flags) {
         Log.debug("AccountLoginHook hit");
         GenericMessage tMsg = (GenericMessage)msg;
         OID accountId = (OID)tMsg.getProperty("accountId");
         if (Log.loggingDebug) {
            Log.debug("AccountLoginHook accountId=" + accountId + "; map=" + ProxyPlugin.this.clientConnections);
         }

         RDPConnection c = (RDPConnection)ProxyPlugin.this.clientConnections.get(accountId);
         if (c != null) {
            Log.debug("Closing client connection");
            Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "duplicate", "status", String.valueOf(c.getState())}).increment();
            ((ClientConnection)ProxyPlugin.this.clientConnections.get(accountId)).close();
            ProxyPlugin.this.clientConnections.remove(accountId);
         }

         return true;
      }

      // $FF: synthetic method
      AccountLoginHook(Object x1) {
         this();
      }
   }

   private class LogoutPlayerRPCThread implements Runnable {
      private Player player;
      private Message message;

      public LogoutPlayerRPCThread(Message message, Player player) {
         this.player = player;
         this.message = message;
      }

      public void run() {
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.run(): start");
         long tStart = System.nanoTime();

         try {
            Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.run(): try { logoutPlayer(); }");
            this.logoutPlayer();
         } catch (Exception var4) {
            Log.exception("LogoutPlayer", var4);
            Engine.getAgent().sendObjectResponse(this.message, (Object)null);
         }

         Timer.builder("logout_thread").publishPercentiles(new double[]{0.95D}).register(Prometheus.registry()).record(Duration.ofNanos(System.nanoTime() - tStart));
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.run(): done");
      }

      public void logoutPlayer() {
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): start");
         ProxyPlugin.PlayerLoginStatus loginStatus = new ProxyPlugin.PlayerLoginStatus();
         loginStatus.oid = this.player.getOid();
         loginStatus.status = this.player.getStatus();
         loginStatus.name = this.player.getName();
         loginStatus.clientCon = this.player.getConnection().toString();
         loginStatus.proxyPluginName = ProxyPlugin.this.getName();
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): about send chat msg");
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): send");

         try {
            Thread.sleep(20L);
         } catch (InterruptedException var6) {
            Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): sleep error " + var6);
         }

         Prometheus.registry().counter("rdp_connection_closed", new String[]{"reason", "logout"}).increment();
         this.player.getConnection().close();
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): close");
         synchronized(this.player) {
            while(ProxyPlugin.this.isPlayerConnectionValid(this.player)) {
               try {
                  this.player.wait();
               } catch (InterruptedException var5) {
                  Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): wait error " + var5);
               }
            }
         }

         if (Log.loggingDebug) {
            Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): Engine.getAgent().sendObjectResponse() message=" + this.message + ", loginStatus=" + loginStatus);
         }

         Engine.getAgent().sendObjectResponse(this.message, loginStatus);
         Log.debug("[CYC] ProxyPlugin.LogoutPlayerRPCThread.logoutPlayer(): done");
      }
   }

   private class LogoutPlayerHook extends ProxyPlugin.BasicProxyHook {
      private LogoutPlayerHook() {
         super();
      }

      public void processMessage(Message message, int flags, Player player) {
         Prometheus.registry().counter("logout_hook", new String[0]).increment();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("LogoutPlayerHook " + player);
         }

         Engine.getAgent().sendObjectResponse(message, true);
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("LogoutPlayerHook Send " + player);
         }

         if (player.getStatus() != 3 && player.getStatus() != 4) {
            player.setStatus(4);
            ProxyPlugin.this.logoutExecutor.execute(ProxyPlugin.this.new LogoutPlayerRPCThread(message, player));
         }

         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("LogoutPlayerHook End " + player);
         }

      }

      // $FF: synthetic method
      LogoutPlayerHook(Object x1) {
         this();
      }
   }

   private class GetPlayerLoginStatusHook extends ProxyPlugin.BasicProxyHook {
      private GetPlayerLoginStatusHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         if (Log.loggingDebug) {
            Log.debug("GetPlayerLoginStatusHook: player=" + player);
         }

         ProxyPlugin.PlayerLoginStatus loginStatus = new ProxyPlugin.PlayerLoginStatus();
         loginStatus.oid = player.getOid();
         loginStatus.status = player.getStatus();
         loginStatus.name = player.getName();
         loginStatus.clientCon = player.getConnection().toString();
         loginStatus.proxyPluginName = ProxyPlugin.this.getName();
         if (Log.loggingDebug) {
            Log.debug("GetPlayerLoginStatusHook: response=" + loginStatus);
         }

         Engine.getAgent().sendObjectResponse(msg, loginStatus);
      }

      // $FF: synthetic method
      GetPlayerLoginStatusHook(Object x1) {
         this();
      }
   }

   public static class PlayerLoginStatus {
      public OID oid;
      public int status;
      public String name;
      public String clientCon;
      public String proxyPluginName;

      public String toString() {
         return "[PlayerLoginStatus: oid=" + this.oid + ", status=" + this.status + ", name=" + this.name + ", proxyPluginName=" + this.proxyPluginName + "]";
      }
   }

   class GetPluginStatusHook implements Hook {
      public boolean processMessage(Message msg, int flags) {
         LinkedHashMap<String, Serializable> status = new LinkedHashMap();
         status.put("plugin", ProxyPlugin.this.getName());
         status.put("user", ProxyPlugin.this.playerManager.getPlayerCount());
         status.put("login", ProxyPlugin.this.playerManager.getLoginCount());
         status.put("login_sec", ProxyPlugin.this.playerManager.getLoginSeconds());
         status.put("instance_entry", ProxyPlugin.this.instanceEntryCount);
         status.put("chat", ProxyPlugin.this.chatSentCount);
         status.put("private_chat", ProxyPlugin.this.privateChatSentCount);
         Engine.getAgent().sendObjectResponse(msg, status);
         return true;
      }
   }

   class AbilityUpdateHook extends ProxyPlugin.BasicProxyHook {
      AbilityUpdateHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AbilityUpdateMessage pMsg = (AbilityUpdateMessage)msg;
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("AbilityUpdateHook: got AbilityUpdate message: " + msg);
         }

         ClientConnection con = player.getConnection();
         con.send(pMsg.toBuffer());
      }
   }

   class RoadHook extends ProxyPlugin.BasicProxyHook {
      RoadHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.RoadMessage roadMsg = (WorldManagerClient.RoadMessage)msg;
         Set<Road> roads = roadMsg.getRoads();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("RoadHook: got " + roads.size() + " roads");
         }

         OID targetOid = roadMsg.getTarget();
         ClientConnection con = player.getConnection();
         List<AOByteBuffer> bufList = roadMsg.toBuffer();
         Iterator var9 = bufList.iterator();

         while(var9.hasNext()) {
            AOByteBuffer buf = (AOByteBuffer)var9.next();
            con.send(buf);
         }

         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("RoadHook: sent new roads to targetOid " + targetOid);
         }

      }
   }

   class FogHook extends ProxyPlugin.BasicProxyHook {
      FogHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.FogMessage fogMsg = (WorldManagerClient.FogMessage)msg;
         FogRegionConfig fogConfig = fogMsg.getFogConfig();
         OID targetOid = fogMsg.getTarget();
         ClientConnection con = player.getConnection();
         WorldManagerClient.FogMessage fogMessage = new WorldManagerClient.FogMessage((OID)null, fogConfig);
         con.send(fogMessage.toBuffer());
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("FogHook: sending new fog to targetOid " + targetOid + " " + fogConfig);
         }

      }
   }

   class InvUpdateHook extends ProxyPlugin.BasicProxyHook {
      InvUpdateHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         InventoryClient.InvUpdateMessage uMsg = (InventoryClient.InvUpdateMessage)msg;
         if (player.getOid().equals(uMsg.getSubject())) {
            ClientConnection con = player.getConnection();
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("InvUpdateHook: sending update to player " + player.getOid() + " msgOid=" + uMsg.getSubject());
            }

            con.send(uMsg.toBuffer());
         }
      }
   }

   class SoundHook extends ProxyPlugin.BasicProxyHook {
      SoundHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.SoundMessage sMsg = (WorldManagerClient.SoundMessage)msg;
         OID target = sMsg.getTarget();
         if (target == null || target.equals(player.getOid())) {
            ClientConnection con = player.getConnection();
            con.send(sMsg.toBuffer());
         }
      }
   }

   class OrientHook extends ProxyPlugin.BasicProxyHook {
      OrientHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.OrientMessage oMsg = (WorldManagerClient.OrientMessage)msg;
         AOByteBuffer buf = oMsg.toBuffer();
         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class WNodeCorrectHook extends ProxyPlugin.BasicProxyHook {
      WNodeCorrectHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.WorldNodeCorrectMessage wMsg = (WorldManagerClient.WorldNodeCorrectMessage)msg;
         OID oid = wMsg.getSubject();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("WNodeCorrectHook.processMessage: oid=" + oid + ", msg=" + msg);
         }

         AOByteBuffer buf = wMsg.toBuffer();
         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class UpdateMobPathHook extends ProxyPlugin.BasicProxyHook {
      UpdateMobPathHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.MobPathMessage pathMsg = (WorldManagerClient.MobPathMessage)msg;
         OID subjectOid = pathMsg.getSubject();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("UpdateMobPathHook.processMessage: MobPathMessage MSG_TYPE_MOB_PATH subjectOid=" + subjectOid + ", msg=" + msg);
         }

         AOByteBuffer buf = pathMsg.toBuffer();
         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class UpdateWNodeHook extends ProxyPlugin.BasicProxyHook {
      UpdateWNodeHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.UpdateWorldNodeMessage wMsg = (WorldManagerClient.UpdateWorldNodeMessage)msg;
         OID subjectOid = wMsg.getSubject();
         OID playerOid = player.getOid();
         if (Log.loggingDebug) {
            Log.debug("UpdateWNodeHook.processMessage: subjectOid=" + subjectOid + ", playerOid=" + playerOid + " msg=" + msg);
         }

         if (playerOid.equals(subjectOid)) {
            if (Log.loggingDebug) {
               Log.debug("UpdateWNodeHook.processMessage: subjectOid=" + subjectOid + ", ignoring msg since playerOid matches subjectOid");
            }

         } else {
            if (Log.loggingDebug) {
               Log.debug("UpdateWNodeHook.processMessage: subjectOid=" + subjectOid + ", playerOid " + playerOid + " " + wMsg.getMsgId() + " " + wMsg.getSenderName() + " " + wMsg.getMsgType() + " " + wMsg.getWorldNode().getDir());
            }

            player.getConnection().send(wMsg.getEventBuf());
         }
      }
   }

   class SysChatHook implements Hook {
      public boolean processMessage(Message msg, int flags) {
         SysChatMessage sysMsg = (SysChatMessage)msg;
         AOByteBuffer buf = sysMsg.toBuffer();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("syschathook:\t " + sysMsg.getString());
         }

         Collection<Player> players = new ArrayList(ProxyPlugin.this.playerManager.getPlayerCount());
         ProxyPlugin.this.playerManager.getPlayers(players);
         Iterator var6 = players.iterator();

         while(var6.hasNext()) {
            Player pp = (Player)var6.next();
            pp.getConnection().send(buf);
         }

         return true;
      }
   }

   class DamageHook extends ProxyPlugin.BasicProxyHook {
      DamageHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         DamageMessage dmgMsg = (DamageMessage)msg;
         OID attackerOid = dmgMsg.getAttackerOid();
         OID targetOid = dmgMsg.getTargetOid();
         AOByteBuffer buf = dmgMsg.toBuffer();
         ClientConnection con = player.getConnection();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("DamageHook: attackerOid= " + attackerOid + ", attacks targetOid=" + targetOid + " for " + dmgMsg.getDmg() + " damage");
         }

         con.send(buf);
      }
   }

   class ComHook extends ProxyPlugin.BasicProxyHook {
      ComHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AOByteBuffer buf = null;
         OID oid;
         if (msg instanceof ComMessage) {
            ComMessage comMsgx = (ComMessage)msg;
            oid = comMsgx.getSubject();
            if (Log.loggingDebug) {
               Log.debug("ComHook.processMessage: ComMessage player:" + player + " plyOid:" + player.getOid() + " getSubject:" + oid + " comMsg:" + comMsgx);
            }

            if (ProxyPlugin.this.isOnBlockList2(player.getOid(), oid)) {
               if (Log.loggingDebug) {
                  Log.debug("ComHook.processMessage: Ignoring chat from player " + oid + " to player " + player.getOid() + " because originator is in the player's ignored list");
               }

               return;
            }

            buf = comMsgx.toBuffer();
            Log.info("ProxyPlugin: CHAT_RECV player=" + player + " from=" + comMsgx.getSubject() + " private=false msg=[" + comMsgx.getString() + "]");
         } else {
            if (!(msg instanceof TargetedComMessage)) {
               if (Log.loggingDebug) {
                  Log.debug("ComHook.processMessage: else player:" + player + " plyOid:" + player.getOid() + " msg " + msg);
               }

               return;
            }

            TargetedComMessage comMsg = (TargetedComMessage)msg;
            oid = comMsg.getSubject();
            if (Log.loggingDebug) {
               Log.debug("ComHook.processMessage: TargetedComMessage player:" + player + " plyOid:" + player.getOid() + " getSubject:" + oid + " comMsg:" + comMsg);
            }

            if (ProxyPlugin.this.isOnBlockList2(player.getOid(), oid)) {
               if (Log.loggingDebug) {
                  Log.debug("ComHook.processMessage: Ignoring chat from player " + oid + " to player " + player.getOid() + " because originator is in the player's ignored list");
               }

               return;
            }

            buf = comMsg.toBuffer();
            Log.info("ProxyPlugin: CHAT_RECV player=" + player + " from=" + comMsg.getSubject() + " private=true msg=[" + comMsg.getString() + "]");
         }

         ClientConnection con = player.getConnection();
         con.send(buf);
      }
   }

   class BlockListHook extends ProxyPlugin.BasicProxyHook {
      BlockListHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         BlockListMessage dmgMsg = (BlockListMessage)msg;
         player.setIgnoredOids(dmgMsg.getBlockList());
      }
   }

   class PlayerPathReqHook extends ProxyPlugin.BasicProxyHook {
      PlayerPathReqHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         OID playerOid = player.getOid();
         BasicWorldNode wnode = WorldManagerClient.getWorldNode(playerOid);
         WorldManagerClient.ExtensionMessage extMsg = (WorldManagerClient.ExtensionMessage)msg;
         WorldManagerClient.PlayerPathWMReqMessage reqMsg = new WorldManagerClient.PlayerPathWMReqMessage(playerOid, wnode.getInstanceOid(), (String)extMsg.getProperty("room_id"), (AOVector)extMsg.getProperty("start"), (Float)extMsg.getProperty("speed"), (Quaternion)extMsg.getProperty("start_orient"), (AOVector)extMsg.getProperty("dest"), (Quaternion)extMsg.getProperty("dest_orient"), (List)extMsg.getProperty("boundary"), (List)extMsg.getProperty("obstacles"), (Float)extMsg.getProperty("avatar_width"));
         Engine.getAgent().sendBroadcast(reqMsg);
      }
   }

   class PlayerIgnoreListReqHook extends ProxyPlugin.BasicProxyHook {
      PlayerIgnoreListReqHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
      }
   }

   class GetMatchingPlayersHook extends ProxyPlugin.BasicProxyHook {
      GetMatchingPlayersHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = (WorldManagerClient.TargetedExtensionMessage)msg;
         String playerName = (String)extMsg.getProperty("player_name");
         Boolean exactMatch = (Boolean)extMsg.getProperty("exact_match");
         boolean match = exactMatch == null ? true : exactMatch;
         List<Object> matchLists = Engine.getDatabase().getOidsAndNamesMatchingName(playerName, match);
         WorldManagerClient.TargetedExtensionMessage response = new WorldManagerClient.TargetedExtensionMessage("player_ignore_list", player.getOid());
         response.setSubject(player.getOid());
         List<OID> oids = (List)matchLists.get(0);
         List<String> names = (List)matchLists.get(1);
         response.setProperty("ignored_oids", (Serializable)oids);
         response.setProperty("ignored_player_names", (Serializable)names);
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("ProxyPlugin.GetMatchingPlayersHook: For player " + player.getOid() + ", found " + (oids == null ? 0 : oids.size()) + " players: " + Database.makeOidCollectionString(oids) + " " + (match ? "exactly matching" : "starting with") + " name '" + playerName + "':" + Database.makeNameCollectionString(names));
         }

         player.getConnection().send(response.toBuffer(player.getVersion()));
      }
   }

   class UpdatePlayerIgnoreListHook extends ProxyPlugin.BasicProxyHook {
      UpdatePlayerIgnoreListHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = (WorldManagerClient.TargetedExtensionMessage)msg;
         LinkedList<OID> nowIgnored = (LinkedList)extMsg.getProperty("now_ignored");
         LinkedList<OID> noLongerIgnored = (LinkedList)extMsg.getProperty("no_longer_ignored");
         ProxyPlugin.this.updateIgnoredOids(player, nowIgnored, noLongerIgnored);
      }
   }

   class VoiceParmsHook extends ProxyPlugin.BasicProxyHook {
      VoiceParmsHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = new WorldManagerClient.TargetedExtensionMessage("voice_parms_response", player.getOid());
         extMsg.setProperty("host", ProxyPlugin.voiceServerHost);
         extMsg.setProperty("port", ProxyPlugin.voiceServerPort);
         SecureTokenSpec tokenSpec = new SecureTokenSpec((byte)2, Engine.getAgent().getName(), System.currentTimeMillis() + 30000L);
         tokenSpec.setProperty("player_oid", player.getOid());
         byte[] authToken = SecureTokenManager.getInstance().generateToken(tokenSpec);
         extMsg.setProperty("auth_token", Base64.encodeBytes(authToken));
         ClientConnection con = player.getConnection();
         AOByteBuffer buf = extMsg.toBuffer(player.getVersion());
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("VoiceParmsHook: sent voice_parm_response ext msg for player " + player.getOid());
            }
         }

      }
   }

   private class RemoveStaticPerceptionHook extends ProxyPlugin.BasicProxyHook {
      private RemoveStaticPerceptionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         TargetMessage message = (TargetMessage)msg;
         boolean proxyPerceptionLoss = ProxyPlugin.this.playerManager.removeStaticPerception(player, message.getSubject());
         Log.debug("ProxyPlugin.RemoveStaticPerceptionHook(): proxyPerceptionLoss = " + proxyPerceptionLoss + ", playerOid=" + player.getOid() + ", oid=" + message.getSubject());
         if (proxyPerceptionLoss) {
            FilterUpdate proxyPerceptionUpdate = new FilterUpdate(1);
            proxyPerceptionUpdate.removeFieldValue(2, message.getSubject());
            Engine.getAgent().applyFilterUpdate(ProxyPlugin.this.perceptionSubId, proxyPerceptionUpdate, 0);
         }

         NotifyFreeObjectEvent freeEvent = new NotifyFreeObjectEvent(player.getOid(), message.getSubject());
         player.getConnection().send(freeEvent.toBytes());
      }

      // $FF: synthetic method
      RemoveStaticPerceptionHook(Object x1) {
         this();
      }
   }

   private class AddStaticPerceptionHook extends ProxyPlugin.BasicProxyHook {
      private AddStaticPerceptionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         ProxyPlugin.AddStaticPerceptionMessage message = (ProxyPlugin.AddStaticPerceptionMessage)msg;
         if (Log.loggingDebug) {
            Log.debug("AddStaticPerceptionHook: player=" + player.getOid() + ", subject=" + message.getSubject());
         }

         if (!message.hasObjectInfo()) {
            ObjectManagerClient.ObjectStatus objectStatus = ObjectManagerClient.getObjectStatus(message.getSubject());
            if (objectStatus == null || objectStatus.namespaces == null) {
               Log.error("AddStaticPerceptionHook: ignoring unknown subject=" + message.getSubject() + " added to " + player);
               return;
            }

            message.setName(objectStatus.name);
            message.setType(objectStatus.type);
         }

         boolean perceptionGain = ProxyPlugin.this.playerManager.addStaticPerception(player, message.getSubject());
         if (perceptionGain) {
            FilterUpdate perceptionUpdate = new FilterUpdate(1);
            perceptionUpdate.addFieldValue(2, message.getSubject());
            Engine.getAgent().applyFilterUpdate(ProxyPlugin.this.perceptionSubId, perceptionUpdate, 0);
            WorldManagerClient.ObjectInfo info = new WorldManagerClient.ObjectInfo();
            info.oid = message.getSubject();
            info.name = message.getName();
            info.objType = message.getType();
            info.dir = new AOVector(0.0F, 0.0F, 0.0F);
            Log.debug("INFO: add static perception hook");
            player.getConnection().send(info.toBuffer(player.getOid()));
            WorldManagerClient.updateObject(player.getOid(), message.getSubject());
         }

      }

      // $FF: synthetic method
      AddStaticPerceptionHook(Object x1) {
         this();
      }
   }

   public static class AddStaticPerceptionMessage extends TargetMessage {
      private String name;
      private ObjectType type;
      private boolean objectInfoProvided;

      public AddStaticPerceptionMessage() {
      }

      public AddStaticPerceptionMessage(MessageType type) {
         super(type);
      }

      public String getName() {
         return this.name;
      }

      public void setName(String name) {
         this.name = name;
      }

      public ObjectType getType() {
         return this.type;
      }

      public void setType(ObjectType type) {
         this.type = type;
      }

      public boolean hasObjectInfo() {
         return this.objectInfoProvided;
      }

      public void setHasObjectInfo(boolean flag) {
         this.objectInfoProvided = flag;
      }
   }

   class PerceptionHook extends ProxyPlugin.BasicProxyHook {
      PerceptionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         PerceptionMessage perceptionMessage = (PerceptionMessage)msg;
         List<PerceptionMessage.ObjectNote> gain = perceptionMessage.getGainObjects();
         List<PerceptionMessage.ObjectNote> lost = perceptionMessage.getLostObjects();
         List<PerceptionMessage.ObjectNote> sGain = perceptionMessage.getStealthedGainObjects();
         List<PerceptionMessage.ObjectNote> sLost = perceptionMessage.getStealthedLostObjects();
         List<OID> stealthed = perceptionMessage.getSteathedObjects();
         if (Log.loggingDebug) {
            Log.debug("PerceptionHook.processMessage: start " + (gain == null ? 0 : gain.size()) + " gain and " + (lost == null ? 0 : lost.size()) + " lost and " + (sGain == null ? 0 : sGain.size()) + " sGain and" + (sLost == null ? 0 : sLost.size()) + " sLost ");
         }

         if (player.getOid().equals(World.DEBUG_OID)) {
            Log.info("PerceptionHook: oid=" + World.DEBUG_OID + " start " + (gain == null ? 0 : gain.size()) + " gain and " + (lost == null ? 0 : lost.size()) + " lost and " + (sGain == null ? 0 : sGain.size()) + " sGain and" + (sLost == null ? 0 : sLost.size()) + " sLost ");
         }

         ClientConnection con = player.getConnection();
         List<OID> newSubjects = new LinkedList();
         List<OID> deleteSubjects = new LinkedList();
         if (lost != null) {
            ProxyPlugin.this.playerManager.removeWorldPerception(player, lost, deleteSubjects);
         }

         if (gain != null) {
            ProxyPlugin.this.playerManager.addWorldPerception(player, gain, newSubjects);
         }

         Iterator var14;
         if (deleteSubjects.size() > 0 || newSubjects.size() > 0) {
            FilterUpdate perceptionUpdate = new FilterUpdate(deleteSubjects.size() + newSubjects.size());
            var14 = newSubjects.iterator();

            while(var14.hasNext()) {
               OID oid = (OID)var14.next();
               perceptionUpdate.addFieldValue(2, oid);
            }

            if (player.getOid().equals(World.DEBUG_OID) && Log.loggingInfo) {
               Log.info("subject changes: " + newSubjects.size() + " gained " + deleteSubjects.size() + " lost");
            }

            Engine.getAgent().applyFilterUpdate(ProxyPlugin.this.perceptionSubId, perceptionUpdate, 0, (Message)perceptionMessage);
         }

         boolean loadingState = false;
         if (player.supportsLoadingState() && (player.getLoadingState() == 0 || gain != null && gain.size() > 20 || lost != null && lost.size() > 20)) {
            con.send((new LoadingStateEvent(true)).toBytes());
            loadingState = true;
         }

         PerceptionMessage.ObjectNote objectNote;
         if (lost != null) {
            var14 = lost.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();
               ProxyPlugin.this.specialCaseFreeProcessing(objectNote, player);
            }
         }

         if (gain != null) {
            var14 = gain.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();

               try {
                  if (stealthed != null && stealthed.contains(objectNote.getSubject())) {
                     ProxyPlugin.this.specialCaseFreeProcessing(objectNote, player);
                  } else {
                     ProxyPlugin.this.specialCaseNewProcessing(objectNote, player);
                  }

                  WorldManagerClient.updateObject(player.getOid(), objectNote.getSubject());
               } catch (Exception var19) {
                  Log.exception("specialCaseNewProcessing: player=" + player + " oid=" + objectNote.getSubject(), var19);
               }
            }
         }

         if (sGain != null) {
            var14 = sGain.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();

               try {
                  ProxyPlugin.this.specialCaseNewProcessing(objectNote, player);
                  WorldManagerClient.updateObject(player.getOid(), objectNote.getSubject());
               } catch (Exception var18) {
                  Log.exception("specialCaseNewProcessing: player=" + player + " stealthed oid=" + objectNote.getSubject(), var18);
               }
            }
         }

         if (sLost != null) {
            var14 = sLost.iterator();

            while(var14.hasNext()) {
               objectNote = (PerceptionMessage.ObjectNote)var14.next();

               try {
                  ProxyPlugin.this.specialCaseFreeProcessing(objectNote, player);
                  WorldManagerClient.updateObject(player.getOid(), objectNote.getSubject());
               } catch (Exception var17) {
                  Log.exception("specialCaseFreeProcessing: player=" + player + " stealthed oid=" + objectNote.getSubject(), var17);
               }
            }
         }

         if (loadingState) {
            player.setLoadingState(1);
            con.send((new LoadingStateEvent(false)).toBytes());
         }

      }
   }

   class TargetedPropertyHook extends ProxyPlugin.BasicProxyHook {
      TargetedPropertyHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedPropertyMessage propMsg = (WorldManagerClient.TargetedPropertyMessage)msg;
         OID targetOid = propMsg.getTarget();
         OID subjectOid = propMsg.getSubject();
         if (Log.loggingDebug) {
            Set<String> keySet = propMsg.keySet();
            Iterator var8 = keySet.iterator();

            while(var8.hasNext()) {
               String key = (String)var8.next();
               ProxyPlugin.log.debug("handleTargetedPropertyMsg: playerOid=" + player.getOid() + ", targetOid=" + targetOid + ", oid = " + subjectOid + ", got key " + key + ", value=" + propMsg.getProperty(key));
            }
         }

         ClientConnection con = player.getConnection();
         Set<String> filter = ProxyPlugin.this.playerSpecificProps.size() > 0 && !player.getOid().equals(subjectOid) ? ProxyPlugin.this.cachedPlayerSpecificFilterProps : ProxyPlugin.this.filteredProps;
         AOByteBuffer buf = propMsg.toBuffer(player.getVersion(), filter);
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("sent targeted prop msg for targetOid " + targetOid + ", subjectOid=" + subjectOid);
            }
         } else if (Log.loggingDebug) {
            ProxyPlugin.log.debug("filtered out targeted prop msg for targetOid " + targetOid + ", subjectOid=" + subjectOid + " because all props were filtered");
         }

      }
   }

   class PropertyHook extends ProxyPlugin.BasicProxyHook {
      PropertyHook() {
         super();
      }

      public boolean processMessage(Message msg, int flags) {
         return true;
      }

      public void processMessage(Message msg, int flags, Player player) {
         PropertyMessage propMsg = (PropertyMessage)msg;
         OID subjectOid = propMsg.getSubject();
         Iterator buf;
         if (Log.loggingDebug) {
            Set<String> keySet = propMsg.keySet();
            buf = keySet.iterator();

            while(buf.hasNext()) {
               String key = (String)buf.next();
               ProxyPlugin.log.debug("handlePropertyMsg: player=" + player + ", oid=" + subjectOid + ", got key " + key + ", value=" + propMsg.getProperty(key));
            }
         }

         ClientConnection con = player.getConnection();
         buf = null;
         AOByteBuffer bufx;
         if (ProxyPlugin.this.playerSpecificProps.size() > 0 && subjectOid != player.getOid()) {
            bufx = propMsg.toBuffer(player.getVersion(), ProxyPlugin.this.cachedPlayerSpecificFilterProps);
         } else {
            bufx = propMsg.toBuffer(player.getVersion(), ProxyPlugin.this.filteredProps);
         }

         if (bufx != null) {
            con.send(bufx);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("sent prop msg for player " + player + ", subjectId=" + subjectOid);
            }
         } else if (Log.loggingDebug) {
            ProxyPlugin.log.debug("filtered out prop msg for player " + player + ", subjectId=" + subjectOid + " because all props were filtered");
         }

      }
   }

   class P2PExtensionHook extends ProxyPlugin.BasicProxyHook {
      P2PExtensionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.TargetedExtensionMessage extMsg = (WorldManagerClient.TargetedExtensionMessage)msg;
         OID objOid = extMsg.getSubject();
         Set<String> keySet = extMsg.keySet();
         Iterator var7 = keySet.iterator();

         while(var7.hasNext()) {
            String key = (String)var7.next();
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("P2PExtensionHook: playerOid=" + player.getOid() + ", oid = " + objOid + ", got key " + key + ", value=" + extMsg.getProperty(key));
            }
         }

         ClientConnection con = player.getConnection();
         AOByteBuffer buf = extMsg.toBuffer(player.getVersion());
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("P2PExtensionHook: sent ext msg for notifyOid " + objOid);
            }
         }

      }
   }

   class ExtensionHook extends ProxyPlugin.BasicProxyHook {
      ExtensionHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AOByteBuffer buf = null;
         ClientConnection con = player.getConnection();
         OID subject = null;
         OID target = null;
         String subType = null;
         Set keySet;
         Iterator var11;
         String key;
         if (msg instanceof WorldManagerClient.TargetedExtensionMessage) {
            WorldManagerClient.TargetedExtensionMessage extMsgx = (WorldManagerClient.TargetedExtensionMessage)msg;
            subject = extMsgx.getSubject();
            target = extMsgx.getTarget();
            subType = extMsgx.getExtensionType();
            if (Log.loggingDebug) {
               keySet = extMsgx.keySet();
               var11 = keySet.iterator();

               while(var11.hasNext()) {
                  key = (String)var11.next();
                  ProxyPlugin.log.debug("ExtensionHook: playerOid=" + player.getOid() + ", oid=" + subject + ", key " + key + ", value=" + extMsgx.getProperty(key));
               }
            }

            buf = extMsgx.toBuffer(player.getVersion());
         } else {
            WorldManagerClient.ExtensionMessage extMsg = (WorldManagerClient.ExtensionMessage)msg;
            subject = extMsg.getSubject();
            subType = extMsg.getExtensionType();
            if (Log.loggingDebug) {
               keySet = extMsg.keySet();
               var11 = keySet.iterator();

               while(var11.hasNext()) {
                  key = (String)var11.next();
                  ProxyPlugin.log.debug("ExtensionHook: playerOid=" + player.getOid() + ", oid=" + subject + ", key " + key + ", value=" + extMsg.getProperty(key));
               }
            }

            buf = extMsg.toBuffer(player.getVersion());
         }

         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("ExtensionHook: sent subType " + subType + " for playerOid=" + player.getOid() + ", target=" + target + ", subject=" + subject);
            }
         }

      }
   }

   class AbilityStatusHook extends ProxyPlugin.BasicProxyHook {
      AbilityStatusHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         AOByteBuffer buf = null;
         ClientConnection con = player.getConnection();
         AbilityStatusMessage asMsg = (AbilityStatusMessage)msg;
         buf = asMsg.toBuffer();
         if (buf != null) {
            con.send(buf);
         }

      }
   }

   class InvokeEffectHook extends ProxyPlugin.BasicProxyHook {
      InvokeEffectHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         InvokeEffectMessage effectMsg = (InvokeEffectMessage)msg;
         OID objOid = effectMsg.getSubject();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("InvokeEffectHook: got msg=" + effectMsg.toString());
         }

         ClientConnection con = player.getConnection();
         AOByteBuffer buf = effectMsg.toBuffer(player.getVersion());
         if (buf != null) {
            con.send(buf);
            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("InvokeEffectHook: sent ext msg for notifyOid " + objOid);
            }
         }

      }
   }

   class AnimationHook extends ProxyPlugin.BasicProxyHook {
      AnimationHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.AnimationMessage animMsg = (WorldManagerClient.AnimationMessage)msg;
         OID playerOid = player.getOid();
         ClientConnection con = player.getConnection();
         OID objOid = animMsg.getSubject();
         List<AnimationCommand> animList = animMsg.getAnimationList();
         NotifyPlayAnimationEvent animEvent = new NotifyPlayAnimationEvent(objOid);
         animEvent.setAnimList(animList);
         con.send(animEvent.toBytes());
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("AnimationHook: send anim msg for playerOid " + playerOid + ", objId=" + objOid + ", animEvent=" + animEvent);
         }

      }
   }

   class DetachHook extends ProxyPlugin.BasicProxyHook {
      DetachHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.DetachMessage dMsg = (WorldManagerClient.DetachMessage)msg;
         OID dcObjOid = dMsg.getSubject();
         OID objBeingDetached = dMsg.getObjBeingDetached();
         String socket = dMsg.getSocketName();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("DetachHook: dcObjOid=" + dcObjOid + ", objBeingDetached=" + objBeingDetached + ", socket=" + socket);
         }

         ClientConnection con = player.getConnection();
         DetachEvent detachEvent = new DetachEvent(dcObjOid, objBeingDetached, socket);
         con.send(detachEvent.toBytes());
      }
   }

   class SetAmbientHook extends ProxyPlugin.BasicProxyHook {
      SetAmbientHook() {
         super();
      }

      public void processMessage(Message m, int flags, Player player) {
         WorldManagerClient.SetAmbientLightMessage msg = (WorldManagerClient.SetAmbientLightMessage)m;
         Color ambientLight = msg.getColor();
         OID playerOid = msg.getTarget();
         if (!playerOid.equals(player.getOid())) {
            Log.error("Message target and perceiver mismatch");
         }

         ClientConnection con = player.getConnection();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("SetAmbientHook: targetOid=" + playerOid + ", ambient=" + ambientLight);
         }

         Event ambientLightEvent = new AmbientLightEvent(ambientLight);
         con.send(ambientLightEvent.toBytes());
      }
   }

   class FreeObjectHook extends ProxyPlugin.BasicProxyHook {
      FreeObjectHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.FreeObjectMessage message = (WorldManagerClient.FreeObjectMessage)msg;
         if (Log.loggingDebug) {
            Log.debug("FreeObjectHook: " + msg + " " + message);
         }

         player.getConnection().send(message.toBuffer());
      }
   }

   class NewDirLightHook extends ProxyPlugin.BasicProxyHook {
      NewDirLightHook() {
         super();
      }

      public void processMessage(Message m, int flags, Player player) {
         WorldManagerClient.NewDirLightMessage msg = (WorldManagerClient.NewDirLightMessage)m;
         OID playerOid = msg.getTarget();
         OID lightOid = msg.getSubject();
         LightData lightData = msg.getLightData();
         if (!playerOid.equals(player.getOid())) {
            Log.error("Message target and perceiver mismatch");
         }

         ClientConnection con = player.getConnection();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("NewDirLightHook: notifyOid=" + playerOid + ", lightOid=" + lightOid + ", light=" + lightData);
         }

         NewLightEvent lightEvent = new NewLightEvent(playerOid, lightOid, lightData);
         con.send(lightEvent.toBytes());
      }
   }

   class DisplayContextHook extends ProxyPlugin.BasicProxyHook {
      DisplayContextHook() {
         super();
      }

      public void processMessage(Message msg, int flags, Player player) {
         WorldManagerClient.DisplayContextMessage dcMsg = (WorldManagerClient.DisplayContextMessage)msg;
         OID dcObjOid = dcMsg.getSubject();
         DisplayContext dc = dcMsg.getDisplayContext();
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("handleDC: oid=" + dcObjOid + " dc=" + dc);
         }

         ClientConnection con = player.getConnection();
         if (dc != null) {
            ModelInfoEvent eventx = new ModelInfoEvent(dcObjOid);
            eventx.setDisplayContext(dc);
            eventx.setForceInstantLoad(dcMsg.getForceInstantLoad());
            con.send(eventx.toBytes());
         }

         Map<String, DisplayContext> childMap = dc.getChildDCMap();
         if (childMap != null && !childMap.isEmpty()) {
            Iterator var9 = childMap.keySet().iterator();

            while(var9.hasNext()) {
               String slot = (String)var9.next();
               DisplayContext attachDC = (DisplayContext)childMap.get(slot);
               if (attachDC == null) {
                  throw new AORuntimeException("attach DC is null for obj: " + dcObjOid);
               }

               OID attacheeOID = attachDC.getObjRef();
               if (attacheeOID == null) {
                  throw new AORuntimeException("attachee oid is null for obj: " + dcObjOid);
               }

               if (Log.loggingDebug) {
                  ProxyPlugin.log.debug("DisplayContextHook: sending attach message to " + player.getOid() + " attaching to obj " + dcObjOid + ", object being attached=" + attacheeOID + " to slot " + slot + ", attachmentDC=" + attachDC);
               }

               AttachEvent event = new AttachEvent(dcObjOid, attacheeOID, slot, attachDC);
               con.send(event.toBytes());
            }

            ProxyPlugin.log.debug("DisplayContextHook: done with processing attachments");
         }

      }
   }

   abstract class BasicProxyHook implements ProxyHook {
      public boolean processMessage(Message msg, int flags) {
         return true;
      }

      public abstract void processMessage(Message var1, int var2, Player var3);
   }

   class ConnectionResetMessage extends Message {
      ClientConnection con;
      Player player;
      public static final long serialVersionUID = 1L;

      ConnectionResetMessage(ClientConnection con, Player player) {
         this.con = con;
         this.player = player;
      }

      public Player getPlayer() {
         return this.player;
      }

      public ClientConnection getConnection() {
         return this.con;
      }
   }

   private static class DefaultInstanceEntryCallback implements InstanceEntryCallback {
      private DefaultInstanceEntryCallback() {
      }

      public boolean instanceEntryAllowed(OID playerOid, OID instanceOid, Point location) {
         return true;
      }

      public OID selectInstance(Player player, int instanceID) {
         return InstanceClient.getInstanceOid(instanceID, player.getOid(), (OID)null, -1, false);
      }

      public OID selectInstance(Player player, int instanceID, OID playerOid) {
         return InstanceClient.getInstanceOid(instanceID, player.getOid(), playerOid, -1, false);
      }

      public OID selectInstance(Player player, int instanceID, OID playerOid, int guildId) {
         if (Log.loggingDebug) {
            ProxyPlugin.log.debug("selectInstance player=" + player + " instanceID=" + instanceID + " OID=" + player.getOid() + " playerOid=" + playerOid + " guildId=" + guildId);
         }

         return InstanceClient.getInstanceOid(instanceID, player.getOid(), playerOid, guildId, false);
      }

      // $FF: synthetic method
      DefaultInstanceEntryCallback(Object x0) {
         this();
      }
   }

   private static class DefaultProxyLoginCallback implements ProxyLoginCallback {
      private DefaultProxyLoginCallback() {
      }

      public boolean duplicateLogin(ProxyPlugin.PlayerLoginStatus existingLogin, ClientConnection con) {
         return existingLogin != null;
      }

      public String preLoad(Player player, ClientConnection con) {
         return null;
      }

      public String postLoad(Player player, ClientConnection con) {
         return null;
      }

      public void postSpawn(Player player, ClientConnection con) {
      }

      // $FF: synthetic method
      DefaultProxyLoginCallback(Object x0) {
         this();
      }
   }

   public class EventCallback implements SQCallback<Player, Event> {
      public void doWork(Event event, Player player) {
         if (event == null) {
            Log.dumpStack("EventCallback.doWork: event object is null, for key " + player);
         } else {
            try {
               ClientConnection con = event.getConnection();
               long startTime = System.currentTimeMillis();
               long inQueue = startTime - event.getEnqueueTime();
               Timer.builder("event_queue_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofMillis(inQueue));
               if (Log.loggingInfo) {
                  Log.info("ProxyPlugin: EventCallback doWork  value" + event + " key=" + player + " in-queue=" + inQueue + " ms");
               }

               if (event instanceof AuthorizedLoginEvent) {
                  int timeout = Integer.parseInt(Engine.properties.getProperty("atavism.proxy_login_event_timeout_seconds", "10"));
                  if (inQueue > (long)(timeout * 1000)) {
                     Prometheus.registry().counter("skipped_login_events", new String[0]).increment();
                     return;
                  }

                  AuthorizedLoginEvent loginEvent = (AuthorizedLoginEvent)event;
                  OID playerOid = loginEvent.getOid();
                  Log.info("ProxyPlugin: LOGIN_BEGIN remote=" + con + " playerOid=" + playerOid + " in-queue=" + inQueue + " ms");
                  boolean loginOK = ProxyPlugin.this.processLogin(con, loginEvent);
                  Player newPlayer = ProxyPlugin.this.playerManager.getPlayer(playerOid);
                  String playerName = null;
                  if (newPlayer != null) {
                     playerName = newPlayer.getName();
                  }

                  if (Log.loggingInfo) {
                     Log.info("ProxyPlugin: LOGIN_END remote=" + con + (loginOK ? " SUCCESS " : " FAILURE ") + " playerOid=" + playerOid + " name=" + playerName + " in-queue=" + inQueue + " ms processing=" + (System.currentTimeMillis() - startTime) + " ms nPlayers=" + ProxyPlugin.this.playerManager.getPlayerCount());
                  }

                  Timer.builder("event_process_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofMillis(System.currentTimeMillis() - startTime));
                  return;
               }

               if (Log.loggingDebug) {
                  Log.debug("ClientEvent: player=" + player + ", in-queue=" + inQueue + " ms: " + event.getName());
               }

               if (Log.loggingInfo && inQueue > 2000L) {
                  Log.info("LONG IN-QUEUE: " + inQueue + " ms: player=" + player + " " + event.getName());
               }

               Lock objLock = ProxyPlugin.this.getObjectLockManager().getLock(player.getOid());
               objLock.lock();

               try {
                  if (Log.loggingDebug) {
                     Log.debug("ClientEvent: event detail: " + event);
                  }

                  if (event instanceof ComEvent) {
                     ProxyPlugin.this.processCom(con, (ComEvent)event);
                  } else if (event instanceof DirLocOrientEvent) {
                     ProxyPlugin.this.processDirLocOrient(con, (DirLocOrientEvent)event);
                  } else if (event instanceof CommandEvent) {
                     ProxyPlugin.this.processCommand(con, (CommandEvent)event);
                  } else if (event instanceof AutoAttackEvent) {
                     ProxyPlugin.this.processAutoAttack(con, (AutoAttackEvent)event);
                  } else if (event instanceof ExtensionMessageEvent) {
                     ProxyPlugin.this.processExtensionMessageEvent(con, (ExtensionMessageEvent)event);
                  } else if (event instanceof AbilityStatusEvent) {
                     ProxyPlugin.this.processAbilityStatusEvent(con, (AbilityStatusEvent)event);
                  } else if (event instanceof RequestQuestInfo) {
                     ProxyPlugin.this.processRequestQuestInfo(con, (RequestQuestInfo)event);
                  } else if (event instanceof QuestResponse) {
                     ProxyPlugin.this.processQuestResponse(con, (QuestResponse)event);
                  } else if (event instanceof ConcludeQuest) {
                     ProxyPlugin.this.processReqConcludeQuest(con, (ConcludeQuest)event);
                  } else if (event instanceof ActivateItemEvent) {
                     ProxyPlugin.this.processActivateItem(con, (ActivateItemEvent)event);
                  } else if (event instanceof LogoutEvent) {
                     ProxyPlugin.this.processLogout(con, (LogoutEvent)event);
                  } else if (event instanceof SceneLoadedEvent) {
                     ProxyPlugin.this.processSceneLoaded(con, (SceneLoadedEvent)event);
                  } else {
                     if (!(event instanceof PlayerHaEvent)) {
                        throw new RuntimeException("Unknown event: " + event);
                     }

                     ProxyPlugin.this.processPlayerHa(con, (PlayerHaEvent)event);
                  }

                  long elapsed = System.currentTimeMillis() - startTime;
                  if (Log.loggingDebug) {
                     Log.debug("ClientEvent: processed event " + event + ", player=" + player + ", processing=" + elapsed + " ms");
                     ProxyPlugin.this.clientMsgMeter.add(elapsed);
                  }

                  if (elapsed > 2000L) {
                     Log.info("LONG PROCESS: " + elapsed + " ms: player=" + player + " " + (event != null ? event.getName() : ""));
                  }

                  Timer.builder("event_process_time").tags(new String[]{"event", event.getClass().getSimpleName()}).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofMillis(elapsed));
               } catch (Exception var18) {
                  throw new RuntimeException("ProxyPlugin.EventCallback " + event + " processing error ", var18);
               } finally {
                  objLock.unlock();
               }
            } catch (Exception var20) {
               throw new RuntimeException("ProxyPlugin.EventCallback " + event + " ", var20);
            }

            ProxyPlugin.log.debug("ProxyPlugin.EventCallback " + event + " doWork End");
         }
      }
   }

   class MessageCallback implements SQCallback<Player, Message> {
      protected ProxyPlugin proxyPlugin;

      public MessageCallback(ProxyPlugin proxyPlugin) {
         this.proxyPlugin = proxyPlugin;
      }

      public void doWork(Message message, Player player) {
         long tStart = System.nanoTime();
         if (message == null) {
            Log.dumpStack("DOMESSAGE: Message for oid=" + player.getOid() + " is not a Message: " + message);
         } else if (message instanceof ProxyPlugin.ConnectionResetMessage) {
            ProxyPlugin.this.processConnectionResetInternal((ProxyPlugin.ConnectionResetMessage)message);
            long tEnd = System.nanoTime();
            Timer.builder("message_qq_callback").tag("message", message.getClass().getSimpleName()).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(tEnd - tStart));
         } else {
            int status = player.getStatus();
            if (status != 3 && status != 0) {
               long inQueue;
               try {
                  inQueue = 0L;
                  if (Log.loggingDebug) {
                     inQueue = System.nanoTime() - message.getEnqueueTime();
                     Log.debug("DOINGSVRMESSAGE: Message for oid=" + player.getOid() + ",msgId=" + message.getMsgId() + ",in-queue=" + inQueue / 1000L + " usec: " + message.getMsgType());
                  }

                  if (Log.loggingInfo && ProxyPlugin.this.proxyQueueHistogram != null) {
                     ProxyPlugin.this.proxyQueueHistogram.addTime(inQueue);
                  }

                  Timer.builder("message_qq_lag").publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(tStart - message.getEnqueueTime()));
                  List<Hook> hooks = ProxyPlugin.this.getHookManager().getHooks(message.getMsgType());
                  long callbackStart = System.nanoTime();
                  Iterator var11 = hooks.iterator();

                  while(var11.hasNext()) {
                     Hook hook = (Hook)var11.next();
                     ((ProxyHook)hook).processMessage(message, 0, player);
                  }

                  long callbackTime = 0L;
                  if (Log.loggingDebug || Log.loggingInfo) {
                     callbackTime = System.nanoTime() - callbackStart;
                  }

                  if (Log.loggingDebug) {
                     Log.debug("DONESVRMESSAGE: Message for oid=" + player.getOid() + ",msgId=" + message.getMsgId() + ",in-queue=" + inQueue / 1000L + " usec: ,execute=" + callbackTime / 1000L + " usec: " + message.getMsgType());
                  }

                  if (Log.loggingInfo && ProxyPlugin.this.proxyCallbackHistogram != null) {
                     ProxyPlugin.this.proxyCallbackHistogram.addTime(callbackTime);
                  }
               } catch (Exception var13) {
                  Prometheus.registry().counter("message_qq_errors", new String[0]).increment();
                  Log.exception("SQ MessageCallback", var13);
               }

               inQueue = System.nanoTime();
               Timer.builder("message_qq_callback").tag("message", message.getClass().getSimpleName()).publishPercentiles(new double[]{0.9D}).register(Prometheus.registry()).record(Duration.ofNanos(inQueue - tStart));
            } else {
               Log.debug("Ignoring message: id=" + message.getMsgId() + " type=" + message.getMsgType() + " for " + player);
               if (message.isRPC()) {
                  if (message.getMsgType() == InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ) {
                     Engine.getAgent().sendBooleanResponse(message, false);
                  } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_PLAYER_IGNORE_LIST_REQ) {
                     Engine.getAgent().sendObjectResponse(message, (Object)null);
                  } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_GET_PLAYER_LOGIN_STATUS) {
                     Engine.getAgent().sendObjectResponse(message, (Object)null);
                  } else {
                     if (message.getMsgType() != ProxyPlugin.MSG_TYPE_LOGOUT_PLAYER) {
                        throw new RuntimeException("Unexpected RPC message " + message + " for player " + player);
                     }

                     ProxyPlugin.log.error("handleMessage MSG_TYPE_LOGOUT_PLAYER");
                     Engine.getAgent().sendObjectResponse(message, (Object)null);
                  }
               }

            }
         }
      }
   }

   private static class DefaultCommandAccess implements ProxyPlugin.CommandAccessCheck {
      private DefaultCommandAccess() {
      }

      public boolean allowed(CommandEvent event, ProxyPlugin proxy) {
         return true;
      }

      // $FF: synthetic method
      DefaultCommandAccess(Object x0) {
         this();
      }
   }

   private static class RegisteredCommand {
      public ProxyPlugin.CommandParser parser;
      public ProxyPlugin.CommandAccessCheck access;

      public RegisteredCommand(ProxyPlugin.CommandParser p, ProxyPlugin.CommandAccessCheck a) {
         this.parser = p;
         this.access = a;
      }
   }

   public interface CommandAccessCheck {
      boolean allowed(CommandEvent var1, ProxyPlugin var2);
   }

   public interface CommandParser {
      void parse(CommandEvent var1);
   }

   public class PlayerMessageCallback implements atavism.msgsys.MessageCallback {
      public void handleMessage(Message message, int flags) {
         Prometheus.registry().counter("handled_messages", new String[]{"message", message.getClass().getSimpleName()}).increment();
         Object perceivers = new ArrayList();

         try {
            if (message instanceof TargetMessage) {
               if (message.getMsgType() == WorldManagerClient.MSG_TYPE_TARGETED_PROPERTY) {
                  ProxyPlugin.this.countMsgTargetedProperty.add();
               }

               OID playerOid = ((TargetMessage)message).getTarget();
               Player player = ProxyPlugin.this.playerManager.getPlayer(playerOid);
               if (player == null) {
                  Log.debug("TargetMessage: player " + playerOid + " not found");
                  if (message.isRPC()) {
                     if (message.getMsgType() == InstanceClient.MSG_TYPE_INSTANCE_ENTRY_REQ) {
                        Engine.getAgent().sendBooleanResponse(message, false);
                     } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_PLAYER_IGNORE_LIST_REQ) {
                        Engine.getAgent().sendObjectResponse(message, (Object)null);
                     } else if (message.getMsgType() == ProxyPlugin.MSG_TYPE_GET_PLAYER_LOGIN_STATUS) {
                        Engine.getAgent().sendObjectResponse(message, (Object)null);
                     } else {
                        if (message.getMsgType() != ProxyPlugin.MSG_TYPE_LOGOUT_PLAYER) {
                           throw new RuntimeException("Unexpected RPC message " + message + " for player " + player);
                        }

                        ProxyPlugin.log.error("handleMessage MSG_TYPE_LOGOUT_PLAYER");
                        Engine.getAgent().sendObjectResponse(message, (Object)null);
                     }
                  }
               } else {
                  long start = System.nanoTime();
                  message.setEnqueueTime();
                  if (Log.loggingTrace) {
                     Log.trace("PlayerMessageCallback.handleMessage " + message.getMsgId() + " TargetMessage " + message.getMsgType() + " add to messageQQ player:" + player);
                  }

                  ProxyPlugin.this.messageQQ.insert(player, message);
                  if (Log.loggingTrace) {
                     Log.trace("ProxyPlugin.handleMessage messageQQ.insert key=" + player + " nanoseconds: " + (System.nanoTime() - start));
                  }
               }

               return;
            }

            if (!(message instanceof SubjectMessage)) {
               if (message instanceof PerceptionMessage) {
                  PerceptionMessage pMsg = (PerceptionMessage)message;
                  ProxyPlugin.this.countMsgPerception.add();
                  ProxyPlugin.this.countMsgPerceptionGain.add((long)pMsg.getGainObjectCount());
                  ProxyPlugin.this.countMsgPerceptionLost.add((long)pMsg.getLostObjectCount());
                  OID playerOidx = pMsg.getTarget();
                  if (Log.loggingTrace) {
                     Log.debug("PERCEP: got perception message with player: " + playerOidx);
                  }

                  Player playerx = ProxyPlugin.this.playerManager.getPlayer(playerOidx);
                  if (playerx == null) {
                     Log.debug("PerceptionMessage: player " + playerOidx + " not found");
                  } else {
                     long startx = System.nanoTime();
                     message.setEnqueueTime();
                     ProxyPlugin.this.messageQQ.insert(playerx, message);
                     if (Log.loggingTrace) {
                        Log.trace("ProxyPlugin.handleMessage2 messageQQ.insert key=" + playerx + "  nanoseconds: " + (System.nanoTime() - startx));
                     }

                     if (Log.loggingTrace) {
                        Log.debug("PERCEP: added perception message to messageQQ: ");
                     }
                  }

                  return;
               }

               Log.error("PlayerMessageCallback unknown type=" + message.getMsgType());
               return;
            }

            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("PlayerMessageCallback.handleMessage: " + message);
            }

            try {
               perceivers = ProxyPlugin.this.playerManager.getPerceivers(((SubjectMessage)message).getSubject());
            } catch (Exception var9) {
               Log.exception("PlayerMessageCallback message=" + message + " " + var9.getMessage() + " " + var9.getLocalizedMessage() + " getPerceivers ", var9);
            }

            if (perceivers == null) {
               Log.warn("No perceivers for " + message);
               return;
            }

            if (Log.loggingDebug) {
               ProxyPlugin.log.debug("PlayerMessageCallback.handleMessage: | " + message + " perceivers=" + perceivers + " " + ((List)perceivers).size());
            }

            if (message instanceof WorldManagerClient.UpdateWorldNodeMessage) {
               WorldManagerClient.UpdateWorldNodeMessage wMsg = (WorldManagerClient.UpdateWorldNodeMessage)message;
               if (Log.loggingTrace) {
                  ProxyPlugin.log.trace("PlayerMessageCallback.handleMessage: UpdateWorldNodeMessage " + wMsg.getMsgId() + " " + wMsg.getSenderName() + " " + wMsg.getSubject() + " " + wMsg.getWorldNode() + " " + message.getMsgType());
               }

               DirLocOrientEvent dloEvent = new DirLocOrientEvent(wMsg.getSubject(), wMsg.getWorldNode());
               wMsg.setEventBuf(dloEvent.toBytes());
            }

            if (message.getMsgType() == WorldManagerClient.MSG_TYPE_UPDATEWNODE) {
               ProxyPlugin.this.countMsgUpdateWNodeIn.add();
               ProxyPlugin.this.countMsgUpdateWNodeOut.add((long)((List)perceivers).size());
            } else if (message.getMsgType() == PropertyMessage.MSG_TYPE_PROPERTY) {
               ProxyPlugin.this.countMsgPropertyIn.add();
               ProxyPlugin.this.countMsgPropertyOut.add((long)((List)perceivers).size());
            } else if (message.getMsgType() == WorldManagerClient.MSG_TYPE_WNODECORRECT) {
               ProxyPlugin.this.countMsgWNodeCorrectIn.add();
               ProxyPlugin.this.countMsgWNodeCorrectOut.add((long)((List)perceivers).size());
            } else if (message.getMsgType() == WorldManagerClient.MSG_TYPE_MOB_PATH) {
               ProxyPlugin.this.countMsgMobPathIn.add();
               ProxyPlugin.this.countMsgMobPathOut.add((long)((List)perceivers).size());
            }
         } catch (Exception var10) {
            Log.exception("PlayerMessageCallback message=" + message + " " + var10.getMessage() + " " + var10.getLocalizedMessage(), var10);
            return;
         }

         message.setEnqueueTime();
         if (Log.loggingTrace) {
            Log.trace("PlayerMessageCallback.handleMessage " + message.getMsgId() + " TargetMessage " + message.getMsgType() + " add to messageQQ ");
         }

         ProxyPlugin.this.messageQQ.insert((List)perceivers, message);
      }
   }

   public class PluginMessageCallback implements atavism.msgsys.MessageCallback {
      ExecutorService executor = Executors.newSingleThreadExecutor();

      public void handleMessage(Message message, int flags) {
         this.executor.execute(ProxyPlugin.this.new ReceivedMessage(message, flags));
      }
   }

   class ReceivedMessage implements Runnable {
      Message message;
      int flags;

      ReceivedMessage(Message message, int flags) {
         this.message = message;
         this.flags = flags;
      }

      public void run() {
         ProxyPlugin.this.callEngineOnMessage(this.message, this.flags);
      }
   }
}
1706122098266.png
 
Назад
Сверху Снизу