├── README.md ├── config.lua ├── fxmanifest.lua └── server.lua /README.md: -------------------------------------------------------------------------------- 1 |

pefcl-esx

2 | 3 | **This is a compatibility resource that enables PEFCL to function properly with ESX. Please ensure that you have the latest version 4 | of PEFCL and ESX installed** 5 | 6 | ## Installation Steps: 7 | 8 | 1. Download this repository and place it in the `resources` directory 9 | 2. Add `ensure pefcl-esx` to your `server.cfg`. Start this resource BEFORE `PEFCL`. 10 | 3. Navigate to the `config.json` in `PEFCL` and change the following settings: 11 | - Under `frameworkIntegration` 12 | - `enabled`: `true` 13 | - `resource`: `pefcl-esx` 14 | -------------------------------------------------------------------------------- /config.lua: -------------------------------------------------------------------------------- 1 | Config = {} 2 | 3 | -- You should not need BusinessAccounts when using ESX & esx_society 4 | Config.BusinessAccounts = { 5 | -- ['police'] = { -- Job Name 6 | -- AccountName = 'Los Santos Police', -- Display name for bank account 7 | -- ContributorRole = 2, -- Minimum role required to contribute to the account 8 | -- AdminRole = 3 -- Minumum role to be able to add/remove money from the account 9 | -- }, 10 | -- ['ambulance'] = { -- Job Name 11 | -- AccountName = 'Los Santos EMS', -- Display name for bank account 12 | -- ContributorRole = 2, -- Minimum role required to contribute to the account 13 | -- AdminRole = 3 -- Minumum role to be able to add/remove money from the account 14 | -- } 15 | } 16 | 17 | -- 18 | -- If you have ox_inventory you can enable it here. 19 | -- This will expose the required exports for physical cards. 20 | -- 21 | -- Make sure to update config.json in "PEFCL" as well to enable physical cards. 22 | -- 23 | Config.OxInventory = false 24 | 25 | Config.Locale = { 26 | deposited = "Deposited money into society account", 27 | withdrew = "Withdrew money from society account" 28 | } 29 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | game 'gta5' 3 | description 'PEFCL framework integration for ESX' 4 | author "Project Error" 5 | lua54 'yes' 6 | 7 | server_scripts { 'config.lua', 'server.lua' } 8 | -------------------------------------------------------------------------------- /server.lua: -------------------------------------------------------------------------------- 1 | ESX = nil 2 | 3 | TriggerEvent('esx:getSharedObject', function(obj) 4 | ESX = obj 5 | end) 6 | 7 | math.randomseed(os.time()) 8 | local charset = {} 9 | 10 | do -- [0-9a-zA-Z] 11 | for c = 48, 57 do 12 | table.insert(charset, string.char(c)) 13 | end 14 | for c = 65, 90 do 15 | table.insert(charset, string.char(c)) 16 | end 17 | for c = 97, 122 do 18 | table.insert(charset, string.char(c)) 19 | end 20 | end 21 | 22 | local function randomString(length) 23 | if not length or length <= 0 then 24 | return '' 25 | end 26 | return randomString(length - 1) .. charset[math.random(1, #charset)] 27 | end 28 | 29 | local AVOID_SYNC = randomString(20) 30 | 31 | local function addCash(src, amount) 32 | local xPlayer = ESX.GetPlayerFromId(src) 33 | xPlayer.addMoney(amount) 34 | end 35 | 36 | local function removeCash(src, amount) 37 | local xPlayer = ESX.GetPlayerFromId(src) 38 | xPlayer.removeMoney(amount) 39 | end 40 | 41 | local function getCash(src) 42 | local xPlayer = ESX.GetPlayerFromId(src) 43 | return xPlayer.getMoney() 44 | end 45 | 46 | local function syncBankBalance(account) 47 | local society = nil 48 | TriggerEvent('esx_society:getSociety', account.ownerIdentifier, function(_society) 49 | society = _society 50 | end) 51 | 52 | if society ~= nil then 53 | TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function(societyAccount) 54 | -- TODO: Fix this asap 55 | -- societyAccount.setMoney(account.balance) 56 | end) 57 | end 58 | 59 | if not account.isDefault then 60 | return 61 | end 62 | 63 | local xPlayer = ESX.GetPlayerFromIdentifier(account.ownerIdentifier) 64 | 65 | if not xPlayer then 66 | return 67 | end 68 | 69 | xPlayer.setAccountMoney('bank', account.balance, AVOID_SYNC) 70 | end 71 | 72 | local function getBank(src) 73 | local xPlayer = ESX.GetPlayerFromId(src) 74 | local account = xPlayer.getAccount('bank') 75 | return account.money 76 | end 77 | 78 | local function getCards(src) 79 | local retval = {} 80 | -- local inv = exports.ox_inventory:Inventory(src) 81 | local cards = exports.ox_inventory:Search(src, 'slots', 'mastercard') 82 | 83 | for _, v in pairs(cards) do 84 | retval[#retval + 1] = { 85 | id = v.metadata.id, 86 | holder = v.metadata.holder, 87 | number = v.metadata.number 88 | } 89 | end 90 | 91 | return retval 92 | end 93 | 94 | local function giveCard(src, card) 95 | -- local inv = exports.ox_inventory:Inventory(src) 96 | exports.ox_inventory:AddItem(src, 'mastercard', 1, { 97 | id = card.id, 98 | holder = card.holder, 99 | number = card.number, 100 | description = ('Card Number: %s'):format(card.number) 101 | }) 102 | end 103 | 104 | local function updateSocietyAccountAccess(player, playerJob, playerLastJob) 105 | local citizenid = player.identifier 106 | local playerSrc = player.source 107 | local society = nil 108 | 109 | TriggerEvent('esx_society:getSociety', playerJob.name, function(_society) 110 | society = _society 111 | end) 112 | 113 | if society == nil then 114 | return 115 | end 116 | 117 | local currentUniqueAccount = exports.pefcl:getUniqueAccount(playerSrc, playerJob.name).data; 118 | 119 | if playerLastJob ~= nil and playerLastJob.name then 120 | local data = { 121 | userIdentifier = player.getIdentifier(), 122 | accountIdentifier = playerLastJob.name 123 | } 124 | exports.pefcl:removeUserFromUniqueAccount(playerSrc, data) 125 | end 126 | 127 | if not currentUniqueAccount then 128 | local data = { 129 | name = society.label, 130 | type = 'shared', 131 | identifier = playerJob.name 132 | } 133 | exports.pefcl:createUniqueAccount(playerSrc, data) 134 | end 135 | 136 | if playerJob.grade_name == "boss" then 137 | local data = { 138 | role = "admin", 139 | accountIdentifier = playerJob.name, 140 | userIdentifier = citizenid, 141 | source = playerSrc 142 | } 143 | exports.pefcl:addUserToUniqueAccount(playerSrc, data) 144 | end 145 | 146 | end 147 | 148 | local function updateBusinessAccountAccess(player, playerJob, playerLastJob) 149 | local citizenid = player.identifier 150 | local playerSrc = player.source 151 | 152 | if Config.BusinessAccounts[playerJob.name] == nil then 153 | return 154 | end 155 | 156 | local currentUniqueAccount = exports.pefcl:getUniqueAccount(playerSrc, playerJob.name).data; 157 | 158 | if playerLastJob ~= nil and playerLastJob.name then 159 | print("Removing from last job ..", playerLastJob.name) 160 | 161 | local data = { 162 | userIdentifier = player.getIdentifier(), 163 | accountIdentifier = playerLastJob.name 164 | } 165 | exports.pefcl:removeUserFromUniqueAccount(playerSrc, data) 166 | end 167 | 168 | if playerJob.grade < Config.BusinessAccounts[playerJob.name].ContributorRole then 169 | print("Grade below Contributor role. Returning.") 170 | return 171 | end 172 | 173 | -- If account doesn't exist, lets create it. 174 | if not exports.pefcl:getUniqueAccount(playerSrc, playerJob.name).data then 175 | local data = { 176 | name = Config.BusinessAccounts[playerJob.name].AccountName, 177 | type = 'shared', 178 | identifier = playerJob.name 179 | } 180 | exports.pefcl:createUniqueAccount(playerSrc, data) 181 | end 182 | 183 | local role = 'contributor' 184 | if playerJob.grade >= Config.BusinessAccounts[playerJob.name].AdminRole then 185 | role = 'admin' 186 | end 187 | 188 | if role then 189 | local data = { 190 | role = role, 191 | accountIdentifier = playerJob.name, 192 | userIdentifier = citizenid, 193 | source = playerSrc 194 | } 195 | exports.pefcl:addUserToUniqueAccount(playerSrc, data) 196 | end 197 | 198 | end 199 | 200 | -- Exports 201 | exports("addCash", addCash) 202 | exports("removeCash", removeCash) 203 | exports("getCash", getCash) 204 | exports("getBank", getBank) 205 | 206 | if Config.OxInventory then 207 | exports("getCards", getCards) 208 | exports("giveCard", giveCard) 209 | end 210 | 211 | -- EVENTS: GLOBAL 212 | AddEventHandler("playerDropped", function() 213 | local src = source 214 | exports.pefcl:unloadPlayer(src) 215 | end) 216 | 217 | AddEventHandler("onServerResourceStart", function(resName) 218 | local resourceName = GetCurrentResourceName(); 219 | 220 | if resName ~= resourceName and resName ~= "pefcl" then 221 | return 222 | end 223 | 224 | if not GetResourceState("pefcl") == 'started' then 225 | return 226 | end 227 | 228 | local xPlayers = ESX.GetExtendedPlayers() 229 | for _, xPlayer in pairs(xPlayers) do 230 | Citizen.Wait(50) 231 | 232 | updateBusinessAccountAccess(xPlayer, xPlayer.getJob()) 233 | updateSocietyAccountAccess(xPlayer, xPlayer.getJob()) 234 | exports.pefcl:loadPlayer(xPlayer.source, { 235 | source = xPlayer.source, 236 | identifier = xPlayer.identifier, 237 | name = xPlayer.getName() 238 | }) 239 | end 240 | end) 241 | 242 | -- EVENTS: ESX 243 | AddEventHandler('esx:playerLoaded', function(playerSrc, xPlayer) 244 | if not xPlayer then 245 | return 246 | end 247 | 248 | exports.pefcl:loadPlayer(playerSrc, { 249 | source = playerSrc, 250 | identifier = xPlayer.getIdentifier(), 251 | name = xPlayer.getName() 252 | }) 253 | end) 254 | 255 | AddEventHandler('esx:playerLogout', function(playerId) 256 | exports.pefcl:unloadPlayer(playerId) 257 | end) 258 | 259 | AddEventHandler('esx:addAccountMoney', function(playerSrc, accountName, amount, message) 260 | if accountName ~= "bank" or message == AVOID_SYNC then 261 | return 262 | end 263 | 264 | exports.pefcl:addBankBalance(playerSrc, { 265 | amount = amount, 266 | message = message 267 | }) 268 | end) 269 | 270 | AddEventHandler('esx:removeAccountMoney', function(playerSrc, accountName, amount, message) 271 | if accountName ~= "bank" or message == AVOID_SYNC then 272 | return 273 | end 274 | 275 | exports.pefcl:removeBankBalance(playerSrc, { 276 | amount = amount, 277 | message = message 278 | }) 279 | end) 280 | 281 | AddEventHandler('esx:setAccountMoney', function(playerSrc, accountName, amount, message) 282 | if accountName ~= "bank" or message == AVOID_SYNC then 283 | return 284 | end 285 | 286 | exports.pefcl:setBankBalance(playerSrc, { 287 | amount = amount, 288 | message = message 289 | }) 290 | end) 291 | 292 | -- Handle society balance updates 293 | AddEventHandler('esx_addonaccount:addMoney', function(identifier, amount) 294 | if string.find(identifier, "society_") then 295 | exports.pefcl:addBankBalanceByIdentifier(0, { 296 | amount = amount, 297 | message = Config.Locale.deposited, 298 | identifier = string.gsub(identifier, "society_", "") 299 | }) 300 | end 301 | end) 302 | 303 | AddEventHandler('esx_addonaccount:removeMoney', function(identifier, amount) 304 | if string.find(identifier, "society_") then 305 | exports.pefcl:removeBankBalanceByIdentifier(0, { 306 | amount = amount, 307 | message = Config.Locale.withdrew, 308 | identifier = string.gsub(identifier, "society_", "") 309 | }) 310 | end 311 | end) 312 | 313 | AddEventHandler('esx_addonaccount:setMoney', function(identifier, amount) 314 | if string.find(identifier, "society_") then 315 | exports.pefcl:setMoneyByIdentifier(0, { 316 | amount = amount, 317 | identifier = string.gsub(identifier, "society_", "") 318 | }) 319 | end 320 | end) 321 | 322 | AddEventHandler('esx:setJob', function(playerSrc, job, lastJob) 323 | local xPlayer = ESX.GetPlayerFromId(playerSrc) 324 | 325 | if not xPlayer then 326 | return 327 | end 328 | 329 | updateBusinessAccountAccess(xPlayer, job, lastJob) 330 | updateSocietyAccountAccess(xPlayer, job, lastJob) 331 | end) 332 | 333 | -- EVENTS: PEFCL 334 | AddEventHandler('pefcl:newAccountBalance', function(account) 335 | syncBankBalance(account) 336 | end) 337 | 338 | AddEventHandler('pefcl:changedDefaultAccount', function(account) 339 | syncBankBalance(account) 340 | end) 341 | 342 | --------------------------------------------------------------------------------