├── 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 |
--------------------------------------------------------------------------------