public override void Setup()
 {
     try {
         shortenedWandererTag = Marshal.AllocHGlobal(60);
         var seStr = new SeString(new List <Payload>()
         {
             new TextPayload(" «"),
             new IconPayload(BitmapFontIcon.CrossWorld),
             new TextPayload("»"),
         });
         var bytes = seStr.Encode();
         Marshal.Copy(bytes, 0, shortenedWandererTag, bytes.Length);
         Marshal.WriteByte(shortenedWandererTag, bytes.Length, 0);
         playerNamePlateSetTextAddress = PluginInterface.TargetModuleScanner.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 4C 8B 5C 24");
         base.Setup();
     } catch (Exception ex) {
         SimpleLog.Log($"Failed Setup of {GetType().Name}: {ex.Message}");
     }
 }
Пример #2
0
        public void SaleDebugCommand(string command, string args)
        {
            // make a sample sale message. This is using Titanium Ore for an item
            Item     sampleitem  = Interface.Data.GetExcelSheet <Item>().GetRow(12537);
            SeString sameplesale = new SeString(new Payload[] { new TextPayload("The "), new ItemPayload(Interface.Data, sampleitem.RowId, true), new TextPayload(sampleitem.Name), new TextPayload(" you put up for sale in the Crystarium markets has sold for 777 gil (after fees).") });

            // PluginLog.Information($"Trying to make a fake sale: {sameplesale.TextValue}");

            this.Discord.MessageQueue.Enqueue(new QueuedRetainerItemSaleEvent
            {
                ChatType = XivChatType.RetainerSale,
                Message  = sameplesale,
                Sender   = new SeString(new Payload[] { new TextPayload("Test Sender"), })
            });

            Interface.Framework.Gui.Chat.PrintChat(new XivChatEntry
            {
                MessageBytes = sameplesale.Encode()
            });
        }
Пример #3
0
 /// <summary>
 /// Show a toast message with the given content.
 /// </summary>
 /// <param name="message">The message to be shown.</param>
 /// <param name="options">Options for the toast.</param>
 public void ShowNormal(SeString message, ToastOptions options = null)
 {
     options ??= new ToastOptions();
     this.normalQueue.Enqueue((message.Encode(), options));
 }
Пример #4
0
        public async Task ProcessChatMessage(XivChatType type, SeString message, SeString sender)
        {
            if (this.dalamud.SeStringManager == null)
            {
                return;
            }

            // Special case for outgoing tells, these should be sent under Incoming tells
            var wasOutgoingTell = false;

            if (type == XivChatType.TellOutgoing)
            {
                type            = XivChatType.TellIncoming;
                wasOutgoingTell = true;
            }

            var chatTypeConfigs =
                this.config.ChatTypeConfigurations.Where(typeConfig => typeConfig.ChatType == type);

            if (!chatTypeConfigs.Any())
            {
                return;
            }

            var chatTypeDetail = type.GetDetails();
            var channels       = chatTypeConfigs.Select(c => GetChannel(c.Channel).GetAwaiter().GetResult());


            var playerLink = sender.Payloads.FirstOrDefault(x => x.Type == PayloadType.Player) as PlayerPayload;

            string senderName;
            string senderWorld;

            if (playerLink == null)
            {
                // chat messages from the local player do not include a player link, and are just the raw name
                // but we should still track other instances to know if this is ever an issue otherwise

                // Special case 2 - When the local player talks in party/alliance, the name comes through as raw text,
                // but prefixed by their position number in the party (which for local player may always be 1)
                if (sender.TextValue.EndsWith(this.dalamud.ClientState.LocalPlayer.Name))
                {
                    senderName = this.dalamud.ClientState.LocalPlayer.Name;
                }
                else
                {
                    Log.Error("playerLink was null. Sender: {0}", BitConverter.ToString(sender.Encode()));

                    senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : sender.TextValue;
                }

                senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.GameData.Name;
            }
            else
            {
                senderName  = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : playerLink.PlayerName;
                senderWorld = playerLink.World.Name;
            }

            var rawMessage = message.TextValue;

            var avatarUrl   = string.Empty;
            var lodestoneId = string.Empty;

            if (!this.config.DisableEmbeds && !string.IsNullOrEmpty(senderName))
            {
                var searchResult = await GetCharacterInfo(senderName, senderWorld);

                lodestoneId = searchResult.LodestoneId;
                avatarUrl   = searchResult.AvatarUrl;
            }

            Thread.Sleep(this.config.ChatDelayMs);

            var name = wasOutgoingTell
                           ? "You"
                           : senderName + (string.IsNullOrEmpty(senderWorld) || string.IsNullOrEmpty(senderName)
                                           ? ""
                                           : $" on {senderWorld}");

            for (var chatTypeIndex = 0; chatTypeIndex < chatTypeConfigs.Count(); chatTypeIndex++)
            {
                if (!this.config.DisableEmbeds)
                {
                    var embedBuilder = new EmbedBuilder
                    {
                        Author = new EmbedAuthorBuilder
                        {
                            IconUrl = avatarUrl,
                            Name    = name,
                            Url     = !string.IsNullOrEmpty(lodestoneId) ? "https://eu.finalfantasyxiv.com/lodestone/character/" + lodestoneId : null
                        },
                        Description = rawMessage,
                        Timestamp   = DateTimeOffset.Now,
                        Footer      = new EmbedFooterBuilder {
                            Text = type.GetDetails().FancyName
                        },
                        Color = new Color((uint)(chatTypeConfigs.ElementAt(chatTypeIndex).Color & 0xFFFFFF))
                    };

                    if (this.config.CheckForDuplicateMessages)
                    {
                        var recentMsg = this.recentMessages.FirstOrDefault(
                            msg => msg.Embeds.FirstOrDefault(
                                embed => embed.Description == embedBuilder.Description &&
                                embed.Author.HasValue &&
                                embed.Author.Value.Name == embedBuilder.Author.Name &&
                                embed.Timestamp.HasValue &&
                                Math.Abs(
                                    (embed.Timestamp.Value.ToUniversalTime().Date -
                                     embedBuilder
                                     .Timestamp.Value.ToUniversalTime().Date)
                                    .Milliseconds) < 15000)
                            != null);

                        if (recentMsg != null)
                        {
                            Log.Verbose("Duplicate message: [{0}] {1}", embedBuilder.Author.Name, embedBuilder.Description);
                            this.recentMessages.Remove(recentMsg);
                            return;
                        }
                    }

                    await channels.ElementAt(chatTypeIndex).SendMessageAsync(embed: embedBuilder.Build());
                }
                else
                {
                    var simpleMessage = $"{name}: {rawMessage}";

                    if (this.config.CheckForDuplicateMessages)
                    {
                        var recentMsg = this.recentMessages.FirstOrDefault(
                            msg => msg.Content == simpleMessage);

                        if (recentMsg != null)
                        {
                            Log.Verbose("Duplicate message: {0}", simpleMessage);
                            this.recentMessages.Remove(recentMsg);
                            return;
                        }
                    }

                    await channels.ElementAt(chatTypeIndex).SendMessageAsync($"**[{chatTypeDetail.Slug}]{name}**: {rawMessage}");
                }
            }
        }
