This class encapsulates database access for ALFA CLR scripts. Unlike the ad-hoc ALFA.MySQLDatabase class, this class supports a single, "canonical" standard default database connection with the following properties: - There is only one underlying connection so queries are completed in order. - The combined query queue ("ACR_AsyncSQLQuery[Ex]") is synchronized with queries issued on an ALFA.Database object. - All instances of ALFA.Database are synchronized with one another. Generally, "state changing" queries that have to synchronize with the updates performed via NWScript must go through this query. Queries that may be processed independently, e.g. the GameWorldManager in the ACR_ServerCommunicator, may use a standalone connection instead for better performance if they do not require synchronization with the canonical database connection.
Inheritance: IALFADatabase
コード例 #1
0
        public ALFA.Database GetDatabase()
        {
            if (Database == null)
                Database = new ALFA.Database(this);

            return Database;
        }
コード例 #2
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                string FormattedMessage = String.Format(
                    "</c><c=#FFFF00>{0}</c>",
                    Message);

                NWScript.Vector3 v;
                v.x = v.y = v.z = 0.0f;

                Script.SendChatMessage(
                    CLRScriptBase.OBJECT_INVALID,
                    PlayerObject,
                    CLRScriptBase.CHAT_MODE_SERVER,
                    FormattedMessage,
                    CLRScriptBase.FALSE);

                Script.FloatingTextStringOnCreature(FormattedMessage,
                                                    PlayerObject,
                                                    CLRScriptBase.FALSE,
                                                    5.0f,
                                                    CLRScriptBase.COLOR_WHITE,
                                                    CLRScriptBase.COLOR_WHITE,
                                                    0.0f,
                                                    v);
            }

            Database.ACR_IncrementStatistic("BROADCAST_MESSAGE");
            Script.WriteTimestampedLogEntry("Received broadcast notification: " + Message);
        }
コード例 #3
0
        /// <summary>
        /// Get the associated database object, creating it on demand if
        /// required.
        /// </summary>
        /// <returns>The database connection object.</returns>
        private ALFA.Database GetDatabase()
        {
            if (Database == null)
            {
                Database = new ALFA.Database(this);
            }

            return(Database);
        }
コード例 #4
0
        private void InitializeLatencyMonitor()
        {
            try
            {
                ServerUdpListener = SystemInfo.GetServerUdpListener(this);
            }
            catch (Exception)
            {
                WriteTimestampedLogEntry("LatencyMonitor.InitializeLatencyMonitor(): Failed to query server data port, retrying in 10 minutes.");
                DelayCommand(600.0f, delegate() { InitializeLatencyMonitor(); });
                return;
            }

            //
            // Create a dummy object so that we may block on its SyncBlock.
            // This object forms the lock for CurrentLatency, which we cannot
            // directly use as boxing a new object would result in a new
            // SyncBlock for every lock attempt.
            //

            CurrentLatencyLock = new int();

            //
            // Create the new UDP socket.  This has to be done AFTER we get the
            // UDP listener, for the get UDP listener code to work, as it finds
            // the first UDP socket opened by nwn2server.
            //

            UdpSocket = new UdpClient(AddressFamily.InterNetwork);

            //
            // Set the default address to point to the server's local UDP
            // listener.
            //

            UdpSocket.Connect(ServerUdpListener);

            ALFA.Database Database = new ALFA.Database(this);

            LocalServerId = Database.ACR_GetServerID();

            //
            // Start the latency measurement thread and the vault ping thread.
            //

            LatencyMeasurementThread = new Thread(LatencyMeasurementThreadRoutine);
            LatencyMeasurementThread.Start();
            VaultPingThread = new Thread(VaultPingThreadRoutine);
            VaultPingThread.Start();

            PollServerLatency();

            WriteTimestampedLogEntry(String.Format("LatencyMonitor.InitializeLatencyMonitor(): Latency monitoring initialized on data port {0}.", ServerUdpListener));
        }
