public TApplication(NativeData nativeData)
            {
                OnMessageOffset = nativeData.Pointers[NativePointers.Application_OnMessageOffset];

                TApplicationInstanceAddr = new IntPtr(nativeData.Pointers[NativePointers.Application_InstancePtr]);
                TApplicationOnMessagePtr = new ObjPtr(TApplicationInstanceAddr, OnMessageOffset);
            }
Пример #2
0
            public TElWind(NativeData nativeData)
            {
                // TElWind object pointer
                InstancePtr = new IntPtr(nativeData.Pointers[NativePointer.ElWdw_InstancePtr]);

                // Object pointers
                ElementIdPtr        = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.ElWdw_ElementIdPtr]);
                ObjectsPtr          = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.ElWdw_ObjectsPtr]);
                ComponentsDataPtr   = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.ElWdw_ComponentsDataPtr]);
                RecentGradePtr      = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.ElWdw_RecentGradePtr]);
                FocusedComponentPtr = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.ElWdw_FocusedComponentPtr]);
                LearningModePtr     = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.ElWdw_LearningModePtr]);

                // Memory patterns
                EnterUpdateLockCallSig = nativeData.GetMemoryPattern(NativeMethod.ElWdw_EnterUpdateLock);
                QuitUpdateLockCallSig  = nativeData.GetMemoryPattern(NativeMethod.ElWdw_QuitUpdateLock);

                // Procedures
                EnterUpdateLock = new Procedure <Action <IntPtr, bool, DelphiUTF16String> >(
                    "EnterUpdateLock",
                    CallingConventions.Register,
                    EnterUpdateLockCallSig
                    );
                QuitUpdateLock = new Procedure <Action <IntPtr, bool> >(
                    "QuitUpdateLock",
                    CallingConventions.Register,
                    QuitUpdateLockCallSig
                    );

                // Substructure
                Components = new TComponentData(ComponentsDataPtr, nativeData);
            }
Пример #3
0
        public void SendNativeCallToAllPlayers(bool safe, ulong hash, params object[] arguments)
        {
            var obj = new NativeData
            {
                Hash       = hash,
                Internal   = safe,
                Arguments  = ParseNativeArguments(arguments),
                ReturnType = null,
                Id         = 0
            };

            var bin = SerializeBinary(obj);

            var msg = Server.CreateMessage();

            msg.Write((byte)PacketType.NativeCall);
            msg.Write(bin.Length);
            msg.Write(bin);

            // todo: check if there's ligdren's function to do that
            lock (Clients)
            {
                foreach (var c in Clients)
                {
                    Server.SendMessage(msg, c.NetConnection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.NativeCall);
                }
            }
        }
Пример #4
0
        public void localTest2()
        {
            var exp = new byte[] { 8 };
            var raw = NativeData._(exp).Raw;

            Assert.Single(raw.Values);
            Assert.Equal(exp[0], raw.Values[0]);
        }
Пример #5
0
                public TComponentData(ObjPtr componentsDataPtr, NativeData nativeData)
                {
                    ComponentDataArrOffset     = nativeData.Pointers[NativePointers.ElWdw_ComponentData_ComponentDataArrOffset];
                    ComponentDataArrItemLength = nativeData.Pointers[NativePointers.ElWdw_ComponentData_ComponentDataArrItemLength];

                    ComponentCountPtr = new ObjPtr(componentsDataPtr, nativeData.Pointers[NativePointers.ElWdw_ComponentData_ComponentCountPtr]);
                    IsModifiedPtr     = new ObjPtr(componentsDataPtr, nativeData.Pointers[NativePointers.ElWdw_ComponentData_IsModifiedPtr]);
                }
            public TGlobals(NativeData nativeData)
            {
                CurrentConceptIdPtr = new IntPtr(nativeData.Pointers[NativePointers.Globals_CurrentConceptIdPtr]);
                CurrentRootIdPtr    = new IntPtr(nativeData.Pointers[NativePointers.Globals_CurrentRootIdPtr]);
                CurrentHookIdPtr    = new IntPtr(nativeData.Pointers[NativePointers.Globals_CurrentHookIdPtr]);

                IgnoreUserConfirmationPtr = new IntPtr(nativeData.Pointers[NativePointers.Globals_IgnoreUserConfirmationPtr]);
            }
