[How-To] Add dirty money into "old" ES mode

Hi, in this tutorial, I will show you how to add dirty money to the “old” ES mode.

First of all, you will need the MySQL version of ES and a working database connection.
Once that is all working, you can continue with this tutorial.
I also know there will be a new FiveM version soon with MySQL integration, but this will help people to get some basics on how to work with classes.

Note : [ES] = folder named essentialmode (to keep the tutorial clean)

STEP 1 Change the database

Add a new field in the table ‘users’ called dirty_money.
SQL :

ALTER TABLE  users ADD  dirty_money DOUBLE NOT NULL

##STEP 2 Change player.lua
Open the file player.lua in resources[ES]\server\classes
Now add our new field to it :

setmetatable(Player, {
	__call = function(self, source, permission_level, money, dirty_money, identifier, group)
		local pl = {}

		pl.source = source
		pl.permission_level = permission_level
		pl.money = money
		pl.dirty_money = dirty_money
		pl.identifier = identifier
		pl.group = group
		pl.coords = {x = 0.0, y = 0.0, z = 0.0}
		pl.session = {}

		return setmetatable(pl, Player)
	end
})

Now we can add new functions who will update this variable :
Add the function at the end of the file.

--==============Dirty money stuff========================
-- Sets the player dirty money (required to call this from now)
function Player:setDirty_Money(m)
	local prevMoney = self.dirty_money
	local newMoney : double = m

	self.dirty_money = m

	if((prevMoney - newMoney) < 0)then
		TriggerClientEvent("es:addedDirtyMoney", self.source, math.abs(prevMoney - newMoney))
	else
		TriggerClientEvent("es:removedDirtyMoney", self.source, math.abs(prevMoney - newMoney))
	end

	TriggerClientEvent('es:activateDirtyMoney', self.source , self.dirty_money)
end

-- Adds to player dirty money (required to call this from now)
function Player:addDirty_Money(m)
	local newMoney : double = self.dirty_money + m

	self.dirty_money = newMoney

	TriggerClientEvent("es:addedDirtyMoney", self.source, m)
	TriggerClientEvent('es:activateDirtyMoney', self.source , self.dirty_money)
end

-- Removes from player dirty money (required to call this from now)
function Player:removeDirty_Money(m)
	local newMoney : double = self.dirty_money - m

	self.dirty_money = newMoney

	TriggerClientEvent("es:removedDirtyMoney", self.source, m)
	TriggerClientEvent('es:activateDirtyMoney', self.source , self.dirty_money)
end
--=============End Dirty money stuff=====================

##STEP 3 Load and save dirty money
Open the file login.lua in the folder resources[ES]\server\player
In this file we will add some code to store and get the dirty money from the database.
Change the GetResult into :

local result = MySQL:getResults(executed_query, {'permission_level', 'money', 'dirty_money', 'identifier', 'group'}, "identifier")

Add the new field to our player creation :

Users[source] = Player(source, result[1].permission_level, result[1].money, result[1].dirty_money, result[1].identifier , group)

In the same file, find the function that will save the money every 60 seconds and change it into :

-- Function to update player money every 60 seconds.
local function savePlayerMoney()
	SetTimeout(60000, function()
		TriggerEvent("es:getPlayers", function(users)
			for k,v in pairs(users)do
				MySQL:executeQuery("UPDATE users SET `money`='@value', `dirty_money`='@v2' WHERE identifier = '@identifier'",
			    {['@value'] = v.money, ['@v2'] = v.dirty_money, ['@identifier'] = v.identifier})
			end
		end)

		savePlayerMoney()
	end)
end

Now open the file main.lua in folder resources[ES]\server and let’s change the playerdropped function :

AddEventHandler('playerDropped', function()
	if(Users[source])then
		MySQL:executeQuery("UPDATE users SET `money`='@value', `dirty_money`='@v2' WHERE identifier = '@identifier'",
		{['@value'] = Users[source].money, ['@v2'] = Users[source].dirty_money, ['@identifier'] = Users[source].identifier})

		Users[source] = nil
	end
end)

##STEP 4 Adding the GUI
In order to display the dirty money on the screen, we will first add some commands that are used to refresh everything.
Open the file main.lua located in resources[ES]\client and add these functions :

--=========Dirty money stuff============
RegisterNetEvent('es:activateDirtyMoney')
AddEventHandler('es:activateDirtyMoney', function(e)
	SendNUIMessage({
		setDirty_money = true,
		dirty_money = e
	})
end)

