[ESX][C#][How-To] Use ESX in C#

Hey Guys Today Im Gonna show you how To use ESX in C# with basic example

i highly Recommend you to stick with lua if you want to use ESX Framework but generaly i love c# and i love esx so why not using them at same time.


First of all After Doing the basics for a Resource in C# (Adding CitizenFx / BaseScript and …)
You need A dynamic called esx.

CODE
public class Class1 : BaseScript
    {
        dynamic ESX;
        public Class1()
        {

        }
    }

After That Same as lua you need to Get SharedObject For Doing that You need to add :arrow_down:

TriggerEvent("esx:getSharedObject", new object[] { new Action<dynamic>(esx => {
            ESX = esx;
        })});

Now you can use Everything that you could use in lua in C#. One thing i recommend is using ‘var’ for your variables
:arrow_down: Here is basic Example.

CODE
public class Class1 : BaseScript
    {
        dynamic ESX;
        public Class1()
        {
            TriggerEvent("esx:getSharedObject", new object[] { new Action<dynamic>(esx => {
            ESX = esx;
        })});

            RegisterCommand("TestESX", new Action<int, List<object>, string>((source, args, raw) =>
            {
                 // Getting xPlayer Using ESX APi
                var xPlayer = ESX.GetPlayerFromId(source);
                var Job = xPlayer.getJob();
                xPlayer.triggerEvent("chat:addMessage", new
                {
                    color = new[] { 255, 0, 0 },
                    args = new[] { "[JobInfo]", $"Your Job is {Job.name}. Your Grade Is {Job.grade_name}. Your Salary is {Job.grade_salary}" }
                });
            }), false);
        }
    }

i registered a command called “TestESX” and i used xPlayer for getting the player job and i added a text message for player to tell him his job and his grade and his salary (This is a server side script)

Be Sure to Drop :heart: If This Topic Helped you. Thanks!

19 Likes

Pashmam damet garm :upside_down_face:

1 Like

thanks so much for this tutorial!!!

1 Like

Thanks man it was very helpful :heart:

1 Like

it’s not working for me it’s show System.Dynamic.ExpandoObject does not contain a definition for GetPlayerFromId()

1 Like

Make Sure You Installed ESX with the correct way.

Thank you :smiley: but I’ve installed ESX and work perfectly with lua, I think it should work with c#, is that correct ?

1 Like

From What i See in your Error note, you didn’t get ESX object correctly and ESX is still a null Variable , Make sure You did the TriggerEvent Step Correctly

1 Like

Hi there!
I’ve downloaded a script [Release] ar_k9 [1.2] [Standalone]

It uses fully c# no Lua except the fxmanifest.
In the sv main.cs file it calls this to check permission job.grade_name

But doesn’t work with job.name

Tried about everything I can in there.

To clarify, I want it to work with job.name instead of job.grade_name

public bool HasPermission(Player source)

        {
            if (settings.standalone == false)
            {
                dynamic player = this.ESX.GetPlayerFromId(source.Handle);
                dynamic job = player != null ? player.getJob() : null;

                if (player == null || job == null)
                    return false;

                if (job.grade_name == settings.allowedJobGrade)
                    return true;

                return false;
            }

            return IsPlayerAceAllowed(source.Handle, "k9");
        }
1 Like

Do I need to remove bool?

Do u want me to mess around with it, since I got what I needed to work on the other one?

Basically if I get job.name == police to work then all my problems are solved😂

Or even better for it to check multiple job.grade_name

set stand alone to false, pick apart the citizen interaction to alter what you have in your server and what you don’t and this will allow all cops access to the k9. If you want only certain people to have access to the dog, then set your ace permissions and set to true for standalone in the ar_k9 script, and you will be good to go. Anyone without AcePermissions can access the k9 menu, but not be able to spawn a dog.

function OpenPoliceActionsMenu()
local elements = {
{label = _U(‘citizen_interaction’), value = ‘citizen_interaction’},
{label = _U(‘vehicle_interaction’), value = ‘vehicle_interaction’},
{label = _U(‘object_spawner’), value = ‘object_spawner’},
----{label = _U(‘Jail Menu’), value = ‘jail_menu’},
{label = _U(‘k9_interaction’), value = ‘k9_interaction’},

}	



ESX.UI.Menu.CloseAll()
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', {
	title    = 'Police',
	align    = 'bottom-right',
	elements = elements
	}, function(data, menu)
	
		
	
	if data.current.value == 'citizen_interaction' then
		local elements = {
			--{label = ('Cuff'),    value = 'ruskicuff'},
			{label = ('Uncuff'), value = 'handcuff'},
			{label = _U('drag'), value = 'drag'},
			{label = _U('gsr_test'), value = 'gsr_test'},
			{label = _U('id_card'), value = 'identity_card'},
			{label = _U('search'), value = 'body_search'},
			{label = _U('put_in_vehicle'), value = 'put_in_vehicle'},
			{label = _U('out_the_vehicle'), value = 'out_the_vehicle'},
			{label = _U('fine'), value = 'fine'},
			{label = _U('revive player'),   value = 'revive'},
			{label = _U('jail_menu'),   value = 'jail_menu'},
			{label = "Community Service", value = 'communityservice'},
			{label = _U('unpaid_bills'), value = 'unpaid_bills'},
			{label = 'Criminal Records', value = 'criminalrecords'},
			
		}

		if Config.EnableLicenses then
			table.insert(elements, { label = _U('license_check'), value = 'license' })
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
			title    = _U('citizen_interaction'),
			align    = 'right',
			elements = elements
		}, function(data2, menu2)
			local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
			if closestPlayer ~= -1 and closestDistance <= 2.0 then
				local action = data2.current.value
				
				if data2.current.value == 'revive' then	
          local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
          local closestPlayerPed = GetPlayerPed(closestPlayer)
          local health = GetEntityHealth(closestPlayerPed)
			if health == 0 then
			local playerPed = GetPlayerPed(-1)
			

			Citizen.CreateThread(function()
					  ESX.ShowNotification(_U('revive_inprogress'))
					  TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true)
					  Wait(10000)
					  ClearPedTasks(playerPed)
					  if GetEntityHealth(closestPlayerPed) == 0 then
						TriggerServerEvent('esx_ambulancejob:revive', GetPlayerServerId(closestPlayer))
						ESX.ShowNotification(_U('revive_complete'))
					  else
						ESX.ShowNotification(_U('isdead'))
					  end
					end)
			end
		  end

				if action == 'identity_card' then
					OpenIdentityCardMenu(closestPlayer)
				elseif action == 'body_search' then
					TriggerServerEvent('esx_policejob:message', GetPlayerServerId(closestPlayer), _U('being_searched'))
					OpenBodySearchMenu(closestPlayer)
				--elseif action == 'ruskicuff' then
					--TriggerServerEvent('esx_ruski_areszt:startAreszt', GetPlayerServerId(closestPlayer))									-- Rozpoczyna Funkcje na Animacje (Cala Funkcja jest Powyzej^^^)
					--Citizen.Wait(3000)
					--TriggerServerEvent('InteractSound_SV:PlayWithinDistance', 2.0, 'cuff', 0.7)
					--TriggerServerEvent('esx_policejob:handcuff',  GetPlayerServerId(closestPlayer))
				elseif action == 'handcuff' then
					TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(closestPlayer))
				elseif action == 'drag' then
					TriggerServerEvent('esx_policejob:drag', GetPlayerServerId(closestPlayer))
				elseif action == 'gsr_test' then
					TriggerServerEvent('GSR:Status2', GetPlayerServerId(closestPlayer))
				elseif action == 'put_in_vehicle' then
					TriggerServerEvent('esx_policejob:putInVehicle', GetPlayerServerId(closestPlayer))
				elseif action == 'out_the_vehicle' then
					TriggerServerEvent('esx_policejob:OutVehicle', GetPlayerServerId(closestPlayer))
				elseif action == 'fine' then
					OpenFineMenu(closestPlayer)
				elseif action == 'jail_menu' then
					TriggerEvent("esx-qalle-jail:openJailMenu")	
				elseif action == 'communityservice' then
					SendToCommunityService(GetPlayerServerId(closestPlayer))					
				elseif action == 'license' then
					ShowPlayerLicense(closestPlayer)
				elseif action == 'unpaid_bills' then
					OpenUnpaidBillsMenu(closestPlayer)
				elseif action == 'criminalrecords' then
					TriggerEvent('esx_criminalrecords:open')
				end
			else
				ESX.ShowNotification(_U('no_players_nearby'))
			end
		end, function(data2, menu2)
			menu2.close()
		end)
		
		
		elseif data.current.value == 'k9_interaction' then
		local elements = {
			{label = 'Spawn K9', value = 'k9spawn'},
			{label = 'K9 Follow', value = 'k9follow'},
			{label = 'K9 Stay', value = 'k9stay'},
			{label = 'K9 Search Vehicle', value = 'k9sehveh'},
			{label = 'K9 Search Citizen', value = 'k9sehcit'},
			{label = 'K9 Enter Vehicle', value = 'k9enterveh'},
			{label = 'K9 Exit Vehicle', value = 'k9exitveh'},
			{label = 'K9 Dismiss', value = 'k9delete'}
		}
		
  ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'k9_interaction', {
    title    = 'K9 Actions',
    align    = 'bottom-right',
    elements = elements
  }, function(data2, menu2)
      local action = data2.current.value

      if action == 'k9spawn' then
          ExecuteCommand('k9 spawn shepherd')
      elseif action == 'k9follow' then
        ExecuteCommand('k9 follow')
      elseif action == 'k9stay' then
      ExecuteCommand('k9 stay')
    elseif action == 'k9sehveh' then
      ExecuteCommand('k9 search vehicle')
    elseif action == 'k9sehcit' then
        ExecuteCommand('k9 search player')
      elseif action == 'k9enterveh' then
        ExecuteCommand('k9 enter')
      elseif action == 'k9exitveh' then
        ExecuteCommand('k9 exit')
      elseif action == 'k9delete' then
        ExecuteCommand('k9 delete')
      end
  end, function(data2, menu2)
    menu2.close()
  end)

