Quantcast

Jump to content

» «
Photo

Community Script Hook V .NET

V Released
1,194 replies to this topic
crosire
  • crosire

    Rat

  • Members
  • Joined: 08 Jul 2012

#1

Posted 27 April 2015 - 06:12 PM Edited by crosire, 08 January 2016 - 01:39 PM.

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

  1. Install both the Microsoft .NET Framework 4.5.2 and the Visual C++ Redistributable Package for Visual Studio 2013 (x64) (or loading will fail).
  2. Download and install the latest Script Hook V (including the ASI loader).
  3. Download Community Script Hook V .NET and copy the ASI file into your game folder.
  4. 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.

  • gamerzworld, Hanneswasco, Frank.s and 39 others like this

SilverRST
  • SilverRST

    Big Homie

  • Members
  • Joined: 25 Mar 2013
  • None

#2

Posted 27 April 2015 - 06:21 PM

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 like this

Inadequate
  • Inadequate

    Midnight Emulator

  • Members
  • Joined: 11 Apr 2012
  • None

#3

Posted 27 April 2015 - 06:27 PM

Lets re-live the GTAIV days again!

 

:D

  • Dictatorce likes this

slik
  • slik

    Player Hater

  • Members
  • Joined: 18 Apr 2015
  • Ukraine

#4

Posted 27 April 2015 - 06:49 PM

Looks promising, thanks


Anthony_y
  • Anthony_y

    Less smart than I'd hoped

  • Members
  • Joined: 20 Apr 2015
  • United-Kingdom

#5

Posted 27 April 2015 - 06:50 PM

Holy sh*t thanks so much. Didn't expect it this quickly :D


Finney
  • Finney

    Player Hater

  • Members
  • Joined: 02 Mar 2015
  • United-States

#6

Posted 27 April 2015 - 07:25 PM Edited by Finney, 27 April 2015 - 07:55 PM.

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..../?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()
  • grearlibedj, grearlibe79, grearlibetv and 1 other like this

wozzy
  • wozzy

    Aspiring Modder

  • Members
  • Joined: 23 Apr 2015
  • Canada

#7

Posted 27 April 2015 - 07:52 PM Edited by wozzy, 27 April 2015 - 07:53 PM.

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()


slik
  • slik

    Player Hater

  • Members
  • Joined: 18 Apr 2015
  • Ukraine

#8

Posted 27 April 2015 - 07:56 PM

Is there a hotkey to unload all the scripts?


Echelonc
  • Echelonc

    Player Hater

  • Members
  • Joined: 23 Sep 2013
  • Sweden

#9

Posted 27 April 2015 - 07:59 PM

I dont get how to add a reference to the scripthook


crosire
  • crosire

    Rat

  • Members
  • Joined: 08 Jul 2012

#10

Posted 27 April 2015 - 07:59 PM Edited by Crosire, 27 April 2015 - 08:04 PM.

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.


Echelonc
  • Echelonc

    Player Hater

  • Members
  • Joined: 23 Sep 2013
  • Sweden

#11

Posted 27 April 2015 - 08:08 PM

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?


Finney
  • Finney

    Player Hater

  • Members
  • Joined: 02 Mar 2015
  • United-States

#12

Posted 27 April 2015 - 08:10 PM

.NET Framework 4.5.1 installed with Windows 8.1 or Windows Server 2012 R2


Anthony_y
  • Anthony_y

    Less smart than I'd hoped

  • Members
  • Joined: 20 Apr 2015
  • United-Kingdom

#13

Posted 27 April 2015 - 08:12 PM Edited by Anthony_y, 27 April 2015 - 08:24 PM.

 

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.


gatienthe
  • gatienthe

  • Members
  • Joined: 28 Jan 2012
  • None

#14

Posted 27 April 2015 - 08:23 PM

It's working well, nice job dude.


wozzy
  • wozzy

    Aspiring Modder

  • Members
  • Joined: 23 Apr 2015
  • Canada

#15

Posted 27 April 2015 - 08:27 PM

I have .NET Framework 4.5.1 SDK

I downloaded the source and built it myself, and now it works

Finney
  • Finney

    Player Hater

  • Members
  • Joined: 02 Mar 2015
  • United-States

#16

Posted 27 April 2015 - 08:30 PM

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.


Anthony_y
  • Anthony_y

    Less smart than I'd hoped

  • Members
  • Joined: 20 Apr 2015
  • United-Kingdom

#17

Posted 27 April 2015 - 08:39 PM

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.


Hanneswasco
  • Hanneswasco

    Awesome KiWii

  • Members
  • Joined: 15 Jun 2007
  • Belgium

#18

Posted 27 April 2015 - 08:45 PM

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. :)


Anthony_y
  • Anthony_y

    Less smart than I'd hoped

  • Members
  • Joined: 20 Apr 2015
  • United-Kingdom

#19

Posted 27 April 2015 - 08:57 PM Edited by Anthony_y, 27 April 2015 - 08:58 PM.

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 :p

 

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?


noahvt
  • noahvt

    Player Hater

  • Members
  • Joined: 26 Mar 2014
  • Belgium

#20

Posted 27 April 2015 - 08:57 PM

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:


Anthony_y
  • Anthony_y

    Less smart than I'd hoped

  • Members
  • Joined: 20 Apr 2015
  • United-Kingdom

#21

Posted 27 April 2015 - 09:10 PM

 

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 :D


unknown modder
  • unknown modder

    Bon Jon Bovi

  • Members
  • Joined: 04 Jul 2012
  • United-Kingdom

#22

Posted 27 April 2015 - 09:36 PM Edited by unknown modder, 27 April 2015 - 10:14 PM.

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


julionib
  • julionib

    Coder

  • Feroci
  • Joined: 13 Sep 2012
  • Brazil

#23

Posted 27 April 2015 - 09:43 PM

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 ^^ 


GN 1992
  • GN 1992

    aka gnad.1992

  • GTAF Crew
  • Joined: 07 Apr 2014
  • Brazil
  • April Fools Winner 2015

#24

Posted 27 April 2015 - 09:53 PM

F*ck yeah. Cool, thanks man.


JohnnyCrazy
  • JohnnyCrazy

    Player Hater

  • Members
  • Joined: 26 Apr 2015
  • Germany

#25

Posted 27 April 2015 - 11:31 PM

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.microso...y/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 :)


unknown modder
  • unknown modder

    Bon Jon Bovi

  • Members
  • Joined: 04 Jul 2012
  • United-Kingdom

#26

Posted 27 April 2015 - 11:40 PM

 

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.microso...y/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


Echelonc
  • Echelonc

    Player Hater

  • Members
  • Joined: 23 Sep 2013
  • Sweden

#27

Posted 27 April 2015 - 11:40 PM Edited by Echelonc, 27 April 2015 - 11:41 PM.

 

 

 

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? :)


crosire
  • crosire

    Rat

  • Members
  • Joined: 08 Jul 2012

#28

Posted 28 April 2015 - 01:26 AM

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.

 


crosire
  • crosire

    Rat

  • Members
  • Joined: 08 Jul 2012

#29

Posted 28 April 2015 - 10:53 AM

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.


gatienthe
  • gatienthe

  • Members
  • Joined: 28 Jan 2012
  • None

#30

Posted 28 April 2015 - 12:29 PM Edited by gatienthe, 28 April 2015 - 12:38 PM.

 

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





4 user(s) are reading this topic

0 members, 4 guests, 0 anonymous users