private void DrawItemList(List <GenericItem> itemList, Vector2 listSize, ref bool isOpen)
        {
            var fontPushed   = false;
            var stylesPushed = 0;
            var colorsPushed = 0;

            try {
                if (itemList.Count != lastItemCount)
                {
                    lastItemCount = itemList.Count;
                    ImGui.SetScrollY(0);
                }

                var   itemSize   = Vector2.Zero;
                float cursorPosY = 0;
                var   scrollY    = ImGui.GetScrollY();
                var   style      = ImGui.GetStyle();
                var   j          = 0;

                var rowSize = Vector2.Zero;

                for (var i = 0; i < itemList.Count; i++)
                {
                    if (i == 0 && itemSize == Vector2.Zero)
                    {
                        itemSize = ImGui.CalcTextSize(itemList[i].Name);
                        rowSize  = new Vector2(ImGui.GetWindowContentRegionWidth() - 20 * ImGui.GetIO().FontGlobalScale, itemSize.Y);
                        if (!doSearchScroll)
                        {
                            var sizePerItem = itemSize.Y + style.ItemSpacing.Y;
                            var skipItems   = (int)Math.Floor(scrollY / sizePerItem);
                            cursorPosY = skipItems * sizePerItem;
                            ImGui.SetCursorPosY(5 + cursorPosY + style.ItemSpacing.X);
                            i = skipItems;
                        }
                    }

                    if (!(doSearchScroll && selectedItemIndex == i) && (cursorPosY < scrollY - itemSize.Y || cursorPosY > scrollY + listSize.Y))
                    {
                        ImGui.SetCursorPosY(cursorPosY + itemSize.Y + style.ItemSpacing.Y);
                    }
                    else
                    {
                        ImGui.PushFont(UiBuilder.IconFont);
                        fontPushed = true;

                        var starText        = $"{(char)FontAwesomeIcon.Heart}";
                        var starTextSize    = ImGui.CalcTextSize(starText);
                        var starTextHovered = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(), ImGui.GetCursorScreenPos() + starTextSize);

                        uint starTextCol = pluginConfig.Favorites.Contains(itemList[i].RowId) ? 0xCC0000AA : 0U;;

                        if (starTextHovered)
                        {
                            starTextCol = pluginConfig.Favorites.Contains(itemList[i].RowId) ? 0xAA777777 : 0xAA0000AAU;
                            ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
                        }

                        ImGui.PushStyleColor(ImGuiCol.Text, starTextCol); colorsPushed++;

                        ImGui.Text(starText);
                        if (ImGui.IsItemClicked())
                        {
                            if (pluginConfig.Favorites.Contains(itemList[i].RowId))
                            {
                                pluginConfig.Favorites.Remove(itemList[i].RowId);
                            }
                            else
                            {
                                pluginConfig.Favorites.Add(itemList[i].RowId);
                            }
                            pluginConfig.Save();
                        }

                        ImGui.PopStyleColor(); colorsPushed--;

                        ImGui.PopFont();
                        fontPushed = false;
                        ImGui.SameLine();

                        var hovered = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(), ImGui.GetCursorScreenPos() + rowSize);
                        var bgCol   = selectedItem == itemList[i] ? (hovered ? 0x88888888 : 0x88444444) : (hovered ? 0x66666666 : 0U);
                        ImGui.PushStyleColor(ImGuiCol.ChildBg, bgCol); colorsPushed++;
                        ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero); stylesPushed++;
                        ImGui.BeginGroup();
                        ImGui.BeginChild($"###ItemContainer{j++}", rowSize, false);


                        ImGui.Text($" {itemList[i].Name}");
                        if (itemList[i].GenericItemType == GenericItem.ItemType.EventItem)
                        {
                            ImGui.SameLine();
                            ImGui.TextDisabled(" [Key Item]");
                        }
                        var textClick = ImGui.IsItemClicked();
                        ImGui.EndChild();
                        var childClicked = ImGui.IsItemClicked();
                        ImGui.EndGroup();
                        var groupHovered = ImGui.IsItemHovered();
                        var groupClicked = ImGui.IsItemClicked();
                        ImGui.PopStyleColor(); colorsPushed--;


                        if (textClick || childClicked || groupClicked)
                        {
                            this.selectedItem      = itemList[i];
                            this.selectedItemIndex = i;

                            if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left))
                            {
                                if (this.selectedItem != null && selectedItem.Icon < 65000)
                                {
                                    try {
                                        plugin.LinkItem(selectedItem);
                                        if (pluginConfig.CloseOnChoose)
                                        {
                                            isOpen = false;
                                        }
                                    } catch (Exception ex) {
                                        PluginLog.LogError(ex.ToString());
                                    }
                                }
                            }

                            if (selectedItem.GenericItemType == GenericItem.ItemType.Item)
                            {
                                if ((autoTryOn = autoTryOn && pluginConfig.ShowTryOn) && plugin.FittingRoomUI.CanUseTryOn && pluginInterface.ClientState.LocalContentId != 0)
                                {
                                    if (selectedItem.ClassJobCategory.Row != 0)
                                    {
                                        plugin.FittingRoomUI.TryOnItem((Item)selectedItem, selectedStain?.RowId ?? 0);
                                    }
                                }
                            }
                        }

                        ImGui.PopStyleVar(); stylesPushed--;
                    }



                    if (doSearchScroll && selectedItemIndex == i)
                    {
                        doSearchScroll = false;
                        ImGui.SetScrollHereY(0.5f);
                    }

                    cursorPosY = ImGui.GetCursorPosY();

                    if (cursorPosY > scrollY + listSize.Y && !doSearchScroll)
                    {
                        var c = itemList.Count - i;
                        ImGui.BeginChild("###scrollFillerBottom", new Vector2(0, c * (itemSize.Y + style.ItemSpacing.Y)), false);
                        ImGui.EndChild();
                        break;
                    }
                }

                var keyStateDown = ImGui.GetIO().KeysDown[0x28] || pluginInterface.ClientState.KeyState[0x28];
                var keyStateUp   = ImGui.GetIO().KeysDown[0x26] || pluginInterface.ClientState.KeyState[0x26];

#if DEBUG
                // Random up/down if both are pressed
                if (keyStateUp && keyStateDown)
                {
                    debounceKeyPress = 0;

                    var r = new Random().Next(0, 5);

                    switch (r)
                    {
                    case 1:
                        keyStateUp   = true;
                        keyStateDown = false;
                        break;

                    case 0:
                        keyStateUp   = false;
                        keyStateDown = false;
                        break;

                    default:
                        keyStateUp   = false;
                        keyStateDown = true;
                        break;
                    }
                }