Hey, for me its not working. Im getting errors when i try to use a method

Excellent work!

Make sure the method is not a something like

private static void SomeMethod()
{

}

but instead is

private void SomeMethod()
{

}
1 Like

with what version of es_extended is this compatible because I have 1.1 and it does not work it prints an error and if you type it a second time your client crashes.

Hey Guys, I wrote some classes. Well I guess im not finished yet but im not sure that I will need more of it. So I am posting the current status of my work:

internal class XPlayer
    {
        dynamic player;
        public XPlayer(dynamic xplayer)
        {
            player = xplayer;
        }
        public void AddAccountMoney(string accountType, int amount)
        {
            if (accountType.ToLower() != "bank"  && accountType.ToLower() != "money") 
            {
                Console.WriteLine("The accountType must be \"bank\" or \"money\"!");
                throw new Exception();
            }
            player.addAccountMoney(accountType, amount);
        }

        public void AddInventoryItem(string itemName, int itemCount) => player.addInventoryItem(itemName, itemCount);

        public void AddMoney(int amount) => player.addMoney(amount);

        public void AddWeapon(string weaponName, int ammo) => player.addWeapon(weaponName, ammo);

        public void AddWeaponAmmo(string weaponName, int ammo) => player.addWeaponAmmo(weaponName, ammo);

        public void AddWeaponComponent(string weaponName, string weaponComponent) => player.addWeaponComponent(weaponName, weaponComponent);

        public bool CanCarryItem(string itemName, int count)
        {
            return player.canCarryItem(itemName, count);
        }

        public bool CanSwapItem(string firstItem, int firstItemCount, string testItem, int testItemCount)
        {
            return player.canSwapItem(firstItem, firstItemCount, testItem, testItemCount);
        }

        //TODO: getAccount(account)
        //TODO: getAccounts()

        //TODO: Schauen obs klappt <3
        public string GetGroup() { return player.getGroup(); }

        public string GetRockstarIdentifier() { return player.getIdentifier(); }

        //TODO: GetInventory(minimal)

        //TODO: GetInventoryItem(item)

        public PlayerJob GetJob() { return new PlayerJob(player.getJob()); }

        //TODO: GetLoadout()
        //TODO: GetMissingAccounts()

        public int GetMoney() { return player.getMoney(); }

        public string GetName() { return player.getName(); }

        //TODO: GetWeapon(weaponName)

        //TODO: GetWeaponTint(weaponName, weaponTintIndex)

        public int GetWeight() { return player.getWeight(); }

        public bool HasItem(string item)
        {
            return player.hasItem(item);
        }

        public bool HasItem(string item, string metadata)
        {
            return player.hasItem(item, metadata);
        }

        public bool HasWeapon(string weaponName) { return player.hasWeapon(weaponName); }

        public bool HasWeaponComponent(string weaponName, string weaponComponent) { return player.hasWeapon(weaponName, weaponComponent); }

        public void Kick(string reason) => player.kick(reason);

        public void RemoveAccountMoney(string accountType, int amount)
        {
            if (accountType.ToLower() != "bank" && accountType.ToLower() != "money")
            {
                Console.WriteLine("The accountType must be \"bank\" or \"money\"!");
                throw new Exception();
            }
            player.removeAccountMoney(accountType, amount);
        }

        public void RemoveInventoryItem(string itemName, int itemCount) => player.removeInventoryItem(itemName, itemCount);

        public void RemoveMoney(int amount) => player.removeMoney(amount);

        public void RemoveWeapon(string weaponName, int ammo) => player.removeWeapon(weaponName, ammo);

        public void RemoveWeaponAmmo(string weaponName, int ammo) => player.removeWeaponAmmo(weaponName, ammo);

        public void RemoveWeaponComponent(string weaponName, string weaponComponent) => player.removeWeaponComponent(weaponName, weaponComponent);

        public void SetAccountMoney(string accountType, int amount)
        {
            if (accountType.ToLower() != "bank" && accountType.ToLower() != "money")
            {
                Console.WriteLine("The accountType must be \"bank\" or \"money\"!");
                throw new Exception();
            }
            player.setAccountMoney(accountType, amount);
        }

        //TODO: setCoords(vector3) !important

        public void SetInventoryItem(string item, int count) => player.setInventoryItem(item, count);

        public void SetJob(string name, int grade) => player.setJob(name, grade);

        public void SetMaxWeight(int maxWeight) => player.setMaxWeight(maxWeight);

        public void SetMoney(int money) => player.setLastMoney(money);

        public void SetName(string name) => player.setName(name);

        public void SetWeaponTint (string weaponName ,int weaponTintIndex) => player.setWeaponTint(weaponName, weaponTintIndex);

        public void ShowHelpNotification (string message, bool thisFrame, bool beep, int duration) => player.showHelpNotification(message, thisFrame, beep, duration);

        public void ShowNotification (string message, bool flash, bool saveToBreif, int hudColorIndex) => player.showNotification(message, flash, saveToBreif, hudColorIndex);
        // ~r~ = RED; ~b~ = BLUE; ~g~ = GREEN; ~y~ = YELLOW; ~p~ = PURBLE; ~o~ = ORANGE; ~c~ = LIGHT_GREY; ~m~ = DARK_GREY; ~u~ = BLACK; ~n~ = NEWLINE; ~s~ = WHITE; ~h~ = BOLD

        //void TriggerEvent(string eventName, dynamic idk...) => TriggerEvent(eventName, idk);
        public dynamic GetESXPlayer() { return player; }
    }