Пример #7
0
        public void localTest2()
        {
            var exp = new byte[] { 8 };
            var raw = NativeData._(exp).Raw;

            Assert.AreEqual(1, raw.Values.Length);
            Assert.AreEqual(exp[0], raw.Values[0]);
        }
Пример #8
0
        public void localTest1()
        {
            var exp = new byte[] { 1, 2 };
            var raw = new NativeData(exp).Raw;

            Assert.AreEqual(2, raw.Values.Length);
            Assert.AreEqual(exp[0], raw.Values[0]);
            Assert.AreEqual(exp[1], raw.Values[1]);
        }
Пример #9
0
            public TGlobals(NativeData nativeData)
            {
                LimitChildrenCountPtr    = new IntPtr(nativeData.Pointers[NativePointer.Globals_LimitChildrenCountPtr]);
                CurrentConceptGroupIdPtr = new IntPtr(nativeData.Pointers[NativePointer.Globals_CurrentConceptGroupIdPtr]);
                CurrentRootIdPtr         = new IntPtr(nativeData.Pointers[NativePointer.Globals_CurrentRootIdPtr]);
                CurrentHookIdPtr         = new IntPtr(nativeData.Pointers[NativePointer.Globals_CurrentHookIdPtr]);
                CurrentConceptIdPtr      = new IntPtr(nativeData.Pointers[NativePointer.Globals_CurrentConceptIdPtr]);

                IgnoreUserConfirmationPtr = new IntPtr(nativeData.Pointers[NativePointer.Globals_IgnoreUserConfirmationPtr]);
            }
Пример #10
0
 public SMNatives(NativeData nativeData)
 {
     Globals     = new TGlobals(nativeData);
     Application = new TApplication(nativeData);
     Control     = new TControl(nativeData);
     ElWind      = new TElWind(nativeData);
     SMMain      = new TSMMain(nativeData);
     Database    = new TDatabase(nativeData);
     Registry    = new TRegistry(Database, nativeData);
 }
Пример #11
0
        protected Native.Core.Field getField(string name, NativeData n)
        {
            var ret = n.Raw.Type.getFieldByName(name);

            if (ret == null)
            {
                throw new KeyNotFoundException($"Field('{name}') was not found inside Raw.Type.");
            }
            return(ret);
        }
Пример #12
0
            public TControl(NativeData nativeData)
            {
                ParentOffset     = nativeData.Pointers[NativePointer.Control_ParentOffset];
                WindowProcOffset = nativeData.Pointers[NativePointer.Control_WindowProcOffset];
                HandleOffset     = nativeData.Pointers[NativePointer.Control_HandleOffset];

                LeftOffset   = nativeData.Pointers[NativePointer.Control_LeftOffset];
                TopOffset    = nativeData.Pointers[NativePointer.Control_TopOffset];
                WidthOffset  = nativeData.Pointers[NativePointer.Control_WidthOffset];
                HeightOffset = nativeData.Pointers[NativePointer.Control_HeightOffset];
            }
Пример #13
0
        public SMInject(RemoteHooking.IContext context,
                        string channelName,
                        NativeData nativeData)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            AppDomain.CurrentDomain.AssemblyResolve    += CurrentDomain_AssemblyResolve;

            SentryInstance = SentrySdk.Init("https://[email protected]/1362046");

            SMA = (SMAHookCallback)RemoteHooking.IpcConnectClient <MarshalByRefObject>(channelName);
            _   = Task.Factory.StartNew(KeepAlive, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }
Пример #14
0
        /// <summary>
        ///   Scan SuperMemo to find the methods matching the signatures provided by
        ///   <paramref name="nativeData" />. Also sets up the WndProc detour.
        /// </summary>
        /// <param name="nativeData">The offsets and method signatures for the running SuperMemo version</param>
        private unsafe void InstallSM(NativeData nativeData)
        {
            _smProcess = new ProcessSharp(System.Diagnostics.Process.GetCurrentProcess(),
                                          MemoryType.Local);

            // WndProc
            _wndProcDelegate = new ManagedWndProc(WndProc);

            WndProcWrapper.SetCallback(Marshal.GetFunctionPointerForDelegate(_wndProcDelegate));
            SMA.SetWndProcHookAddr(WndProcWrapper.GetWndProcNativeWrapperAddr());

            // Native calls
            ScanSMMethods(nativeData);
        }
        public static bool CheckSuperMemoExecutable(
            NativeDataCfg nativeDataCfg,
            FilePath smFile,
            out NativeData nativeData,
            out SMAException ex)
        {
            nativeData = null;

            if (smFile == null)
            {
                ex = new SMAException("SM exe file path is null", new ArgumentNullException(nameof(smFile)));
                return(false);
            }

            if (smFile.Exists() == false)
            {
                ex = new SMAException(
                    $"Invalid file path for sm executable file: '{smFile}' could not be found. SMA cannot continue.");
                return(false);
            }

            if (smFile.HasPermission(FileIOPermissionAccess.Read) == false)
            {
                ex = new SMAException($"SMA needs read access to execute SM executable at {smFile.FullPath}.");
                return(false);
            }

            if (smFile.IsLocked())
            {
                ex = new SMAException($"{smFile.FullPath} is locked. Make sure it isn't already running.");
                return(false);
            }

            var smFileCrc32 = FileEx.GetCrc32(smFile.FullPath);

            nativeData = nativeDataCfg.SafeGet(smFileCrc32.ToUpper(CultureInfo.InvariantCulture));

            if (nativeData == null)
            {
                ex = new SMAException($"Unknown SM executable version with crc32 {smFileCrc32}.");
                return(false);
            }

            ex = null;

            return(true);
        }
Пример #16
0
        public void SendNativeCallToPlayer(Client player, bool safe, ulong hash, params object[] arguments)
        {
            var obj = new NativeData
            {
                Hash      = hash,
                Internal  = safe,
                Arguments = ParseNativeArguments(arguments)
            };
            var bin = SerializeBinary(obj);

            var msg = Server.CreateMessage();

            msg.Write((byte)PacketType.NativeCall);
            msg.Write(bin.Length);
            msg.Write(bin);
            player.NetConnection.SendMessage(msg, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.NativeCall);
        }
Пример #17
0
        public void Run(RemoteHooking.IContext inContext,
                        string channelName,
                        NativeData nativeData)
        {
            try
            {
                try
                {
                    InstallHooks();
                    InstallSM(nativeData);

                    SMA.OnHookInstalled(true);
                }
                catch (Exception ex)
                {
                    SMA.OnHookInstalled(false, ex);
                    Environment.Exit(1);
                    return;
                }
                finally
                {
                    RemoteHooking.WakeUpProcess();
                }

                DispatchMessages();
            }
            catch (RemotingException)
            {
                // Channel closed, exit.
                SMA = null;
            }
            catch (Exception ex)
            {
                OnException(ex);
            }
            finally
            {
                HasExited = true;

                CleanupHooks();

                SentryInstance.Dispose();
            }
        }
Пример #18
0
            public TQueue(NativeData nativeData)
            {
                SizeOffset = nativeData.Pointers[NativePointer.Queue_SizeOffset];

                LastCallSig    = nativeData.GetMemoryPattern(NativeMethod.Queue_Last);
                GetItemCallSig = nativeData.GetMemoryPattern(NativeMethod.Queue_GetItem);

                Last = new Procedure <Func <IntPtr, int> >(
                    "Last",
                    CallingConventions.Register,
                    LastCallSig
                    );

                GetItem = new Procedure <Func <IntPtr, int, int> >(
                    "GetItem",
                    CallingConventions.Register,
                    GetItemCallSig
                    );
            }