#endif

                var hotkeyUsed = false;
                if (keyStateUp && !keyStateDown)
                {
                    if (debounceKeyPress == 0)
                    {
                        debounceKeyPress = 5;
                        if (selectedItemIndex > 0)
                        {
                            hotkeyUsed         = true;
                            selectedItemIndex -= 1;
                        }
                    }
                }
                else if (keyStateDown && !keyStateUp)
                {
                    if (debounceKeyPress == 0)
                    {
                        debounceKeyPress = 5;
                        if (selectedItemIndex < itemList.Count - 1)
                        {
                            selectedItemIndex += 1;
                            hotkeyUsed         = true;
                        }
                    }
                }
                else if (debounceKeyPress > 0)
                {
                    debounceKeyPress -= 1;
                    if (debounceKeyPress < 0)
                    {
                        debounceKeyPress = 5;
                    }
                }

                if (hotkeyUsed)
                {
                    doSearchScroll    = true;
                    this.selectedItem = itemList[selectedItemIndex];
                    if (selectedItem.GenericItemType == GenericItem.ItemType.Item)
                    {
                        if ((autoTryOn = autoTryOn && pluginConfig.ShowTryOn) && plugin.FittingRoomUI.CanUseTryOn && pluginInterface.ClientState.LocalContentId != 0)
                        {
                            if (selectedItem.ClassJobCategory.Row != 0)
                            {
                                plugin.FittingRoomUI.TryOnItem((Item)selectedItem, selectedStain?.RowId ?? 0);
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                PluginLog.LogError($"{ex}");
                ImGui.SetScrollY(0);
            }

            if (fontPushed)
            {
                ImGui.PopFont();
            }
            if (colorsPushed > 0)
            {
                ImGui.PopStyleColor(colorsPushed);
            }
            if (stylesPushed > 0)
            {
                ImGui.PopStyleColor(stylesPushed);
            }
        }
示例#2
0
        public void DrawActionsTab()
        {
            if (MonitorDisplays.Count > 0)
            {
                ImGui.Columns(1 + MonitorDisplays.Values.Count, "###", false);
                ImGui.SetColumnWidth(0, 220);
                for (var i = 1; i <= MonitorDisplays.Count; i++)
                {
                    ImGui.SetColumnWidth(i, 100);
                }

                ImGui.Text("技能");
                ImGui.SameLine(80);

                ImGui.Text("GCD技能");
                ImGui.SameLine();
                ImGui.SetWindowFontScale(0.7f);
                ImGui.Checkbox("###showGCDCheckbox", ref showGlobalCooldowns);
                ImGui.SetWindowFontScale(1);

                ImGui.NextColumn();

                foreach (var d in MonitorDisplays.Values)
                {
                    ImGui.Text(d.Name);
                    ImGui.NextColumn();
                }

                ImGui.Separator();
                ImGui.Separator();
                ImGui.Columns(1);
                ImGui.BeginChild("###scrolling", new Vector2(-1));
                ImGui.Columns(1 + MonitorDisplays.Values.Count, "###", false);
                ImGui.SetColumnWidth(0, 220);
                for (var i = 1; i <= MonitorDisplays.Count; i++)
                {
                    ImGui.SetColumnWidth(i, 100);
                }
                var gcdTextSize = ImGui.CalcTextSize("[GCD]");
                foreach (var a in plugin.ActionManager.PlayerActions.Where(a => (showGlobalCooldowns || a.CooldownGroup != GlobalCooldownGroup || MonitorDisplays.Any(d => d.Value.Cooldowns.Any(c => c.ActionId == a.RowId && c.ClassJob == pluginInterface.ClientState.LocalPlayer.ClassJob.Id))) && a.IsPvP == false && a.ClassJobCategory.Value.HasClass(pluginInterface.ClientState.LocalPlayer.ClassJob.Id)))
                {
                    var cdm = new CooldownMonitor {
                        ActionId = a.RowId, ClassJob = pluginInterface.ClientState.LocalPlayer.ClassJob.Id
                    };

                    var icon = plugin.IconManager.GetActionIcon(a);
                    if (icon != null)
                    {
                        ImGui.Image(icon.ImGuiHandle, new Vector2(25));
                    }
                    else
                    {
                        ImGui.Dummy(new Vector2(24));
                    }

                    ImGui.SameLine();
                    if (a.CooldownGroup == GlobalCooldownGroup)
                    {
                        var x = ImGui.GetCursorPosX();
                        ImGui.SetCursorPosX(ImGui.GetColumnWidth() - gcdTextSize.X);
                        ImGui.TextColored(new Vector4(0.8f), "[GCD]");
                        ImGui.SameLine();
                        ImGui.SetCursorPosX(x);
                    }

                    ImGui.Text(a.Name);

                    ImGui.NextColumn();

                    foreach (var d in MonitorDisplays.Values)
                    {
                        var i = d.Cooldowns.Contains(cdm);

                        if (ImGui.Checkbox($"###action{a.RowId}in{d.Guid}", ref i))
                        {
                            try {
                                if (i)
                                {
                                    d.Cooldowns.Add(cdm);
                                }
                                else
                                {
                                    d.Cooldowns.Remove(cdm);
                                }
                                Save();
                            } catch (Exception ex) {
                                PluginLog.LogError(ex.ToString());
                            }
                        }

                        ImGui.NextColumn();
                    }

                    ImGui.Separator();
                }

                ImGui.Columns(1);

                ImGui.TextWrapped("\n有东西缺失了?\n请到 goat place discord 向 Caraxi 反馈,之后它便会被添加。");
            }
            else
            {
                ImGui.Text("没有显示区域可供设置。");
            }

            ImGui.EndChild();
        }
        private async Task InstallDependency(Dependency dependency)
        {
            PluginLog.Log($"Downloading {dependency.Directory} {dependency.Version}");

            // Ensure the downloads dir exists
            var downloadDir = Path.Combine(dependencyDir, DOWNLOAD_DIR);

            Directory.CreateDirectory(downloadDir);

            // Get the file name we'll download to - if it's already in downloads, it may be corrupt, delete
            var filePath = Path.Combine(downloadDir, $"{dependency.Directory}-{dependency.Version}.zip");

            File.Delete(filePath);

            // Set up the download and kick it off
            using WebClient client          = new WebClient();
            client.DownloadProgressChanged += (sender, args) => installProgress.AddOrUpdate(
                dependency.Directory,
                args.ProgressPercentage,
                (key, oldValue) => Math.Max(oldValue, args.ProgressPercentage));
            await client.DownloadFileTaskAsync(
                dependency.Url.Replace("{VERSION}", dependency.Version),
                filePath);

            // Download complete, mark as extracting
            installProgress.AddOrUpdate(dependency.Directory, DEP_EXTRACTING, (key, oldValue) => DEP_EXTRACTING);

            // Calculate the checksum for the download
            string downloadedChecksum;

            try
            {
                using (var sha = SHA256.Create())
                    using (var stream = new FileStream(filePath, FileMode.Open))
                    {
                        stream.Position = 0;
                        var rawHash = sha.ComputeHash(stream);
                        var builder = new StringBuilder(rawHash.Length);
                        for (var i = 0; i < rawHash.Length; i++)
                        {
                            builder.Append($"{rawHash[i]:X2}");
                        }
                        downloadedChecksum = builder.ToString();
                    }
            }
            catch
            {
                PluginLog.LogError($"Failed to calculate checksum for {filePath}");
                downloadedChecksum = "FAILED";
            }

            // Make sure the checksum matches
            if (downloadedChecksum != dependency.Checksum)
            {
                PluginLog.LogError($"Mismatched checksum for {filePath}");
                installProgress.AddOrUpdate(dependency.Directory, DEP_FAILED, (key, oldValue) => DEP_FAILED);
                File.Delete(filePath);
                return;
            }

            installProgress.AddOrUpdate(dependency.Directory, DEP_COMPLETE, (key, oldValue) => DEP_COMPLETE);

            // Extract to the destination dir
            var destinationDir = GetDependencyPath(dependency);

            try { Directory.Delete(destinationDir, true); }
            catch { }
            ZipFile.ExtractToDirectory(filePath, destinationDir);

            // Clear out the downloaded file now we're done with it
            File.Delete(filePath);
        }
        /// <summary>
        /// Builds the controls for the gui screen by first building the base
        /// controls and then adding the checkbox to enable the plugin and a button to edit
        /// its settings for the world, also initializes an instance of plugin settings to edit.
        /// Adds a new delegate to the create world button, to transfere the set plugin settings
        /// to the plugins settings session component.
        /// </summary>
        protected override void BuildControls()
        {
            base.BuildControls();

            Vector2 vector  = -m_size.Value / 2f + new Vector2(m_isNewGame ? (MARGIN_LEFT_LIST + MyGuiConstants.LISTBOX_WIDTH + MARGIN_LEFT_INFO) : MARGIN_LEFT_LIST, m_isNewGame ? (MARGIN_TOP + 0.015f) : (MARGIN_TOP - 0.105f));
            Vector2 value   = new Vector2(0f, 0.052f);
            Vector2 vector2 = m_size.Value / 2f - vector;

            vector2.X -= MARGIN_RIGHT + 0.005f;
            vector2.Y -= MARGIN_BOTTOM;
            Vector2 vector3 = vector2 * (m_isNewGame ? 0.339f : 0.329f);
            Vector2 vector4 = vector2 - vector3;

            m_enablePluginLabel = new MyGuiControlLabel(null, null, "Enable SEWorldGenPlugin");

            m_enablePlugin = new MyGuiControlCheckbox();
            m_enablePlugin.SetToolTip("Enable the SEWorldGenPlugin for this world");
            m_enablePlugin.IsCheckedChanged = (Action <MyGuiControlCheckbox>) Delegate.Combine(m_enablePlugin.IsCheckedChanged, (Action <MyGuiControlCheckbox>) delegate(MyGuiControlCheckbox s)
            {
                if (PlSettings != null)
                {
                    PlSettings.Enable = s.IsChecked;
                }
            });

            m_enablePlugin.IsChecked = MySettings.Static.Settings.Enable;

            m_pluginSettingsButton = new MyGuiControlButton(null, MyGuiControlButtonStyleEnum.Small, null, null, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, null, new StringBuilder("Plugin settings"), 0.8f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, MyGuiControlHighlightType.WHEN_ACTIVE, OnSettingsClick);
            Controls.Add(m_enablePluginLabel);
            Controls.Add(m_enablePlugin);
            Controls.Add(m_pluginSettingsButton);

            m_enablePluginLabel.Position       = vector + value * 5;
            m_enablePluginLabel.PositionY     += MyGuiConstants.BACK_BUTTON_SIZE.Y * 2;
            m_enablePlugin.Position            = GetControlPosition();
            m_enablePlugin.PositionY           = m_enablePluginLabel.PositionY;
            m_enablePlugin.OriginAlign         = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER;
            m_pluginSettingsButton.Position    = m_enablePlugin.Position;
            m_pluginSettingsButton.PositionX  += m_enablePlugin.Size.X + 0.009f;
            m_pluginSettingsButton.OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER;
            foreach (var c in Controls)
            {
                if (c is MyGuiControlButton)
                {
                    MyGuiControlButton b = (MyGuiControlButton)c;
                    if (b.Text == MyTexts.GetString(MyCommonTexts.Start) || b.Text == MyTexts.GetString(MyCommonTexts.Ok))
                    {
                        if (m_isNewGame)
                        {
                            b.ButtonClicked += delegate
                            {
                                if (!UseGlobal)
                                {
                                    MySettings.Static.SessionSettings = PlSettings;
                                    PluginLog.Log("Settings: " + PlSettings.ToString());
                                }
                                else
                                {
                                    MySettings.Static.SessionSettings        = new MyObjectBuilder_PluginSettings();
                                    MySettings.Static.SessionSettings.Enable = m_enablePlugin.IsChecked;
                                }
                            };
                        }
                        else
                        {
                            b.ButtonClicked += delegate
                            {
                                var name = Checkpoint.SessionName;
                                var path = Path.Combine(MyFileSystem.SavesPath, name.Replace(":", "-"));
                                FileUtils.WriteXmlFileToPath(PlSettings, path, SettingsSession.FILE_NAME, typeof(PluginWorldSettings));
                            };
                        }
                    }
                }
            }

            if (m_isNewGame)
            {
                PlSettings = MySettings.Static.Settings.copy();
            }
            else
            {
                LoadValues();
            }
        }
示例#5
0
        private void Chat_OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
        {
            if (!Config.Recording)
            {
                return;
            }
            bool           hasMapLink     = false;
            float          coordX         = 0;
            float          coordY         = 0;
            float          scale          = 100;
            MapLinkPayload maplinkPayload = null;

            foreach (var payload in message.Payloads)
            {
                if (payload is MapLinkPayload mapLinkload)
                {
                    maplinkPayload = mapLinkload;
                    hasMapLink     = true;
                    // float fudge = 0.05f;
                    scale = mapLinkload.TerritoryType.Map.Value.SizeFactor;
                    // coordX = ConvertRawPositionToMapCoordinate(mapLinkload.RawX, scale) - fudge;
                    // coordY = ConvertRawPositionToMapCoordinate(mapLinkload.RawY, scale) - fudge;
                    coordX = mapLinkload.XCoord;
                    coordY = mapLinkload.YCoord;
                    Log($"TerritoryId: {mapLinkload.TerritoryType.RowId} {mapLinkload.PlaceName} ({coordX} ,{coordY})");
                }
            }
            string messageText = message.TextValue;

            if (hasMapLink)
            {
                var newMapLinkMessage = new MapLinkMessage(
                    (ushort)type,
                    sender.TextValue,
                    messageText,
                    coordX,
                    coordY,
                    scale,
                    maplinkPayload.TerritoryType.RowId,
                    maplinkPayload.PlaceName,
                    DateTime.Now
                    );
                bool filteredOut = false;
                if (sender.TextValue.ToLower() == "sonar")
                {
                    filteredOut = true;
                }
                bool alreadyInList = Config.MapLinkMessageList.Any(w => {
                    bool sameText  = w.Text == newMapLinkMessage.Text;
                    var timeoutMin = new TimeSpan(0, Config.FilterDupTimeout, 0);
                    if (newMapLinkMessage.RecordTime < w.RecordTime + timeoutMin)
                    {
                        bool sameX         = (int)(w.X * 10) == (int)(newMapLinkMessage.X * 10);
                        bool sameY         = (int)(w.Y * 10) == (int)(newMapLinkMessage.Y * 10);
                        bool sameTerritory = w.TerritoryId == newMapLinkMessage.TerritoryId;
                        return(sameTerritory && sameX && sameY);
                    }
                    return(sameText);
                });
                if (Config.FilterDuplicates && alreadyInList)
                {
                    filteredOut = true;
                }
                if (!filteredOut && Config.FilteredChannels.IndexOf((ushort)type) != -1)
                {
                    filteredOut = true;
                }
                if (!filteredOut)
                {
                    Config.MapLinkMessageList.Add(newMapLinkMessage);
                    if (Config.MapLinkMessageList.Count > Config.MaxRecordings)
                    {
                        var tempList = Config.MapLinkMessageList.OrderBy(e => e.RecordTime);
                        Config.MapLinkMessageList.RemoveRange(0, Config.MapLinkMessageList.Count - Config.MaxRecordings);
                        var infoMsg = $"There are too many records, truncated to the latest {Config.MaxRecordings} records";
                        PluginLog.Information(infoMsg);
                    }
                    Config.Save();
                }
            }
        }
        public void OnMacroCommandHandler(string command, string args)
        {
            try {
                if (macroBasePtr != IntPtr.Zero && macroDataPtr != IntPtr.Zero)
                {
                    var argSplit = args.Split(' ');

                    var num = byte.Parse(argSplit[0]);

                    if (num > 99)
                    {
                        pluginInterface.Framework.Gui.Chat.PrintError("Invalid Macro number.\nShould be 0 - 99");
                        return;
                    }

                    var shared       = false;
                    var startingLine = 0;
                    foreach (var arg in argSplit.Skip(1))
                    {
                        switch (arg.ToLower())
                        {
                        case "shared":
                        case "share":
                        case "s": {
                            shared = true;
                            break;
                        }

                        case "individual":
                        case "i": {
                            shared = false;
                            break;
                        }

                        default: {
                            int.TryParse(arg, out startingLine);
                            break;
                        }
                        }
                    }

                    if (shared)
                    {
                        num += 100;
                    }

                    var macroPtr = macroDataPtr + 0x688 * num;
                    PluginLog.Log($"Executing Macro #{num} @ {macroPtr}");
                    MacroLock = false;
                    macroCallHook.Original(macroBasePtr, macroPtr);

                    if (startingLine > 0 && startingLine <= 15)
                    {
                        CurrentMacroLine = startingLine - 1;
                    }
                }
                else
                {
                    pluginInterface.Framework.Gui.Chat.PrintError("OldMacroRecursion is not ready.\nExecute a macro to finish setup.");
                }
            } catch (Exception ex) {
                PluginLog.LogError(ex.ToString());
            }
        }
示例#7
0
        public void Initialize(DalamudPluginInterface pluginInterface)
        {
            var imagePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), @"Chat_Box_A.png");

            goatImage = pluginInterface.UiBuilder.LoadImage(imagePath);


            // Initializing plugin, hooking into chat.
            this.pluginInterface = pluginInterface;
            Configuration        = pluginInterface.GetPluginConfig() as ChatExtenderPluginConfiguration ?? new ChatExtenderPluginConfiguration();
            this.pluginInterface.UiBuilder.OnBuildFonts += AddFont;
            this.pluginInterface.UiBuilder.RebuildFonts();


            //Hooks for FFXIV ChatBox
            scan1 = pluginInterface.TargetModuleScanner.ScanText("E8 ?? ?? ?? ?? 41 b8 01 00 00 00 48 8d 15 ?? ?? ?? ?? 48 8b 48 20 e8 ?? ?? ?? ?? 48 8b cf");
            scan2 = pluginInterface.TargetModuleScanner.ScanText("e8 ?? ?? ?? ?? 48 8b cf 48 89 87 ?? ?? 00 00 e8 ?? ?? ?? ?? 41 b8 01 00 00 00");

            getBaseUIObj    = Marshal.GetDelegateForFunctionPointer <GetBaseUIObjDelegate>(scan1);
            getUI2ObjByName = Marshal.GetDelegateForFunctionPointer <GetUI2ObjByNameDelegate>(scan2);
            chatLog         = getUI2ObjByName(Marshal.ReadIntPtr(getBaseUIObj(), 0x20), "ChatLog", 1);
            chatLogStuff    = getUI2ObjByName(Marshal.ReadIntPtr(getBaseUIObj(), 0x20), "ChatLog", 1);
            chatLogPanel_0  = getUI2ObjByName(Marshal.ReadIntPtr(getBaseUIObj(), 0x20), "ChatLog", 1);
            chatLogPosition = new float[2];

            tab_ind       = UintCol(255, 50, 70, 50);
            tab_ind_text  = UintCol(255, 150, 150, 150);
            tab_norm      = UintCol(255, 50, 50, 50);
            tab_norm_text = UintCol(255, 150, 150, 150);
            tab_sel       = UintCol(255, 90, 90, 90);
            tab_sel_text  = UintCol(255, 250, 255, 255);

            try
            { allowTranslation = Configuration.AllowTranslation; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Translation setting!");
                allowTranslation = false;
            }

            try
            { bubblesWindow = Configuration.BubblesWindow; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load BubbleWindow setting!");
                bubblesWindow = false;
            }

            try
            { hourTime = Configuration.HourTime; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Hour Time Config!");
                bubblesWindow = false;
            }

            try
            { rTr = Configuration.RTr.ToString(); }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load right Translate Surround!");
            }

            try
            { lTr = Configuration.LTr.ToString(); }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load left Translate Surround!");
            }

            try
            { chanColour = Configuration.ChanColour.ToArray(); }
            catch (Exception)
            { PluginLog.LogError("No ChanColour to load!"); }

            try
            { bubbleEnable = Configuration.BubbleEnable.ToArray(); }
            catch (Exception)
            { PluginLog.LogError("No BubbleEnable to load!"); }

            try
            { logColour = Configuration.LogColour.ToArray(); }
            catch (Exception)
            { PluginLog.LogError("No LogColour to load!"); }

            try
            { bubbleColour = Configuration.BubbleColour.ToArray(); }
            catch (Exception)
            { PluginLog.LogError("No BubbleColour to load!"); }

            try
            { injectChat = Configuration.Inject; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Inject Status!");
                injectChat = false;
            }

            try
            { fontShadow = Configuration.FontShadow; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Font Shadow!");
                fontShadow = false;
            }

            try
            {
                if (Configuration.BubbleTime.HasValue)
                {
                    bubbleTime = Configuration.BubbleTime.Value;
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load BubbleTime!");
                bubbleTime = 15;
            }

            try
            {
                if (Configuration.Translator.HasValue)
                {
                    translator = Configuration.Translator.Value;
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Translator Choice!");
                translator = 1;
            }

            try
            {
                if (Configuration.FontSize.HasValue)
                {
                    fontsize = Configuration.FontSize.Value;
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Font Size!");
                fontsize = 15;
            }

            try
            { yandex = Configuration.YandexKey.ToString(); }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Yandex Key!");
                yandex = "";
            }

            try
            { chatWindow = Configuration.Extender; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Extender Choice!");
                chatWindow = false;
            }

            try
            { alpha = Configuration.Alpha; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Alpha!");
                alpha = 0.2f;
            }

            try
            { no_move = Configuration.NoMove; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load NoMove Config!");
                no_move = false;
            }

            try
            { no_resize = Configuration.NoResize; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load NoMove Config!");
                no_resize = false;
            }

            try
            { no_mouse = Configuration.NoMouse; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load NoMouse Config!");
                no_mouse = false;
            }

            try
            {
                high     = Configuration.High;
                tempHigh = String.Join(",", high.highlights);
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Highlighter");
                high = new Highlighter();
            }

            try
            {
                if (high.highlights.Length < 1)
                {
                    high = new Highlighter();
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Highlighter");
                high = new Highlighter();
            }


            try
            { no_mouse2 = Configuration.NoMouse2; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load NoMouse2 Config!");
                no_mouse2 = false;
            }

            try
            { no_scrollbar = Configuration.NoScrollBar; }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load ScrollBar Config!");
                no_scrollbar = false;
            }

            try
            {
                if (Configuration.Space_Hor.HasValue)
                {
                    space_hor = Configuration.Space_Hor.Value;
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Horizontal Spacing!");
                space_hor = 4;
            }

            try
            {
                if (Configuration.Space_Ver.HasValue)
                {
                    space_ver = Configuration.Space_Ver.Value;
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Vertical Spacing!");
                space_ver = 0;
            }

            try
            {
                if (Configuration.TimeColour.Z > 0)
                {
                    timeColour = Configuration.TimeColour;
                }
                else
                {
                    timeColour = new Num.Vector4(255, 255, 255, 255);
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Time Colour!");
                timeColour = new Num.Vector4(255, 255, 255, 255);
            }

            try
            {
                if (Configuration.NameColour.Z > 0)
                {
                    nameColour = Configuration.NameColour;
                }
                else
                {
                    nameColour = new Num.Vector4(255, 255, 255, 255);
                }
            }
            catch (Exception)
            {
                PluginLog.LogError("Failed to Load Name Colour!");
                nameColour = new Num.Vector4(255, 255, 255, 255);
            }

            //TODO: try/catch this?
            if (Configuration.Items == null)
            {
                //Serilog.Log.Information("Null DynTab List");
                items.Add(new DynTab("XXX", new ConcurrentQueue <ChatText>(), true));
            }
            else
            {
                //Serilog.Log.Information("Not Null DynTab List");
                if (Configuration.Items.Count == 0)
                {
                    //Serilog.Log.Information("Empty DynTab List");
                    items.Add(new DynTab("YYY", new ConcurrentQueue <ChatText>(), true));
                }
                else
                {
                    //Serilog.Log.Information("Normal DynTab List");
                    items = Configuration.Items.ToList();
                }
            }

            if (items[0].Config.Length == 3)
            {
                foreach (TabBase item in items)
                {
                    bool[] temp = { false, false, false, false, false, false, false, false, false, false };
                    temp[0]     = item.Config[0];
                    temp[1]     = item.Config[1];
                    temp[2]     = item.Config[2];
                    item.Config = temp;
                }
            }

            if (items[0].Filter == null)
            {
                foreach (TabBase item in items)
                {
                    item.Filter   = "";
                    item.FilterOn = false;
                }
            }

            try
            {
                if (Configuration.Items[0].Logs.Length < Channels.Length)
                {
                    int            l        = 0;
                    List <TabBase> templist = new List <TabBase>();
                    foreach (TabBase items in Configuration.Items)
                    {
                        TabBase temp = new TabBase();
                        temp.AutoScroll = items.AutoScroll;
                        temp.Chat       = items.Chat;
                        temp.Config     = items.Config;
                        temp.Enabled    = items.Enabled;
                        temp.Scroll     = items.Scroll;
                        temp.Title      = items.Title;
                        int i = 0;
                        foreach (bool set in items.Logs)
                        {
                            //PluginLog.Log(i.ToString());
                            temp.Logs[i] = set;
                            i++;
                        }
                        //PluginLog.Log("bool length:" + temp.Logs.Length.ToString());
                        templist.Add(temp);
                        l++;
                    }

                    items = templist;

                    Num.Vector4[] logColour_temp =
                    {
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255)
                    };

                    int j = 0;
                    foreach (Num.Vector4 vec in logColour)
                    {
                        logColour_temp[j] = vec;
                        j++;
                    }
                    logColour = logColour_temp;

                    Num.Vector4[] chanColour_temp =
                    {
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255),
                        new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255), new Num.Vector4(255, 255, 255, 255)
                    };

                    int k = 0;
                    foreach (Num.Vector4 vec in chanColour)
                    {
                        chanColour_temp[k] = vec;
                        k++;
                    }
                    chanColour = chanColour_temp;
                }
            }
            catch (Exception)
            {
                PluginLog.Log("Fresh install, no log to fix!");
            }

            //Adding in Chans
            try
            {
                if (Configuration.Items[0].Chans.Length < Channels.Length)
                {
                    int            l        = 0;
                    List <TabBase> templist = new List <TabBase>();
                    foreach (TabBase items in Configuration.Items)
                    {
                        TabBase temp = new TabBase();
                        temp.AutoScroll = items.AutoScroll;
                        temp.Chat       = items.Chat;
                        temp.Config     = items.Config;
                        temp.Enabled    = items.Enabled;
                        temp.Scroll     = items.Scroll;
                        temp.Title      = items.Title;
                        temp.Logs       = items.Logs.ToArray();
                        temp.Chans      =
                            new bool[] {
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true, true,
                            true, true, true, true
                        };
                        templist.Add(temp);
                        l++;
                    }

                    items = templist;
                }
            }
            catch (Exception)
            {
                PluginLog.Log("Fresh install, no Chans to fix!");
            }

            try
            {
                if (Configuration.Chan.Length > 30)
                {
                    Chan = Configuration.Chan.ToArray();
                }
            }
            catch (Exception)
            {
                PluginLog.Log("No Chan list to load");
            }

            if (translator == 0)
            {
                translator = 1;
            }

            SaveConfig();

            TransY.Make("https://translate.yandex.net/api/v1.5/tr.json/translate", Configuration.YandexKey);

            // Set up command handlers
            this.pluginInterface.CommandManager.AddHandler("/cht", new CommandInfo(OnTranslateCommand)
            {
                HelpMessage = "Open config with '/cht c', and the extender with '/cht w'"
            });

            this.pluginInterface.Framework.Gui.Chat.OnChatMessage += Chat_OnChatMessage;
            this.pluginInterface.UiBuilder.OnBuildUi      += ChatUI;
            this.pluginInterface.UiBuilder.OnOpenConfigUi += Chat_ConfigWindow;
            this.pluginInterface.UiBuilder.OnBuildUi      += ChatBubbles;
        }
示例#8
0
 public void Start(IPluginContext <ExceptionConfig> context)
 {
     PluginLog.Add(Name + ".Start");
     throw new IOException("Failure in plugin provider");
 }
示例#9
0
 public void Stop(bool cancel)
 {
     PluginLog.Add(Name + ".Stop");
 }
        public void Initialize(DalamudPluginInterface pluginInterface)
        {
            lastCleanup            = Ms();
            actionToDamageTypeDict = new Dictionary <uint, DamageType>();
            futureFlyText          = new ConcurrentDictionary <uint, List <Tuple <long, DamageType, int> > >();
            text = new ConcurrentQueue <Tuple <IntPtr, long> >();
            ignoredCastActions = new HashSet <uint>();

            pi = pluginInterface;

            configuration = pi.GetPluginConfig() as Configuration ?? new Configuration();
            configuration.Initialize(pi, this);
            ui = new PluginUI(configuration, this);

            pi.CommandManager.AddHandler(commandName, new CommandInfo(OnCommand)
            {
                HelpMessage = "Display the Damage Info configuration interface."
            });

            var actionSheet = pi.Data.GetExcelSheet <Action>();

            foreach (var row in actionSheet)
            {
                DamageType tmpType = (DamageType)row.AttackType.Row;
                if (tmpType != DamageType.Magic && tmpType != DamageType.Darkness && tmpType != DamageType.Unknown)
                {
                    tmpType = DamageType.Physical;
                }

                actionToDamageTypeDict.Add(row.RowId, tmpType);

                if (row.ActionCategory.Row > 4 && row.ActionCategory.Row < 11)
                {
                    ignoredCastActions.Add(row.ActionCategory.Row);
                }
            }

            try
            {
                IntPtr createFlyTextFuncPtr = pi.TargetModuleScanner.ScanText(
                    "48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 40 48 63 FA 45 8B F0 48 8B F1 83 FF 34 7C 13 33 C0 48 8B 74 24 ?? 48 8B 7C 24 ?? 48 83 C4 40 41 5E C3");
                createFlyTextHook =
                    new Hook <CreateFlyTextDelegate>(createFlyTextFuncPtr, (CreateFlyTextDelegate)CreateFlyText);

                IntPtr receiveActionEffectFuncPtr =
                    pi.TargetModuleScanner.ScanText("4C 89 44 24 18 53 56 57 41 54 41 57 48 81 EC ?? 00 00 00 8B F9");
                receiveActionEffectHook = new Hook <ReceiveActionEffectDelegate>(receiveActionEffectFuncPtr,
                                                                                 (ReceiveActionEffectDelegate)ReceiveActionEffect);

                IntPtr setCastBarFuncPtr = pi.TargetModuleScanner.ScanText(
                    "48 89 5C 24 ?? 48 89 6C 24 ?? 56 48 83 EC 20 80 7C 24 ?? ?? 49 8B D9 49 8B E8 48 8B F2 74 22 49 8B 09 66 41 C7 41 ?? ?? ?? E8 ?? ?? ?? ?? 66 83 F8 69 75 0D 48 8B 0B BA ?? ?? ?? ?? E8 ?? ?? ?? ??");
                setCastBarHook = new Hook <SetCastBarDelegate>(setCastBarFuncPtr, (SetCastBarDelegate)SetCastBarDetour);

                IntPtr setFocusTargetCastBarFuncPtr = pi.TargetModuleScanner.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 41 0F B6 F9 49 8B E8 48 8B F2 48 8B D9");
                setFocusTargetCastBarHook = new Hook <SetCastBarDelegate>(setFocusTargetCastBarFuncPtr, (SetCastBarDelegate)SetFocusTargetCastBarDetour);
            }
            catch (Exception ex)
            {
                PluginLog.Log($"Encountered an error loading DamageInfoPlugin: {ex.Message}");
                PluginLog.Log("Plugin will not be loaded.");

                createFlyTextHook?.Disable();
                createFlyTextHook?.Dispose();
                receiveActionEffectHook?.Disable();
                receiveActionEffectHook?.Dispose();
                setCastBarHook?.Disable();
                setCastBarHook?.Dispose();
                setFocusTargetCastBarHook?.Disable();
                setFocusTargetCastBarHook?.Dispose();

                throw;
            }

            createFlyTextHook.Enable();
            receiveActionEffectHook.Enable();
            setCastBarHook.Enable();
            setFocusTargetCastBarHook.Enable();

            pi.UiBuilder.OnBuildUi      += DrawUI;
            pi.UiBuilder.OnOpenConfigUi += (sender, args) => DrawConfigUI();
        }
        private async void RunMessageQueue()
        {
            while (this.runQueue)
            {
                if (this.eventQueue.TryDequeue(out var resultEvent))
                {
                    try
                    {
                        if (resultEvent is QueuedRetainerItemSaleEvent retainerSaleEvent)
                        {
                            try
                            {
                                //foreach (var regex in retainerSaleRegexes[this.plugin.Interface.ClientState.ClientLanguage])
                                {
                                    //var matchInfo = regex.Match(retainerSaleEvent.Message.TextValue);

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

                                    var avatarUrl = Constant.LogoLink;

                                    if (itemLink == null)
                                    {
                                        PluginLog.Error("itemLink was null. Msg: {0}", BitConverter.ToString(retainerSaleEvent.Message.Encode()));
                                        break;
                                    }
                                    else
                                    {
                                        // XIVAPI wants these padded with 0s in the front if under 6 digits
                                        // at least if Titanium Ore testing is to be believed.
                                        var iconFolder = $"{itemLink.Item.Icon / 1000 * 1000}".PadLeft(6, '0');
                                        var iconFile   = $"{itemLink.Item.Icon}".PadLeft(6, '0');

                                        avatarUrl = $"https://xivapi.com" + $"/i/{iconFolder}/{iconFile}.png";

                                        /*
                                         * // we don't need this anymore because the above should work
                                         * // but it doesn't hurt to have it commented out as a fallback for the future
                                         * try
                                         * {
                                         *  ItemResult res = XivApiClient.GetItem(itemLink.Item.RowId).GetAwaiter().GetResult();
                                         *  avatarUrl = $"https://xivapi.com{res.Icon}";
                                         * }
                                         * catch (Exception ex)
                                         * {
                                         *  PluginLog.Error(ex, "Cannot fetch XIVAPI item search.");
                                         * }
                                         */
                                    }

                                    //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;

                                    //SendItemSaleEvent(uint itemId, int amount, bool isHq, string message, XivChatType chatType)

                                    await this.plugin.Discord.SendItemSaleEvent(itemLink.Item.Name, avatarUrl, itemLink.Item.RowId, retainerSaleEvent.Message.TextValue, retainerSaleEvent.ChatType);
                                }
                            }
                            catch (Exception e)
                            {
                                PluginLog.Error(e, "Could not send discord message.");
                            }
                        }

                        if (resultEvent is QueuedChatEvent chatEvent)
                        {
                            var senderName = (chatEvent.ChatType == XivChatType.TellOutgoing || chatEvent.ChatType == XivChatType.Echo)
                                ? this.plugin.State.LocalPlayer.Name
                                : chatEvent.Sender.ToString();
                            var senderWorld = string.Empty;

                            // for debugging. Make sure to comment this out for releases.

                            /*
                             * PluginLog.Debug($"Type: {chatEvent.ChatType} Sender: {chatEvent.Sender.TextValue} "
                             + $"Message: {chatEvent.Message.TextValue}");
                             */

                            try
                            {
                                if (this.plugin.State.LocalPlayer != null)
                                {
                                    var playerLink = chatEvent.Sender.Payloads.FirstOrDefault(x => x.Type == PayloadType.Player) as PlayerPayload;

                                    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 (chatEvent.Sender.TextValue.EndsWith(this.plugin.State.LocalPlayer.Name.TextValue))
                                        {
                                            senderName = this.plugin.State.LocalPlayer.Name;
                                        }
                                        else
                                        {
                                            // Franz is really tired of getting playerlink is null when there shouldn't be a player link for certain things
                                            switch (chatEvent.ChatType)
                                            {
                                            case XivChatType.Debug:
                                                break;

                                            case XivChatType.Urgent:
                                                break;

                                            case XivChatType.Notice:
                                                break;

                                            case XivChatType.TellOutgoing:
                                                senderName = this.plugin.State.LocalPlayer.Name;
                                                // senderWorld = this.plugin.Interface.ClientState.LocalPlayer.HomeWorld.GameData.Name;
                                                break;

                                            case XivChatType.StandardEmote:
                                                playerLink  = chatEvent.Message.Payloads.FirstOrDefault(x => x.Type == PayloadType.Player) as PlayerPayload;
                                                senderName  = playerLink.PlayerName;
                                                senderWorld = playerLink.World.Name;
                                                // we need to get the world here because cross-world people will be assumed local player's otherwise.

                                                /*
                                                 * senderWorld = chatEvent.Message.TextValue.TrimStart(senderName.ToCharArray()).Split(' ')[0];
                                                 * if (senderWorld.EndsWith("'s")) // f**k having to do this
                                                 *  senderWorld = senderWorld.Substring(0, senderWorld.Length - 2);
                                                 */
                                                break;

                                            case XivChatType.Echo:
                                                senderName = this.plugin.State.LocalPlayer.Name;
                                                // senderWorld = this.plugin.Interface.ClientState.LocalPlayer.HomeWorld.GameData.Name;
                                                break;

                                            case (XivChatType)61:     // NPC Talk
                                                senderName  = chatEvent.Sender.TextValue;
                                                senderWorld = "NPC";
                                                break;

                                            case (XivChatType)68:     // NPC Announcement
                                                senderName  = chatEvent.Sender.TextValue;
                                                senderWorld = "NPC";
                                                break;

                                            default:
                                                if ((int)chatEvent.ChatType >= 41 && (int)chatEvent.ChatType <= 55)     //ignore a bunch of non-chat messages
                                                {
                                                    break;
                                                }
                                                if ((int)chatEvent.ChatType >= 57 && (int)chatEvent.ChatType <= 70)     //ignore a bunch of non-chat messages
                                                {
                                                    break;
                                                }
                                                if ((int)chatEvent.ChatType >= 72 && (int)chatEvent.ChatType <= 100)     // ignore a bunch of non-chat messages
                                                {
                                                    break;
                                                }
                                                if ((int)chatEvent.ChatType > 107)     // don't handle anything past CWLS8 for now
                                                {
                                                    break;
                                                }
                                                PluginLog.Error($"playerLink was null.\nChatType: {chatEvent.ChatType} ({(int)chatEvent.ChatType}) Sender: {chatEvent.Sender.TextValue} Message: {chatEvent.Message.TextValue}");
                                                senderName = chatEvent.Sender.TextValue;
                                                break;
                                            }
                                        }

                                        // only if we still need one
                                        if (senderWorld.Equals(string.Empty))
                                        {
                                            senderWorld = this.plugin.State.LocalPlayer.HomeWorld.GameData.Name;
                                        }

                                        // PluginLog.Information($"FRANZDEBUGGINGNULL Playerlink is null: {senderName}@{senderWorld}");
                                    }
                                    else
                                    {
                                        senderName = chatEvent.ChatType == XivChatType.TellOutgoing
                                            ? this.plugin.State.LocalPlayer.Name
                                            : playerLink.PlayerName;
                                        senderWorld = chatEvent.ChatType == XivChatType.TellOutgoing
                                            ? this.plugin.State.LocalPlayer.HomeWorld.GameData.Name
                                            : playerLink.World.Name;
                                        // PluginLog.Information($"FRANZDEBUGGING Playerlink was not null: {senderName}@{senderWorld}");
                                    }
                                }
                                else
                                {
                                    // only do this one if it's debug

                                    /*
                                     * PluginLog.Debug($"Plugin interface LocalPlayer was null.\n"
                                     + $"ChatType: {chatEvent.ChatType} ({(int)chatEvent.ChatType}) Sender: {chatEvent.Sender.TextValue} Message: {chatEvent.Message.TextValue}");
                                     */
                                    senderName  = string.Empty;
                                    senderWorld = string.Empty;
                                }
                            }
                            catch (Exception ex)
                            {
                                PluginLog.Error(ex, "Could not deduce player name.");
                            }


                            try
                            {
                                await this.plugin.Discord.SendChatEvent(chatEvent.Message.TextValue, senderName.TextValue, senderWorld, chatEvent.ChatType, chatEvent.AvatarUrl);
                            }
                            catch (Exception e)
                            {
                                PluginLog.Error(e, "Could not send discord message.");
                            }
                        }

                        if (resultEvent is QueuedContentFinderEvent cfEvent)
                        {
                            try
                            {
                                await this.plugin.Discord.SendContentFinderEvent(cfEvent);
                            }
                            catch (Exception e)
                            {
                                PluginLog.Error(e, "Could not send discord message.");
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        PluginLog.Error(e, "Could not process event.");
                    }
                }

                Thread.Yield();
            }
        }
        public unsafe void ReceiveActionEffect(int sourceId, IntPtr sourceCharacter, IntPtr pos,
                                               IntPtr effectHeader,
                                               IntPtr effectArray, IntPtr effectTrail)
        {
            try
            {
                Cleanup();
                // no log, no processing... just get him outta here
                if ((!configuration.EffectLogEnabled &&
                     !(configuration.IncomingColorEnabled || configuration.OutgoingColorEnabled) &&
                     !configuration.SourceTextEnabled))
                {
                    receiveActionEffectHook.Original(sourceId, sourceCharacter, pos, effectHeader, effectArray,
                                                     effectTrail);
                    return;
                }

                uint   id          = *((uint *)effectHeader.ToPointer() + 0x2);
                uint   animId      = *((ushort *)effectHeader.ToPointer() + 0xE);
                ushort op          = *((ushort *)effectHeader.ToPointer() - 0x7);
                byte   targetCount = *(byte *)(effectHeader + 0x21);
                EffectLog(
                    $"--- source actor: {sourceId}, action id {id}, anim id {animId}, opcode: {op:X} numTargets: {targetCount} ---");

// #if DEBUG
                if (configuration.EffectLogEnabled)
                {
                    // EffectLog($"packet (effectHeader): {effectHeader.ToInt64():X}");
                    // LogFromPtr(effectHeader, 1024);
                    //
                    // EffectLog($"effectArray: {effectArray.ToInt64():X}");
                    // LogFromPtr(effectArray, 64);
                    //
                    // EffectLog($"effectTrail: {effectTrail.ToInt64():X}");
                    // LogFromPtr(effectTrail, 64);

                    // LogFromPtr(unk6, 64);
                }
// #endif

                int effectsEntries = 0;
                int targetEntries  = 1;
                if (targetCount == 0)
                {
                    effectsEntries = 0;
                    targetEntries  = 1;
                }
                else if (targetCount == 1)
                {
                    effectsEntries = 8;
                    targetEntries  = 1;
                }
                else if (targetCount <= 8)
                {
                    effectsEntries = 64;
                    targetEntries  = 8;
                }
                else if (targetCount <= 16)
                {
                    effectsEntries = 128;
                    targetEntries  = 16;
                }
                else if (targetCount <= 24)
                {
                    effectsEntries = 192;
                    targetEntries  = 24;
                }
                else if (targetCount <= 32)
                {
                    effectsEntries = 256;
                    targetEntries  = 32;
                }

                List <EffectEntry> entries = new List <EffectEntry>(effectsEntries);

                for (int i = 0; i < effectsEntries; i++)
                {
                    entries.Add(*(EffectEntry *)(effectArray + i * 8));
                }

                ulong[] targets = new ulong[targetEntries];

                for (int i = 0; i < targetCount; i++)
                {
                    targets[i] = *(ulong *)(effectTrail + i * 8);
                }

                for (int i = 0; i < entries.Count; i++)
                {
                    ulong tTarget = targets[i / 8];
                    uint  tDmg    = entries[i].value;
                    if (entries[i].mult != 0)
                    {
                        tDmg += ((uint)ushort.MaxValue + 1) * entries[i].mult;
                    }

                    if (entries[i].type == ActionEffectType.Damage ||
                        entries[i].type == ActionEffectType.BlockedDamage ||
                        entries[i].type == ActionEffectType.ParriedDamage
                        // || entries[i].type == ActionEffectType.Miss
                        )
                    {
                        EffectLog($"{entries[i]}, s: {sourceId} t: {tTarget}");
                        if (tDmg == 0)
                        {
                            continue;
                        }

                        int actId    = GetCharacterActorId();
                        int charaPet = FindCharaPet();

                        // if source text is enabled, we know exactly when to add it
                        if (configuration.SourceTextEnabled &&
                            ((int)tTarget == actId || configuration.PetSourceTextEnabled && sourceId == charaPet))
                        {
                            AddToFutureFlyText(tDmg, actionToDamageTypeDict[animId], sourceId);
                        }
                        else if (configuration.OutgoingColorEnabled &&
                                 (sourceId == actId || configuration.PetDamageColorEnabled && sourceId == charaPet))
                        {
                            AddToFutureFlyText(tDmg, actionToDamageTypeDict[animId], sourceId);
                        }
                        else if ((int)tTarget == actId && configuration.IncomingColorEnabled)
                        {
                            AddToFutureFlyText(tDmg, actionToDamageTypeDict[animId], sourceId);
                        }
                    }
                }

                receiveActionEffectHook.Original(sourceId, sourceCharacter, pos, effectHeader, effectArray,
                                                 effectTrail);
            }
            catch (Exception e)
            {
                PluginLog.Log($"{e.Message} {e.StackTrace}");
            }
        }
        public unsafe IntPtr CreateFlyText(
            IntPtr flyTextMgr, // or something
            UInt32 kind,
            UInt32 val1,
            UInt32 val2,
            IntPtr text1,
            UInt32 color,
            UInt32 icon,
            IntPtr text2,
            float unk3
            )
        {
            uint tColor = color;
            uint tVal1  = val1;

            if (Randomize)
            {
                int ttVal1 = ModifyDamageALittle((int)val1);
                tVal1 = (uint)ttVal1;
            }

            try
            {
                if (Hijack)
                {
                    string hjText1 = Marshal.PtrToStringAnsi(hijackStruct.text1);
                    string hjText2 = Marshal.PtrToStringAnsi(hijackStruct.text2);

                    FlyTextLog(
                        $"flytext hijacked: kind: {hijackStruct.kind}, val1: {hijackStruct.val1}, val2: {hijackStruct.val2}, color: {hijackStruct.color:X}, icon: {hijackStruct.icon}");
                    FlyTextLog($"text1: {hjText1} | text2: {hjText2}");

                    return(createFlyTextHook.Original(flyTextMgr, hijackStruct.kind, hijackStruct.val1,
                                                      hijackStruct.val2, hijackStruct.text1, hijackStruct.color, hijackStruct.icon,
                                                      hijackStruct.text2, unk3));
                }

                FlyTextKind ftKind = (FlyTextKind)kind;

                // wrap this here to lower overhead when not logging
                if (configuration.FlyTextLogEnabled)
                {
                    string strText1 = Marshal.PtrToStringAnsi(text1);
                    string strText2 = Marshal.PtrToStringAnsi(text2);

                    strText1 = strText1?.Replace("%", "%%");
                    strText2 = strText2?.Replace("%", "%%");

                    FlyTextLog(
                        $"flytext created: kind: {ftKind}, val1: {tVal1}, val2: {val2}, color: {color:X}, icon: {icon}");
                    FlyTextLog($"text1: {strText1} | text2: {strText2}");
                }

                if (TryGetFlyTextDamageType(tVal1, out DamageType dmgType, out int sourceId))
                {
                    int charaId = GetCharacterActorId();
                    int petId   = FindCharaPet();

                    if (configuration.OutgoingColorEnabled || configuration.IncomingColorEnabled)
                    {
                        // sourceId == GetCharacterActorId() && configuration.OutgoingColorEnabled || (sourceId != GetCharacterActorId() && sourceId != FindCharaPet() && configuration.IncomingColorEnabled)
                        bool outPlayer = sourceId == charaId && configuration.OutgoingColorEnabled;
                        bool outPet    = sourceId == petId && configuration.PetDamageColorEnabled;
                        bool outCheck  = outPlayer || outPet;

                        bool incCheck = sourceId != charaId && sourceId != petId && configuration.IncomingColorEnabled;

                        // match up the condition with what to check
                        // because right now with this OR, it doesn't care if the source is incoming and outgoing is enabled
                        // so make sure that it oes it right
                        if (outCheck && !incCheck || !outCheck && incCheck)
                        {
                            if (ftKind == FlyTextKind.AutoAttack ||
                                ftKind == FlyTextKind.CriticalHit ||
                                ftKind == FlyTextKind.DirectHit ||
                                ftKind == FlyTextKind.CriticalDirectHit ||
                                ftKind == FlyTextKind.NamedAttack ||
                                ftKind == FlyTextKind.NamedDirectHit ||
                                ftKind == FlyTextKind.NamedCriticalHit ||
                                ftKind == FlyTextKind.NamedCriticalDirectHit)
                            {
                                switch (dmgType)
                                {
                                case DamageType.Physical:
                                    tColor = ImGui.GetColorU32(configuration.PhysicalColor);
                                    break;

                                case DamageType.Magic:
                                    tColor = ImGui.GetColorU32(configuration.MagicColor);
                                    break;

                                case DamageType.Darkness:
                                    tColor = ImGui.GetColorU32(configuration.DarknessColor);
                                    break;
                                }
                            }
                        }
                    }

                    if (configuration.SourceTextEnabled)
                    {
                        bool tgtCheck = sourceId != charaId && sourceId != petId;
                        bool petCheck = sourceId == petId && configuration.PetSourceTextEnabled;

                        if (tgtCheck || petCheck)
                        {
                            string name = GetActorName(sourceId);

                            if (!string.IsNullOrEmpty(name))
                            {
                                string existingText = "";
                                if (text1 != IntPtr.Zero)
                                {
                                    existingText = Marshal.PtrToStringUni(text1);
                                    existingText = Encoding.UTF8.GetString(Encoding.Unicode.GetBytes(existingText));
                                }

                                string combined = $"from {name} {existingText}";
                                combined = Encoding.Unicode.GetString(Encoding.UTF8.GetBytes(combined));
                                text1    = Marshal.StringToHGlobalUni(combined);
                                text.Enqueue(new Tuple <IntPtr, long>(text1, Ms()));
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                PluginLog.Log($"{e.Message} {e.StackTrace}");
            }

            return(createFlyTextHook.Original(flyTextMgr, kind, tVal1, val2, text1, tColor, icon, text2, unk3));
        }
示例#14
0
        private List <DisplayTimer> GetTimerList(MonitorDisplay display)
        {
            var timerList = new List <DisplayTimer>();

            if (InPvP)
            {
                return(timerList);
            }
            try {
                if (display.Cooldowns.Count > 0)
                {
                    foreach (var cd in display.Cooldowns.Where(cd => {
                        if (cd.ClassJob != PluginInterface.ClientState.LocalPlayer.ClassJob.Id)
                        {
                            return(false);
                        }
                        var action = ActionManager.GetAction(cd.ActionId);
                        if (action == null || !action.ClassJobCategory.Value.HasClass(PluginInterface.ClientState.LocalPlayer.ClassJob.Id))
                        {
                            return(false);
                        }
                        if (action.ClassJobLevel > PluginInterface.ClientState.LocalPlayer.Level)
                        {
                            return(false);
                        }
                        var cooldown = ActionManager.GetActionCooldown(action);
                        if (display.OnlyShowReady && cooldown.IsOnCooldown)
                        {
                            return(false);
                        }
                        if (display.OnlyShowCooldown && !cooldown.IsOnCooldown)
                        {
                            return(false);
                        }
                        if (display.LimitDisplayTime && cooldown.Countdown > display.LimitDisplayTimeSeconds)
                        {
                            return(false);
                        }
                        if (display.LimitDisplayReadyTime && cooldown.CompleteFor > display.LimitDisplayReadyTimeSeconds)
                        {
                            return(false);
                        }
                        return(true);
                    }))
                    {
                        var action = ActionManager.GetAction(cd.ActionId);

                        if (action != null)
                        {
                            var cooldown = ActionManager.GetActionCooldown(action);
                            timerList.Add(new DisplayTimer {
                                TimerMax      = cooldown.CooldownTotal,
                                TimerCurrent  = cooldown.CooldownElapsed + cooldown.CompleteFor,
                                FinishedColor = display.AbilityReadyColor,
                                ProgressColor = display.AbilityCooldownColor,
                                IconId        = IconManager.GetActionIconId(action),
                                Name          = action.Name
                            });
                        }
                    }
                }
            } catch (Exception ex) {
                PluginLog.LogError("Error parsing cooldowns.");
                PluginLog.Log(ex.ToString());
            }

            try {
                if (display.StatusMonitors.Count > 0)
                {
                    var localPlayerAsList = new List <Actor>()
                    {
                        PluginInterface.ClientState.LocalPlayer
                    };

                    foreach (var sd in display.StatusMonitors.Where(sm => sm.ClassJob == PluginInterface.ClientState.LocalPlayer.ClassJob.Id))
                    {
                        foreach (var sid in sd.StatusIDs)
                        {
                            var status = PluginInterface.Data.Excel.GetSheet <Status>().GetRow(sid);
                            if (status == null)
                            {
                                continue;
                            }

                            if (!ActorsWithStatus.ContainsKey(status.RowId))
                            {
                                continue;
                            }

                            foreach (var a in sd.SelfOnly ? localPlayerAsList : ActorsWithStatus[status.RowId])
                            {
                                if (a != null)
                                {
                                    foreach (var se in a.StatusEffects)
                                    {
                                        if (sd.IsRaid == false && se.OwnerId != PluginInterface.ClientState.LocalPlayer.ActorId)
                                        {
                                            continue;
                                        }
                                        if (sd.LimitedZone > 0 && sd.LimitedZone != PluginInterface.ClientState.TerritoryType)
                                        {
                                            continue;
                                        }
                                        if (display.LimitDisplayTime && se.Duration > display.LimitDisplayTimeSeconds)
                                        {
                                            continue;
                                        }
                                        if (se.EffectId == (short)status.RowId)
                                        {
                                            var t = new DisplayTimer {
                                                TimerMax      = sd.MaxDuration,
                                                TimerCurrent  = sd.MaxDuration - se.Duration,
                                                FinishedColor = display.AbilityReadyColor,
                                                ProgressColor = display.StatusEffectColor,
                                                IconId        = status.Icon,
                                                Name          = status.Name
                                            };

                                            if (!sd.SelfOnly)
                                            {
                                                t.TargetName  = a.Name;
                                                t.ClickAction = sd.ClickHandler;
                                                t.ClickParam  = a;
                                            }

                                            timerList.Add(t);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                PluginLog.LogError("Error parsing statuses.");
                PluginLog.Log(ex.ToString());
            }

            timerList.Sort((a, b) => {
                var diff = a.TimerRemaining - b.TimerRemaining;
                if (Math.Abs(diff) < 0.1)
                {
                    return(string.CompareOrdinal(a.Name, b.Name));                      // Equal
                }
                if (diff < 0)
                {
                    return(-1);
                }
                return(1);
            });

            foreach (var reminder in display.GeneralReminders)
            {
                if (reminder.ShouldShow(PluginInterface, this, display))
                {
                    timerList.Insert(0, new DisplayTimer {
                        TimerMax       = 1,
                        TimerCurrent   = 1 + generalStopwatch.ElapsedMilliseconds / 1000f,
                        FinishedColor  = display.AbilityReadyColor,
                        ProgressColor  = display.StatusEffectColor,
                        IconId         = reminder.GetIconID(PluginInterface, this, display),
                        Name           = reminder.GetText(PluginInterface, this, display),
                        AllowCountdown = false
                    });
                }
            }

            return(timerList);
        }
示例#15
0
    // Parse a single rgsp file.
    public static TexToolsMeta FromRgspFile(string filePath, byte[] data)
    {
        if (data.Length != 45 && data.Length != 42)
        {
            PluginLog.Error("Error while parsing .rgsp file:\n\tInvalid number of bytes.");
            return(Invalid);
        }

        using var s  = new MemoryStream(data);
        using var br = new BinaryReader(s);
        // The first value is a flag that signifies version.
        // If it is byte.max, the following two bytes are the version,
        // otherwise it is version 1 and signifies the sub race instead.
        var flag    = br.ReadByte();
        var version = flag != 255 ? ( uint )1 : br.ReadUInt16();

        var ret = new TexToolsMeta(filePath, version);

        // SubRace is offset by one due to Unknown.
        var subRace = ( SubRace )(version == 1 ? flag + 1 : br.ReadByte() + 1);

        if (!Enum.IsDefined(typeof(SubRace), subRace) || subRace == SubRace.Unknown)
        {
            PluginLog.Error($"Error while parsing .rgsp file:\n\t{subRace} is not a valid SubRace.");
            return(Invalid);
        }

        // Next byte is Gender. 1 is Female, 0 is Male.
        var gender = br.ReadByte();

        if (gender != 1 && gender != 0)
        {
            PluginLog.Error($"Error while parsing .rgsp file:\n\t{gender} is neither Male nor Female.");
            return(Invalid);
        }

        // Add the given values to the manipulations if they are not default.
        void Add(RspAttribute attribute, float value)
        {
            var def = CmpFile.GetDefault(subRace, attribute);

            if (value != def)
            {
                ret.MetaManipulations.Add(new RspManipulation(subRace, attribute, value));
            }
        }

        if (gender == 1)
        {
            Add(RspAttribute.FemaleMinSize, br.ReadSingle());
            Add(RspAttribute.FemaleMaxSize, br.ReadSingle());
            Add(RspAttribute.FemaleMinTail, br.ReadSingle());
            Add(RspAttribute.FemaleMaxTail, br.ReadSingle());

            Add(RspAttribute.BustMinX, br.ReadSingle());
            Add(RspAttribute.BustMinY, br.ReadSingle());
            Add(RspAttribute.BustMinZ, br.ReadSingle());
            Add(RspAttribute.BustMaxX, br.ReadSingle());
            Add(RspAttribute.BustMaxY, br.ReadSingle());
            Add(RspAttribute.BustMaxZ, br.ReadSingle());
        }
        else
        {
            Add(RspAttribute.MaleMinSize, br.ReadSingle());
            Add(RspAttribute.MaleMaxSize, br.ReadSingle());
            Add(RspAttribute.MaleMinTail, br.ReadSingle());
            Add(RspAttribute.MaleMaxTail, br.ReadSingle());
        }

        return(ret);
    }
示例#16
0
 public void OnIgniteStart()
 {
     PluginLog.Add(Name + ".OnIgniteStart");
 }
 public void Initialize(DalamudPluginInterface pluginInterface)
 {
     PluginLog.Log("Starting");
     this.PluginInterface = pluginInterface;
     pluginInterface.UiBuilder.OnBuildUi += this.BuildUI;
 }
示例#18
0
 public void OnIgniteStop(bool cancel)
 {
     PluginLog.Add(Name + ".OnIgniteStop");
 }
示例#19
0
        private void Chat_OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
        {
            try
            {
                var            senderName = sender.TextValue;
                List <Payload> payloads   = message.Payloads;


                foreach (var tab in items)
                {
                    int chan = ConvertForArray(type.ToString());
                    if (chan < Channels.Length)
                    {
                        if (tab.Logs[chan])
                        {
                            ChatText tmp = new ChatText();

                            tmp.Time         = GetTime();
                            tmp.ChannelShort = GetChannelName(type.ToString());
                            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;
                            foreach (var payload in payloads)
                            {
                                //if (payload.Type == PayloadType.AutoTranslateText) { texttype = 0; }
                                //if (payload.Type == PayloadType.Item) { texttype = 1; }
                                if (payload.Type == PayloadType.MapLink)
                                {
                                    replace     = 2;
                                    payloadType = PayloadType.MapLink;
                                    payloader   = payload;
                                }
                                //if (payload.Type == PayloadType.Player) { texttype = 3; }
                                //if (payload.Type == PayloadType.RawText) { texttype = 4; }
                                //if (payload.Type == PayloadType.Status) { texttype = 5; }
                                //if (payload.Type == PayloadType.UIForeground) { texttype = 6; }
                                //if (payload.Type == PayloadType.UIGlow) { texttype = 7; }

                                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--;
                                    }
                                }

                                //PluginLog.Log(payload.ToString());
                            }

                            tmp.Text = rawtext;

                            String messageString     = message.TextValue;
                            String predictedLanguage = Lang(messageString);

                            if (predictedLanguage == language)
                            {
                                Task.Run(() => Tran(type, messageString, senderName));
                            }

                            tab.Chat.Add(tmp);

                            if (tab.Chat.Count > 256)
                            {
                                tab.Chat.RemoveAt(0);
                            }

                            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;
                            }
                            tab.msg = true;
                        }
                    }
                    else
                    {
                        PluginLog.Log("[" + chan.ToString() + "] " + message.TextValue);
                    }
                }
            }
            catch (Exception e)
            {
                PluginLog.LogError(e.ToString());
            }
        }
示例#20
0
 public void Start(IPluginContext <NormalConfig> context)
 {
     PluginLog.Add(Name + ".Start");
 }
示例#21
0
        private void Chat_OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
        {
            try
            {
                if (!isHandled)
                {
                    if (outputAllJsons)
                    {
                        try
                        {
                            JsonLog(new OnChatMessageArgs(type, senderId, sender, message));
                        }
                        catch (Exception e)
                        {
                            ErrorLog(e.ToString());
                        }
                    }

                    ChannelSettings channel = GetChannelSettings(type);

                    if (channel.Name == "None" && type != XivChatType.None)
                    {
                        DebugLog($"{type.ToString()} ({(int)type})\t{message.TextValue}");
                    }

                    var splitPayloads      = new List <List <Payload> >();
                    var currentPayloadList = new List <Payload>();

                    foreach (var payload in message.Payloads)
                    {
                        if (payload.Type == PayloadType.RawText && ((TextPayload)payload).Text.Contains('\n'))
                        {
                            var newPayloads = ((TextPayload)payload).Text.Split('\n').Select(x => new TextPayload(x)).ToList();

                            currentPayloadList.Add(newPayloads[0]);
                            splitPayloads.Add(currentPayloadList);
                            for (int i = 1; i < newPayloads.Count - 1; i++)
                            {
                                splitPayloads.Add(new List <Payload>
                                {
                                    newPayloads[i]
                                });
                            }
                            currentPayloadList = new List <Payload>
                            {
                                newPayloads[newPayloads.Count - 1]
                            };
                        }
                        else
                        {
                            currentPayloadList.Add(payload);
                        }
                    }
                    splitPayloads.Add(currentPayloadList);

                    var textLogEntries = new List <TextLogEntry>();
                    textLogEntries.Add(CreateTextLogEntry(channel, senderId, sender.Payloads, splitPayloads.First()));

                    foreach (var payloads in splitPayloads.Skip(1))
                    {
                        textLogEntries.Add(CreateTextLogEntry(channel, 0, null, payloads));
                    }

                    foreach (var textLogEntry in textLogEntries)
                    {
                        chatBuffer.Enqueue(textLogEntry);

                        while (chatBuffer.Count > 200000)
                        {
                            TextLogEntry removedLogEntry;
                            chatBuffer.TryDequeue(out removedLogEntry);

                            foreach (var tab in tabs)
                            {
                                if (tab.EnabledChannels.ContainsKey(channel.Name) && tab.EnabledChannels[channel.Name])
                                {
                                    tab.FilteredLogs.RemoveAt(0);
                                }
                            }
                        }

                        foreach (var tab in tabs)
                        {
                            if (tab.EnabledChannels.ContainsKey(channel.Name))
                            {
                                if (tab.EnabledChannels[channel.Name])
                                {
                                    tab.AddLine(textLogEntry);
                                }
                            }
                            else
                            {
                                ErrorLog($"Channel name not found: {channel.Name}");
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                PluginLog.LogError(e.ToString());
                if (outputErrorJsons)
                {
                    JsonLogError(new OnChatMessageArgs(type, senderId, sender, message));
                }
            }
        }
示例#22
0
        void DrawSettingsTab()
        {
            var ret = ImGui.BeginTabItem("Settings");

            if (!ret)
            {
                return;
            }

            // FUCKKKKK
            var basePath = _plugin.Configuration.BaseFolder;

            if (ImGui.InputText("Root Folder", ref basePath, 255))
            {
                _plugin.Configuration.BaseFolder = basePath;
            }

            if (ImGui.Button("Rediscover Mods"))
            {
                ReloadMods();
            }

            if (ImGui.Button("Reload Player Resource"))
            {
                _plugin.ResourceLoader.ReloadPlayerResource();
            }

            if (!_isImportRunning)
            {
                if (ImGui.Button("Import TexTools Modpacks"))
                {
                    _isImportRunning = true;

                    Task.Run(async() =>
                    {
                        var picker = new OpenFileDialog
                        {
                            Multiselect     = true,
                            Filter          = "TexTools TTMP Modpack (*.ttmp2)|*.ttmp*|All files (*.*)|*.*",
                            CheckFileExists = true,
                            Title           = "Pick one or more modpacks."
                        };

                        var result = await picker.ShowDialogAsync();

                        if (result == DialogResult.OK)
                        {
                            try
                            {
                                var importer =
                                    new TexToolsImport(new DirectoryInfo(_plugin.Configuration.BaseFolder));

                                foreach (var fileName in picker.FileNames)
                                {
                                    PluginLog.Log("-> {0} START", fileName);

                                    importer.ImportModPack(new FileInfo(fileName));

                                    PluginLog.Log("-> {0} OK!", fileName);
                                }

                                ReloadMods();
                            }
                            catch (Exception ex)
                            {
                                PluginLog.LogError(ex, "Could not import one or more modpacks.");
                            }
                        }

                        _isImportRunning = false;
                    });
                }
            }
            else
            {
                ImGui.Button("Import in progress...");
            }

            if (ImGui.Button("Save Settings"))
            {
                _plugin.Configuration.Save();
            }

            if (_plugin.ResourceLoader != null)
            {
                ImGui.Checkbox("DEBUG Log all loaded files", ref _plugin.ResourceLoader.LogAllFiles);
            }

            ImGui.EndTabItem();
        }
示例#23
0
        public Plugin()
        {
            _pluginConfiguration = (PluginConfiguration)(PluginInterface.GetPluginConfig() ?? new PluginConfiguration());

            PluginInterface.UiBuilder.BuildFonts += UiBuilderOnBuildFonts;
            PluginInterface.UiBuilder.RebuildFonts();

            _hudWindowWindow     = new HudWindow(_pluginConfiguration);
            _configurationWindow = new ConfigurationWindow(this, _pluginConfiguration);

            var items = new[]
            {
                "CleanCurves",
                "GlowArc",
                "RivetBar"
            };

            foreach (var item in items)
            {
                LoadStyle(item, Path.Combine(PluginInterface.AssemblyLocation.DirectoryName !, "Styles"), false);
            }

            if (!string.IsNullOrEmpty(_pluginConfiguration.UserStylePath))
            {
                if (!Directory.Exists(_pluginConfiguration.UserStylePath))
                {
                    PluginLog.Error($"{_pluginConfiguration.UserStylePath} was not found.");
                }
                else
                {
                    foreach (var item in Directory.GetDirectories(_pluginConfiguration.UserStylePath))
                    {
                        LoadStyle(item, _pluginConfiguration.UserStylePath, true);
                    }
                }
            }

            if (_pluginConfiguration.IsUserStyle && !UserStyles.ContainsKey(_pluginConfiguration.SelectedStyle))
            {
                _pluginConfiguration.IsUserStyle   = false;
                _pluginConfiguration.SelectedStyle = items[0];
                _pluginConfiguration.Save();
            }

            if (_pluginConfiguration.IsUserStyle)
            {
                _pluginConfiguration.BarImage           = UserStyles[_pluginConfiguration.SelectedStyle][0];
                _pluginConfiguration.BarBackgroundImage =
                    UserStyles[_pluginConfiguration.SelectedStyle][1];
                _pluginConfiguration.BarCastImage           = UserStyles[_pluginConfiguration.SelectedStyle][2];
                _pluginConfiguration.BarCastBackgroundImage =
                    UserStyles[_pluginConfiguration.SelectedStyle][3];
            }
            else
            {
                _pluginConfiguration.BarImage           = Styles[_pluginConfiguration.SelectedStyle][0];
                _pluginConfiguration.BarBackgroundImage =
                    Styles[_pluginConfiguration.SelectedStyle][1];
                _pluginConfiguration.BarCastImage           = Styles[_pluginConfiguration.SelectedStyle][2];
                _pluginConfiguration.BarCastBackgroundImage =
                    Styles[_pluginConfiguration.SelectedStyle][3];
            }

            CommandManager.AddHandler("/pside", new CommandInfo(PluginCommand)
            {
                HelpMessage = "Opens configuration window",
                ShowInHelp  = true
            });

            PluginInterface.UiBuilder.Draw         += UiBuilderOnOnBuildUi;
            PluginInterface.UiBuilder.OpenConfigUi += UiBuilderOnOnOpenConfigUi;
        }
示例#24
0
 public SeFunctionBase(SigScanner sigScanner, int offset)
 {
     Address = sigScanner.Module.BaseAddress + offset;
     PluginLog.Debug($"{GetType().Name} address 0x{Address.ToInt64():X16}, baseOffset 0x{offset:X16}.");
 }
示例#25
0
        private void Framework_OnUpdateEvent(Framework framework)
        {
            try
            {
                if (!_pi.Data.IsDataReady)
                {
                    return;
                }

                if (_territoryTypes == null)
                {
                    _territoryTypes = _pi.Data.GetExcelSheet <TerritoryType>().ToList();
                }

                var localPlayer     = _pi.ClientState.LocalPlayer;
                var territoryTypeId = _pi.ClientState.TerritoryType;

                // Data not ready
                if (localPlayer == null)
                {
                    return;
                }

                var placeName       = "The Source";
                var placeNameZone   = "Void";
                var loadingImageKey = 1;

                if (territoryTypeId != 0)
                {
                    var territoryType = _territoryTypes.First(x => x.RowId == territoryTypeId);
                    placeName       = territoryType.PlaceName.Value?.Name ?? "Unknown";
                    placeNameZone   = territoryType.PlaceNameRegion.Value?.Name ?? "Unknown";
                    loadingImageKey = territoryType.LoadingImage;
                }

                var largeImageKey = $"li_{loadingImageKey}";

                var fcName = localPlayer.CompanyTag;

                if (fcName != string.Empty)
                {
                    fcName = $" <{fcName}>";
                }

                var worldName = localPlayer.CurrentWorld.GameData.Name.ToString();

                if (localPlayer.CurrentWorld.Id != localPlayer.HomeWorld.Id)
                {
                    worldName = $"{worldName} (🏠{localPlayer.HomeWorld.GameData.Name})";
                }

                var playerName = $"{localPlayer.Name}{fcName}";
                if (!Config.ShowName)
                {
                    playerName = placeName;
                }

                if (!Config.ShowWorld)
                {
                    worldName = Config.ShowName ? placeName : placeNameZone;
                }


                var rp = new DiscordRPC.RichPresence
                {
                    Details = playerName,
                    State   = worldName,
                    Assets  = new Assets
                    {
                        LargeImageKey  = largeImageKey,
                        LargeImageText = placeName,
                        SmallImageKey  = $"class_{localPlayer.ClassJob.Id}",
                        SmallImageText = localPlayer.ClassJob.GameData.Abbreviation + " Lv." + localPlayer.Level
                    },
                };

                if (Config.ShowStartTime)
                {
                    rp.Timestamps = new Timestamps(startTime);
                }


                _discordPresenceManager.SetPresence(rp);
            }
            catch (Exception ex)
            {
                PluginLog.LogError(ex, "Could not run RichPresence OnUpdate.");
            }
        }
示例#26
0
        private unsafe void ContextMenuOpenedImplementation(AddonContextMenu *addonContextMenu, ref int atkValueCount, ref AtkValue *atkValues)
        {
            if (this.ContextMenuOpened == null ||
                this.currentAgentContextInterface == null)
            {
                return;
            }

            var contextMenuReaderWriter = new ContextMenuReaderWriter(this.currentAgentContextInterface, atkValueCount, atkValues);

            // Check for a title.
            string?title = null;

            if (this.selectedOpenSubContextMenuItem != null)
            {
                title = this.selectedOpenSubContextMenuItem.Name.TextValue;

                // Write the custom title
                var titleAtkValue = &atkValues[1];
                fixed(byte *titlePtr = this.selectedOpenSubContextMenuItem.Name.Encode().NullTerminate())
                {
                    titleAtkValue->SetString(titlePtr);
                }
            }
            else if (contextMenuReaderWriter.Title != null)
            {
                title = contextMenuReaderWriter.Title.TextValue;
            }

            // Determine which event to raise.
            var contextMenuOpenedDelegate = this.ContextMenuOpened;

            // this.selectedOpenSubContextMenuItem is OpenSubContextMenuItem openSubContextMenuItem
            if (this.selectedOpenSubContextMenuItem != null)
            {
                contextMenuOpenedDelegate = this.selectedOpenSubContextMenuItem.Opened;
            }

            // Get the existing items from the game.
            // TODO: For inventory sub context menus, we take only the last item -- the return item.
            // This is because we're doing a hack to spawn a Second Tier sub context menu and then appropriating it.
            var contextMenuItems = contextMenuReaderWriter.Read();

            if (IsInventoryContext(this.currentAgentContextInterface) && this.selectedOpenSubContextMenuItem != null)
            {
                contextMenuItems = contextMenuItems.TakeLast(1).ToArray();
            }

            var beforeHashCode = GetContextMenuItemsHashCode(contextMenuItems);

            // Raise the event and get the context menu changes.
            this.currentContextMenuOpenedArgs = this.NotifyContextMenuOpened(addonContextMenu, this.currentAgentContextInterface, title, contextMenuOpenedDelegate, contextMenuItems);
            if (this.currentContextMenuOpenedArgs == null)
            {
                return;
            }

            var afterHashCode = GetContextMenuItemsHashCode(this.currentContextMenuOpenedArgs.Items);

            PluginLog.Warning($"{beforeHashCode}={afterHashCode}");

            // Only write to memory if the items were actually changed.
            if (beforeHashCode != afterHashCode)
            {
                // Write the new changes.
                contextMenuReaderWriter.Write(this.currentContextMenuOpenedArgs.Items);

                // Update the addon.
                atkValueCount = *(&addonContextMenu->AtkValuesCount) = (ushort)contextMenuReaderWriter.AtkValueCount;
                atkValues     = *(&addonContextMenu->AtkValues) = contextMenuReaderWriter.AtkValues;
            }
        }
示例#27
0
        private void Update()
        {
            var currentSong    = (ushort)0;
            var currentSong2   = (ushort)0;
            var activePriority = 0;

            this.Address.UpdateBGMControl();
            if (this.Address.BGMControl != IntPtr.Zero)
            {
                unsafe
                {
                    var bgms = (BGMPlayback *)this.Address.BGMControl.ToPointer();

                    // as far as I have seen, the control blocks are in priority order
                    // and the highest priority populated song is what the client current plays
                    for (var ap = 0; ap < ControlBlockCount; ap++)
                    {
                        // TODO: everything here is awful and makes me sad

                        // This value isn't a collection of flags, but it seems like if it's 0 entirely, the song at this
                        // priority isn't playing
                        // Earlying out here since the checks below are already awful enough
                        if (bgms[ap].songId == 0)
                        {
                            continue;
                        }

                        // reading songId2 here, because occasionally songId is something different
                        // not sure of what the meaning is when that is the case
                        // eg, songId2 and songId3 are 0x7, which is correct, but songId was 0x3EB
                        // We could also read songId3, but there are cases where it is set despite not playing
                        // (eg, user disables mount music, songId and songId2 will be 0, but songId3 will be the non-playing mount song)

                        // An attempt to deal with the weird "fighting" sound issue, which results in a lot of incorrect spam
                        // of song changes.
                        // Often with overlaid zone music (beast tribes, festivals, etc), prio 10 will be the actual music the user
                        // hears, but it will very quickly reset songId2 to 0 and then back, while songId3 doesn't change.
                        // This leads to song transition messages to the prio 11 zone music and then back to the overlaid prio 10 music
                        // over and over again, despite the actual music being played not changing.
                        if (ap == previousSongInfo.priority && bgms[ap].songId2 == 0 &&
                            previousSongInfo.songId != 0 && bgms[ap].songId3 == previousSongInfo.songId)
                        {
#if DEBUG
                            PluginLog.Log("skipping change from {0} to {1} on prio {2}", previousSongInfo.songId, bgms[ap].songId2, ap);
#endif
                            return;
                        }

                        // TODO: might want to have a method to check if an id is valid, in case there are other weird cases
                        if (bgms[ap].songId2 != 0 && bgms[ap].songId2 != 9999)
                        {
                            if (currentSong == 0)
                            {
                                currentSong    = bgms[ap].songId2;
                                activePriority = ap;
                                if (ap > 0)
                                {
                                    currentSong2 = currentSong;
                                    break;
                                }
                            }
                            else
                            {
                                currentSong2 = bgms[ap].songId2;
                                break;
                            }
                        }
                    }
                }
            }

            // separate variable because 0 is valid if nothing is playing
            if (CurrentSongId != currentSong)
            {
#if DEBUG
                PluginLog.Log($"changed to song {currentSong} at priority {activePriority}");
#endif
                CurrentSongId = currentSong;

                OnSongChanged?.Invoke(currentSong);

                previousSongInfo.Set(activePriority, currentSong);
            }

            if (CurrentSongId2 != currentSong2)
            {
#if DEBUG
                PluginLog.Log($"Area song changed to {currentSong2} ");
#endif
                CurrentSongId2 = currentSong2;

                OnSongChanged2?.Invoke(currentSong2);
            }
        }
示例#28
0
        private unsafe ContextMenuOpenedArgs?NotifyContextMenuOpened(AddonContextMenu *addonContextMenu, AgentContextInterface *agentContextInterface, string?title, ContextMenus.ContextMenuOpenedDelegate contextMenuOpenedDelegate, IEnumerable <ContextMenuItem> initialContextMenuItems)
        {
            var parentAddonName = this.GetParentAddonName(&addonContextMenu->AtkUnitBase);

            Log.Warning($"AgentContextInterface at: {new IntPtr(agentContextInterface):X}");

            InventoryItemContext?inventoryItemContext = null;
            GameObjectContext?   gameObjectContext    = null;

            if (IsInventoryContext(agentContextInterface))
            {
                var agentInventoryContext = (AgentInventoryContext *)agentContextInterface;
                inventoryItemContext = new InventoryItemContext(agentInventoryContext->InventoryItemId, agentInventoryContext->InventoryItemCount, agentInventoryContext->InventoryItemIsHighQuality);
            }
            else
            {
                var agentContext = (AgentContext *)agentContextInterface;

                uint?id = agentContext->GameObjectId;
                if (id == 0)
                {
                    id = null;
                }

                ulong?contentId = agentContext->GameObjectContentId;
                if (contentId == 0)
                {
                    contentId = null;
                }

                var name = MemoryHelper.ReadSeStringNullTerminated((IntPtr)agentContext->GameObjectName.StringPtr).TextValue;
                if (string.IsNullOrEmpty(name))
                {
                    name = null;
                }

                ushort?worldId = agentContext->GameObjectWorldId;
                if (worldId == 0)
                {
                    worldId = null;
                }

                if (id != null ||
                    contentId != null ||
                    name != null ||
                    worldId != null)
                {
                    gameObjectContext = new GameObjectContext(id, contentId, name, worldId);
                }
            }

            // Temporarily remove the < Return item, for UX we should enforce that it is always last in the list.
            var lastContextMenuItem = initialContextMenuItems.LastOrDefault();

            if (lastContextMenuItem is GameContextMenuItem gameContextMenuItem && gameContextMenuItem.SelectedAction == 102)
            {
                initialContextMenuItems = initialContextMenuItems.SkipLast(1);
            }

            var contextMenuOpenedArgs = new ContextMenuOpenedArgs(addonContextMenu, agentContextInterface, parentAddonName, initialContextMenuItems)
            {
                Title = title,
                InventoryItemContext = inventoryItemContext,
                GameObjectContext    = gameObjectContext,
            };

            try
            {
                contextMenuOpenedDelegate.Invoke(contextMenuOpenedArgs);
            }
            catch (Exception ex)
            {
                PluginLog.LogError(ex, "NotifyContextMenuOpened");
                return(null);
            }

            // Readd the < Return item
            if (lastContextMenuItem is GameContextMenuItem gameContextMenuItem1 && gameContextMenuItem1.SelectedAction == 102)
            {
                contextMenuOpenedArgs.Items.Add(lastContextMenuItem);
            }

            foreach (var contextMenuItem in contextMenuOpenedArgs.Items.ToArray())
            {
                // TODO: Game doesn't support nested sub context menus, but we might be able to.
                if (contextMenuItem is OpenSubContextMenuItem && contextMenuOpenedArgs.Title != null)
                {
                    contextMenuOpenedArgs.Items.Remove(contextMenuItem);
                    PluginLog.Warning($"Context menu '{contextMenuOpenedArgs.Title}' item '{contextMenuItem}' has been removed because nested sub context menus are not supported.");
                }
            }

            if (contextMenuOpenedArgs.Items.Count > MaxContextMenuItemsPerContextMenu)
            {
                PluginLog.LogWarning($"Context menu requesting {contextMenuOpenedArgs.Items.Count} of max {MaxContextMenuItemsPerContextMenu} items. Resizing list to compensate.");
                contextMenuOpenedArgs.Items.RemoveRange(MaxContextMenuItemsPerContextMenu, contextMenuOpenedArgs.Items.Count - MaxContextMenuItemsPerContextMenu);
            }

            return(contextMenuOpenedArgs);
        }
示例#29
0
 private IntPtr AddonSalvageDialogOnSetupDetour(IntPtr addon, uint a2, IntPtr dataPtr)
 {
     PluginLog.Debug($"AddonSalvageDialog.OnSetup");
     return(AddonNoTextMatchDetour(addon, a2, dataPtr, AddonSalvageDialogOnSetupHook, Configuration.DesynthDialogEnabled, "desynthesize_checkbox", "desynthesize"));
 }
示例#30
0
        public bool Draw()
        {
            var isOpen = true;

            try {
                var isSearch = false;
                if (triedLoadingItems == false || pluginConfig.SelectedClientLanguage != plugin.LuminaItemsClientLanguage)
                {
                    UpdateItemList(1000);
                }

                if ((selectedItemIndex < 0 && selectedItem != null) || (selectedItemIndex >= 0 && selectedItem == null))
                {
                    // Should never happen, but just incase
                    selectedItemIndex = -1;
                    selectedItem      = null;
                    return(true);
                }

                ImGui.SetNextWindowSize(new Vector2(500, 500), ImGuiCond.FirstUseEver);

                PushStyle(ImGuiStyleVar.WindowMinSize, new Vector2(350, 400));

                if (!ImGui.Begin(Loc.Localize("ItemSearchPlguinMainWindowHeader", $"Item Search") + "###itemSearchPluginMainWindow", ref isOpen, ImGuiWindowFlags.NoCollapse))
                {
                    ResetStyle();
                    ImGui.End();
                    return(false);
                }

                if (ImGui.IsWindowAppearing())
                {
                    SearchFilters.ForEach(f => f._ForceVisible = false);
                }

                PopStyle();

                // Main window
                ImGui.AlignTextToFramePadding();

                if (selectedItem != null)
                {
                    var icon = selectedItem.Icon;

                    plugin.DrawIcon(icon, new Vector2(45 * ImGui.GetIO().FontGlobalScale));


                    ImGui.SameLine();
                    ImGui.BeginGroup();

                    if (selectedItem.GenericItemType == GenericItem.ItemType.EventItem)
                    {
                        ImGui.TextDisabled("[Key Item]");
                        ImGui.SameLine();
                    }

                    ImGui.Text(selectedItem.Name);

                    if (pluginConfig.ShowItemID)
                    {
                        ImGui.SameLine();
                        ImGui.Text($"(ID: {selectedItem.RowId}) (Rarity: {selectedItem.Rarity})");
                    }

                    var imGuiStyle    = ImGui.GetStyle();
                    var windowVisible = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X;

                    IActionButton[] buttons = this.ActionButtons.Where(ab => ab.ButtonPosition == ActionButtonPosition.TOP).ToArray();

                    for (var i = 0; i < buttons.Length; i++)
                    {
                        var button = buttons[i];

                        if (button.GetShowButton(selectedItem))
                        {
                            var buttonText = button.GetButtonText(selectedItem);
                            ImGui.PushID($"TopActionButton{i}");
                            if (ImGui.Button(buttonText))
                            {
                                button.OnButtonClicked(selectedItem);
                            }

                            if (i < buttons.Length - 1)
                            {
                                var lX2 = ImGui.GetItemRectMax().X;
                                var nbw = ImGui.CalcTextSize(buttons[i + 1].GetButtonText(selectedItem)).X + imGuiStyle.ItemInnerSpacing.X * 2;
                                var nX2 = lX2 + (imGuiStyle.ItemSpacing.X * 2) + nbw;
                                if (nX2 < windowVisible)
                                {
                                    ImGui.SameLine();
                                }
                            }

                            ImGui.PopID();
                        }
                    }

                    ImGui.EndGroup();
                }
                else
                {
                    ImGui.BeginChild("NoSelectedItemBox", new Vector2(-1, 45) * ImGui.GetIO().FontGlobalScale);
                    ImGui.Text(Loc.Localize("ItemSearchSelectItem", "Please select an item."));


                    if (!pluginConfig.HideKofi)
                    {
                        ImGui.PushStyleColor(ImGuiCol.Button, 0xFF5E5BFF);
                        ImGui.PushStyleColor(ImGuiCol.ButtonActive, 0xFF5E5BAA);
                        ImGui.PushStyleColor(ImGuiCol.ButtonHovered, 0xFF5E5BDD);
                        ImGui.SameLine(ImGui.GetWindowWidth() - ImGui.CalcTextSize("Support on Ko-fi").X - ImGui.GetStyle().FramePadding.X * 3);
                        if (ImGui.Button("Support on Ko-Fi"))
                        {
                            Process.Start("https://ko-fi.com/Caraxi");
                        }
                        ImGui.PopStyleColor(3);
                    }

                    ImGui.EndChild();
                }

                ImGui.Separator();

                ImGui.Columns(2);
                var filterNameMax = SearchFilters.Where(x => x.IsEnabled && x.ShowFilter).Select(x => {
                    x._LocalizedName      = Loc.Localize(x.NameLocalizationKey, x.Name);
                    x._LocalizedNameWidth = ImGui.CalcTextSize($"{x._LocalizedName}").X;
                    return(x._LocalizedNameWidth);
                }).Max();

                ImGui.SetColumnWidth(0, filterNameMax + ImGui.GetStyle().ItemSpacing.X * 2);
                var filterInUseColour    = new Vector4(0, 1, 0, 1);
                var filterUsingTagColour = new Vector4(0.4f, 0.7f, 1, 1);

                foreach (var filter in SearchFilters.Where(x => x.IsEnabled && x.ShowFilter))
                {
                    if (!extraFiltersExpanded && filter.CanBeDisabled && !filter.IsSet && !filter._ForceVisible)
                    {
                        continue;
                    }
                    ImGui.SetCursorPosX((filterNameMax + ImGui.GetStyle().ItemSpacing.X) - filter._LocalizedNameWidth);
                    ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3);
                    if (filter.IsSet)
                    {
                        ImGui.TextColored(filter.IsFromTag ? filterUsingTagColour : filterInUseColour, $"{filter._LocalizedName}: ");
                    }
                    else
                    {
                        ImGui.Text($"{filter._LocalizedName}: ");
                    }

                    ImGui.NextColumn();
                    ImGui.BeginGroup();
                    if (filter.IsFromTag && filter.GreyWithTags)
                    {
                        ImGui.PushStyleColor(ImGuiCol.Text, 0xFF888888);
                    }
                    filter.DrawEditor();
                    if (filter.IsFromTag && filter.GreyWithTags)
                    {
                        ImGui.PopStyleColor();
                    }
                    ImGui.EndGroup();
                    while (ImGui.GetColumnIndex() != 0)
                    {
                        ImGui.NextColumn();
                    }
                }
                ImGui.Columns(1);

                ImGui.PushFont(UiBuilder.IconFont);
                ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(0, -5 * ImGui.GetIO().FontGlobalScale));
                ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
                if (ImGui.Button($"{(extraFiltersExpanded ? (char) FontAwesomeIcon.CaretUp : (char) FontAwesomeIcon.CaretDown)}", new Vector2(-1, 10 * ImGui.GetIO().FontGlobalScale)))
                {
                    extraFiltersExpanded = !extraFiltersExpanded;
                    SearchFilters.ForEach(f => f._ForceVisible = f.IsEnabled && f.ShowFilter && f.IsSet);
                    pluginConfig.ExpandedFilters = extraFiltersExpanded;
                    pluginConfig.Save();
                }
                ImGui.PopStyleVar(2);
                ImGui.PopFont();

                var windowSize = ImGui.GetWindowSize();
                var childSize  = new Vector2(0, Math.Max(100 * ImGui.GetIO().FontGlobalScale, windowSize.Y - ImGui.GetCursorPosY() - 45 * ImGui.GetIO().FontGlobalScale));
                ImGui.BeginChild("scrolling", childSize, true, ImGuiWindowFlags.HorizontalScrollbar);

                PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));

                if (errorLoadingItems)
                {
                    ImGui.TextColored(new Vector4(1f, 0.1f, 0.1f, 1.00f), Loc.Localize("ItemSearchListLoadFailed", "Error loading item list."));
                    if (ImGui.SmallButton("Retry"))
                    {
                        UpdateItemList();
                    }
                }
                else if (plugin.LuminaItems != null)
                {
                    if (SearchFilters.Any(x => x.IsEnabled && x.ShowFilter && x.IsSet))
                    {
                        showingFavourites = false;
                        isSearch          = true;
                        var scrollTop = false;
                        if (SearchFilters.Any(x => x.IsEnabled && x.ShowFilter && x.HasChanged) || forceReload)
                        {
                            forceReload = false;
                            this.searchCancelTokenSource?.Cancel();
                            this.searchCancelTokenSource = new CancellationTokenSource();
                            var asyncEnum = plugin.LuminaItems.ToAsyncEnumerable();

                            if (!pluginConfig.ShowLegacyItems)
                            {
                                asyncEnum = asyncEnum.Where(x => x.RowId < 100 || x.RowId > 1600);
                            }

                            asyncEnum = SearchFilters.Where(filter => filter.IsEnabled && filter.ShowFilter && filter.IsSet).Aggregate(asyncEnum, (current, filter) => current.Where(filter.CheckFilter));
                            this.selectedItemIndex = -1;
                            selectedItem           = null;
                            this.searchTask        = asyncEnum.ToListAsync(this.searchCancelTokenSource.Token);
                        }

                        if (this.searchTask.IsCompletedSuccessfully)
                        {
                            DrawItemList(this.searchTask.Result, childSize, ref isOpen);
                        }
                    }
                    else
                    {
                        if (pluginConfig.Favorites.Count > 0)
                        {
                            if (!showingFavourites || favouritesList.Count != pluginConfig.Favorites.Count)
                            {
                                showingFavourites      = true;
                                this.selectedItemIndex = -1;
                                selectedItem           = null;
                                favouritesList         = plugin.LuminaItems.Where(i => pluginConfig.Favorites.Contains(i.RowId)).ToList();
                            }

                            DrawItemList(favouritesList, childSize, ref isOpen);
                        }
                        else
                        {
                            ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectHint", "Type to start searching..."));
                        }
                    }
                }
                else
                {
                    ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectLoading", "Loading item list..."));
                }

                PopStyle();

                ImGui.EndChild();

                // Darken choose button if it shouldn't be clickable
                PushStyle(ImGuiStyleVar.Alpha, this.selectedItemIndex < 0 || selectedItem == null || selectedItem.Icon >= 65000 ? 0.25f : 1);

                if (ImGui.Button(Loc.Localize("Choose", "Choose")))
                {
                    try {
                        if (selectedItem != null && selectedItem.Icon < 65000)
                        {
                            plugin.LinkItem(selectedItem);
                            if (pluginConfig.CloseOnChoose)
                            {
                                isOpen = false;
                            }
                        }
                    } catch (Exception ex) {
                        Log.Error($"Exception in Choose: {ex.Message}");
                    }
                }

                PopStyle();

                if (!pluginConfig.CloseOnChoose)
                {
                    ImGui.SameLine();
                    if (ImGui.Button(Loc.Localize("Close", "Close")))
                    {
                        selectedItem = null;
                        isOpen       = false;
                    }
                }

                if (this.selectedItemIndex >= 0 && this.selectedItem != null && selectedItem.Icon >= 65000)
                {
                    ImGui.SameLine();
                    ImGui.Text(Loc.Localize("DalamudItemNotLinkable", "This item is not linkable."));
                }

                if (pluginConfig.ShowTryOn && pluginInterface.ClientState?.LocalContentId != 0)
                {
                    ImGui.SameLine();
                    if (ImGui.Checkbox(Loc.Localize("ItemSearchTryOnButton", "Try On"), ref autoTryOn))
                    {
                        pluginConfig.TryOnEnabled = autoTryOn;
                        pluginConfig.Save();
                    }

                    ImGui.SameLine();


                    ImGui.PushStyleColor(ImGuiCol.Border, selectedStain != null && selectedStain.Unknown4 ? new Vector4(1, 1, 0, 1) : new Vector4(1, 1, 1, 1));
                    PushStyle(ImGuiStyleVar.FrameBorderSize, 2f);
                    if (ImGui.ColorButton("X", selectedStainColor, ImGuiColorEditFlags.NoTooltip))
                    {
                        showStainSelector = true;
                    }

                    if (ImGui.IsItemClicked(1))
                    {
                        selectedStainColor         = Vector4.Zero;
                        selectedStain              = null;
                        pluginConfig.SelectedStain = 0;
                        pluginConfig.Save();
                    }

                    PopStyle();

                    ImGui.PopStyleColor();

                    if (ImGui.IsItemHovered())
                    {
                        ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
                        ImGui.BeginTooltip();
                        ImGui.Text(selectedStain == null ? "No Dye Selected" : selectedStain.Name);
                        if (selectedStain != null)
                        {
                            ImGui.TextDisabled("Right click to clear selection.");
                        }
                        ImGui.EndTooltip();
                    }
                }
                ImGui.PushFont(UiBuilder.IconFont);
                var configText     = $"{(char)FontAwesomeIcon.Cog}";
                var configTextSize = ImGui.CalcTextSize(configText);
                ImGui.PopFont();
                var itemCountText = isSearch ? string.Format(Loc.Localize("ItemCount", "{0} Items"), this.searchTask.Result.Count) : $"v{plugin.Version}";
                ImGui.SameLine(ImGui.GetWindowWidth() - (configTextSize.X + ImGui.GetStyle().ItemSpacing.X) - (ImGui.CalcTextSize(itemCountText).X + ImGui.GetStyle().ItemSpacing.X *(isSearch ? 3 : 2)));
                if (isSearch)
                {
                    if (ImGui.Button(itemCountText))
                    {
                        PluginLog.Log("Copying results to Clipboard");

                        var sb = new StringBuilder();

                        if (pluginConfig.PrependFilterListWithCopy)
                        {
                            foreach (var f in SearchFilters.Where(f => f.IsSet))
                            {
                                sb.AppendLine($"{f.Name}: {f}");
                            }

                            sb.AppendLine();
                        }

                        foreach (var i in this.searchTask.Result)
                        {
                            sb.AppendLine(i.Name);
                        }
                        ImGui.SetClipboardText(sb.ToString());
                    }

                    if (ImGui.IsItemHovered())
                    {
                        ImGui.SetTooltip("Copy results to clipboard");
                    }
                }
                else
                {
                    ImGui.Text(itemCountText);
                }

                ImGui.SameLine(ImGui.GetWindowWidth() - (configTextSize.X + ImGui.GetStyle().ItemSpacing.X * 2));
                ImGui.PushFont(UiBuilder.IconFont);
                if (ImGui.Button(configText))
                {
                    plugin.ToggleConfigWindow();
                }
                ImGui.PopFont();

                var mainWindowPos  = ImGui.GetWindowPos();
                var mainWindowSize = ImGui.GetWindowSize();

                ImGui.End();


                if (showStainSelector)
                {
                    ImGui.SetNextWindowSize(new Vector2(210, 180));
                    ImGui.SetNextWindowPos(mainWindowPos + mainWindowSize - new Vector2(0, 180));
                    ImGui.Begin("Select Dye", ref showStainSelector, ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove);

                    ImGui.BeginTabBar("stainShadeTabs");

                    var unselectedModifier = new Vector4(0, 0, 0, 0.7f);

                    foreach (var shade in stainShadeHeaders)
                    {
                        ImGui.PushStyleColor(ImGuiCol.TabActive, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.TabHovered, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.TabUnfocused, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.TabUnfocusedActive, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.Tab, shade.Value - unselectedModifier);

                        if (ImGui.BeginTabItem($"    ###StainShade{shade.Key}"))
                        {
                            var c = 0;

                            PushStyle(ImGuiStyleVar.FrameBorderSize, 2f);
                            foreach (var stain in stains.Where(s => s.Shade == shade.Key && !string.IsNullOrEmpty(s.Name)))
                            {
                                var b = stain.Color & 255;
                                var g = (stain.Color >> 8) & 255;
                                var r = (stain.Color >> 16) & 255;

                                var stainColor = new Vector4(r / 255f, g / 255f, b / 255f, 1f);

                                ImGui.PushStyleColor(ImGuiCol.Border, stain.Unknown4 ? new Vector4(1, 1, 0, 1) : new Vector4(1, 1, 1, 1));

                                if (ImGui.ColorButton($"###stain{stain.RowId}", stainColor, ImGuiColorEditFlags.NoTooltip))
                                {
                                    selectedStain              = stain;
                                    selectedStainColor         = stainColor;
                                    showStainSelector          = false;
                                    pluginConfig.SelectedStain = stain.RowId;
                                    pluginConfig.Save();
                                }

                                ImGui.PopStyleColor(1);

                                if (ImGui.IsItemHovered())
                                {
                                    ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
                                    ImGui.SetTooltip(stain.Name);
                                }

                                if (c++ < 5)
                                {
                                    ImGui.SameLine();
                                }
                                else
                                {
                                    c = 0;
                                }
                            }

                            PopStyle(1);

                            ImGui.EndTabItem();
                        }

                        ImGui.PopStyleColor(5);
                    }

                    ImGui.EndTabBar();
                    ImGui.End();
                }


                return(isOpen);
            } catch (Exception ex) {
                ResetStyle();
                PluginLog.LogError(ex.ToString());
                selectedItem      = null;
                selectedItemIndex = -1;
                return(isOpen);
            }
        }