コード例 #5
0
        /// <summary>
        /// Run the event queue down.  All events in the queue are given a
        /// chance to run.
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void RunQueue(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
#if DEBUG_MODE
            Script.WriteTimestampedLogEntry(String.Format("ACR_ServerCommunicator: Running queue of {0} entries", EventQueue.Count));
#endif

            while (!Empty())
            {
                IGameEventQueueEvent Event = EventQueue.Dequeue();

                Event.DispatchEvent(Script, Database);
            }
        }
コード例 #6
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            string FormattedMessage = String.Format(
                "ACR_ServerCommunicator: Received unsupported IPC event {0}: {1}.{2}.{3}.{4}.  Record ID was {5}.",
                EventType,
                P0,
                P1,
                P2,
                P3,
                RecordId);

            Script.WriteTimestampedLogEntry(FormattedMessage);
        }
コード例 #7
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            //
            // If the event was for the local server, then don't re-broadcast
            // it.
            //

            if (Database.ACR_GetServerID() == Server.ServerId)
            {
                return;
            }

            string Message = String.Format(
                "<c=#FFFF00>Server {0} is now online.</c>",
                Server.Name);
            string ChatMessage = "</c>" + Message;

            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                PlayerState Player = Script.TryGetPlayerState(PlayerObject);

                if (Player == null)
                {
                    continue;
                }

                if (!Script.IsCrossServerNotificationEnabled(PlayerObject))
                {
                    continue;
                }

                if ((Player.Flags & PlayerStateFlags.SendCrossServerNotificationsToCombatLog) != 0)
                {
                    Script.SendMessageToPC(PlayerObject, Message);
                }
                else
                {
                    Script.SendChatMessage(
                        CLRScriptBase.OBJECT_INVALID,
                        PlayerObject,
                        CLRScriptBase.CHAT_MODE_SERVER,
                        ChatMessage,
                        CLRScriptBase.FALSE);
                }
            }

#if DEBUG_MODE
            Script.WriteTimestampedLogEntry(Message);
#endif
        }
コード例 #8
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            int SourceServerId = (SourceServer != null) ? SourceServer.ServerId : 0;

            Script.WriteTimestampedLogEntry(String.Format("RunScriptEvent.DispatchEvent: Executing script {0} ({1}) on request from {2}.",
                                                          ScriptName,
                                                          ScriptArgument,
                                                          SourceServerId));
            Script.ClearScriptParams();
            Script.AddScriptParameterInt(SourceServerId);
            Script.AddScriptParameterString(ScriptArgument);
            Script.ExecuteScriptEnhanced(ScriptName, Script.GetModule(), CLRScriptBase.TRUE);

            Database.ACR_IncrementStatistic("RUN_REMOTE_SCRIPT");
        }
コード例 #9
0
        /// <summary>
        /// Convert legacy database settings to their new format.
        /// </summary>
        private void UpgradeLegacySettings()
        {
            ALFA.Database Database = Communicator.GetDatabase();

            //
            // If the user has the old ACR_DISABLE_CROSS_SERVER_NOTIFICATIONS
            // value set from the pre-1.85 release, clear that variable and set
            // the flags bitmap as appropriate.
            //

            if (Database.ACR_GetPersistentInt(ObjectId, "ACR_DISABLE_CROSS_SERVER_NOTIFICATIONS") != CLRScriptBase.FALSE)
            {
                StateFlags |= PlayerStateFlags.DisableCrossServerNotifications;
                Database.ACR_DeletePersistentVariable(ObjectId, "ACR_DISABLE_CROSS_SERVER_NOTIFICATIONS");
            }
        }
コード例 #10
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                if (Database.ACR_GetPlayerID(PlayerObject) != Player.PlayerId)
                {
                    continue;
                }

                Database.ACR_IncrementStatistic("DISCONNECT_PLAYER");
                Script.WriteTimestampedLogEntry("DisconnectPlayerEvent.DispatchEvent: Disconnecting player " + Script.GetPCPlayerName(PlayerObject) + " due to IPC request.");
                Script.BootPC(PlayerObject);
                return;
            }

            Script.WriteTimestampedLogEntry("DisconnectPlayerEvent.DispatchEvent: No player '" + Player.PlayerName + "' found locally connected to disconnect.");
        }