Пример #19
0
            public TFileSpace(TDatabase db, NativeData nativeData)
            {
                InstancePtr = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointer.Registry_FileSpaceInstance]);

                EmptySlotsPtr     = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.FileSpace_EmptySlotsOffset]);
                AllocatedSlotsPtr = new ObjPtr(InstancePtr, nativeData.Pointers[NativePointer.FileSpace_AllocatedSlotsOffset]);

                GetTopSlotCallSig     = nativeData.GetMemoryPattern(NativeMethod.FileSpace_GetTopSlot);
                IsSlotOccupiedCallSig = nativeData.GetMemoryPattern(NativeMethod.FileSpace_IsSlotOccupied);

                GetTopSlot = new Procedure <Func <IntPtr, bool, int> >(
                    "GetTopSlot",
                    CallingConventions.Register,
                    GetTopSlotCallSig
                    );
                IsSlotOccupied = new Procedure <Func <IntPtr, int, bool> >(
                    "IsSlotOccupied",
                    CallingConventions.Register,
                    IsSlotOccupiedCallSig
                    );
            }
Пример #20
0
        public void GetNativeCallFromPlayer(Client player, bool safe, uint salt, ulong hash, NativeArgument returnType, Action <object> callback, params object[] arguments)
        {
            var obj = new NativeData
            {
                Hash       = hash,
                ReturnType = returnType,
                Id         = salt,
                Arguments  = ParseNativeArguments(arguments),
                Internal   = safe
            };

            var bin = SerializeBinary(obj);

            var msg = Server.CreateMessage();

            msg.Write((byte)PacketType.NativeCall);
            msg.Write(bin.Length);
            msg.Write(bin);

            _callbacks.Add(salt, callback);
            player.NetConnection.SendMessage(msg, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.NativeCall);
        }
Пример #21
0
        public static IEnumerable <(NativeMethod method, IMemoryPattern pattern)> GetAllMemoryPatterns(
            this NativeData nativeData)
        {
            foreach (var keyVal in nativeData.NativeCallPatterns)
            {
                var patternData = keyVal.Value;

                yield return(keyVal.Key, new DwordCallPattern(patternData.Pattern, patternData.Offset));
            }

            foreach (var keyVal in nativeData.NativeDataPatterns)
            {
                var patternData = keyVal.Value;

                yield return(keyVal.Key, new DwordDataPattern(patternData.Pattern, patternData.Offset));
            }

            foreach (var keyVal in nativeData.NativeFunctionPatterns)
            {
                yield return(keyVal.Key, new DwordFunctionPattern(keyVal.Value));
            }
        }
Пример #22
0
        public static IMemoryPattern GetMemoryPattern(this NativeData nativeData, NativeMethod nativeMethod)
        {
            if (nativeData.NativeCallPatterns.ContainsKey(nativeMethod))
            {
                var patternData = nativeData.NativeCallPatterns[nativeMethod];

                return(new DwordCallPattern(patternData.Pattern, patternData.Offset));
            }

            if (nativeData.NativeDataPatterns.ContainsKey(nativeMethod))
            {
                var patternData = nativeData.NativeDataPatterns[nativeMethod];

                return(new DwordDataPattern(patternData.Pattern, patternData.Offset));
            }

            if (nativeData.NativeFunctionPatterns.ContainsKey(nativeMethod))
            {
                return(new DwordFunctionPattern(nativeData.NativeFunctionPatterns[nativeMethod]));
            }

            return(null);
        }
            public TRegistry(TDatabase db, NativeData nativeData)
            {
                TextRegistryInstance     = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_TextRegistryInstance]);
                ImageRegistryInstance    = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_ImageRegistryInstance]);
                SoundRegistryInstance    = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_SoundRegistryInstance]);
                VideoRegistryInstance    = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_VideoRegistryInstance]);
                BinaryRegistryInstance   = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_BinaryRegistryInstance]);
                TemplateRegistryInstance = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_TemplateRegistryInstance]);
                ConceptRegistryInstance  = new ObjPtr(db.InstancePtr, nativeData.Pointers[NativePointers.Registry_ConceptRegistryInstance]);

                AddMemberCallSig  = nativeData.GetMemoryPattern(NativeMethod.TRegistry_AddMember);
                ImportFileCallSig = nativeData.GetMemoryPattern(NativeMethod.TRegistry_ImportFile);

                AddMember = new Procedure <Func <IntPtr, DelphiUTF16String, int> >(
                    "AddMember",
                    CallingConventions.Register,
                    AddMemberCallSig
                    );
                ImportFile = new Procedure <Func <IntPtr, DelphiUTF16String, DelphiUTF16String, int> >(
                    "ImportFile",
                    CallingConventions.Register,
                    ImportFileCallSig
                    );
            }
