private static string BuildTellLog()
        {
            var sender            = NWNXChat.GetSender();
            var receiver          = NWNXChat.GetTarget();
            var channel           = NWNXChat.GetChannel();
            var message           = NWNXChat.GetMessage();
            var senderIPAddress   = GetPCIPAddress(sender);
            var senderCDKey       = GetPCPublicCDKey(sender);
            var senderAccount     = GetPCPlayerName(sender);
            var senderPCName      = GetName(sender);
            var receiverIPAddress = GetPCIPAddress(receiver);
            var receiverCDKey     = GetPCPublicCDKey(receiver);
            var receiverAccount   = GetPCPlayerName(receiver);
            var receiverPCName    = GetName(receiver);

            var log = $"{senderPCName} - {senderAccount} - {senderCDKey} - {senderIPAddress} - {channel} (SENT TO {receiverPCName} - {receiverAccount} - {receiverCDKey} - {receiverIPAddress}): {message}";

            return(log);
        }
        private static void OnModuleNWNXChat()
        {
            NWPlayer sender = OBJECT_SELF;

            if (!sender.IsPlayer && !sender.IsDM)
            {
                return;
            }
            string text = NWNXChat.GetMessage();

            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            var      mode          = NWNXChat.GetChannel();
            int      channel       = ConvertNWNXChatChannelIDToDatabaseID(mode);
            NWObject recipient     = NWNXChat.GetTarget();
            var      channelEntity = DataService.ChatChannel.GetByID(channel);

            // Sender - should always have this data.
            string senderCDKey       = GetPCPublicCDKey(sender.Object);
            string senderAccountName = sender.Name;
            Guid?  senderPlayerID    = null;
            string senderDMName      = null;

            // DMs do not have PlayerIDs so store their name in another field.
            if (sender.IsDM)
            {
                senderDMName = "[DM: " + sender.Name + " (" + senderCDKey + ")]";
            }
            else
            {
                senderPlayerID = sender.GlobalID;
            }

            // Receiver - may or may not have the data.

            string receiverCDKey       = null;
            string receiverAccountName = null;
            Guid?  receiverPlayerID    = null;
            string receiverDMName      = null;

            if (recipient.IsValid)
            {
                receiverCDKey       = GetPCPublicCDKey(recipient.Object);
                receiverAccountName = recipient.Name;

                // DMs do not have PlayerIDs so store their name in another field.
                if (recipient.IsDM)
                {
                    receiverDMName = "[DM: " + recipient.Name + " (" + senderCDKey + ")]";
                }
                else
                {
                    receiverPlayerID = recipient.GlobalID;
                }
            }

            ChatLog entity = new ChatLog
            {
                Message             = text,
                SenderCDKey         = senderCDKey,
                SenderAccountName   = senderAccountName,
                SenderPlayerID      = senderPlayerID,
                SenderDMName        = senderDMName,
                ReceiverCDKey       = receiverCDKey,
                ReceiverAccountName = receiverAccountName,
                ReceiverPlayerID    = receiverPlayerID,
                ReceiverDMName      = receiverDMName,
                ChatChannelID       = channelEntity.ID,
                DateSent            = DateTime.UtcNow
            };

            // Bypass the caching logic
            DataService.DataQueue.Enqueue(new DatabaseAction(entity, DatabaseActionType.Insert));
        }