RegisterNetEvent("es:addedDirtyMoney")
AddEventHandler("es:addedDirtyMoney", function(m)
	SendNUIMessage({
		addDirty_cash = true,
		dirty_money = m
	})

end)

RegisterNetEvent("es:removedDirtyMoney")
AddEventHandler("es:removedDirtyMoney", function(m)
	SendNUIMessage({
		removeDirty_cash = true,
		dirty_money = m
	})
end)

Also in this file, we need to initialize the money :

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(1000)
		local pos = GetEntityCoords(GetPlayerPed(-1))

		if(oldPos ~= pos)then
			TriggerServerEvent('es:updatePositions', pos.x, pos.y, pos.z)

			if(loaded)then
				SendNUIMessage({
					setmoney = true,
					money = cashy,
					setDirty_money = true,
					dirty_money = cashy
				})

				loaded = false
			end
			oldPos = pos
		end
	end
end)

Now we can change the ui.html located in resources[ES]
Since this is a basic file, I will post all of it here and add in comment where I added everything.

<head>
	<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
	<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
	<script>
		function addCommas(nStr) {
			nStr += '';
			var x = nStr.split('.');
			var x1 = x[0];
			var x2 = x.length > 1 ? '.' + x[1] : '';
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(x1)) {
				x1 = x1.replace(rgx, '$1' + '<span style="margin-left: 3px; margin-right: 3px;"/>' + '$2');
			}
			return x1 + x2;
		}

		var moneyIcon = "$"

		window.onload = function(e){
			// NUI Callback
			window.addEventListener('message', function(event){
				var item = event.data;

				if(item.seticon == true)
					moneyIcon = item.icon;
				if(item.setmoney == true)
					document.getElementById("cash").innerHTML = "<div><font style='color: rgb(0, 125, 0); font-weight: 700; margin-right: 6px;'>" + moneyIcon + "</font>" + addCommas(item.money);
				if(item.setDirty_money == true)
					document.getElementById("dirty_cash").innerHTML = "<div><font style='color: rgb(125, 0, 0); font-weight: 700; margin-right: 6px;'>" + moneyIcon + "</font>" + addCommas(item.dirty_money);
				if(item.addcash == true){
					$(".tiny").remove();

					var element = $("<div class='tiny'>+<font style='color: rgb(0, 125, 0); font-weight: 700; margin-right: 6px;'>" + moneyIcon + "</font>"+addCommas(item.money)+"</div>")
					$("#money").append(element)

					setTimeout(function(){
						$(element).fadeOut(600, function() { $(this).remove(); })
					}, 1000)
				}
				if(item.removecash == true){
					$(".tiny").remove();
					
					var element = $("<div class='tiny'>-<font style='color: rgb(250, 0, 0); font-weight: 700; margin-right: 6px;'>" + moneyIcon + "</font>"+addCommas(item.money)+"</div>")
					$("#money").append(element)

					setTimeout(function(){
						$(element).fadeOut(600, function() { $(this).remove(); })
					}, 1000)
				}
				if(item.removeStartWindow == true){
					$("#starter").remove();
				}
				if(item.setDisplay == true){
					$("#money").css('opacity', item.display)
					$("#dirty_money").css('opacity', item.display)
				}
			})
		}
	</script>

	<style>
		@font-face {
			font-family: pcdown;
			src: url(pdown.ttf);
		}
		.tiny {
			font-size: 29px;
			position: absolute; right: 10;
		}
		#money {
			font-family: pcdown;
			font-size: 35px;
			color: white;
			padding: 4px;
		text-shadow:
		   -1px -1px 0 #000,
			1px -1px 0 #000,
			-1px 1px 0 #000,
			 1px 1px 0 #000;
				}

		#container {
			position: absolute;
			top: 40; right: 40;
		}
	</style>
</head>

<body>
	<div id="starter" style="font-family: 'roboto'; color: white; position: absolute; left: 20%; top: 5%; width: 60%; background: rgba(40, 40, 40, 0.8)">

	</div>
	<div id="container">
		<div id="money">

			<div id="cash"/>
		</div>
		<div id="dirty_money"/>
			<div id="dirty_cash"/>
		</div>
	</div>
</body>

Now that we have finished with adding the dirty money, it is time to use it. Like this :
This is only an example. You cannot put this exact code somewhere and call 1000 gods in order to get it working.