Пример #24
0
        protected void ScanSMMethods(NativeData nativeData)
        {
            var scanner   = new PatternScanner(_smProcess.ModuleFactory.MainModule);
            var hintAddrs = SMA.GetPatternsHintAddresses();

            foreach (var(method, pattern) in nativeData.GetAllMemoryPatterns())
            {
                int hintAddr = 0;

                if (hintAddrs.ContainsKey(pattern.PatternText))
                {
                    hintAddr = hintAddrs[pattern.PatternText];
                }

                var scanRes = scanner.Find(pattern,
                                           hintAddr);
                var procAddr = scanRes.BaseAddress.ToInt32();

                hintAddrs[pattern.PatternText] = scanRes.Offset;
                _callTable[method]             = procAddr;
            }

            SMA.SetPatternsHintAddresses(hintAddrs);
        }
Пример #25
0
        protected TExInfo addrOfExport(LONG e_lfanew)
        {
            var stream = reader.BaseStream;

            /* IMAGE_NT_HEADERS */
            // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680336.aspx

            stream.Seek(e_lfanew, SeekOrigin.Begin);

            char[] sig = new char[4];
            reader.Read(sig, 0, sig.Length); // A 4-byte signature identifying the file as a PE image

            // The bytes are "PE\0\0"
            if (sig[0] != 'P' || sig[1] != 'E' || sig[2] != '\0' || sig[3] != '\0')
            {
                throw new PECorruptDataException();
            }

            /* IMAGE_FILE_HEADER */
            // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680313.aspx

            byte[] IMAGE_FILE_HEADER = new byte[20];
            reader.Read(IMAGE_FILE_HEADER, 0, IMAGE_FILE_HEADER.Length);

            dynamic ifh = NativeData
                          ._(IMAGE_FILE_HEADER)
                          .t <WORD, WORD>(null, "NumberOfSections")
                          .align <DWORD>(3)
                          .t <WORD, WORD>("SizeOfOptionalHeader")
                          .Raw.Type;

            /* IMAGE_OPTIONAL_HEADER */
            // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339.aspx

            // move to NumberOfRvaAndSizes

            if (ifh.SizeOfOptionalHeader == 0xE0)  // IMAGE_OPTIONAL_HEADER32
            {
                stream.Seek(0x5C, SeekOrigin.Current);
            }
            else if (ifh.SizeOfOptionalHeader == 0xF0)  // IMAGE_OPTIONAL_HEADER64
            {
                stream.Seek(0x6C, SeekOrigin.Current);
            }
            else
            {
                // also known 0 for object files
                throw new PECorruptDataException($"SizeOfOptionalHeader: {ifh.SizeOfOptionalHeader}");
            }

            DWORD NumberOfRvaAndSizes = reader.ReadUInt32(); // The number of directory entries.

            /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
             *
             *  winnt.h Directory Entries:
             *
             #define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
             #define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
             #define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   // Resource Directory
             *      ...
             */
            /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */
            // IMAGE_DATA_DIRECTORY struct: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680305.aspx

            byte[] DIRECTORY_EXPORT = new byte[8];
            reader.Read(DIRECTORY_EXPORT, 0, DIRECTORY_EXPORT.Length);

            dynamic idd = NativeData
                          ._(DIRECTORY_EXPORT)
                          .t <DWORD>("VirtualAddress")
                          .t <DWORD>("Size")
                          .Raw.Type;

            // to the end of directories
            stream.Seek(8 * (NumberOfRvaAndSizes - 1), SeekOrigin.Current);

            return(new TExInfo()
            {
                VirtualAddress = idd.VirtualAddress,
                Size = idd.Size,
                NumberOfSections = ifh.NumberOfSections,
            });
        }
