[Release] C#/.NET wrapper for server-side scripts (1.4.1)

#C#/.NET Server Wrapper
A temporary wrapper to let servers support C#/.NET server-side scripts until FXServer is available.

##Source-code + Example script

  • To build a script, add reference to System.ComponentModel.Composition and the ServerWrapper binary, inherit the ServerScript class and add the Export attribute to it with the typeof() interface IServerScript, the project has to be built for .NET Framework 4.6.1 targeting x64.
    ** Dependencies that aren’t other scripts go to the server’s root folder since the scripts’ domain base folder is the same as the server domain’s, this is intentional, use this class and add the dependencies as embedded resources to the project if you wish to avoid bloating the server folder.

##Download

##Setup

  • Download the zip archive from the link above
  • Make sure you’re using the latest CitizenMP.Server available
  • Drag and drop all the files and folders onto the root folder of the server (where “CitizenMP.Server.exe” is located)
  • Make sure all the assemblies (*.dll) are unblocked (Right click -> Properties -> “Unblock” if available).
  • Add ServerWrapper as a resource in the server config
  • Add any scripts to the “Scripts” subfolder inside the ServerWrapper folder.

##Rcon commands

  • reloadscripts - reload all scripts.
  • unloadscripts - unload all scripts.
  • loadscripts - (when unloaded) load all scripts.
  • swupdate - open this page in the default browser.
7 Likes

Updated to 1.1, see releases on GitHub for changes.

I’ve included a proof-of-concept MySQL script to demo use cases of the wrapper - queries can be executed on a separate thread, no longer stalling the main thread, which should reduce instancing (with the provided code callbacks are invoked back on the main thread).

EDIT: Update 1.2 will address some issues people were having. As for anyone experiencing issues with the “/example” command in the example script, I haven’t actually tested the command in-game and forgot that the color array is a NeoLua type which cannot be marshaled, causing an error when used, I’ll try to work on a workaround devs would manually configure, although it would likely require a server restart when you add/remove other events to the workaround.

1 Like

Update 1.2 now available, see releases on GitHub for changes.

This could be very useful for me, thanks!

Thanks, Very UseFul !

CitizenMP.Server.exe Close after this:

https://gyazo.com/94ad873a0797f610e17594042a01ad9a

Same Way if i use server ServerScriptExample.dll…

Any Idea ?

Could you share the code you have so far? Make sure you follow the notes in the example script.

I do. but if i take all files in the ServerScriptExample download on latest release on github, the result is exatly the same way, crash after creating proxy.

My script is not the problem…

Does it happen with a clean server too?

In a server completely cleen yep…

If i remove all scripts in folder Scripts, server stop after that:

https://gyazo.com/25747b868710901dacc78c7fd1804062

i really dont know if the last log because, cfx server dont log in file…

Try a quick recording to see whether the message “ServerWrapper: Proxy created for script…” ever appears.

I already done and no i dont see that

Tested on 3 computer, and crash for all of them

Thanks for Helping

I’m unable to reproduce it, I’ll give you something to try when I get the chance

I find the problem… I just need the latest fivem server, sorry for the time lost

I detect one problem of AddEventHandler() when i get my event this function dont send the source of event.

And on playerConnecting event i cant get identifier of player call this event because is not registered yet in ReadOnlyDictionary<ushort, Player> PlayersByNetId or ReadOnlyDictionary<string, Player> Players, and GetPlayerIdentifiers crash with Player null.

You need to explicitly add “source” as a parameter in the event handler, see how chatMessage is handled in the example script.
Seems like chatMessage passes source and other events aren’t handled the same way, working on a way to obtain “source” now.

PlayersByNetId and Players are both cloned from the server’s internal dictionaries, if the player is not available there, then the server hasn’t added said player to the dictionaries yet. The GetPlayerSOMETHING functions are all based on the dictionaries, there’s no point using them if you know the player isn’t in the dictionary.

Update 1.4 now available, see releases on GitHub for changes.

EDIT: There’s an issue with remote object references expiring, working on a fix.

Update 1.4.1 with a fix to the issue above and some more small changes now available on GitHub.