Пример #5
0
        private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender,
                                   ref SeString message, ref bool isHandled)
        {
            if (type == XivChatType.Notice && !this.hasSeenLoadingMsg)
            {
                PrintWelcomeMessage();
            }

            // For injections while logged in
            if (this.dalamud.ClientState.LocalPlayer != null && this.dalamud.ClientState.TerritoryType == 0 && !this.hasSeenLoadingMsg)
            {
                PrintWelcomeMessage();
            }

#if !DEBUG && false
            if (!this.hasSeenLoadingMsg)
            {
                return;
            }
#endif

            if (type == XivChatType.RetainerSale)
            {
                foreach (var regex in retainerSaleRegexes[dalamud.StartInfo.Language])
                {
                    var matchInfo = regex.Match(message.TextValue);

                    // we no longer really need to do/validate the item matching since we read the id from the byte array
                    // but we'd be checking the main match anyway
                    var itemInfo = matchInfo.Groups["item"];
                    if (!itemInfo.Success)
                    {
                        continue;
                    }

                    var itemLink =
                        message.Payloads.First(x => x.Type == PayloadType.Item) as ItemPayload;

                    if (itemLink == null)
                    {
                        Log.Error("itemLink was null. Msg: {0}", BitConverter.ToString(message.Encode()));
                        break;
                    }

                    Log.Debug($"Probable retainer sale: {message}, decoded item {itemLink.Item.RowId}, HQ {itemLink.IsHQ}");

                    var valueInfo = matchInfo.Groups["value"];
                    // not sure if using a culture here would work correctly, so just strip symbols instead
                    if (!valueInfo.Success || !int.TryParse(valueInfo.Value.Replace(",", "").Replace(".", ""), out var itemValue))
                    {
                        continue;
                    }

                    //Task.Run(() => this.dalamud.BotManager.ProcessRetainerSale(itemLink.Item.RowId, itemValue, itemLink.IsHQ));
                    break;
                }
            }

            var messageCopy = message;
            var senderCopy  = sender;


            // Handle all of this with SeString some day

            /*
             * if ((this.HandledChatTypeColors.ContainsKey(type) || type == XivChatType.Say || type == XivChatType.Shout ||
             *  type == XivChatType.Alliance || type == XivChatType.TellOutgoing || type == XivChatType.Yell)) {
             *  var italicsStart = message.TextValue.IndexOf("*", StringComparison.InvariantCulture);
             *  var italicsEnd = message.TextValue.IndexOf("*", italicsStart + 1, StringComparison.InvariantCulture);
             *
             *  var messageString = message.TextValue;
             *
             *  while (italicsEnd != -1) {
             *      var it = MakeItalics(
             *          messageString.Substring(italicsStart, italicsEnd - italicsStart + 1).Replace("*", ""));
             *      messageString = messageString.Remove(italicsStart, italicsEnd - italicsStart + 1);
             *      messageString = messageString.Insert(italicsStart, it);
             *      italicsStart = messageString.IndexOf("*");
             *      italicsEnd = messageString.IndexOf("*", italicsStart + 1);
             *  }
             *
             *  message.RawData = Encoding.UTF8.GetBytes(messageString);
             * }
             */

            var linkMatch = this.urlRegex.Match(message.TextValue);
            if (linkMatch.Value.Length > 0)
            {
                LastLink = linkMatch.Value;
            }
        }