Пример #26
0
        //
        // Core hook methods

        public async Task <ProcessSharp <SMNatives> > CreateAndHookAsync(
            SMCollection collection,
            string binPath,
            IEnumerable <ISMAHookIO> ioCallbacks,
            NativeData nativeData)
        {
            LogTo.Debug("Starting and injecting SuperMemo");

            IOCallbacks.AddRange(ioCallbacks);

            IOTargetFilePaths.AddRange(IOCallbacks.SelectMany(c => c.GetTargetFilePaths()));

            HookSuccess   = false;
            HookException = null;

            // Start a new IPC server
            var channelName = StartIPCServer();

            // Start SuperMemo application with given collection as parameter,
            // and immediately install hooks
            int pId = -1;

            try
            {
                RemoteHooking.CreateAndInject(
                    binPath,
                    collection.GetKnoFilePath().Quotify(),
                    0,
                    InjectionOptions.Default,
                    SMAFileSystem.InjectionLibFile.FullPath,
                    null,
                    out pId,
                    channelName,
                    nativeData
                    );
            }
            catch (ArgumentException ex)
            {
                LogTo.Warning(ex, "Failed to start and inject SuperMemo. Command line: '{BinPath} {V}'", binPath, collection.GetKnoFilePath().Quotify());
            }

            LogTo.Debug("Waiting for signal from Injected library");

            // Wait for Signal from OnHookInstalled with timeout
            await HookInitEvent.WaitAsync(WaitTimeout).ConfigureAwait(false);

            if (HookSuccess == false)
            {
                LogTo.Debug("Hook failed, aborting");

                StopIPCServer();

                var ex = new HookException("Hook setup failed: " + HookException?.Message,
                                           HookException);
                HookException = null;

                throw ex;
            }

            LogTo.Debug("SuperMemo started and injected, pId: {PId}", pId);

            return(new ProcessSharp <SMNatives>(
                       pId,
                       Process.NET.Memory.MemoryType.Remote,
                       true,
                       Core.CoreConfig.SuperMemo.PatternsHintAddresses,
                       nativeData));
        }
Пример #27
0
 /// <summary>
 /// Gets next value in byte-sequence with size of type by default.
 /// </summary>
 /// <param name="type">The type of value.</param>
 /// <returns></returns>
 public dynamic next(Type type)
 {
     return(next(type, NativeData.SizeOf(type)));
 }
