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 essenti
almode (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.) )