コード例 #11
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                string FormattedMessage = String.Format(
                    "</c><c=#FFFF00>Server shutting down: {0}</c>",
                    Message);

                NWScript.Vector3 v;
                v.x = v.y = v.z = 0.0f;

                Script.SendChatMessage(
                    CLRScriptBase.OBJECT_INVALID,
                    PlayerObject,
                    CLRScriptBase.CHAT_MODE_SERVER,
                    FormattedMessage,
                    CLRScriptBase.FALSE);

                Script.FloatingTextStringOnCreature(FormattedMessage,
                                                    PlayerObject,
                                                    CLRScriptBase.FALSE,
                                                    5.0f,
                                                    CLRScriptBase.COLOR_WHITE,
                                                    CLRScriptBase.COLOR_WHITE,
                                                    0.0f,
                                                    v);
            }

            Script.WriteTimestampedLogEntry("Received shutdown request: " + Message);

            Database.ACR_IncrementStatistic("SERVER_SHUTDOWN");
            Script.SendInfrastructureIrcMessage(String.Format(
                                                    "Server '{0}' shutting down or restarting: {1}",
                                                    Script.GetName(Script.GetModule()),
                                                    Message));

            Script.DelayCommand(5.0f, delegate()
            {
                Database.ACR_FlushAllQueryQueues();
                SystemInfo.ShutdownGameServer(Script);
            });
        }
コード例 #12
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                if (Database.ACR_GetPlayerID(PlayerObject) != Recipient.PlayerId)
                {
                    continue;
                }

                string FormattedMessage = String.Format(
                    "</c><c=#FFCC99>{0}: </c><c=#30DDCC>[ServerTell] {1}</c>",
                    Sender.CharacterName,
                    Message);

                Script.SetLastTellFromPlayerId(PlayerObject, Sender.Player.PlayerId);
                Script.SendChatMessage(
                    CLRScriptBase.OBJECT_INVALID,
                    PlayerObject,
                    CLRScriptBase.CHAT_MODE_SERVER,
                    FormattedMessage,
                    CLRScriptBase.FALSE);

                //
                // If this is the first time that we have delivered a
                // cross-server tell to this player (since login), remind them
                // of how to respond.
                //

                if ((Database.ACR_GetPCLocalFlags(PlayerObject) & ALFA.Database.ACR_PC_LOCAL_FLAG_SERVER_TELL_HELP) == 0)
                {
                    Script.SendMessageToPC(
                        PlayerObject,
                        "To respond to a [ServerTell] from a player on a different server, type: #re [message], or #t \"character name\" [message], or #tp \"player name\" [message].  Quotes are optional unless the name has spaces.  The #rt [message] command will send a tell to the last player that you had sent a tell to.");
                    Database.ACR_SetPCLocalFlags(
                        PlayerObject,
                        Database.ACR_GetPCLocalFlags(PlayerObject) | ALFA.Database.ACR_PC_LOCAL_FLAG_SERVER_TELL_HELP);
                }
                break;
            }
        }