Пример #28
0
        public void DecodeNativeCall(NativeData obj)
        {
            if (!NativeWhitelist.IsAllowed(obj.Hash) && obj.Internal == false)
            {
                throw new ArgumentException("Hash \"" + obj.Hash.ToString("X") + "\" is not allowed!");
            }
            else if (obj.Hash == (ulong)Hash.REQUEST_SCRIPT_AUDIO_BANK)
            {
                if (!SoundWhitelist.IsAllowed(((StringArgument)obj.Arguments[0]).Data))
                {
                    throw new ArgumentException("Such SoundSet is not allowed!");
                }
            }
            else if (obj.Hash == (ulong)Hash.PLAY_SOUND_FRONTEND)
            {
                if (!SoundWhitelist.IsAllowed(((StringArgument)obj.Arguments[1]).Data) || !SoundWhitelist.IsAllowed(((StringArgument)obj.Arguments[2]).Data))
                {
                    throw new ArgumentException("SoundSet/Name is not allowed!");
                }
            }


            var list = new List <InputArgument>();

            var nativeType = CheckNativeHash(obj.Hash);

            LogManager.DebugLog("NATIVE TYPE IS " + nativeType);
            int playerHealth = Game.Player.Character.Health;

            if (((int)nativeType & (int)Enums.NativeType.VehicleWarp) > 0)
            {
                int veh  = ((EntityArgument)obj.Arguments[1]).NetHandle;
                var item = NetEntityHandler.NetToStreamedItem(veh);
                if (item != null && !item.StreamedIn)
                {
                    NetEntityHandler.StreamIn(item);
                }
            }

            if (((int)nativeType & (int)Enums.NativeType.EntityWarp) > 0)
            {
                float x = ((FloatArgument)obj.Arguments[1]).Data;
                float y = ((FloatArgument)obj.Arguments[2]).Data;
                float z = ((FloatArgument)obj.Arguments[3]).Data;

                int interior;
                if ((interior = Function.Call <int>(Hash.GET_INTERIOR_AT_COORDS, x, y, z)) != 0)
                {
                    Function.Call((Hash)0x2CA429C029CCF247, interior); // LOAD_INTERIOR
                    Function.Call(Hash.SET_INTERIOR_ACTIVE, interior, true);
                    Function.Call(Hash.DISABLE_INTERIOR, interior, false);
                    if (Function.Call <bool>(Hash.IS_INTERIOR_CAPPED, interior))
                    {
                        Function.Call(Hash.CAP_INTERIOR, interior, false);
                    }
                }
            }

            var objectList = DecodeArgumentList(obj.Arguments.ToArray());

            var enumerable = objectList as object[] ?? objectList.ToArray();

            list.AddRange(enumerable.Select(ob => ob is OutputArgument ? (OutputArgument)ob : new InputArgument(ob)));

            if (enumerable.Any())
            {
                LogManager.DebugLog("NATIVE CALL ARGUMENTS: " + enumerable.Aggregate((f, s) => f + ", " + s) + ", RETURN TYPE: " + obj.ReturnType);
            }
            Model model = null;

            if (((int)nativeType & (int)Enums.NativeType.NeedsModel) > 0)
            {
                LogManager.DebugLog("REQUIRES MODEL");
                int position = 0;
                if (((int)nativeType & (int)Enums.NativeType.NeedsModel1) > 0)
                {
                    position = 0;
                }
                if (((int)nativeType & (int)Enums.NativeType.NeedsModel2) > 0)
                {
                    position = 1;
                }
                if (((int)nativeType & (int)Enums.NativeType.NeedsModel3) > 0)
                {
                    position = 2;
                }
                LogManager.DebugLog("POSITION IS " + position);
                var modelObj  = obj.Arguments[position];
                int modelHash = 0;
                if (modelObj is UIntArgument)
                {
                    modelHash = unchecked ((int)((UIntArgument)modelObj).Data);
                }
                else if (modelObj is IntArgument)
                {
                    modelHash = ((IntArgument)modelObj).Data;
                }
                LogManager.DebugLog("MODEL HASH IS " + modelHash);
                model = new Model(modelHash);

                if (model.IsValid)
                {
                    LogManager.DebugLog("MODEL IS VALID, REQUESTING");
                    model.Request(10000);
                }
            }

            if (((int)nativeType & (int)Enums.NativeType.NeedsAnimDict) > 0)
            {
                var animDict = ((StringArgument)obj.Arguments[1]).Data;
                Util.Util.LoadDict(animDict);
            }

            if (((int)nativeType & (int)Enums.NativeType.PtfxAssetRequest) != 0)
            {
                var animDict = ((StringArgument)obj.Arguments[0]).Data;

                Util.Util.LoadPtfxAsset(animDict);
                Function.Call(Hash._SET_PTFX_ASSET_NEXT_CALL, animDict);

                list.RemoveAt(0);
            }

            if (((int)nativeType & (int)Enums.NativeType.ReturnsEntity) > 0)
            {
                var entId = Function.Call <int>((Hash)obj.Hash, list.ToArray());
                lock (EntityCleanup) EntityCleanup.Add(entId);
                if (obj.ReturnType is IntArgument)
                {
                    SendNativeCallResponse(obj.Id, entId);
                }

                if (model != null)
                {
                    model.MarkAsNoLongerNeeded();
                }
                return;
            }

            if (nativeType == Enums.NativeType.ReturnsBlip)
            {
                var blipId = Function.Call <int>((Hash)obj.Hash, list.ToArray());
                lock (BlipCleanup) BlipCleanup.Add(blipId);
                if (obj.ReturnType is IntArgument)
                {
                    SendNativeCallResponse(obj.Id, blipId);
                }
                return;
            }

            if (((int)nativeType & (int)Enums.NativeType.TimeSet) > 0)
            {
                var newHours   = ((IntArgument)obj.Arguments[0]).Data;
                var newMinutes = ((IntArgument)obj.Arguments[1]).Data;
                Time = new TimeSpan(newHours, newMinutes, 0);
            }

            if (((int)nativeType & (int)Enums.NativeType.WeatherSet) > 0)
            {
                var newWeather = ((IntArgument)obj.Arguments[0]).Data;
                if (newWeather >= 0 && newWeather < Enums._weather.Length)
                {
                    Weather = Enums._weather[newWeather];
                    Function.Call((Hash)obj.Hash, Enums._weather[newWeather]);
                    return;
                }
            }

            var tmpArgs = obj.Arguments;

            if (!ReplacePointerNatives(obj.Hash, ref list, ref tmpArgs))
            {
                return;
            }

            if (obj.ReturnType == null)
            {
                Function.Call((Hash)obj.Hash, list.ToArray());
            }
            else
            {
                if (obj.ReturnType is IntArgument)
                {
                    SendNativeCallResponse(obj.Id, Function.Call <int>((Hash)obj.Hash, list.ToArray()));
                }
                else if (obj.ReturnType is UIntArgument)
                {
                    SendNativeCallResponse(obj.Id, Function.Call <uint>((Hash)obj.Hash, list.ToArray()));
                }
                else if (obj.ReturnType is StringArgument)
                {
                    SendNativeCallResponse(obj.Id, Function.Call <string>((Hash)obj.Hash, list.ToArray()));
                }
                else if (obj.ReturnType is FloatArgument)
                {
                    SendNativeCallResponse(obj.Id, Function.Call <float>((Hash)obj.Hash, list.ToArray()));
                }
                else if (obj.ReturnType is BooleanArgument)
                {
                    SendNativeCallResponse(obj.Id, Function.Call <bool>((Hash)obj.Hash, list.ToArray()));
                }
                else if (obj.ReturnType is Vector3Argument)
                {
                    SendNativeCallResponse(obj.Id, Function.Call <Vector3>((Hash)obj.Hash, list.ToArray()));
                }
            }

            if (((int)nativeType & (int)Enums.NativeType.PlayerSkinChange) > 0)
            {
                Ped PlayerChar = Game.Player.Character;
                PlayerChar.Style.SetDefaultClothes();
                PlayerChar.MaxHealth = 200;
                PlayerChar.Health    = playerHealth;
            }
        }
Пример #29
0
 public TSMMain(NativeData nativeData)
 {
     InstancePtr = new IntPtr(nativeData.Pointers[NativePointers.SMMain_InstancePtr]);
 }
Пример #30
0
 public TDatabase(NativeData nativeData)
 {
     InstancePtr = new IntPtr(nativeData.Pointers[NativePointers.Database_InstancePtr]);
 }