private void OnCheckMessageHandled(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { if (type == XivChatType.ErrorMessage && senderId == 0) { var cmdMatch = this.currentLangCommandRegex.Match(message.TextValue).Groups["command"]; if (cmdMatch.Success) { // Yes, it's a chat command. var command = cmdMatch.Value; if (ProcessCommand(command)) { isHandled = true; } } } }
public override void PopulateData(RowParser parser, GameData gameData, Language language) { base.PopulateData(parser, gameData, language); Description = parser.ReadColumn <SeString>(0); }
private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { var payload = (sender ?? message)?.Payloads.FirstOrDefault(p => p is PlayerPayload); if (payload == null) { return; } var player = payload as PlayerPayload; // ReSharper disable PossibleNullReferenceException if (this.playerQueue.All(p => p.Key != player.PlayerName && p.Value != player.World.Name)) { this.playerQueue.Enqueue(new KeyValuePair <string, string>(player.PlayerName, player.World.Name)); } // ReSharper restore PossibleNullReferenceException }
public static void SetSeString(this Utf8String utf8String, SeString seString) { SimpleTweaksPlugin.Plugin.Common.WriteSeString(utf8String, seString); }
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; } }
public override void OnItemTooltip(TooltipTweaks.ItemTooltip tooltip, InventoryItem itemInfo) { var id = PluginInterface.Framework.Gui.HoveredItem; if (id < 2000000) { var hq = id >= 500000; id %= 500000; var item = PluginInterface.Data.Excel.GetSheet <Sheets.ExtendedItem>().GetRow((uint)id); var action = item.ItemAction?.Value; if (action != null && (action.Type == 844 || action.Type == 845 || action.Type == 846)) { var itemFood = PluginInterface.Data.Excel.GetSheet <ItemFood>().GetRow(hq ? action.DataHQ[1] : action.Data[1]); if (itemFood != null) { var payloads = new List <Payload>(); var hasChange = false; foreach (var bonus in itemFood.UnkStruct1) { if (bonus.BaseParam == 0) { continue; } var param = PluginInterface.Data.Excel.GetSheet <BaseParam>().GetRow(bonus.BaseParam); var value = hq ? bonus.ValueHQ : bonus.Value; var max = hq ? bonus.MaxHQ : bonus.Max; if (bonus.IsRelative) { hasChange = true; var currentStat = getBaseParam(playerStaticAddress, bonus.BaseParam); var relativeAdd = (short)(currentStat * (value / 100f)); var change = relativeAdd > max ? max : relativeAdd; if (payloads.Count > 0) { payloads.Add(new TextPayload("\n")); } payloads.Add(new TextPayload($"{param.Name} +")); if (PluginConfig.TooltipTweaks.FoodStatsHighlight && change < max) { payloads.Add(new UIForegroundPayload(PluginInterface.Data, 500)); } payloads.Add(new TextPayload($"{value}%")); if (change < max) { if (PluginConfig.TooltipTweaks.FoodStatsHighlight) { payloads.Add(new UIForegroundPayload(PluginInterface.Data, 0)); } payloads.Add(new TextPayload($" (Current ")); if (PluginConfig.TooltipTweaks.FoodStatsHighlight) { payloads.Add(new UIForegroundPayload(PluginInterface.Data, 500)); } payloads.Add(new TextPayload($"{change}")); if (PluginConfig.TooltipTweaks.FoodStatsHighlight) { payloads.Add(new UIForegroundPayload(PluginInterface.Data, 0)); } payloads.Add(new TextPayload($")")); } payloads.Add(new TextPayload(" (Max ")); if (PluginConfig.TooltipTweaks.FoodStatsHighlight && change == max) { payloads.Add(new UIForegroundPayload(PluginInterface.Data, 500)); } payloads.Add(new TextPayload($"{max}")); if (PluginConfig.TooltipTweaks.FoodStatsHighlight && change == max) { payloads.Add(new UIForegroundPayload(PluginInterface.Data, 0)); } payloads.Add(new TextPayload(")")); } else { if (payloads.Count > 0) { payloads.Add(new TextPayload("\n")); } payloads.Add(new TextPayload($"{param.Name} +{value}")); } } if (payloads.Count > 0 && hasChange) { var seStr = new SeString(payloads); tooltip[TooltipTweaks.ItemTooltip.TooltipField.Effects] = seStr; } } } } }
public async Task ProcessChatMessage(XivChatType type, string message, string sender) { // Special case for outgoing tells, these should be sent under Incoming tells var wasOutgoingTell = false; if (type == XivChatType.TellOutgoing) { type = XivChatType.TellIncoming; sender = this.dalamud.ClientState.LocalPlayer.Name; 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 senderSplit = sender.Split(new[] { this.worldIcon }, StringSplitOptions.None); var world = string.Empty; if (this.dalamud.ClientState.Actors.Length > 0) { world = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Name; } if (senderSplit.Length == 2) { world = senderSplit[1]; sender = senderSplit[0]; } sender = SeString.Parse(sender).Output; message = SeString.Parse(message).Output; sender = RemoveAllNonLanguageCharacters(sender); var avatarUrl = ""; var lodestoneId = ""; if (!this.config.DisableEmbeds) { var searchResult = await GetCharacterInfo(sender, world); lodestoneId = searchResult.LodestoneId; avatarUrl = searchResult.AvatarUrl; } Thread.Sleep(this.config.ChatDelayMs); var name = wasOutgoingTell ? "You" : sender + (string.IsNullOrEmpty(world) || string.IsNullOrEmpty(sender) ? "" : $" on {world}"); 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 = message, 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}: {message}"; 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}**: {message}"); } } }
private void ChatOnOnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { foreach (var payload in message.Payloads) { if (payload is TextPayload textPayload) { textPayload.Text = LeetSpeakify(textPayload.Text); } } }
private SeString Tran(SeString messageSeString) { var cleanMessage = new SeString(new List <Payload>()); cleanMessage.Append(messageSeString); var originalMessage = new SeString(new List <Payload>()); originalMessage.Append(messageSeString); var run = true; if (messageSeString.Payloads.Count < 2) { } else if (messageSeString.Payloads[0] == new UIForegroundPayload(_pluginInterface.Data, 48) && messageSeString.Payloads[1] == new UIForegroundPayload(_pluginInterface.Data, 0)) { PluginLog.Log("Caught loop B"); run = false; } if (!run) { return(messageSeString); } var tranDone = false; for (var i = 0; i < messageSeString.Payloads.Count; i++) { if (messageSeString.Payloads[i].Type == PayloadType.MapLink || messageSeString.Payloads[i].Type == PayloadType.Item || messageSeString.Payloads[i].Type == PayloadType.Quest) { i += 7; continue; } if (messageSeString.Payloads[i].Type == PayloadType.Player) { i += 2; continue; } if (messageSeString.Payloads[i].Type == PayloadType.Status) { i += 10; continue; } if (messageSeString.Payloads[i].Type != PayloadType.RawText) { continue; } //PluginLog.Log("Type PASS"); var text = (TextPayload)messageSeString.Payloads[i]; var translatedText = Translate(text.Text); if (translatedText == "LOOP") { continue; } messageSeString.Payloads[i] = new TextPayload(translatedText); messageSeString.Payloads.Insert(i, new UIForegroundPayload(_pluginInterface.Data, (ushort)_textColour[0].Option)); messageSeString.Payloads.Insert(i, new UIForegroundPayload(_pluginInterface.Data, 0)); if (i + 3 < messageSeString.Payloads.Count) { messageSeString.Payloads.Insert(i + 3, new UIForegroundPayload(_pluginInterface.Data, 0)); } else { messageSeString.Payloads.Append(new UIForegroundPayload(_pluginInterface.Data, 0)); } i += 2; tranDone = true; } if (!tranDone) { return(messageSeString); } // Adding to the rolling "last translation" list _lastTranslations.Insert(0, cleanMessage.TextValue); if (_lastTranslations.Count > 10) { _lastTranslations.RemoveAt(10); } if (_tranMode == 0) // Append { var tranMessage = new SeString(new List <Payload>()); tranMessage.Payloads.Add(new TextPayload(" | ")); //originalMessage.Payloads.Insert(0, new UIForegroundPayload(_pluginInterface.Data, 0)); //originalMessage.Payloads.Insert(0, new UIForegroundPayload(_pluginInterface.Data, 48)); originalMessage.Append(tranMessage); originalMessage.Append(messageSeString); return(originalMessage); //PrintChat(type, senderName, originalMessage); } return(messageSeString); }
private unsafe void ShowItemLevel(bool reset = false) { SimpleLog.Log("Add ItemLevel to CharacterInspect"); try { if (examineIsValidPtr == IntPtr.Zero) { return; } if (*(byte *)(examineIsValidPtr + 0x2A8) == 0) { return; } var container = Common.GetContainer(InventoryType.Examine); if (container == null) { return; } var examineWindow = (AddonCharacterInspect *)Common.GetUnitBase("CharacterInspect"); if (examineWindow == null) { return; } var compInfo = (ULDComponentInfo *)examineWindow->PreviewComponent->UldManager.Objects; if (compInfo == null || compInfo->ComponentType != ComponentType.Preview) { return; } if (examineWindow->PreviewComponent->UldManager.NodeListCount < 4) { return; } if (reset) { examineWindow->PreviewComponent->UldManager.NodeListCount = 4; return; } var nodeList = examineWindow->PreviewComponent->UldManager.NodeList; var node = nodeList[3]; var textNode = UiAdjustments.CloneNode((AtkTextNode *)node); var inaccurate = false; var sum = 0U; var c = 13; for (var i = 0; i < 13; i++) { var slot = Common.GetContainerItem(container, i); if (slot == null) { continue; } var id = slot->ItemId; var item = PluginInterface.Data.Excel.GetSheet <Sheets.ExtendedItem>().GetRow(id); if (ignoreCategory.Contains(item.ItemUICategory.Row)) { if (i == 0) { c -= 1; } c -= 1; continue; } if ((item.LevelSyncFlag & 2) == 2) { inaccurate = true; } if (i == 0 && !canHaveOffhand.Contains(item.ItemUICategory.Row)) { sum += item.LevelItem.Row; i++; } sum += item.LevelItem.Row; } var avgItemLevel = sum / c; var seStr = new SeString(new List <Payload>() { new TextPayload($"{avgItemLevel:0000}"), }); Plugin.Common.WriteSeString((byte *)allocText, seStr); textNode->NodeText.StringPtr = (byte *)allocText; textNode->FontSize = 14; textNode->AlignmentFontType = 37; textNode->FontSize = 16; textNode->CharSpacing = 0; textNode->LineSpacing = 24; textNode->TextColor = new ByteColor() { R = (byte)(inaccurate ? 0xFF : 0x45), G = (byte)(inaccurate ? (byte)0x83 : (byte)0xB2), B = (byte)(inaccurate ? 0x75 : 0xAE), A = 0xFF }; textNode->AtkResNode.Height = 24; textNode->AtkResNode.Width = 80; textNode->AtkResNode.Flags |= 0x10; textNode->AtkResNode.Y = 0; textNode->AtkResNode.X = 92; textNode->AtkResNode.Flags_2 |= 0x1; var a = UiAdjustments.CopyNodeList(examineWindow->PreviewComponent->UldManager.NodeList, examineWindow->PreviewComponent->UldManager.NodeListCount, (ushort)(examineWindow->PreviewComponent->UldManager.NodeListCount + 5)); examineWindow->PreviewComponent->UldManager.NodeList = a; examineWindow->PreviewComponent->UldManager.NodeList[examineWindow->PreviewComponent->UldManager.NodeListCount++] = (AtkResNode *)textNode; if (PluginConfig.UiAdjustments.ExamineItemLevel.ShowItemLevelIcon) { var iconNode = (AtkImageNode *)UiAdjustments.CloneNode(examineWindow->AtkUnitBase.UldManager.NodeList[8]); iconNode->PartId = 47; iconNode->PartsList->Parts[47].Height = 24; iconNode->PartsList->Parts[47].Width = 24; iconNode->PartsList->Parts[47].U = 176; iconNode->PartsList->Parts[47].V = 138; iconNode->AtkResNode.Height = 24; iconNode->AtkResNode.Width = 24; iconNode->AtkResNode.X = textNode->AtkResNode.X + 2; iconNode->AtkResNode.Y = textNode->AtkResNode.Y + 3; iconNode->AtkResNode.Flags |= 0x10; // Visible iconNode->AtkResNode.Flags_2 |= 0x1; // Update iconNode->AtkResNode.ParentNode = textNode->AtkResNode.ParentNode; iconNode->AtkResNode.PrevSiblingNode = textNode->AtkResNode.PrevSiblingNode; if (iconNode->AtkResNode.PrevSiblingNode != null) { iconNode->AtkResNode.PrevSiblingNode->NextSiblingNode = (AtkResNode *)iconNode; } iconNode->AtkResNode.NextSiblingNode = (AtkResNode *)textNode; textNode->AtkResNode.PrevSiblingNode = (AtkResNode *)iconNode; examineWindow->PreviewComponent->UldManager.NodeList[examineWindow->PreviewComponent->UldManager.NodeListCount++] = (AtkResNode *)iconNode; } } catch (Exception ex) { SimpleLog.Log(ex); Plugin.Error(this, ex, true); } }
public override void PopulateData(RowParser parser, GameData gameData, Language language) { base.PopulateData(parser, gameData, language); Name = parser.ReadColumn <SeString>(0); Id = parser.ReadColumn <SeString>(1); Expansion = new LazyRow <ExVersion>(gameData, parser.ReadColumn <byte>(2), language); ClassJobCategory0 = new LazyRow <ClassJobCategory>(gameData, parser.ReadColumn <byte>(3), language); ClassJobLevel0 = parser.ReadColumn <ushort>(4); QuestLevelOffset = parser.ReadColumn <byte>(5); ClassJobCategory1 = new LazyRow <ClassJobCategory>(gameData, parser.ReadColumn <byte>(6), language); ClassJobLevel1 = parser.ReadColumn <ushort>(7); PreviousQuestJoin = parser.ReadColumn <byte>(8); PreviousQuest0 = new LazyRow <Quest>(gameData, parser.ReadColumn <uint>(9), language); Unknown10 = parser.ReadColumn <byte>(10); PreviousQuest1 = new LazyRow <Quest>(gameData, parser.ReadColumn <uint>(11), language); PreviousQuest2 = new LazyRow <Quest>(gameData, parser.ReadColumn <uint>(12), language); QuestLockJoin = parser.ReadColumn <byte>(13); QuestLock = new LazyRow <Quest> [2]; for (var i = 0; i < 2; i++) { QuestLock[i] = new LazyRow <Quest>(gameData, parser.ReadColumn <uint>(14 + i), language); } Header = parser.ReadColumn <ushort>(16); Unknown17 = parser.ReadColumn <byte>(17); Unknown18 = parser.ReadColumn <byte>(18); ClassJobUnlock = new LazyRow <ClassJob>(gameData, parser.ReadColumn <byte>(19), language); GrandCompany = new LazyRow <GrandCompany>(gameData, parser.ReadColumn <byte>(20), language); GrandCompanyRank = new LazyRow <GrandCompanyRank>(gameData, parser.ReadColumn <byte>(21), language); InstanceContentJoin = parser.ReadColumn <byte>(22); InstanceContent = new LazyRow <InstanceContent> [3]; for (var i = 0; i < 3; i++) { InstanceContent[i] = new LazyRow <InstanceContent>(gameData, parser.ReadColumn <uint>(23 + i), language); } Festival = new LazyRow <Festival>(gameData, parser.ReadColumn <byte>(26), language); FestivalBegin = parser.ReadColumn <byte>(27); FestivalEnd = parser.ReadColumn <byte>(28); BellStart = parser.ReadColumn <ushort>(29); BellEnd = parser.ReadColumn <ushort>(30); BeastTribe = new LazyRow <BeastTribe>(gameData, parser.ReadColumn <byte>(31), language); BeastReputationRank = new LazyRow <BeastReputationRank>(gameData, parser.ReadColumn <byte>(32), language); BeastReputationValue = parser.ReadColumn <ushort>(33); Unknown34 = parser.ReadColumn <byte>(34); Unknown35 = parser.ReadColumn <byte>(35); MountRequired = new LazyRow <Mount>(gameData, parser.ReadColumn <int>(36), language); IsHouseRequired = parser.ReadColumn <bool>(37); DeliveryQuest = new LazyRow <DeliveryQuest>(gameData, parser.ReadColumn <byte>(38), language); IssuerStart = parser.ReadColumn <uint>(39); IssuerLocation = new LazyRow <Level>(gameData, parser.ReadColumn <uint>(40), language); ClientBehavior = new LazyRow <Behavior>(gameData, parser.ReadColumn <ushort>(41), language); TargetEnd = parser.ReadColumn <uint>(42); IsRepeatable = parser.ReadColumn <bool>(43); RepeatIntervalType = parser.ReadColumn <byte>(44); QuestRepeatFlag = new LazyRow <QuestRepeatFlag>(gameData, parser.ReadColumn <byte>(45), language); CanCancel = parser.ReadColumn <bool>(46); Type = parser.ReadColumn <byte>(47); QuestClassJobSupply = new LazyRow <QuestClassJobSupply>(gameData, parser.ReadColumn <ushort>(48), language); ScriptInstruction = new SeString[50]; for (var i = 0; i < 50; i++) { ScriptInstruction[i] = parser.ReadColumn <SeString>(49 + i); } ScriptArg = new uint[50]; for (var i = 0; i < 50; i++) { ScriptArg[i] = parser.ReadColumn <uint>(99 + i); } ActorSpawnSeq = new byte[64]; for (var i = 0; i < 64; i++) { ActorSpawnSeq[i] = parser.ReadColumn <byte>(149 + i); } ActorDespawnSeq = new byte[64]; for (var i = 0; i < 64; i++) { ActorDespawnSeq[i] = parser.ReadColumn <byte>(213 + i); } Listener = new uint[64]; for (var i = 0; i < 64; i++) { Listener[i] = parser.ReadColumn <uint>(277 + i); } QuestUInt8A = new byte[32]; for (var i = 0; i < 32; i++) { QuestUInt8A[i] = parser.ReadColumn <byte>(341 + i); } QuestUInt8B = new byte[32]; for (var i = 0; i < 32; i++) { QuestUInt8B[i] = parser.ReadColumn <byte>(373 + i); } ConditionType = new byte[64]; for (var i = 0; i < 64; i++) { ConditionType[i] = parser.ReadColumn <byte>(405 + i); } ConditionValue = new uint[64]; for (var i = 0; i < 64; i++) { ConditionValue[i] = parser.ReadColumn <uint>(469 + i); } ConditionOperator = new byte[64]; for (var i = 0; i < 64; i++) { ConditionOperator[i] = parser.ReadColumn <byte>(533 + i); } Behavior = new ushort[64]; for (var i = 0; i < 64; i++) { Behavior[i] = parser.ReadColumn <ushort>(597 + i); } VisibleBool = new bool[64]; for (var i = 0; i < 64; i++) { VisibleBool[i] = parser.ReadColumn <bool>(661 + i); } ConditionBool = new bool[64]; for (var i = 0; i < 64; i++) { ConditionBool[i] = parser.ReadColumn <bool>(725 + i); } ItemBool = new bool[64]; for (var i = 0; i < 64; i++) { ItemBool[i] = parser.ReadColumn <bool>(789 + i); } AnnounceBool = new bool[64]; for (var i = 0; i < 64; i++) { AnnounceBool[i] = parser.ReadColumn <bool>(853 + i); } BehaviorBool = new bool[64]; for (var i = 0; i < 64; i++) { BehaviorBool[i] = parser.ReadColumn <bool>(917 + i); } AcceptBool = new bool[64]; for (var i = 0; i < 64; i++) { AcceptBool[i] = parser.ReadColumn <bool>(981 + i); } QualifiedBool = new bool[64]; for (var i = 0; i < 64; i++) { QualifiedBool[i] = parser.ReadColumn <bool>(1045 + i); } CanTargetBool = new bool[64]; for (var i = 0; i < 64; i++) { CanTargetBool[i] = parser.ReadColumn <bool>(1109 + i); } ToDoCompleteSeq = new byte[24]; for (var i = 0; i < 24; i++) { ToDoCompleteSeq[i] = parser.ReadColumn <byte>(1173 + i); } ToDoQty = new byte[24]; for (var i = 0; i < 24; i++) { ToDoQty[i] = parser.ReadColumn <byte>(1197 + i); } ToDoMainLocation = new LazyRow <Level> [24]; for (var i = 0; i < 24; i++) { ToDoMainLocation[i] = new LazyRow <Level>(gameData, parser.ReadColumn <uint>(1221 + i), language); } Unknown1245 = new uint[7]; for (var i = 0; i < 7; i++) { Unknown1245[i] = parser.ReadColumn <uint>(1245 + i); } Unknown1252 = parser.ReadColumn <uint>(1252); Unknown1253 = parser.ReadColumn <uint>(1253); Unknown1254 = parser.ReadColumn <uint>(1254); Unknown1255 = parser.ReadColumn <uint>(1255); Unknown1256 = parser.ReadColumn <uint>(1256); Unknown1257 = parser.ReadColumn <uint>(1257); Unknown1258 = parser.ReadColumn <uint>(1258); Unknown1259 = parser.ReadColumn <uint>(1259); Unknown1260 = parser.ReadColumn <uint>(1260); Unknown1261 = parser.ReadColumn <uint>(1261); Unknown1262 = parser.ReadColumn <uint>(1262); Unknown1263 = parser.ReadColumn <uint>(1263); Unknown1264 = parser.ReadColumn <uint>(1264); Unknown1265 = parser.ReadColumn <uint>(1265); Unknown1266 = parser.ReadColumn <uint>(1266); Unknown1267 = parser.ReadColumn <uint>(1267); Unknown1268 = parser.ReadColumn <uint>(1268); Unknown1269 = parser.ReadColumn <uint>(1269); Unknown1270 = parser.ReadColumn <uint>(1270); Unknown1271 = parser.ReadColumn <uint>(1271); Unknown1272 = parser.ReadColumn <uint>(1272); Unknown1273 = parser.ReadColumn <uint>(1273); Unknown1274 = parser.ReadColumn <uint>(1274); Unknown1275 = parser.ReadColumn <uint>(1275); Unknown1276 = parser.ReadColumn <uint>(1276); Unknown1277 = parser.ReadColumn <uint>(1277); Unknown1278 = parser.ReadColumn <uint>(1278); Unknown1279 = parser.ReadColumn <uint>(1279); Unknown1280 = parser.ReadColumn <uint>(1280); Unknown1281 = parser.ReadColumn <uint>(1281); Unknown1282 = parser.ReadColumn <uint>(1282); Unknown1283 = parser.ReadColumn <uint>(1283); Unknown1284 = parser.ReadColumn <uint>(1284); Unknown1285 = parser.ReadColumn <uint>(1285); Unknown1286 = parser.ReadColumn <uint>(1286); Unknown1287 = parser.ReadColumn <uint>(1287); Unknown1288 = parser.ReadColumn <uint>(1288); Unknown1289 = parser.ReadColumn <uint>(1289); Unknown1290 = parser.ReadColumn <uint>(1290); Unknown1291 = parser.ReadColumn <uint>(1291); Unknown1292 = parser.ReadColumn <uint>(1292); Unknown1293 = parser.ReadColumn <uint>(1293); Unknown1294 = parser.ReadColumn <uint>(1294); Unknown1295 = parser.ReadColumn <uint>(1295); Unknown1296 = parser.ReadColumn <uint>(1296); Unknown1297 = parser.ReadColumn <uint>(1297); Unknown1298 = parser.ReadColumn <uint>(1298); Unknown1299 = parser.ReadColumn <uint>(1299); Unknown1300 = parser.ReadColumn <uint>(1300); Unknown1301 = parser.ReadColumn <uint>(1301); Unknown1302 = parser.ReadColumn <uint>(1302); Unknown1303 = parser.ReadColumn <uint>(1303); Unknown1304 = parser.ReadColumn <uint>(1304); Unknown1305 = parser.ReadColumn <uint>(1305); Unknown1306 = parser.ReadColumn <uint>(1306); Unknown1307 = parser.ReadColumn <uint>(1307); Unknown1308 = parser.ReadColumn <uint>(1308); Unknown1309 = parser.ReadColumn <uint>(1309); Unknown1310 = parser.ReadColumn <uint>(1310); Unknown1311 = parser.ReadColumn <uint>(1311); Unknown1312 = parser.ReadColumn <uint>(1312); Unknown1313 = parser.ReadColumn <uint>(1313); Unknown1314 = parser.ReadColumn <uint>(1314); Unknown1315 = parser.ReadColumn <uint>(1315); Unknown1316 = parser.ReadColumn <uint>(1316); Unknown1317 = parser.ReadColumn <uint>(1317); Unknown1318 = parser.ReadColumn <uint>(1318); Unknown1319 = parser.ReadColumn <uint>(1319); Unknown1320 = parser.ReadColumn <uint>(1320); Unknown1321 = parser.ReadColumn <uint>(1321); Unknown1322 = parser.ReadColumn <uint>(1322); Unknown1323 = parser.ReadColumn <uint>(1323); Unknown1324 = parser.ReadColumn <uint>(1324); Unknown1325 = parser.ReadColumn <uint>(1325); Unknown1326 = parser.ReadColumn <uint>(1326); Unknown1327 = parser.ReadColumn <uint>(1327); Unknown1328 = parser.ReadColumn <uint>(1328); Unknown1329 = parser.ReadColumn <uint>(1329); Unknown1330 = parser.ReadColumn <uint>(1330); Unknown1331 = parser.ReadColumn <uint>(1331); Unknown1332 = parser.ReadColumn <uint>(1332); Unknown1333 = parser.ReadColumn <uint>(1333); Unknown1334 = parser.ReadColumn <uint>(1334); Unknown1335 = parser.ReadColumn <uint>(1335); Unknown1336 = parser.ReadColumn <uint>(1336); Unknown1337 = parser.ReadColumn <uint>(1337); Unknown1338 = parser.ReadColumn <uint>(1338); Unknown1339 = parser.ReadColumn <uint>(1339); Unknown1340 = parser.ReadColumn <uint>(1340); Unknown1341 = parser.ReadColumn <uint>(1341); Unknown1342 = parser.ReadColumn <uint>(1342); Unknown1343 = parser.ReadColumn <uint>(1343); Unknown1344 = parser.ReadColumn <uint>(1344); Unknown1345 = parser.ReadColumn <uint>(1345); Unknown1346 = parser.ReadColumn <uint>(1346); Unknown1347 = parser.ReadColumn <uint>(1347); Unknown1348 = parser.ReadColumn <uint>(1348); Unknown1349 = parser.ReadColumn <uint>(1349); Unknown1350 = parser.ReadColumn <uint>(1350); Unknown1351 = parser.ReadColumn <uint>(1351); Unknown1352 = parser.ReadColumn <uint>(1352); Unknown1353 = parser.ReadColumn <uint>(1353); Unknown1354 = parser.ReadColumn <uint>(1354); Unknown1355 = parser.ReadColumn <uint>(1355); Unknown1356 = parser.ReadColumn <uint>(1356); Unknown1357 = parser.ReadColumn <uint>(1357); Unknown1358 = parser.ReadColumn <uint>(1358); Unknown1359 = parser.ReadColumn <uint>(1359); Unknown1360 = parser.ReadColumn <uint>(1360); Unknown1361 = parser.ReadColumn <uint>(1361); Unknown1362 = parser.ReadColumn <uint>(1362); Unknown1363 = parser.ReadColumn <uint>(1363); Unknown1364 = parser.ReadColumn <uint>(1364); Unknown1365 = parser.ReadColumn <uint>(1365); Unknown1366 = parser.ReadColumn <uint>(1366); Unknown1367 = parser.ReadColumn <uint>(1367); Unknown1368 = parser.ReadColumn <uint>(1368); Unknown1369 = parser.ReadColumn <uint>(1369); Unknown1370 = parser.ReadColumn <uint>(1370); Unknown1371 = parser.ReadColumn <uint>(1371); Unknown1372 = parser.ReadColumn <uint>(1372); Unknown1373 = parser.ReadColumn <uint>(1373); Unknown1374 = parser.ReadColumn <uint>(1374); Unknown1375 = parser.ReadColumn <uint>(1375); Unknown1376 = parser.ReadColumn <uint>(1376); Unknown1377 = parser.ReadColumn <uint>(1377); Unknown1378 = parser.ReadColumn <uint>(1378); Unknown1379 = parser.ReadColumn <uint>(1379); Unknown1380 = parser.ReadColumn <uint>(1380); Unknown1381 = parser.ReadColumn <uint>(1381); Unknown1382 = parser.ReadColumn <uint>(1382); Unknown1383 = parser.ReadColumn <uint>(1383); Unknown1384 = parser.ReadColumn <uint>(1384); Unknown1385 = parser.ReadColumn <uint>(1385); Unknown1386 = parser.ReadColumn <uint>(1386); Unknown1387 = parser.ReadColumn <uint>(1387); Unknown1388 = parser.ReadColumn <uint>(1388); Unknown1389 = parser.ReadColumn <uint>(1389); Unknown1390 = parser.ReadColumn <uint>(1390); Unknown1391 = parser.ReadColumn <uint>(1391); Unknown1392 = parser.ReadColumn <uint>(1392); Unknown1393 = parser.ReadColumn <uint>(1393); Unknown1394 = parser.ReadColumn <uint>(1394); Unknown1395 = parser.ReadColumn <uint>(1395); Unknown1396 = parser.ReadColumn <uint>(1396); Unknown1397 = parser.ReadColumn <uint>(1397); Unknown1398 = parser.ReadColumn <uint>(1398); Unknown1399 = parser.ReadColumn <uint>(1399); Unknown1400 = parser.ReadColumn <uint>(1400); Unknown1401 = parser.ReadColumn <uint>(1401); Unknown1402 = parser.ReadColumn <uint>(1402); Unknown1403 = parser.ReadColumn <uint>(1403); Unknown1404 = parser.ReadColumn <uint>(1404); Unknown1405 = parser.ReadColumn <uint>(1405); Unknown1406 = parser.ReadColumn <uint>(1406); Unknown1407 = parser.ReadColumn <uint>(1407); Unknown1408 = parser.ReadColumn <uint>(1408); Unknown1409 = parser.ReadColumn <uint>(1409); Unknown1410 = parser.ReadColumn <uint>(1410); Unknown1411 = parser.ReadColumn <uint>(1411); Unknown1412 = parser.ReadColumn <uint>(1412); CountableNum = new byte[24]; for (var i = 0; i < 24; i++) { CountableNum[i] = parser.ReadColumn <byte>(1413 + i); } LevelMax = parser.ReadColumn <byte>(1437); ClassJobRequired = new LazyRow <ClassJob>(gameData, parser.ReadColumn <byte>(1438), language); Unknown1439 = parser.ReadColumn <byte>(1439); ExpFactor = parser.ReadColumn <ushort>(1440); GilReward = parser.ReadColumn <uint>(1441); Unknown1442 = parser.ReadColumn <uint>(1442); GCSeals = parser.ReadColumn <uint>(1443); ItemCatalyst = new LazyRow <Item> [3]; for (var i = 0; i < 3; i++) { ItemCatalyst[i] = new LazyRow <Item>(gameData, parser.ReadColumn <byte>(1444 + i), language); } ItemCountCatalyst = new byte[3]; for (var i = 0; i < 3; i++) { ItemCountCatalyst[i] = parser.ReadColumn <byte>(1447 + i); } ItemRewardType = parser.ReadColumn <byte>(1450); ItemReward0 = new uint[7]; for (var i = 0; i < 7; i++) { ItemReward0[i] = parser.ReadColumn <uint>(1451 + i); } ItemCountReward0 = new byte[6]; for (var i = 0; i < 6; i++) { ItemCountReward0[i] = parser.ReadColumn <byte>(1458 + i); } Unknown1464 = parser.ReadColumn <byte>(1464); StainReward0 = new LazyRow <Stain> [6]; for (var i = 0; i < 6; i++) { StainReward0[i] = new LazyRow <Stain>(gameData, parser.ReadColumn <byte>(1465 + i), language); } Unknown1471 = parser.ReadColumn <byte>(1471); ItemReward1 = new LazyRow <Item> [5]; for (var i = 0; i < 5; i++) { ItemReward1[i] = new LazyRow <Item>(gameData, parser.ReadColumn <uint>(1472 + i), language); } ItemCountReward1 = new byte[5]; for (var i = 0; i < 5; i++) { ItemCountReward1[i] = parser.ReadColumn <byte>(1477 + i); } IsHQReward1 = new bool[5]; for (var i = 0; i < 5; i++) { IsHQReward1[i] = parser.ReadColumn <bool>(1482 + i); } StainReward1 = new LazyRow <Stain> [5]; for (var i = 0; i < 5; i++) { StainReward1[i] = new LazyRow <Stain>(gameData, parser.ReadColumn <byte>(1487 + i), language); } EmoteReward = new LazyRow <Emote>(gameData, parser.ReadColumn <byte>(1492), language); ActionReward = new LazyRow <Action>(gameData, parser.ReadColumn <ushort>(1493), language); GeneralActionReward = new LazyRow <GeneralAction> [2]; for (var i = 0; i < 2; i++) { GeneralActionReward[i] = new LazyRow <GeneralAction>(gameData, parser.ReadColumn <byte>(1494 + i), language); } SystemReward0 = new LazyRow <Action>(gameData, parser.ReadColumn <ushort>(1496), language); OtherReward = new LazyRow <QuestRewardOther>(gameData, parser.ReadColumn <byte>(1497), language); SystemReward1 = new LazyRow <Action>(gameData, parser.ReadColumn <ushort>(1498), language); GCTypeReward = new LazyRow <Action>(gameData, parser.ReadColumn <ushort>(1499), language); InstanceContentUnlock = new LazyRow <InstanceContent>(gameData, parser.ReadColumn <uint>(1500), language); Unknown1501 = parser.ReadColumn <byte>(1501); TomestoneReward = parser.ReadColumn <byte>(1502); TomestoneCountReward = parser.ReadColumn <byte>(1503); ReputationReward = parser.ReadColumn <byte>(1504); PlaceName = new LazyRow <PlaceName>(gameData, parser.ReadColumn <ushort>(1505), language); JournalGenre = new LazyRow <JournalGenre>(gameData, parser.ReadColumn <byte>(1506), language); Unknown1507 = parser.ReadColumn <byte>(1507); Icon = parser.ReadColumn <uint>(1508); IconSpecial = parser.ReadColumn <uint>(1509); Introduction = parser.ReadColumn <bool>(1510); HideOfferIcon = parser.ReadColumn <bool>(1511); EventIconType = new LazyRow <EventIconType>(gameData, parser.ReadColumn <byte>(1512), language); Unknown1513 = parser.ReadColumn <byte>(1513); SortKey = parser.ReadColumn <ushort>(1514); Unknown1515 = parser.ReadColumn <bool>(1515); }
public void PopulateData(RowParser parser, Lumina lumina, Language language) { RowId = parser.Row; SubRowId = parser.SubRow; RequiredFlag = parser.ReadColumn <byte>(0); UnlockFlag = parser.ReadColumn <byte>(1); RequiredLevel = parser.ReadColumn <byte>(2); RequiredSeals = parser.ReadColumn <ushort>(3); RewardExperience = parser.ReadColumn <uint>(4); PercentBase = parser.ReadColumn <byte>(5); Unknown6 = parser.ReadColumn <byte>(6); GcArmyExpeditionType = new LazyRow <GcArmyExpeditionType>(lumina, parser.ReadColumn <byte>(7), language); Name = parser.ReadColumn <SeString>(8); Description = parser.ReadColumn <SeString>(9); UnkStruct10 = new UnkStruct10Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct10[i] = new UnkStruct10Struct(); UnkStruct10[i].RewardItem = parser.ReadColumn <int>(10 + (i * 1 + 0)); } UnkStruct16 = new UnkStruct16Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct16[i] = new UnkStruct16Struct(); UnkStruct16[i].RewardQuantity = parser.ReadColumn <byte>(16 + (i * 1 + 0)); } UnkStruct22 = new UnkStruct22Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct22[i] = new UnkStruct22Struct(); UnkStruct22[i].RequiredPhysical = parser.ReadColumn <ushort>(22 + (i * 1 + 0)); } UnkStruct28 = new UnkStruct28Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct28[i] = new UnkStruct28Struct(); UnkStruct28[i].PercentPhysicalMet = parser.ReadColumn <byte>(28 + (i * 1 + 0)); } UnkStruct34 = new UnkStruct34Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct34[i] = new UnkStruct34Struct(); UnkStruct34[i].RequiredMental = parser.ReadColumn <ushort>(34 + (i * 1 + 0)); } UnkStruct40 = new UnkStruct40Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct40[i] = new UnkStruct40Struct(); UnkStruct40[i].PercentMentalMet = parser.ReadColumn <byte>(40 + (i * 1 + 0)); } UnkStruct46 = new UnkStruct46Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct46[i] = new UnkStruct46Struct(); UnkStruct46[i].RequiredTactical = parser.ReadColumn <ushort>(46 + (i * 1 + 0)); } UnkStruct52 = new UnkStruct52Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct52[i] = new UnkStruct52Struct(); UnkStruct52[i].PercentTacticalMet = parser.ReadColumn <byte>(52 + (i * 1 + 0)); } UnkStruct58 = new UnkStruct58Struct[6]; for (var i = 0; i < 6; i++) { UnkStruct58[i] = new UnkStruct58Struct(); UnkStruct58[i].PercentAllMet = parser.ReadColumn <byte>(58 + (i * 1 + 0)); } }
private void Chat_OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { try { if (!isHandled) { var senderName = sender.TextValue; List <Payload> payloads = message.Payloads; int chan = ConvertForArray(type.ToString()); ChatText tmp = new ChatText(); tmp.Time = GetTime(); tmp.DateTime = DateTime.Now; tmp.ChannelShort = GetChannelName(type.ToString()); tmp.SenderId = senderId; //PluginLog.Log(senderId.ToString()); //PluginLog.Log(senderName); try { tmp.Channel = Channels[chan].Trim().Replace(" ", ""); } catch (Exception) { tmp.Channel = chan.ToString(); } tmp.Sender = senderName; tmp.ChannelColour = ConvertForArray(type.ToString()); List <TextTypes> rawtext = new List <TextTypes>(); int replace = 0; Payload payloader = null; PayloadType payloadType = PayloadType.RawText; //Handling Emotes if (tmp.Channel == "StandardEmote") { tmp.Sender = ""; } if (tmp.Channel == "CustomEmote") { tmp.Sender = ""; TextTypes wrangle = new TextTypes(); wrangle.Type = PayloadType.RawText; wrangle.Text = senderName; rawtext.Add(wrangle); } //Handling Tells if (tmp.Channel == "TellOutgoing") { TextTypes wrangle = new TextTypes(); wrangle.Type = PayloadType.RawText; wrangle.Text = ">>" + tmp.Sender + ":"; rawtext.Add(wrangle); tmp.Sender = pluginInterface.ClientState.LocalPlayer.Name.ToString(); } if (tmp.Channel == "TellIncoming") { TextTypes wrangle = new TextTypes(); wrangle.Type = PayloadType.RawText; wrangle.Text = ">>"; rawtext.Add(wrangle); } foreach (var payload in payloads) { if (payload.Type == PayloadType.MapLink) { replace = 2; payloadType = PayloadType.MapLink; payloader = payload; } if (payload.Type == PayloadType.RawText) { TextTypes wrangler = new TextTypes(); wrangler.Text = payload.ToString().Split(new[] { ' ' }, 4)[3]; if (replace == 1) { if (payloadType == PayloadType.MapLink) { rawtext.RemoveAt(rawtext.Count - 1); wrangler.Payload = payloader; } } if (replace == 0) { payloadType = PayloadType.RawText; } wrangler.Type = payloadType; rawtext.Add(wrangler); if (replace > 0) { replace--; } } } tmp.Text = rawtext; if (System.Text.RegularExpressions.Regex.Match(tmp.Sender, "^[-]").Success) { tmp.Sender = tmp.Sender.Substring(1); } if (bubbleEnable[chan]) { ChatBubbleAdd(tmp); } foreach (var tab in items) { if (chan < Channels.Length && tab.Logs[chan]) { tab.Chat.Enqueue(tmp); tab.msg = true; if (tab.Chat.Count > 256) { tab.Chat.TryDequeue(out ChatText pop); } if (tab.Config[3]) { //Writing to file string filename = GetDate() + "_" + tab.Title + ".txt"; if (!System.IO.Directory.Exists(pathString)) { System.IO.Directory.CreateDirectory(pathString); } if (!System.IO.File.Exists(pathString + filename)) { System.IO.File.WriteAllText(pathString + filename, tab.Title + "\n"); } using (System.IO.StreamWriter file = new System.IO.StreamWriter(pathString + filename, true)) { file.WriteLine(tmp.Time + "[" + tmp.Channel + "]" + "<" + tmp.Sender + ">:" + TextTypesToString(rawtext)); } } if (tab.AutoScroll == true) { tab.Scroll = true; } } else { } //PluginLog.Log("[" + chan.ToString() + "] " + message.TextValue); } if (allowTranslation) { String messageString = message.TextValue; String predictedLanguage = Lang(messageString); if (predictedLanguage == language) { Task.Run(() => Tran(type, messageString, senderName)); } } } } catch (Exception e) { PluginLog.LogError(e.ToString()); } }
private void OnChatMessageHandled(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { // check if enabled if (!Configuration.Enabled) { return; } // log for debugging if (Configuration.DebugLoggingEnabled) { LogInfo("[ChatMessage]" + type + ":" + message); } // combat check if (Configuration.RestrictInCombat && InCombat()) { return; } // lookup territory and content var xivChatType = (ushort)type; var territoryTypeId = GetTerritoryType(); var contentId = GetContentId(territoryTypeId); // update content InContent = contentId != 0; // restrict by user settings if (Configuration.RestrictToContent && contentId == 0) { return; } if (Configuration.RestrictToHighEndDuty && !IsHighEndDuty(contentId)) { return; } if (Configuration.RestrictToCustomContent && !Configuration.PermittedContent.Contains(contentId)) { return; } // filter out bad messages if (!Enum.IsDefined(typeof(LootMessageType), xivChatType)) { return; } if (!message.Payloads.Any(payload => payload is ItemPayload)) { return; } var logKind = (LogKind)((uint)type & ~(~0 << 7)); if (!Enum.IsDefined(typeof(LogKind), logKind)) { return; } // build initial loot message var lootMessage = new LootMessage { XivChatType = xivChatType, LogKind = logKind, LootMessageType = (LootMessageType)xivChatType, Message = message.TextValue }; // add name fields for logging/display lootMessage.LogKindName = Enum.GetName(typeof(LogKind), lootMessage.LogKind); lootMessage.LootMessageTypeName = Enum.GetName(typeof(LootMessageType), lootMessage.LootMessageType); // add item and message part payloads foreach (var payload in message.Payloads) { switch (payload) { case TextPayload textPayload: lootMessage.MessageParts.Add(textPayload.Text); break; case ItemPayload itemPayload: if (lootMessage.ItemId != 0) { break; } lootMessage.ItemId = itemPayload.Item.RowId; lootMessage.ItemName = itemPayload.Item.Name.ToString(); lootMessage.Item = itemPayload.Item; lootMessage.IsHq = itemPayload.IsHQ; break; } } // filter out non-permitted item ids if (Configuration.RestrictToCustomItems && !Configuration.PermittedItems.Contains(lootMessage.ItemId)) { return; } // log for debugging if (Configuration.DebugLoggingEnabled) { LogInfo("[LootChatMessage]" + lootMessage); } // send to loot processor var lootEvent = LootProcessor.ProcessLoot(lootMessage); // kick out if didn't process if (lootEvent == null) { return; } // log for debugging if (Configuration.DebugLoggingEnabled) { LogInfo("[LootEvent]" + lootEvent); } // enrich lootEvent.Timestamp = DateUtil.CurrentTime(); lootEvent.LootEventId = Guid.NewGuid(); lootEvent.TerritoryTypeId = territoryTypeId; lootEvent.ContentId = contentId; // add to list if (LootProcessor.IsEnabledEvent(lootEvent)) { LootEvents.Add(lootEvent); } // process for roll monitor RollMonitor.LootEvents.Enqueue(lootEvent); // output if (Configuration.LoggingEnabled) { LootLogger.LogLoot(lootEvent); } }
/// <summary> /// Read an SeString from a specified Utf8String structure. /// </summary> /// <param name="utf8String">The memory address to read from.</param> /// <param name="value">The read in string.</param> public static unsafe void ReadSeString(Utf8String *utf8String, out SeString value) => value = ReadSeString(utf8String);
public void PopulateData(RowParser parser, Lumina lumina, Language language) { RowId = parser.Row; SubRowId = parser.SubRow; Name = parser.ReadColumn <SeString>(0); Unknown1 = parser.ReadColumn <bool>(1); Icon = parser.ReadColumn <ushort>(2); ActionCategory = new LazyRow <ActionCategory>(lumina, parser.ReadColumn <byte>(3), language); Unknown4 = parser.ReadColumn <byte>(4); AnimationStart = new LazyRow <ActionCastTimeline>(lumina, parser.ReadColumn <byte>(5), language); VFX = new LazyRow <ActionCastVFX>(lumina, parser.ReadColumn <byte>(6), language); AnimationEnd = new LazyRow <ActionTimeline>(lumina, parser.ReadColumn <short>(7), language); ActionTimelineHit = new LazyRow <ActionTimeline>(lumina, parser.ReadColumn <ushort>(8), language); Unknown9 = parser.ReadColumn <byte>(9); ClassJob = new LazyRow <ClassJob>(lumina, parser.ReadColumn <sbyte>(10), language); BehaviourType = parser.ReadColumn <byte>(11); ClassJobLevel = parser.ReadColumn <byte>(12); IsRoleAction = parser.ReadColumn <bool>(13); Range = parser.ReadColumn <sbyte>(14); CanTargetSelf = parser.ReadColumn <bool>(15); CanTargetParty = parser.ReadColumn <bool>(16); CanTargetFriendly = parser.ReadColumn <bool>(17); CanTargetHostile = parser.ReadColumn <bool>(18); Unknown19 = parser.ReadColumn <bool>(19); Unknown20 = parser.ReadColumn <bool>(20); TargetArea = parser.ReadColumn <bool>(21); Unknown22 = parser.ReadColumn <bool>(22); Unknown23 = parser.ReadColumn <bool>(23); Unknown24 = parser.ReadColumn <sbyte>(24); CanTargetDead = parser.ReadColumn <bool>(25); Unknown26 = parser.ReadColumn <bool>(26); CastType = parser.ReadColumn <byte>(27); EffectRange = parser.ReadColumn <byte>(28); XAxisModifier = parser.ReadColumn <byte>(29); Unknown30 = parser.ReadColumn <bool>(30); PrimaryCostType = parser.ReadColumn <byte>(31); PrimaryCostValue = parser.ReadColumn <ushort>(32); SecondaryCostType = parser.ReadColumn <byte>(33); SecondaryCostValue = parser.ReadColumn <ushort>(34); ActionCombo = new LazyRow <Action>(lumina, parser.ReadColumn <ushort>(35), language); PreservesCombo = parser.ReadColumn <bool>(36); Cast100ms = parser.ReadColumn <ushort>(37); Recast100ms = parser.ReadColumn <ushort>(38); CooldownGroup = parser.ReadColumn <byte>(39); Unknown40 = parser.ReadColumn <byte>(40); MaxCharges = parser.ReadColumn <byte>(41); AttackType = new LazyRow <AttackType>(lumina, parser.ReadColumn <sbyte>(42), language); Aspect = parser.ReadColumn <byte>(43); ActionProcStatus = new LazyRow <ActionProcStatus>(lumina, parser.ReadColumn <byte>(44), language); Unknown45 = parser.ReadColumn <byte>(45); StatusGainSelf = new LazyRow <Status>(lumina, parser.ReadColumn <ushort>(46), language); UnlockLink = parser.ReadColumn <uint>(47); ClassJobCategory = new LazyRow <ClassJobCategory>(lumina, parser.ReadColumn <byte>(48), language); Unknown49 = parser.ReadColumn <byte>(49); Unknown50 = parser.ReadColumn <bool>(50); AffectsPosition = parser.ReadColumn <bool>(51); Omen = new LazyRow <Omen>(lumina, parser.ReadColumn <ushort>(52), language); IsPvP = parser.ReadColumn <bool>(53); Unknown54 = parser.ReadColumn <bool>(54); Unknown55 = parser.ReadColumn <bool>(55); Unknown56 = parser.ReadColumn <bool>(56); Unknown57 = parser.ReadColumn <bool>(57); Unknown58 = parser.ReadColumn <bool>(58); Unknown59 = parser.ReadColumn <bool>(59); Unknown60 = parser.ReadColumn <bool>(60); Unknown61 = parser.ReadColumn <bool>(61); Unknown62 = parser.ReadColumn <byte>(62); Unknown63 = parser.ReadColumn <bool>(63); Unknown64 = parser.ReadColumn <bool>(64); IsPlayerAction = parser.ReadColumn <bool>(65); }
private void Chat_OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { String messageString = message.TextValue; String temp = Lang(messageString); var senderName = sender.TextValue; if (temp == language) { Task.Run(() => Tran(type, messageString, senderName)); } foreach (var tab in items) { if (tab.Logs[(int)type]) { tab.Text += senderName + ":" + messageString + "\n"; } } }
public void OnChatMessage(Dalamud.Game.Chat.XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) { if (cachedCommendationString == "") { if (pi.Data.IsDataReady) { cachedCommendationString = pi.Data.GetExcelSheet <LogMessage>().GetRow(926).Text; } } if (message.TextValue == cachedCommendationString && sender.TextValue == "") { if (configuration.classes.FindIndex(a => a.ClassID == cachedClass) != -1) { configuration.classes.Find(a => a.ClassID == cachedClass).CommendationsReceived++; } } else if ((message.TextValue.Contains("You are defeated") || message.TextValue.Contains("Du brichst zusammen") || (message.TextValue.Contains("Du wurdest von") && message.TextValue.Contains("besiegt")) || message.TextValue.Contains("Vous vous effondrez") || message.TextValue.Contains("Vous avez été vaincue") || message.TextValue == "\u306f\u3001\u529b\u5c3d\u304d\u305f\u3002") && sender.TextValue == "") { if (configuration.classes.FindIndex(a => a.ClassID == cachedClass) != -1) { configuration.classes.Find(a => a.ClassID == cachedClass).Deaths++; } if (ui.InDuty) { ui.DutyDeaths++; } } if (configuration.ParseChat) { if (((message.TextValue.Contains("You use") || message.TextValue.Contains("You cast")) && sender.TextValue == "")) { spellCasted = true; } else if (message.TextValue.Contains("takes") && message.TextValue.Contains("damage") && spellCasted) { if (configuration.classes.FindIndex(a => a.ClassID == cachedClass) != -1) { configuration.classes.Find(a => a.ClassID == cachedClass).DamageDealt += long.Parse(Regex.Match(message.TextValue, @"\d+").Value); } } else if (message.TextValue.Contains("recover") && message.TextValue.Contains("HP") && spellCasted) { if (configuration.classes.FindIndex(a => a.ClassID == cachedClass) != -1) { configuration.classes.Find(a => a.ClassID == cachedClass).HealthHealed += long.Parse(Regex.Match(message.TextValue, @"\d+").Value); } } else if (spellCasted && !message.TextValue.Contains("recover") && (!message.TextValue.Contains("takes") && !message.TextValue.Contains("damage")) && !message.TextValue.Contains("defeat") && !message.TextValue.Contains("suffers") && !message.TextValue.Contains("misses")) { spellCasted = false; } else if (message.TextValue.Contains("You hit the") && sender.TextValue == "") { if (configuration.classes.FindIndex(a => a.ClassID == cachedClass) != -1) { configuration.classes.Find(a => a.ClassID == cachedClass).DamageDealt += long.Parse(Regex.Match(message.TextValue, @"\d+").Value); } } } }
/// <summary> /// Displays a fly text in-game on the local player. /// </summary> /// <param name="kind">The FlyTextKind. See <see cref="FlyTextKind"/>.</param> /// <param name="actorIndex">The index of the actor to place flytext on. Indexing unknown. 1 places flytext on local player.</param> /// <param name="val1">Value1 passed to the native flytext function.</param> /// <param name="val2">Value2 passed to the native flytext function. Seems unused.</param> /// <param name="text1">Text1 passed to the native flytext function.</param> /// <param name="text2">Text2 passed to the native flytext function.</param> /// <param name="color">Color passed to the native flytext function. Changes flytext color.</param> /// <param name="icon">Icon ID passed to the native flytext function. Only displays with select FlyTextKind.</param> public unsafe void AddFlyText(FlyTextKind kind, uint actorIndex, uint val1, uint val2, SeString text1, SeString text2, uint color, uint icon) { // Known valid flytext region within the atk arrays var numIndex = 28; var strIndex = 25; var numOffset = 147u; var strOffset = 28u; // Get the UI module and flytext addon pointers var gameGui = Service <GameGui> .Get(); var ui = (FFXIVClientStructs.FFXIV.Client.UI.UIModule *)gameGui.GetUIModule(); var flytext = gameGui.GetAddonByName("_FlyText", 1); if (ui == null || flytext == IntPtr.Zero) { return; } // Get the number and string arrays we need var atkArrayDataHolder = ui->RaptureAtkModule.AtkModule.AtkArrayDataHolder; var numArray = atkArrayDataHolder._NumberArrays[numIndex]; var strArray = atkArrayDataHolder._StringArrays[strIndex]; // Write the values to the arrays using a known valid flytext region numArray->IntArray[numOffset + 0] = 1; // Some kind of "Enabled" flag for this section numArray->IntArray[numOffset + 1] = (int)kind; numArray->IntArray[numOffset + 2] = unchecked ((int)val1); numArray->IntArray[numOffset + 3] = unchecked ((int)val2); numArray->IntArray[numOffset + 4] = 5; // Unknown numArray->IntArray[numOffset + 5] = unchecked ((int)color); numArray->IntArray[numOffset + 6] = unchecked ((int)icon); numArray->IntArray[numOffset + 7] = 0; // Unknown numArray->IntArray[numOffset + 8] = 0; // Unknown, has something to do with yOffset fixed(byte *pText1 = text1.Encode()) { fixed(byte *pText2 = text2.Encode()) { strArray->StringArray[strOffset + 0] = pText1; strArray->StringArray[strOffset + 1] = pText2; this.addFlyTextNative( flytext, actorIndex, 1, (IntPtr)numArray, numOffset, 9, (IntPtr)strArray, strOffset, 2, 0); } } }
protected static unsafe void SetTooltipString(StringArrayData *stringArrayData, TooltipTweaks.ItemTooltipField field, SeString seString) { try { if (!ItemStringPointers.ContainsKey(field)) { ItemStringPointers.Add(field, Marshal.AllocHGlobal(4096)); } var bytes = seString.Encode(); Marshal.Copy(bytes, 0, ItemStringPointers[field], bytes.Length); Marshal.WriteByte(ItemStringPointers[field], bytes.Length, 0); stringArrayData->StringArray[(int)field] = (byte *)ItemStringPointers[field]; } catch { // } }
// TODO: Ignore messages that realistically will never have links (Battle) private void OnChatMessage(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool ishandled) { var isModified = false; var payloads = new List <Payload>(); var cLinkDepth = 0; message.Payloads.ForEach(p => { // Don't create links inside other links. if (p is DalamudLinkPayload) { cLinkDepth++; } else if (cLinkDepth > 0 && p is RawPayload && RawPayload.LinkTerminator.Equals(p)) { cLinkDepth--; } if (cLinkDepth == 0 && p is TextPayload textPayload) { var match = urlRegex.Match(textPayload.Text); if (urlRegex.IsMatch(textPayload.Text)) { var i = 0; do { if (match.Index > i) { payloads.Add(new TextPayload(textPayload.Text.Substring(i, match.Index - i))); i = match.Index; } payloads.Add(urlLinkPayload); payloads.Add(new TextPayload($"{match.Value}")); payloads.Add(RawPayload.LinkTerminator); i += match.Value.Length; match = match.NextMatch(); } while (match.Success); if (i < textPayload.Text.Length) { payloads.Add(new TextPayload(textPayload.Text.Substring(i))); } isModified = true; } else { payloads.Add(p); } } else { payloads.Add(p); } }); if (!isModified) { return; } message.Payloads.Clear(); message.Payloads.AddRange(payloads); }
private unsafe void OnChatMessage(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool isHandled) { if (type != XivChatType.ErrorMessage) { return; } if (Common.LastCommand == null || Common.LastCommand->StringPtr == null) { return; } var lastCommandStr = Encoding.UTF8.GetString(Common.LastCommand->StringPtr, (int)Common.LastCommand->BufUsed); if (!(lastCommandStr.StartsWith("/target ") || lastCommandStr.StartsWith("/ziel ") || lastCommandStr.StartsWith("/cibler ") || lastCommandStr.StartsWith("/选中 "))) { return; } var match = regex.Match(message.TextValue); if (!match.Success) { return; } var searchName = match.Groups[1].Value.ToLowerInvariant(); GameObject closestMatch = null; var closestDistance = float.MaxValue; var player = Service.ClientState.LocalPlayer; foreach (var actor in Service.Objects) { if (actor == null) { continue; } if (actor.Name.TextValue.ToLowerInvariant().Contains(searchName) && ((GameObjectStruct *)actor.Address)->GetIsTargetable()) { var distance = Vector3.Distance(player.Position, actor.Position); if (closestMatch == null) { closestMatch = actor; closestDistance = distance; continue; } if (closestDistance > distance) { closestMatch = actor; closestDistance = distance; } } } if (closestMatch != null) { isHandled = true; Service.Targets.SetTarget(closestMatch); } }
private void OnCheckMessageHandled(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool isHandled) { var textVal = message.TextValue; var matched = this.rmtRegex.IsMatch(textVal); if (matched) { // This seems to be a RMT ad - let's not show it Log.Debug("Handled RMT ad: " + message.TextValue); isHandled = true; return; } if (this.dalamud.Configuration.BadWords != null && this.dalamud.Configuration.BadWords.Any(x => !string.IsNullOrEmpty(x) && textVal.Contains(x))) { // This seems to be in the user block list - let's not show it Log.Debug("Blocklist triggered"); isHandled = true; return; } }
/// <summary> /// Read a null-terminated SeString from a specified memory address. /// </summary> /// <param name="memoryAddress">The memory address to read from.</param> /// <returns>The read in string.</returns> public static SeString ReadSeStringNullTerminated(IntPtr memoryAddress) { var buffer = ReadRawNullTerminated(memoryAddress); return(SeString.Parse(buffer)); }
private void OpenFolder(uint arg1, SeString arg2) { var dir = arg2.TextValue.Replace($"{(char)0x00A0}", "").Replace("\n", "").Replace("\r", ""); Process.Start("explorer.exe", dir); }
/// <summary> /// Read a null-terminated SeString from a specified memory address. /// </summary> /// <param name="memoryAddress">The memory address to read from.</param> /// <param name="value">The read in SeString.</param> public static void ReadSeStringNullTerminated(IntPtr memoryAddress, out SeString value) => value = ReadSeStringNullTerminated(memoryAddress);
public async Task ProcessChatMessage(XivChatType type, StdString message, StdString sender) { // 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 parsedSender = SeString.Parse(sender.RawData); var playerLink = parsedSender.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 if (parsedSender.TextValue != this.dalamud.ClientState.LocalPlayer.Name) { Log.Error("playerLink was null. Sender: {0}", BitConverter.ToString(sender.RawData)); } senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : parsedSender.TextValue; senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.Name; } else { playerLink.Resolve(); senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : playerLink.PlayerName; senderWorld = playerLink.ServerName; } var rawMessage = SeString.Parse(message.RawData).TextValue; var avatarUrl = string.Empty; var lodestoneId = string.Empty; if (!this.config.DisableEmbeds) { 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}"); } } }
/// <summary> /// Read an SeString from a specified memory address. /// </summary> /// <param name="memoryAddress">The memory address to read from.</param> /// <param name="maxLength">The maximum length of the string.</param> /// <param name="value">The read in SeString.</param> public static void ReadSeString(IntPtr memoryAddress, int maxLength, out SeString value) => value = ReadSeString(memoryAddress, maxLength);
private void UrlLinkHandle(uint id, SeString message) { Process.Start(message.TextValue); }
private IntPtr HandlePrintMessageDetour(IntPtr manager, XivChatType chattype, IntPtr pSenderName, IntPtr pMessage, uint senderid, IntPtr parameter) { var retVal = IntPtr.Zero; try { var sender = StdString.ReadFromPointer(pSenderName); var message = StdString.ReadFromPointer(pMessage); var parsedSender = SeString.Parse(sender.RawData); var parsedMessage = SeString.Parse(message.RawData); Log.Verbose("[CHATGUI][{0}][{1}]", parsedSender.TextValue, parsedMessage.TextValue); //Log.Debug($"HandlePrintMessageDetour {manager} - [{chattype}] [{BitConverter.ToString(message.RawData).Replace("-", " ")}] {message.Value} from {senderName.Value}"); var originalMessageData = (byte[])message.RawData.Clone(); var oldEdited = parsedMessage.Encode(); // Call events var isHandled = false; OnCheckMessageHandled?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled); OnChatMessage?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled); OnChatMessageRaw?.Invoke(chattype, senderid, ref sender, ref message, ref isHandled); var newEdited = parsedMessage.Encode(); if (!FastByteArrayCompare(oldEdited, newEdited)) { Log.Verbose("SeString was edited, taking precedence over StdString edit."); message.RawData = newEdited; Log.Debug($"\nOLD: {BitConverter.ToString(originalMessageData)}\nNEW: {BitConverter.ToString(newEdited)}"); } var messagePtr = pMessage; OwnedStdString allocatedString = null; if (!FastByteArrayCompare(originalMessageData, message.RawData)) { allocatedString = this.dalamud.Framework.Libc.NewString(message.RawData); Log.Debug( $"HandlePrintMessageDetour String modified: {originalMessageData}({messagePtr}) -> {message}({allocatedString.Address})"); messagePtr = allocatedString.Address; } // Print the original chat if it's handled. if (!isHandled) { retVal = this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter); } if (this.baseAddress == IntPtr.Zero) { this.baseAddress = manager; } allocatedString?.Dispose(); } catch (Exception ex) { Log.Error(ex, "Exception on OnChatMessage hook."); retVal = this.printMessageHook.Original(manager, chattype, pSenderName, pMessage, senderid, parameter); } return(retVal); }