diff --git a/modules/addonaccount b/modules/addonaccount deleted file mode 160000 index 9e6b9b28..00000000 --- a/modules/addonaccount +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9e6b9b28249dc2c3745e243562c898d123cdcb4a diff --git a/modules/addonaccount/migrations/0.sql b/modules/addonaccount/migrations/0.sql new file mode 100644 index 00000000..762af916 --- /dev/null +++ b/modules/addonaccount/migrations/0.sql @@ -0,0 +1,20 @@ +USE `es_extended`; + +CREATE TABLE IF NOT EXISTS `addon_account` ( + `name` VARCHAR(60) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `shared` INT(11) NOT NULL, + + PRIMARY KEY (`name`) +); + +CREATE TABLE IF NOT EXISTS `addon_account_data` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `account_name` VARCHAR(100) DEFAULT NULL, + `money` INT(11) NOT NULL, + `owner` VARCHAR(40) DEFAULT NULL, + + PRIMARY KEY (`id`), + UNIQUE INDEX `index_addon_account_data_account_name_owner` (`account_name`, `owner`), + INDEX `index_addon_account_data_account_name` (`account_name`) +); diff --git a/modules/addonaccount/server/events.lua b/modules/addonaccount/server/events.lua new file mode 100644 index 00000000..ae22e53a --- /dev/null +++ b/modules/addonaccount/server/events.lua @@ -0,0 +1,117 @@ +local self = ESX.Modules['addonaccount'] + +AddEventHandler('esx:migrations:ensure', function(register) + register('addonaccount') +end) + +AddEventHandler('esx_addonaccount:getAccount', function(name, owner, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetAccount(name, owner)) + + end) + +end) + +AddEventHandler('esx_addonaccount:getSharedAccount', function(name, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetSharedAccount(name)) + + end) + +end) + +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) + + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + local addonAccounts = {} + + for i=1, #self.AccountsIndex, 1 do + local name = self.AccountsIndex[i] + local account = GetAccount(name, xPlayer.identifier) + + if account == nil then + MySQL.Async.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, @owner)', { + ['@account_name'] = name, + ['@money'] = 0, + ['@owner'] = xPlayer.identifier + }) + + account = self.CreateAddonAccount(name, xPlayer.identifier, 0) + table.insert(self.Accounts[name], account) + end + + table.insert(addonAccounts, account) + end + + xPlayer.set('addonAccounts', addonAccounts) + + end) + +end) + +MySQL.ready(function() + + local result = MySQL.Sync.fetchAll('SELECT * FROM addon_account') + + for i=1, #result, 1 do + + local name = result[i].name + local label = result[i].label + local shared = result[i].shared + + local result2 = MySQL.Sync.fetchAll('SELECT * FROM addon_account_data WHERE account_name = @account_name', { + ['@account_name'] = name + }) + + if shared == 0 then + + table.insert(self.AccountsIndex, name) + self.Accounts[name] = {} + + for j=1, #result2, 1 do + local addonAccount = CreateAddonAccount(name, result2[j].owner, result2[j].money) + table.insert(self.Accounts[name], addonAccount) + end + + else + + local money = nil + + if #result2 == 0 then + MySQL.Sync.execute('INSERT INTO addon_account_data (account_name, money, owner) VALUES (@account_name, @money, NULL)', { + ['@account_name'] = name, + ['@money'] = 0 + }) + + money = 0 + else + money = result2[1].money + end + + local addonAccount = self.CreateAddonAccount(name, nil, money) + self.SharedAccounts[name] = addonAccount + + end + end + + self.Ready = true + +end) diff --git a/modules/addonaccount/server/main.lua b/modules/addonaccount/server/main.lua new file mode 100644 index 00000000..72fe0f5c --- /dev/null +++ b/modules/addonaccount/server/main.lua @@ -0,0 +1,2 @@ +local self = ESX.Modules['addonaccount'] + diff --git a/modules/addonaccount/server/module.lua b/modules/addonaccount/server/module.lua new file mode 100644 index 00000000..4b485a3a --- /dev/null +++ b/modules/addonaccount/server/module.lua @@ -0,0 +1,67 @@ +ESX.Modules['addonaccount'] = {} +local self = ESX.Modules['addonaccount'] + +self.Ready = false +self.AccountsIndex = {} +self.Accounts = {} +self.SharedAccounts = {} + +self.GetAccount = function(name, owner) + for i=1, #self.Accounts[name], 1 do + if self.Accounts[name][i].owner == owner then + return self.Accounts[name][i] + end + end +end + +self.GetSharedAccount = function(name) + return self.SharedAccounts[name] +end + +self.CreateAddonAccount = function(name, owner, money) + + local self = {} + + self.name = name + self.owner = owner + self.money = money + + self.addMoney = function(m) + self.money = self.money + m + self.save() + + TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) + end + + self.removeMoney = function(m) + self.money = self.money - m + self.save() + + TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) + end + + self.setMoney = function(m) + self.money = m + self.save() + + TriggerClientEvent('esx_addonaccount:setMoney', -1, self.name, self.money) + end + + self.save = function() + if self.owner == nil then + MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name', { + ['@account_name'] = self.name, + ['@money'] = self.money + }) + else + MySQL.Async.execute('UPDATE addon_account_data SET money = @money WHERE account_name = @account_name AND owner = @owner', { + ['@account_name'] = self.name, + ['@money'] = self.money, + ['@owner'] = self.owner + }) + end + end + + return self + +end diff --git a/modules/addoninventory b/modules/addoninventory deleted file mode 160000 index c339d442..00000000 --- a/modules/addoninventory +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c339d44214aaf4ec1e436df42fe85884df458cd1 diff --git a/modules/addoninventory/migrations/0.sql b/modules/addoninventory/migrations/0.sql new file mode 100644 index 00000000..0a411bb3 --- /dev/null +++ b/modules/addoninventory/migrations/0.sql @@ -0,0 +1,22 @@ +USE `es_extended`; + +CREATE TABLE IF NOT EXISTS `addon_inventory` ( + `name` VARCHAR(60) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `shared` INT(11) NOT NULL, + + PRIMARY KEY (`name`) +); + +CREATE TABLE IF NOT EXISTS `addon_inventory_items` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `inventory_name` VARCHAR(100) NOT NULL, + `name` VARCHAR(100) NOT NULL, + `count` INT(11) NOT NULL, + `owner` VARCHAR(40) DEFAULT NULL, + + PRIMARY KEY (`id`), + INDEX `index_addon_inventory_items_inventory_name_name` (`inventory_name`, `name`), + INDEX `index_addon_inventory_items_inventory_name_name_owner` (`inventory_name`, `name`, `owner`), + INDEX `index_addon_inventory_inventory_name` (`inventory_name`) +); diff --git a/modules/addoninventory/server/events.lua b/modules/addoninventory/server/events.lua new file mode 100644 index 00000000..482c49b5 --- /dev/null +++ b/modules/addoninventory/server/events.lua @@ -0,0 +1,128 @@ +local self = ESX.Modules['addoninventory'] + +AddEventHandler('esx:migrations:ensure', function(register) + register('addoninventory') +end) + +AddEventHandler('esx_addoninventory:getInventory', function(name, owner, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetInventory(name, owner)) + + end) + +end) + +AddEventHandler('esx_addoninventory:getSharedInventory', function(name, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetSharedInventory(name)) + + end) + +end) + +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + local addonInventories = {} + + for i=1, #self.InventoriesIndex, 1 do + local name = self.InventoriesIndex[i] + local inventory = self.GetInventory(name, xPlayer.identifier) + + if inventory == nil then + inventory = self.CreateAddonInventory(name, xPlayer.identifier, {}) + table.insert(self.Inventories[name], inventory) + end + + table.insert(addonInventories, inventory) + end + + xPlayer.set('addonInventories', addonInventories) + + end) + +end) + +MySQL.ready(function() + + local items = MySQL.Sync.fetchAll('SELECT * FROM items') + + for i=1, #items, 1 do + self.Items[items[i].name] = items[i].label + end + + local result = MySQL.Sync.fetchAll('SELECT * FROM addon_inventory') + + for i=1, #result, 1 do + local name = result[i].name + local label = result[i].label + local shared = result[i].shared + + local result2 = MySQL.Sync.fetchAll('SELECT * FROM addon_inventory_items WHERE inventory_name = @inventory_name', { + ['@inventory_name'] = name + }) + + if shared == 0 then + + table.insert(self.InventoriesIndex, name) + + self.Inventories[name] = {} + local items = {} + + for j=1, #result2, 1 do + local itemName = result2[j].name + local itemCount = result2[j].count + local itemOwner = result2[j].owner + + if items[itemOwner] == nil then + items[itemOwner] = {} + end + + table.insert(items[itemOwner], { + name = itemName, + count = itemCount, + label = Items[itemName] + }) + end + + for k,v in pairs(items) do + local addonInventory = CreateAddonInventory(name, k, v) + table.insert(self.Inventories[name], addonInventory) + end + + else + local items = {} + + for j=1, #result2, 1 do + table.insert(items, { + name = result2[j].name, + count = result2[j].count, + label = self.Items[result2[j].name] + }) + end + + local addonInventory = self.CreateAddonInventory(name, nil, items) + self.SharedInventories[name] = addonInventory + end + end + + self.Ready = true + +end) diff --git a/modules/addoninventory/server/main.lua b/modules/addoninventory/server/main.lua new file mode 100644 index 00000000..ff563ef6 --- /dev/null +++ b/modules/addoninventory/server/main.lua @@ -0,0 +1,2 @@ +local self = ESX.Modules['addoninventory'] + diff --git a/modules/addoninventory/server/module.lua b/modules/addoninventory/server/module.lua new file mode 100644 index 00000000..b5950112 --- /dev/null +++ b/modules/addoninventory/server/module.lua @@ -0,0 +1,104 @@ +ESX.Modules['addoninventory'] = {} +local self = ESX.Modules['addoninventory'] + +self.Ready = false +self.Items = {} +self.InventoriesIndex = {} +self.Inventories = {} +self.SharedInventories = {} + +self.GetInventory = function(name, owner) + for i=1, #self.Inventories[name], 1 do + if self.Inventories[name][i].owner == owner then + return self.Inventories[name][i] + end + end +end + +self.GetSharedInventory = function(name) + return self.SharedInventories[name] +end + +self.CreateAddonInventory = function(name, owner, items) + local self = {} + + self.name = name + self.owner = owner + self.items = items + + self.addItem = function(name, count) + local item = self.getItem(name) + item.count = item.count + count + + self.saveItem(name, item.count) + end + + self.removeItem = function(name, count) + local item = self.getItem(name) + item.count = item.count - count + + self.saveItem(name, item.count) + end + + self.setItem = function(name, count) + local item = self.getItem(name) + item.count = count + + self.saveItem(name, item.count) + end + + self.getItem = function(name) + for i=1, #self.items, 1 do + if self.items[i].name == name then + return self.items[i] + end + end + + item = { + name = name, + count = 0, + label = Items[name] + } + + table.insert(self.items, item) + + if self.owner == nil then + MySQL.Async.execute('INSERT INTO addon_inventory_items (inventory_name, name, count) VALUES (@inventory_name, @item_name, @count)', + { + ['@inventory_name'] = self.name, + ['@item_name'] = name, + ['@count'] = 0 + }) + else + MySQL.Async.execute('INSERT INTO addon_inventory_items (inventory_name, name, count, owner) VALUES (@inventory_name, @item_name, @count, @owner)', + { + ['@inventory_name'] = self.name, + ['@item_name'] = name, + ['@count'] = 0, + ['@owner'] = self.owner + }) + end + + return item + end + + self.saveItem = function(name, count) + if self.owner == nil then + MySQL.Async.execute('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name', { + ['@inventory_name'] = self.name, + ['@item_name'] = name, + ['@count'] = count + }) + else + MySQL.Async.execute('UPDATE addon_inventory_items SET count = @count WHERE inventory_name = @inventory_name AND name = @item_name AND owner = @owner', { + ['@inventory_name'] = self.name, + ['@item_name'] = name, + ['@count'] = count, + ['@owner'] = self.owner + }) + end + end + + return self +end + diff --git a/modules/datastore b/modules/datastore deleted file mode 160000 index 88fd62fe..00000000 --- a/modules/datastore +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 88fd62fe7c566b998166a458df4abbbd67d5d538 diff --git a/modules/datastore/migrations/0.sql b/modules/datastore/migrations/0.sql new file mode 100644 index 00000000..b84a69cd --- /dev/null +++ b/modules/datastore/migrations/0.sql @@ -0,0 +1,20 @@ +USE `es_extended`; + +CREATE TABLE IF NOT EXISTS `datastore` ( + `name` VARCHAR(60) NOT NULL, + `label` VARCHAR(100) NOT NULL, + `shared` INT(11) NOT NULL, + + PRIMARY KEY (`name`) +); + +CREATE TABLE IF NOT EXISTS `datastore_data` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(60) NOT NULL, + `owner` VARCHAR(40), + `data` LONGTEXT, + + PRIMARY KEY (`id`), + UNIQUE INDEX `index_datastore_data_name_owner` (`name`, `owner`), + INDEX `index_datastore_data_name` (`name`) +); diff --git a/modules/datastore/server/events.lua b/modules/datastore/server/events.lua new file mode 100644 index 00000000..b74f246a --- /dev/null +++ b/modules/datastore/server/events.lua @@ -0,0 +1,118 @@ +local self = ESX.Modules['datastore'] + +AddEventHandler('esx:migrations:ensure', function(register) + register('datastore') +end) + +AddEventHandler('esx_datastore:getDataStore', function(name, owner, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetDataStore(name, owner)) + + end) + +end) + +AddEventHandler('esx_datastore:getDataStoreOwners', function(name, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetDataStoreOwners(name)) + + end) + +end) + +AddEventHandler('esx_datastore:getSharedDataStore', function(name, cb) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + cb(self.GetSharedDataStore(name)) + + end) + +end) + +AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) + + Citizen.CreateThread(function() + + while not self.Ready do + Citizen.Wait(0) + end + + for i=1, #self.DataStoresIndex, 1 do + local name = self.DataStoresIndex[i] + local dataStore = self.GetDataStore(name, xPlayer.identifier) + + if not dataStore then + MySQL.Async.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', { + ['@name'] = name, + ['@owner'] = xPlayer.identifier, + ['@data'] = '{}' + }) + + dataStore = CreateDataStore(name, xPlayer.identifier, {}) + table.insert(self.DataStores[name], dataStore) + end + end + + end) + +end) + +MySQL.ready(function() + local result = MySQL.Sync.fetchAll('SELECT * FROM datastore') + + for i=1, #result, 1 do + local name, label, shared = result[i].name, result[i].label, result[i].shared + local result2 = MySQL.Sync.fetchAll('SELECT * FROM datastore_data WHERE name = @name', { + ['@name'] = name + }) + + if shared == 0 then + table.insert(self.DataStoresIndex, name) + self.DataStores[name] = {} + + for j=1, #result2, 1 do + local storeName = result2[j].name + local storeOwner = result2[j].owner + local storeData = (result2[j].data == nil and {} or json.decode(result2[j].data)) + local dataStore = self.CreateDataStore(storeName, storeOwner, storeData) + + table.insert(self.DataStores[name], dataStore) + end + else + local data + + if #result2 == 0 then + MySQL.Sync.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, NULL, \'{}\')', { + ['@name'] = name + }) + + data = {} + else + data = json.decode(result2[1].data) + end + + local dataStore = self.CreateDataStore(name, nil, data) + self.SharedDataStores[name] = dataStore + end + end + + self.Ready = true + +end) diff --git a/modules/datastore/server/main.lua b/modules/datastore/server/main.lua new file mode 100644 index 00000000..0444466a --- /dev/null +++ b/modules/datastore/server/main.lua @@ -0,0 +1,2 @@ +local self = ESX.Modules['datastore'] + diff --git a/modules/datastore/server/module.lua b/modules/datastore/server/module.lua new file mode 100644 index 00000000..1a1ebe49 --- /dev/null +++ b/modules/datastore/server/module.lua @@ -0,0 +1,118 @@ +ESX.Modules['datastore'] = {} +local self = ESX.Modules['datastore'] + +self.Ready = false +self.DataStores = {} +self.DataStoresIndex = {} +self.SharedDataStores = {} + +local stringsplit = function(inputstr, sep) + if sep == nil then + sep = "%s" + end + + local t={} ; i=1 + for str in string.gmatch(inputstr, "([^"..sep.."]+)") do + t[i] = str + i = i + 1 + end + + return t +end + +self.GetDataStore = function(name, owner) + for i=1, #self.DataStores[name], 1 do + if self.DataStores[name][i].owner == owner then + return self.DataStores[name][i] + end + end +end + +self.GetDataStoreOwners = function(name) + local identifiers = {} + + for i=1, #self.DataStores[name], 1 do + table.insert(identifiers, self.DataStores[name][i].owner) + end + + return identifiers +end + +self.GetSharedDataStore = function(name) + return self.SharedDataStores[name] +end + +self.CreateDataStore = function(name, owner, data) + local self = {} + + self.name = name + self.owner = owner + self.data = data + + local timeoutCallbacks = {} + + self.set = function(key, val) + data[key] = val + self.save() + end + + self.get = function(key, i) + local path = stringsplit(key, '.') + local obj = self.data + + for i=1, #path, 1 do + obj = obj[path[i]] + end + + if i == nil then + return obj + else + return obj[i] + end + end + + self.count = function(key, i) + local path = stringsplit(key, '.') + local obj = self.data + + for i=1, #path, 1 do + obj = obj[path[i]] + end + + if i ~= nil then + obj = obj[i] + end + + if obj == nil then + return 0 + else + return #obj + end + end + + self.save = function() + for i=1, #timeoutCallbacks, 1 do + ESX.ClearTimeout(timeoutCallbacks[i]) + timeoutCallbacks[i] = nil + end + + local timeoutCallback = ESX.SetTimeout(10000, function() + if self.owner == nil then + MySQL.Async.execute('UPDATE datastore_data SET data = @data WHERE name = @name', { + ['@data'] = json.encode(self.data), + ['@name'] = self.name, + }) + else + MySQL.Async.execute('UPDATE datastore_data SET data = @data WHERE name = @name and owner = @owner', { + ['@data'] = json.encode(self.data), + ['@name'] = self.name, + ['@owner'] = self.owner, + }) + end + end) + + table.insert(timeoutCallbacks, timeoutCallback) + end + + return self +end