crosire Posted April 27, 2015 Share Posted April 27, 2015 (edited) Community Script Hook V .NET You may remember the .NET ScriptHook back from GTAIV, it allowed using the easy to learn, but extremly powerful .NET languages to write scripts that can be executed ingame. About This ASI plugin for the just released Script Hook V attempts to recreate this experience for GTAV. It's full source code is hosted on Github, development is community-driven and open to everybody, so contributions are warmly welcomed. Right now it's able to load, compile and run .NET scripts and reload them while the game is running (press the "Insert" key). It also comes with a vast scripting API abstracting away the native function calls (you can still do those manually through "GTA.Native.Function.Call" though). Scripts are executed in a separate AppDomain, any exceptions thrown thus shouldn't affect the game or ScriptHook. Thanks a lot to Alexander Blade for Script Hook V and HazardX for the inspiration with his GTAIV .NET ScriptHook. Download Latest Binary Release Installation Install both the Microsoft .NET Framework 4.5.2 and the Visual C++ Redistributable Package for Visual Studio 2013 (x64) (or loading will fail). Download and install the latest Script Hook V (including the ASI loader). Download Community Script Hook V .NET and copy the ASI file into your game folder. Create (or download) a C#/VisualBasic code file (.cs, .vb) or compiled .NET assembly (.dll) inside the "scripts" folder in your game directory and start scripting! Contributing Important files: source/core/Main.cpp: The main script entry point source/core/ScriptDomain.cpp: .NET script manager. Loads, compiles and executes the scripts. source/core/Script.hpp: Class from which all scripts have to inherit, handles the script main loop. source/core/Native.cpp: Managed to native function call conversion. source/core/NativeHashes.hpp: Native function hash enumeration. The remaining files in source/scripting implement the scripting API. Any help on improving that API is much appreciated. Documentation Either use notepad to edit source code scripts directly or use Visual Studio to compile them to assemblies. Going down the Visual Studio way has the advantage of syntax highlighting, code completion and Intellisense (since there is no API documentation yet). Just create a C# or VisualBasic class library project, add a reference to Script Hook V .NET (rename the ASI to DLL) in the project properties and you are ready to go. If something doesn't work, check the log file. It catches exceptions and gives you all the information to get to the bottom of the problem. Visit the wiki for more help on how to get started and write scripts. Edited November 12, 2022 by crosire new repository kagikn, kenryk, wolfrunner86 and 42 others 45 Link to comment Share on other sites More sharing options...
SilverRST Posted April 27, 2015 Share Posted April 27, 2015 This is f*cking awesome! I didn't expected .NET would be possible for GTAV. Lets re-live the GTAIV days again! Jinx., PkUnzipper and XCalinX 3 Link to comment Share on other sites More sharing options...
inadequate Posted April 27, 2015 Share Posted April 27, 2015 Lets re-live the GTAIV days again! Dictatorce 1 Link to comment Share on other sites More sharing options...
slik Posted April 27, 2015 Share Posted April 27, 2015 Looks promising, thanks Link to comment Share on other sites More sharing options...
Anthony_y Posted April 27, 2015 Share Posted April 27, 2015 Holy sh*t thanks so much. Didn't expect it this quickly Link to comment Share on other sites More sharing options...
Finney Posted April 27, 2015 Share Posted April 27, 2015 (edited) Hmm, unable to get the example script to run - just testing to make sure it works before I do anything. Got everything setup. Didn't have a problem testing out the Lua one either. I'll keep toying and report back if its just me being retarded. Got a project warmed up and ready to test more in VS, so I'll throw together something real fast and see if I'm still having a issue. Didn't check the log. Wondering if anyone else was having a issue? Well that explains it. [15:49:50] Failed to create script domain: System.IO.FileLoadException: Could not load file or assembly 'file:///H:\Games\Steam\steamapps\steamapps\common\Grand Theft Auto V\ScriptHookVDotNet.asi' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) File name: 'file:///H:\Games\Steam\steamapps\steamapps\common\Grand Theft Auto V\ScriptHookVDotNet.asi' ---> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569for more information. at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark) at System.Reflection.Assembly.LoadFrom(String assemblyFile, Evidence securityEvidence) at System.Activator.CreateInstanceFromInternal(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo) at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName) at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName) at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName) at GTA.ScriptDomain.Reload() Edited April 27, 2015 by Finney itandeddy, grearlibetv, grearlibe79 and 1 other 4 Link to comment Share on other sites More sharing options...
wozzy Posted April 27, 2015 Share Posted April 27, 2015 (edited) I also couldn't get the sample to run. Here's the error from my log: [15:46:19] Failed to create script domain:System.IO.FileLoadException: Could not load file or assembly 'file:///D:\Program Files (x86)\Steam\steamapps\common\Grand Theft Auto V\ScriptHookVDotNet.asi' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)File name: 'file:///D:\Program Files (x86)\Steam\steamapps\common\Grand Theft Auto V\ScriptHookVDotNet.asi' ---> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information. at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark) at System.Reflection.Assembly.LoadFrom(String assemblyFile, Evidence securityEvidence) at System.Activator.CreateInstanceFromInternal(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo) at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName) at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName) at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName) at GTA.ScriptDomain.Reload() Edited April 27, 2015 by wozzy Link to comment Share on other sites More sharing options...
slik Posted April 27, 2015 Share Posted April 27, 2015 Is there a hotkey to unload all the scripts? Link to comment Share on other sites More sharing options...
Echelonc Posted April 27, 2015 Share Posted April 27, 2015 I dont get how to add a reference to the scripthook Link to comment Share on other sites More sharing options...
crosire Posted April 27, 2015 Author Share Posted April 27, 2015 (edited) That's unfortunate. May I ask which .NET framework version you have installed on your ends (full or client profile)? It's possible the combination of .NET 4.0 together with the VC++ 2013 compiler doesn't work out very well (although it's working on two different computers here). It's probably best to update the project to 4.5. Is there a hotkey to unload all the scripts? Not yet. You could rename the "scripts" folder and then force a reload to unload everything. I dont get how to add a reference to the scripthook Just rename the ScriptHookVDotNet.asi to ScriptHookVDotNet.dll and add that file as a reference. Edited April 27, 2015 by Crosire Link to comment Share on other sites More sharing options...
Echelonc Posted April 27, 2015 Share Posted April 27, 2015 That's unfortunate. May I ask which .NET framework version you have installed on your ends (full or client profile)? It's possible the combination of .NET 4.0 together with the VC++ 2013 compiler doesn't work out very well (although it's working on two different computers here). It's probably best to update the project to 4.5. Is there a hotkey to unload all the scripts? Not yet. You could rename the "scripts" folder and then force a reload to unload everything. I dont get how to add a reference to the scripthook Just rename the ScriptHookVDotNet.asi to ScriptHookVDotNet.dll and add that file as a reference. The extension doesnt change as i rename it? Link to comment Share on other sites More sharing options...
Finney Posted April 27, 2015 Share Posted April 27, 2015 .NET Framework 4.5.1 installed with Windows 8.1 or Windows Server 2012 R2 Link to comment Share on other sites More sharing options...
Anthony_y Posted April 27, 2015 Share Posted April 27, 2015 (edited) I also couldn't get the sample to run. Here's the error from my log: Got the exact same error trying to run my own script EDIT: running .NET 4.5 on Windows 8.1 64bit Pro. Edited April 27, 2015 by Anthony_y Link to comment Share on other sites More sharing options...
gatienthe Posted April 27, 2015 Share Posted April 27, 2015 It's working well, nice job dude. Link to comment Share on other sites More sharing options...
wozzy Posted April 27, 2015 Share Posted April 27, 2015 I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works Link to comment Share on other sites More sharing options...
Finney Posted April 27, 2015 Share Posted April 27, 2015 I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works I'll have to try that. Link to comment Share on other sites More sharing options...
Anthony_y Posted April 27, 2015 Share Posted April 27, 2015 I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works Thanks I'll try it now. Link to comment Share on other sites More sharing options...
Hanneswasco Posted April 27, 2015 Share Posted April 27, 2015 This looks very nice! C++ can really be a pain in the bass, so I can give this a try for my next scripting mod. Link to comment Share on other sites More sharing options...
Anthony_y Posted April 27, 2015 Share Posted April 27, 2015 (edited) I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works Well now my .NET Script Hook works but not my plugins EDIT: [21:50:30] Initialized script domain.[21:50:30] Loading scripts from 'D:\Steam\steamapps\common\Grand Theft Auto V\scripts' ... means it should all work, right? Edited April 27, 2015 by Anthony_y Link to comment Share on other sites More sharing options...
noahvt Posted April 27, 2015 Share Posted April 27, 2015 I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works Can you send me the .asi file you built? I built one as well and I get a different error when loading the asi: ScriptHookVDotNet.asi ---> System.NotSupportedException: Link to comment Share on other sites More sharing options...
Anthony_y Posted April 27, 2015 Share Posted April 27, 2015 I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works Can you send me the .asi file you built? I built one as well and I get a different error when loading the asi: ScriptHookVDotNet.asi ---> System.NotSupportedException: Here's mine, report back if it works Link to comment Share on other sites More sharing options...
unknown modder Posted April 27, 2015 Share Posted April 27, 2015 (edited) That big lookup table and calling natives by strings of their name surely for everything surely cant be good for performance, would maybe storing natives in an long enum be better Edited April 27, 2015 by unknown modder Link to comment Share on other sites More sharing options...
julionib Posted April 27, 2015 Share Posted April 27, 2015 ahhh .Net languages, loving this, c++ is cool but, damn man, thats too much to write ^^ and i simple dont see good reason for case sensitive lol, vb.net owns here ^^ Link to comment Share on other sites More sharing options...
GN 92 Posted April 27, 2015 Share Posted April 27, 2015 F*ck yeah. Cool, thanks man. Link to comment Share on other sites More sharing options...
JohnnyCrazy Posted April 27, 2015 Share Posted April 27, 2015 That big lookup table and calling natives by strings of their name surely for everything surely cant be good for performance, would maybe storing natives in an long enum be better Not actually, since the lookup-complexity of Dictionaries is nearly O(1), since it's using a HashTable internally. (https://msdn.microsoft.com/en-us/library/xfhwa508.aspx) But the lookup-table is kind of unnecessary, since you can just call them directly without the name. Good Job! I may contribute if I have some spare time Link to comment Share on other sites More sharing options...
unknown modder Posted April 27, 2015 Share Posted April 27, 2015 That big lookup table and calling natives by strings of their name surely for everything surely cant be good for performance, would maybe storing natives in an long enum be better Not actually, since the lookup-complexity of Dictionaries is nearly O(1), since it's using a HashTable internally. (https://msdn.microsoft.com/en-us/library/xfhwa508.aspx) But the lookup-table is kind of unnecessary, since you can just call them directly without the name. Good Job! I may contribute if I have some spare time the way i see it is every time a native gets called thats up to 5000 string compares to find the address(quite alot). Using something like this http://pastebin.com/iEddhpWkwould mean that finding addresses is done when the script gets compiled, instead of everytime a script is ran Link to comment Share on other sites More sharing options...
Echelonc Posted April 27, 2015 Share Posted April 27, 2015 (edited) I dont get how to add a reference to the scripthook Just rename the ScriptHookVDotNet.asi to ScriptHookVDotNet.dll and add that file as a reference. The extension doesnt change as i rename it? Can anyone clarify this please? Edited April 27, 2015 by Echelonc Link to comment Share on other sites More sharing options...
crosire Posted April 28, 2015 Author Share Posted April 28, 2015 I have .NET Framework 4.5.1 SDK I downloaded the source and built it myself, and now it works Looking into that error a bit more it seems to happen because Windows flags the file as being from a network source when you download it, which then triggers that exception. Building it yourself makes it a local file, which works. Need to find a way to get around that. the way i see it is every time a native gets called thats up to 5000 string compares to find the address(quite alot). Using something like this http://pastebin.com/iEddhpWkwould mean that finding addresses is done when the script gets compiled, instead of everytime a script is ran If implemented correctly the dictonary should hash the string and then use that hash to do the lookup (and no linear lookup, these structures are usually ordered in buckets of data and the hash indexes into those). as JonnyCrazy mentioned. So no super slow string comparison (you would definitily notice that). But you're right, such an enumeration would make a lookup unecessary and is much better for performance, good idea! Can anyone clarify this please? You'll have to configure WIndows explorer to not hide file extensions in order to be able to change them. I'll add a copy of the ASI already renamed to DLL in the next release. Link to comment Share on other sites More sharing options...
crosire Posted April 28, 2015 Author Share Posted April 28, 2015 Updated to 0.2.0: Hopefully fixes the System.IO.FileLoadException on script domain creation some have experienced. Also changed native function calling to use an enumeration of hashes (GTA.Native.Hash) instead of strings, like unknown modder suggested. Link to comment Share on other sites More sharing options...
gatienthe Posted April 28, 2015 Share Posted April 28, 2015 (edited) 1>C:\Program Files (x86)\MSBuild\12.0\bin\Microsoft.Common.CurrentVersion.targets(1697,5): warning MSB3270: There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "ScriptHookVDotNet", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. 1> Mod_1 -> F:\GTAV_MOD\Projects\Mod_1\Mod_1\bin\Debug\Mod_1.dll I get this when i try to call a native. And [14:37:07] CORE: An exception occurred while executing 'ScriptHookVDotNet.asi' On ScrtipHoobV.log Edited April 28, 2015 by gatienthe Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now