internal class PlayerJob
    {
        public string Name { get; }
        public string Label { get; }
        //public int Id { get; }
        public int Grade { get; }
        public string GradeName { get; }
        public string GradeLabel { get; }
        public int GradeSalary { get; }

        //TODO: Skin_Male (denke unwichtig)
        //TODO: Skin_Female (denke noch unwichtiger <3)

        public PlayerJob(dynamic Job)
        {
            Name = Job.name;
            Label = Job.label;
            //Console.WriteLine(Job.id);
            //Id = Job.id;
            Grade = Job.grade;
            GradeName = Job.grade_name;
            GradeLabel = Job.grade_label;
            GradeSalary = Job.grade_salary;
        }
    }
internal class ESX
    {
        dynamic ESO;
        public ESX(dynamic esx_object)
        {
            ESO = esx_object;
        }

        public void ClearTimeout() => ESO.ClearTimeout();

        public void CreatePickup(string type, string name, int count, string label, int playerId) => ESO.CreatePickup(type, name, count, label, playerId);
        //TODO: CreateWeaponPickup (...,table components, int tintIndex)
        public bool DoesJobExist(string job, int grade) { return ESO.DoesJobExist(job, grade); }
        //TODO: GetExtendedPlayers
        public string GetItemLabel(string item) { return ESO.GetItemLabel(item); }
        //TODO GetJobs
        public XPlayer GetPlayerById(int playerId) { return new XPlayer(ESO.GetPlayerById(playerId)); }
        public XPlayer GetPlayerByRockstarIdentifier(string identifier) { return new XPlayer(ESO.GetPlayerByIdentifier(identifier)); }
        //public void RegisterCommand(List<string> aliases, string permission, callback function, bool allowConsole, bool suggestion)
        // -> Wird nicht klappen
        //public void RegisterUsableItem(item, callback) -> Wird wegen Callback function vermutlich auch nicht klappen
        public void TraceException(string message) => ESO.Trace(message);

        public void UseItem(int playerId, string itemName) => ESO.UseItem(playerId, itemName); 
    }
1 Like

You need to setup in the ressource.lua your script as a Server script.