AddEventHandler("item:sell", function(id, qty, price)
    local player = getPlayerID(source)
    MySQL:executeQuery("UPDATE user_inventory SET `quantity` = @qty WHERE `user_id` = '@username' AND `item_id` = @id", { ['@username'] = player, ['@qty'] = tonumber(qty), ['@id'] = tonumber(id) })
	TriggerEvent("es:getPlayerFromId", source, function(user)
		
		user:addDirty_Money(tonumber(price)) --When selling illegal items, add the money to dirty money
	
	end)
end)

As a bonus, here is an admin command that you can add in order to set the dirty money from the rcon console :

elseif commandName == 'setdirtymoney' then
		if #args ~= 2 then
				RconPrint("Usage: setdirtymoney [user-id] [money]\n")
				CancelEvent()
				return
		end

		if(GetPlayerName(tonumber(args[1])) == nil)then
			RconPrint("Player not ingame\n")
			CancelEvent()
			return
		end

		TriggerEvent("es:getPlayerFromId", tonumber(args[1]), function(user)
			if(user)then
				user:setDirty_Money((args[2] + 0.0))

				RconPrint("Money set")
				TriggerClientEvent('chatMessage', tonumber(args[1]), "CONSOLE", {0, 0, 0}, "Your dirty money has been set to: $" .. tonumber(args[2]))
			end
		end)

		CancelEvent()

To load the money, all you must do is this :

AddEventHandler('es:playerLoaded', function(source)
	-- Get the players money amount
	TriggerEvent("es:getPlayerFromId", source, function(user)
	user:setMoney((user.money))
	user:setDirty_Money((user.dirty_money))
	end)
end)

You will find a similar code in most of the freeroam or advancedRP servers. If you don’t do this, you will not see your money.

If something is not clear enough, let me know and I will glad to help.
Only thing is that I will not add this to your server.

UPDATE

New files only compatible with CouchDB can be found here : https://github.com/boermansjo/Developper-Server

(PS to forum admins/mods, is it possible to not put smileys when you type : + enter without a space ? It was frustrating to see smileys coming instead of just the : and go to the next line.) )

8 Likes

Thank you men ! It’s very nice release :slight_smile:
But i have an error :dagger:
Can you help me ?

3 Likes

Hello all, i have same error.

Thanks For release guy.

Thanks for this ! but the dirtymoney is not in the ui ? can you help me ?

I made a small mistake in there… there was one quote to many.

Yeah i saw that error but i have always the error in my console :grimacing:

You have a fixe for my problem :slight_smile: ? thanks you !

Hello,

Nothing is displayed, can you put your file online please

Good work, but can you make a pack with the file please?

1 Like

I am working on a basic sample server for this.

local result = MySQL:getResults(executed_query, {‘permission_level’, ‘money’, ‘dirty_money’, ‘identifier’, ‘group’}, “identifier”)
You said there was a small mistake or

[quote="SKKiLL, post:8, topic:18001"] </head> [/quote]

Where is it put ?

Yes I removed the ’

I fixed the error…

So I will not be impacted by your error

I have an error when i sell some illegal items, i don’t have dirty money :frowning:.
and i have this error whe i sell that.

Maintenant que nous avons fini d’ajouter l’argent sale, il est temps de l’utiliser. Comme ceci:
ceci n’est qu’un exemple. Vous ne pouvez pas mettre ce code exact quelque part et appeler 1000 dieux afin de le faire fonctionner.

AddEventHandler(“item:sell”, function(id, qty, price)
local player = getPlayerID(source)
MySQL:executeQuery(“UPDATE user_inventory SET quantity = @qty WHERE user_id = ‘@username’ AND item_id = @id”, { [’@username’] = player, [’@qty’] = tonumber(qty), [’@id’] = tonumber(id) })
TriggerEvent(“es:getPlayerFromId”, source, function(user)

	user:adddirtyMoney(tonumber(price)) --When selling illegal items, add the money to dirty money

end)

end)

I just found my mistake but I wanted to know where I have to put this.

you fixed the error, have you ccorrected the codes?

I found !!

AddEventHandler("item:sellb", function(id, qty, price)
    local player = getPlayerID(source)
    MySQL:executeQuery("UPDATE user_inventory SET `quantity` = @qty WHERE `user_id` = '@username' AND `item_id` = @id", { ['@username'] = player, ['@qty'] = tonumber(qty), ['@id'] = tonumber(id) })
	TriggerEvent("es:getPlayerFromId", source, function(user)
		
		user:addDirtyMoney(tonumber(price)) --When selling illegal items, add the money to dirty money
	
	end)
end)

user:addDirtyMone D in In capital letters !!

thank you But I wanted to know where I have to put this