private void init()
        {
            NeverKeywords    = (Settings.Instance.IgnoreKeywords ?? "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            AlwaysKeywords   = (Settings.Instance.AlwaysKeywords ?? "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            RequiredKeywords = (Settings.Instance.RequireKeywords ?? "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            MaxPrice         = Settings.Instance.MaxPrice;

            if (Settings.Instance.Enabled)
            {
                Events.OnMainMenu.Register(e =>
                {
                    ExcludeForms = CachedFormList.TryParse(Settings.Instance.ExcludeFormIds ?? "", "BetterStealing", "ExcludeFormIds");
                });

                this.InstallHook("send steal alarm #1", 36427, 0, 7, "48 8B C4 44 89 48 20", ctx =>
                {
                    var info = StealInfo.Begin();
                    if (info == null)
                    {
                        return;
                    }

                    info.Type                  = StealInfo.GetCalledFromType(Memory.ReadPointer(ctx.SP));
                    info.Thief                 = MemoryObject.FromAddress <Actor>(ctx.CX);
                    info.TargetObjRef          = MemoryObject.FromAddress <TESObjectREFR>(ctx.DX);
                    info.TargetObjBase         = MemoryObject.FromAddress <TESForm>(ctx.R8);
                    info.TargetObjCount        = ctx.R9.ToInt32Safe();
                    info.UnspecifiedItemsWorth = Memory.ReadInt32(ctx.SP + 0x28);
                    info.OwnerForm             = MemoryObject.FromAddress <TESForm>(Memory.ReadPointer(ctx.SP + 0x30));
                });

                this.InstallHook("send steal alarm #2", 36427, 0x9D3, 7, "48 81 C4 38 01 00 00", ctx =>
                {
                    var info = StealInfo.Get();
                    if (info == null)
                    {
                        return;
                    }

                    info.WasDetected = Memory.ReadUInt8(ctx.SP + 0x40) != 0;
                    info.State       = 1;
                    ApplyStolenSoon.Queue(1);
                });

                this.InstallHook("open container", 50195, 0x20, 5, "E8", ctx =>
                {
                    StealInfo.BeginContainer();

                    ApplyFixCDataSoon.Queue(3);

                    var pickpocket = _InventoryExtensions.GetCurrentlyPickPocketing();
                    if (pickpocket != null)
                    {
                        var info = StealInfo.Begin();
                        if (info != null)
                        {
                            info.Type                  = StealTypes.PickPocketCustom;
                            info.Thief                 = PlayerCharacter.Instance;
                            info.TargetObjRef          = pickpocket;
                            info.TargetObjBase         = null;
                            info.TargetObjCount        = 0;
                            info.WasDetected           = false;
                            info.UnspecifiedItemsWorth = 0;
                            info.OwnerForm             = pickpocket.BaseForm;
                            info.State                 = 1;
                            FinishPickPocketCheck.Queue(3);
                        }
                    }
                });

                this.InstallHook("actor add item", 36525, 0, 5, "44 89 4C 24 20", ctx =>
                {
                    var pickpocket = _InventoryExtensions.GetCurrentlyPickPocketing();
                    if (pickpocket != null)
                    {
                        var who = MemoryObject.FromAddress <TESObjectREFR>(ctx.CX);
                        if (who == null || !(who is Actor) || !((Actor)who).IsPlayer)
                        {
                            return;
                        }

                        var where = MemoryObject.FromAddress <TESObjectREFR>(Memory.ReadPointer(ctx.SP + 0x28));
                        if (where == null || !where.Equals(pickpocket))
                        {
                            return;
                        }

                        var item  = MemoryObject.FromAddress <TESForm>(ctx.DX);
                        var data  = MemoryObject.FromAddress <BSExtraDataList>(ctx.R8);
                        int count = ctx.R9.ToInt32Safe();

                        StealInfo.PushContainerItem(item, data, count);
                    }
                    else
                    {
                        var stealing = _InventoryExtensions.GetCurrentlyStealingFromContainer();
                        if (stealing == null)
                        {
                            return;
                        }

                        var who = MemoryObject.FromAddress <TESObjectREFR>(ctx.CX);
                        if (who == null || !(who is Actor) || !((Actor)who).IsPlayer)
                        {
                            return;
                        }

                        var where = MemoryObject.FromAddress <TESObjectREFR>(Memory.ReadPointer(ctx.SP + 0x28));
                        if (where == null || !where.Equals(stealing))
                        {
                            return;
                        }

                        var item  = MemoryObject.FromAddress <TESForm>(ctx.DX);
                        var data  = MemoryObject.FromAddress <BSExtraDataList>(ctx.R8);
                        int count = ctx.R9.ToInt32Safe();

                        StealInfo.PushContainerItem(item, data, count);
                    }
                });

                this.InstallHook("object add item", 19282, 0, 6, "40 55 56 57 41 54", ctx =>
                {
                    var pickpocket = _InventoryExtensions.GetCurrentlyPickPocketing();
                    if (pickpocket != null)
                    {
                        var who = MemoryObject.FromAddress <TESObjectREFR>(ctx.CX);
                        if (who == null || !who.Equals(pickpocket))
                        {
                            return;
                        }

                        var where = MemoryObject.FromAddress <TESObjectREFR>(Memory.ReadPointer(ctx.SP + 0x28));
                        if (where == null || !(where is Actor) || !((Actor) where).IsPlayer)
                        {
                            return;
                        }

                        var item  = MemoryObject.FromAddress <TESForm>(ctx.DX);
                        var data  = MemoryObject.FromAddress <BSExtraDataList>(ctx.R8);
                        int count = ctx.R9.ToInt32Safe();

                        StealInfo.RemoveContainerItem(item, data, count);
                    }
                    else
                    {
                        var stealing = _InventoryExtensions.GetCurrentlyStealingFromContainer();
                        if (stealing == null)
                        {
                            return;
                        }

                        var who = MemoryObject.FromAddress <TESObjectREFR>(ctx.CX);
                        if (who == null || !who.Equals(stealing))
                        {
                            return;
                        }

                        var where = MemoryObject.FromAddress <TESObjectREFR>(Memory.ReadPointer(ctx.SP + 0x28));
                        if (where == null || !(where is Actor) || !((Actor) where).IsPlayer)
                        {
                            return;
                        }

                        var item  = MemoryObject.FromAddress <TESForm>(ctx.DX);
                        var data  = MemoryObject.FromAddress <BSExtraDataList>(ctx.R8);
                        int count = ctx.R9.ToInt32Safe();

                        StealInfo.RemoveContainerItem(item, data, count);
                    }
                });

                Events.OnFrame.Register(e =>
                {
                    FinishPickPocketCheck.Do();
                    ApplyStolenSoon.Do();
                    ApplyFixCDataSoon.Do();
                });

                _SetItemOwner_Func = NetScriptFramework.Main.GameInfo.GetAddressOf(15784);
                _SetListOwner_Func = NetScriptFramework.Main.GameInfo.GetAddressOf(11463);
                _GetCount_Func     = NetScriptFramework.Main.GameInfo.GetAddressOf(11558);
                _GetNorth_Func     = NetScriptFramework.Main.GameInfo.GetAddressOf(11773);
                _SetNorth_Func     = NetScriptFramework.Main.GameInfo.GetAddressOf(11774);
                _ContOpenType_Var  = NetScriptFramework.Main.GameInfo.GetAddressOf(519396);
                _ContOpen_Var      = NetScriptFramework.Main.GameInfo.GetAddressOf(519421);
                _CalcCost_Func     = NetScriptFramework.Main.GameInfo.GetAddressOf(15757);
            }

            if (Settings.Instance.FixBadStolenItemCount)
            {
                var ptr = NetScriptFramework.Main.GameInfo.GetAddressOf(15821, 0x110A, 0, "0F B7 95 A0 01 00 00");
                Memory.WriteBytes(ptr, new byte[] { 0x8B, 0x54, 0x24, 0x60, 0x90, 0x90, 0x90 }, true);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Tries to parse from input. Returns null if failed.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="pluginForLog">The plugin for log.</param>
        /// <param name="settingNameForLog">The setting name for log.</param>
        /// <param name="warnOnMissingForm">If set to <c>true</c> warn on missing form.</param>
        /// <param name="dontWriteAnythingToLog">Don't write any errors to log if failed to parse.</param>
        /// <returns></returns>
        public static CachedFormList TryParse(string input, string pluginForLog, string settingNameForLog, bool warnOnMissingForm = true, bool dontWriteAnythingToLog = false)
        {
            if (string.IsNullOrEmpty(settingNameForLog))
            {
                settingNameForLog = "unknown form list setting";
            }
            if (string.IsNullOrEmpty(pluginForLog))
            {
                pluginForLog = "unknown plugin";
            }

            var ls  = new CachedFormList();
            var spl = input.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var x in spl)
            {
                string idstr;
                string file;

                int ix = x.IndexOf(':');
                if (ix <= 0)
                {
                    if (!dontWriteAnythingToLog)
                    {
                        NetScriptFramework.Main.Log.AppendLine("Failed to parse " + settingNameForLog + " for " + pluginForLog + "! Invalid input: `" + x + "`.");
                    }
                    return(null);
                }

                idstr = x.Substring(0, ix);
                file  = x.Substring(ix + 1);

                if (!idstr.All(q => (q >= '0' && q <= '9') || (q >= 'a' && q <= 'f') || (q >= 'A' && q <= 'F')))
                {
                    if (!dontWriteAnythingToLog)
                    {
                        NetScriptFramework.Main.Log.AppendLine("Failed to parse " + settingNameForLog + " for " + pluginForLog + "! Invalid form ID: `" + idstr + "`.");
                    }
                    return(null);
                }

                if (string.IsNullOrEmpty(file))
                {
                    if (!dontWriteAnythingToLog)
                    {
                        NetScriptFramework.Main.Log.AppendLine("Failed to parse " + settingNameForLog + " for " + pluginForLog + "! Missing file name.");
                    }
                    return(null);
                }

                uint id = 0;
                if (!uint.TryParse(idstr, System.Globalization.NumberStyles.HexNumber, null, out id) || (id & 0xFF000000) != 0)
                {
                    if (!dontWriteAnythingToLog)
                    {
                        NetScriptFramework.Main.Log.AppendLine("Failed to parse " + settingNameForLog + " for " + pluginForLog + "! Invalid form ID: `" + idstr + "`. Don't include plugin index in form ID.");
                    }
                    return(null);
                }

                var form = NetScriptFramework.SkyrimSE.TESForm.LookupFormFromFile(id, file);
                if (form == null)
                {
                    if (!dontWriteAnythingToLog && warnOnMissingForm)
                    {
                        NetScriptFramework.Main.Log.AppendLine("Failed to find form " + settingNameForLog + " for " + pluginForLog + "! Form ID was " + id.ToString("X") + " and file was " + file + ".");
                    }
                    continue;
                }

                if (ls.Ids.Add(form.FormId))
                {
                    ls.Forms.Add(form);
                }
            }

            return(ls);
        }