コード例 #13
0
        /// <summary>
        /// Construct a new PlayerState object.
        /// </summary>
        /// <param name="ObjectId">Supplies the NWScript object id of the PC
        /// object.</param>
        /// <param name="Communicator">Supplies the server communicator
        /// instance that the PlayerState object is bound to.</param>
        public PlayerState(uint ObjectId, ACR_ServerCommunicator Communicator)
        {
            ALFA.Database Database = Communicator.GetDatabase();

            this.Communicator                 = Communicator;
            this.PCObjectId                   = ObjectId;
            this.PCCharacterId                = Database.ACR_GetCharacterID(ObjectId);
            this.PCPlayerId                   = Database.ACR_GetPlayerID(ObjectId);
            this.StateFlags                   = (PlayerStateFlags)Database.ACR_GetPersistentInt(ObjectId, "ACR_COMMUNICATOR_STATE_FLAGS");
            this.LatencyTickCount             = 0;
            this.LatencyToServer              = 0;
            this.ChatSelectLocalPlayersShown  = 0;
            this.ChatSelectLocalDMsShown      = 0;
            this.ChatSelectRemotePlayersShown = 0;
            this.ChatSelectRemoteDMsShown     = 0;

            //
            // Upgrade any legacy database settings to their new format.
            //

            UpgradeLegacySettings();
        }
コード例 #14
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                if (Database.ACR_GetPlayerID(PlayerObject) != Recipient.PlayerId)
                {
                    continue;
                }

                string FormattedMessage = String.Format(
                    "</c><c=#FFCC99>{0}: </c><c=#30DDCC>[Page] {1}</c>",
                    Sender.PlayerName,
                    Message);

                Script.SendChatMessage(
                    CLRScriptBase.OBJECT_INVALID,
                    PlayerObject,
                    CLRScriptBase.CHAT_MODE_SERVER,
                    FormattedMessage,
                    CLRScriptBase.FALSE);
                break;
            }
        }
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            PlayerState State = Script.TryGetPlayerState(PlayerObject);
            string      RequestURL;

            //
            // If the player is logged off, then there's nothing to do.
            //

            if (State == null || State.IsDM)
            {
                return;
            }

            if (String.IsNullOrEmpty(AccountAssociationSecret))
            {
                return;
            }

            RequestURL = AccountAssociator.GenerateAssociationURL(Script.GetPCPlayerName(PlayerObject), AccountAssociationSecret, AccountAssociationURL);

            Script.DisplayGuiScreen(PlayerObject, "acr_account_association", CLRScriptBase.FALSE, "acr_account_association.XML", CLRScriptBase.FALSE);
            Script.SetLocalGUIVariable(PlayerObject, "acr_account_association", 0, RequestURL);
        }
コード例 #16
0
 public ACR_ServerMisc([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     InitScript(Intrinsics, Host);
     Database = new ALFA.Database(this);
 }
コード例 #17
0
 public ACR_ServerMisc([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     InitScript(Intrinsics, Host);
     Database = new ALFA.Database(this);
 }
コード例 #18
0
 public ACR_CreatureBehavior([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     InitScript(Intrinsics, Host);
     Database = new ALFA.Database(this);
 }
コード例 #19
0
        /// <summary>
        /// This method initializes the server communicator (one-time startup
        /// processing).
        /// </summary>
        private void InitializeServerCommunicator()
        {
            int ServerId;

            if (Database == null)
                Database = new ALFA.Database(this);

            ServerId = Database.ACR_GetServerID();

            WorldManager = new GameWorldManager(
                ServerId,
                GetName(GetModule()));
            NetworkManager = new ServerNetworkManager(WorldManager, ServerId, this);
            PlayerStateTable = new Dictionary<uint, PlayerState>();

            //
            // Remove any stale IPC commands to this server, as we are starting
            // up fresh.
            //

            Database.ACR_SQLExecute(String.Format(
                "DELETE FROM `server_ipc_events` WHERE `DestinationServerID`={0}",
                Database.ACR_GetServerID()));

            WriteTimestampedLogEntry(String.Format(
                "ACR_ServerCommunicator.InitializeServerCommunicator: Purged {0} old records from server_ipc_events for server id {1}.",
                Database.ACR_SQLGetAffectedRows(),
                Database.ACR_GetServerID()));
            WriteTimestampedLogEntry(String.Format(
                "ACR_ServerCommunicator.InitializeServerCommunicator: Server started with ACR version {0} and IPC subsystem version {1}.",
                Database.ACR_GetVersion(),
                Assembly.GetExecutingAssembly().GetName().Version.ToString()));

            if (GetLocalInt(GetModule(), "ACR_SERVER_IPC_DISABLE_LATENCY_CHECK") == FALSE)
                EnableLatencyCheck = true;
            else
                EnableLatencyCheck = false;

            if (!EnableLatencyCheck)
                WriteTimestampedLogEntry("ACR_ServerCommunicator.InitializeServerCommunicator: Latency check turned off by configuration.");

            WorldManager.SynchronizeInitialConfiguration(Database);

            //
            // Check that the module is allowed to come online.  If it may be
            // hosted on another machine due to a recovery event, do not allow
            // the module to come online.
            //

            if (!ConfirmModuleOnline())
            {
                //
                // This module has been administratively prevented from loading
                // on all but a specific machine.  Await that condition to be
                // cleared from the database.  Do not initialize the vault
                // connector so that new logons are blocked, and set the
                // offline variable so that periodic time update does not mark
                // the server as online in the database.
                //

                WriteTimestampedLogEntry("ACR_ServerCommunicator.InitializeServerCommunicator: Module offlined because MachineName in servers table for this server is not NULL and does not match the machine name of this server.  This indicates that server startup was blocked for manual recovery.  Clear the MachineName field from the servers table in the database for this server to allow this server to start up normally.");
                SetLocalInt(GetModule(), "ACR_MODULE_OFFLINE", TRUE);
                PollModuleOnlineAllowed();
                SendInfrastructureDiagnosticIrcMessage(String.Format(
                    "Server '{0}' started on a machine that is administratively prohibited from loading the module, going into offline mode until MachineName is cleared in the servers table in the database for this server.",
                    GetName(GetModule())));
                WorldManager.PauseUpdates = true;
                return;
            }

            if (!ServerVaultConnector.Initialize(this, WorldManager.Configuration.VaultConnectionString, WorldManager.Configuration.VerboseVaultLogging))
                WriteTimestampedLogEntry("ACR_ServerCommunicator.InitializeServerCommunicator: ServerVaultConnector failed to initialize.");

            if (!String.IsNullOrEmpty(WorldManager.Configuration.VaultConnectionString))
                WriteTimestampedLogEntry("ACR_ServerCommunicator.InitializeServerCommunicator: Using Azure-based vault storage.");

            RecordModuleResources();
            PatchContentFiles();
            ConfigureWer();

            RunPatchInitScript();

            //
            // Finally, drop into the command polling loop.
            //

            CommandDispatchLoop();
            UpdateServerExternalAddress();
            GameDifficultyCheck();
        }
コード例 #20
0
 /// <summary>
 /// Dispatch the event (in a script context).
 /// </summary>
 /// <param name="Script">Supplies the script object.</param>
 /// <param name="Database">Supplies the database connection.</param>
 public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
 {
     Script.WriteTimestampedLogEntry("ACR_ServerCommunicator: " + Message);
 }
コード例 #21
0
 public TestClrScript([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     Database = new ALFA.Database(this);
     InitScript(Intrinsics, Host);
 }
コード例 #22
0
 public ACR_CreatureBehavior([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     InitScript(Intrinsics, Host);
     Database = new ALFA.Database(this);
 }
コード例 #23
0
 public ACR_HealthMonitor([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     InitScript(Intrinsics, Host);
     Database = new ALFA.Database(this);
 }
コード例 #24
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            //
            // If the event was for a player logging on to the local server,
            // then don't re-broadcast it.
            //
            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                PlayerState Player = Script.TryGetPlayerState(PlayerObject);

                if (Player == null)
                {
                    continue;
                }

                if (!Player.CharacterIdsShown.Contains(Character.CharacterId))
                {
                    string sPlayerListBox = "";

                    if (Server.ServerId == Script.GetDatabase().ACR_GetServerID() || Script.GetLocalInt(PlayerObject, "chatselect_expanded") == 0)
                    {
                        if (IsDM == true)
                        {
                            sPlayerListBox = "LocalDMList";
                            Player.ChatSelectLocalDMsShown += 1;
                        }
                        else
                        {
                            sPlayerListBox = "LocalPlayerList";
                            Player.ChatSelectLocalPlayersShown += 1;
                        }

                        if (Server.ServerId == Script.GetDatabase().ACR_GetServerID())
                        {
                            Script.AddListBoxRow(Player.ObjectId, "ChatSelect", sPlayerListBox, Character.CharacterName, "RosterData=/t \"" + Character.CharacterName + "\"", "", "5=/t \"" + Character.CharacterName + "\" ", "");
                        }
                        else
                        {
                            if (Player.Flags.HasFlag(PlayerStateFlags.ChatSelectShowLocalPlayersOnlyWhenCollapsed))
                            {
                                continue;
                            }

                            Script.AddListBoxRow(Player.ObjectId, "ChatSelect", sPlayerListBox, Character.CharacterName, "RosterData=#t \"" + Character.CharacterName + "\"", "", "5=#t \"" + Character.CharacterName + "\" ", "");
                        }
                    }
                    else
                    {
                        if (IsDM == true)
                        {
                            sPlayerListBox = "RemoteDMList";
                            Player.ChatSelectRemoteDMsShown += 1;
                        }
                        else
                        {
                            sPlayerListBox = "RemotePlayerList";
                            Player.ChatSelectRemotePlayersShown += 1;
                        }

                        Script.AddListBoxRow(Player.ObjectId, "ChatSelect", sPlayerListBox, Character.CharacterName, "RosterData=#t \"" + Character.CharacterName + "\"", "", "5=#t \"" + Character.CharacterName + "\" ", "");
                    }

                    Player.CharacterIdsShown.Add(Character.CharacterId);
                    Player.UpdateChatSelectGUIHeaders();
                }
            }

            if (Database.ACR_GetServerID() == Server.ServerId)
            {
                return;
            }

            string Message = String.Format(
                "{0}<c=#FFA500>{1} ({2}) joined {3}.</c>", // <c=Orange...>
                IsDM ? "<c=#99CCFF>[DM] </c>": "",
                Character.Name,
                Character.Player.Name,
                Server.Name);
            string ChatMessage = "</c>" + Message;

            foreach (uint PlayerObject in Script.GetPlayers(true))
            {
                PlayerState Player = Script.TryGetPlayerState(PlayerObject);

                if (Player == null)
                {
                    continue;
                }

                if (!Script.IsCrossServerNotificationEnabled(PlayerObject))
                {
                    continue;
                }

                if ((Player.Flags & PlayerStateFlags.SendCrossServerNotificationsToCombatLog) != 0)
                {
                    Script.SendMessageToPC(PlayerObject, Message);
                }
                else
                {
                    Script.SendChatMessage(
                        CLRScriptBase.OBJECT_INVALID,
                        PlayerObject,
                        CLRScriptBase.CHAT_MODE_SERVER,
                        ChatMessage,
                        CLRScriptBase.FALSE);
                }
            }

#if DEBUG_MODE
            Script.WriteTimestampedLogEntry(Message);
#endif
        }
コード例 #25
0
        /// <summary>
        /// Dispatch the event (in a script context).
        /// </summary>
        /// <param name="Script">Supplies the script object.</param>
        /// <param name="Database">Supplies the database connection.</param>
        public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
        {
            string PlayerName = Player.Name;

            if (!SystemInfo.IsSafeFileName(PlayerName))
            {
                Script.WriteTimestampedLogEntry(String.Format(
                                                    "PurgeCachedCharacterEvent.DispatchEvent: Invalid player name '{0}'.", PlayerName));
                return;
            }

            string VaultPath = SystemInfo.GetServerVaultPathForAccount(PlayerName);

            if (VaultPath == null)
            {
                Script.WriteTimestampedLogEntry(String.Format(
                                                    "PurgeCachedCharacterEvent.DispatchEvent: Could not resolve vault path for player '{0}'.",
                                                    Player.PlayerName));
                return;
            }

            VaultPath += CharacterFileName;

            if (!File.Exists(VaultPath))
            {
                Script.WriteTimestampedLogEntry(String.Format(
                                                    "PurgeCachedCharacterEvent.DispatchEvent: Character file '{0}' for player '{1}' was not locally cached.",
                                                    CharacterFileName,
                                                    Player.PlayerName));
                return;
            }

            try
            {
                File.Delete(VaultPath);
            }
            catch (Exception e)
            {
                Script.WriteTimestampedLogEntry(String.Format(
                                                    "PurgeCachedCharacterEvent.DispatchEvent: Exception '{0}' removing cached character '{1}' for player '{2}'.",
                                                    e,
                                                    CharacterFileName,
                                                    Player.PlayerName));
                return;
            }

            try
            {
                if (SystemInfo.GetVaultStoragePluginInUse())
                {
                    VaultPath = SystemInfo.GetCentralVaultPathForAccount(PlayerName);

                    VaultPath += CharacterFileName;

                    if (File.Exists(VaultPath))
                    {
                        File.Delete(VaultPath);
                    }
                }
            }
            catch (Exception e)
            {
                Script.WriteTimestampedLogEntry(String.Format(
                                                    "PurgeCachedCharacterEvent.DispatchEvent: Exception '{0}' removing cached character from Azure vault temporary local storage '{1}' for player '{2}'.",
                                                    e,
                                                    CharacterFileName,
                                                    Player.PlayerName));
                return;
            }

            Script.WriteTimestampedLogEntry(String.Format(
                                                "PurgeCachedCharacterEvent.DispatchEvent: Removed cached character '{0}' from player '{1}' vault cache.",
                                                CharacterFileName,
                                                Player.PlayerName));
        }
コード例 #26
0
 public TestClrScript([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     Database = new ALFA.Database(this);
     InitScript(Intrinsics, Host);
 }
コード例 #27
0
        public Int32 ScriptMain([In] object[] ScriptParameters, [In] Int32 DefaultReturnCode)
        {
            if (LatencyMeasurementThread != null)
                return DefaultReturnCode;

            ServerUdpListener = SystemInfo.GetServerUdpListener(this);

            //
            // Create a dummy object so that we may block on its SyncBlock.
            // This object forms the lock for CurrentLatency, which we cannot
            // directly use as boxing a new object would result in a new
            // SyncBlock for every lock attempt.
            //

            CurrentLatencyLock = new int();

            //
            // Create the new UDP socket.  This has to be done AFTER we get the
            // UDP listener, for the get UDP listener code to work, as it finds
            // the first UDP socket opened by nwn2server.
            //

            UdpSocket = new UdpClient(AddressFamily.InterNetwork);

            //
            // Set the default address to point to the server's local UDP
            // listener.
            //

            UdpSocket.Connect(ServerUdpListener);

            ALFA.Database Database = new ALFA.Database(this);

            LocalServerId = Database.ACR_GetServerID();

            //
            // Start the latency measurement thread and the vault ping thread.
            //

            LatencyMeasurementThread = new Thread(LatencyMeasurementThreadRoutine);
            LatencyMeasurementThread.Start();
            VaultPingThread = new Thread(VaultPingThreadRoutine);
            VaultPingThread.Start();

            PollServerLatency();

            return DefaultReturnCode;
        }
コード例 #28
0
        /// <summary>
        /// This method initializes the server communicator (one-time startup
        /// processing).
        /// </summary>
        private void InitializeServerCommunicator()
        {
            int ServerId;

            if (Database == null)
                Database = new ALFA.Database(this);

            ServerId = Database.ACR_GetServerID();

            WorldManager = new GameWorldManager(
                ServerId,
                GetName(GetModule()));
            NetworkManager = new ServerNetworkManager(WorldManager, ServerId);
            PlayerStateTable = new Dictionary<uint, PlayerState>();

            //
            // Remove any stale IPC commands to this server, as we are starting
            // up fresh.
            //

            Database.ACR_SQLExecute(String.Format(
                "DELETE FROM `server_ipc_events` WHERE `DestinationServerID`={0}",
                Database.ACR_GetServerID()));

            WriteTimestampedLogEntry(String.Format(
                "ACR_ServerCommunicator.InitializeServerCommunicator: Purged {0} old records from server_ipc_events for server id {1}.",
                Database.ACR_SQLGetAffectedRows(),
                Database.ACR_GetServerID()));
            WriteTimestampedLogEntry(String.Format(
                "ACR_ServerCommunicator.InitializeServerCommunicator: Server started with ACR version {0} and IPC subsystem version {1}.",
                Database.ACR_GetVersion(),
                Assembly.GetExecutingAssembly().GetName().Version.ToString()));

            if (GetLocalInt(GetModule(), "ACR_SERVER_IPC_DISABLE_LATENCY_CHECK") == FALSE)
                EnableLatencyCheck = true;
            else
                EnableLatencyCheck = false;

            if (!EnableLatencyCheck)
                WriteTimestampedLogEntry("ACR_ServerCommunicator.InitializeServerCommunicator: Latency check turned off by configuration.");

            RecordModuleResources();
            PatchContentFiles();
            ConfigureWer();

            RunPatchInitScript();

            //
            // Finally, drop into the command polling loop.
            //

            CommandDispatchLoop();
            UpdateServerExternalAddress();
        }
コード例 #29
0
 /// <summary>
 /// Dispatch the event (in a script context).
 /// </summary>
 /// <param name="Script">Supplies the script object.</param>
 /// <param name="Database">Supplies the database connection.</param>
 public void DispatchEvent(ACR_ServerCommunicator Script, ALFA.Database Database)
 {
     Script.SendMessageToPC(PlayerObject, Message);
 }
コード例 #30
0
        private void InitializeLatencyMonitor()
        {
            try
            {
                ServerUdpListener = SystemInfo.GetServerUdpListener(this);
            }
            catch (Exception)
            {
                WriteTimestampedLogEntry("LatencyMonitor.InitializeLatencyMonitor(): Failed to query server data port, retrying in 10 minutes.");
                DelayCommand(600.0f, delegate() { InitializeLatencyMonitor(); });
                return;
            }

            //
            // Create a dummy object so that we may block on its SyncBlock.
            // This object forms the lock for CurrentLatency, which we cannot
            // directly use as boxing a new object would result in a new
            // SyncBlock for every lock attempt.
            //

            CurrentLatencyLock = new int();

            //
            // Create the new UDP socket.  This has to be done AFTER we get the
            // UDP listener, for the get UDP listener code to work, as it finds
            // the first UDP socket opened by nwn2server.
            //

            UdpSocket = new UdpClient(AddressFamily.InterNetwork);

            //
            // Set the default address to point to the server's local UDP
            // listener.
            //

            UdpSocket.Connect(ServerUdpListener);

            ALFA.Database Database = new ALFA.Database(this);

            LocalServerId = Database.ACR_GetServerID();

            //
            // Start the latency measurement thread and the vault ping thread.
            //

            LatencyMeasurementThread = new Thread(LatencyMeasurementThreadRoutine);
            LatencyMeasurementThread.Start();
            VaultPingThread = new Thread(VaultPingThreadRoutine);
            VaultPingThread.Start();

            PollServerLatency();

            WriteTimestampedLogEntry(String.Format("LatencyMonitor.InitializeLatencyMonitor(): Latency monitoring initialized on data port {0}.", ServerUdpListener));
        }
コード例 #31
0
 public ACR_HealthMonitor([In] NWScriptJITIntrinsics Intrinsics, [In] INWScriptProgram Host)
 {
     InitScript(Intrinsics, Host);
     Database = new ALFA.Database(this);
 }