From 22e877aef8d9e395096eaf5e9cd7ca4d164bc2e7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 24 Sep 2018 17:25:49 +0200 Subject: [PATCH] mysql-async v3.0.1 support --- README.md | 79 +++++++++-------- __resource.lua | 10 +-- esx_datastore.sql | 22 ++--- server/classes/datastore.lua | 155 ++++++++++++++++----------------- server/main.lua | 160 +++++++++++++++-------------------- 5 files changed, 199 insertions(+), 227 deletions(-) diff --git a/README.md b/README.md index 46ad022a..c7da533d 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,64 @@ -# fxserver-esx_datastore -FXServer ESX DataStore +# esx_datastore -[INSTALLATION] +## Download & Installation -1) CD in your resources/[esx] folder -2) Clone the repository +### Using [fvm](https://github.com/qlaffont/fvm-installer) ``` -git clone https://github.com/FXServer-ESX/fxserver-esx_datastore esx_datastore +fvm install --save --folder=esx esx-org/esx_datastore ``` -3) Import esx_datastore.sql in your database -1) Add this in your server.cfg : + +### Using Git +``` +cd resources +git clone https://github.com/ESX-Org/esx_datastore [esx]/esx_datastore +``` + +### Manually +- Download https://github.com/ESX-Org/esx_datastore/archive/master.zip +- Put it in the `[esx]` directory + +## Installation +- Import `esx_datastore.sql` in your database +- Add this in your `server.cfg`: ``` start esx_datastore ``` -[USAGE] +## Usage +There are two types of datastores: shared and not shared. -There is two types of datastores : shared and not shared. +- Shared datastores does not belong to a specific user, Example: police armory +- None-shared datastores are created for every user in the server. They are created in db when player is loaded, Example: property (weapons, dressing). -- Shared datastores dont belong to a specific user. Example : property (weapons, dressing). -- Not shared datastores are created for every user in the server. They are created in db when player is loaded, Example : police armory +### `datastore` database information +An datastore must be configured in the database before using it. Don't forget to run a server restart afterwards (you can alternative restart the script and relog all clients) -You must create the datastore in the database (datastore) before using it : +| `name` | `label` | `shared` | +| -------- | ------- | -------- | +| name of the datastore | label of the datastore (not used) | is the datastore shared with others? (boolean either `0` or `1`) | -name = name of the datastore, label = label of the datastore, shared (0 or 1) = Is datastore shared - -``` +```lua TriggerEvent('esx_datastore:getSharedDataStore', 'police', function(store) - - local weapons = store.get('weapons') - - if weapons == nil then - weapons = {} - end - - table.insert(weapons, {name = 'WEAPON_PUMPSHOTGUN', ammo = 50}) - - store.set('weapons', weapons) - + local weapons = store.get('weapons') or {} + + table.insert(weapons, {name = 'WEAPON_PUMPSHOTGUN', ammo = 50}) + store.set('weapons', weapons) end) TriggerEvent('esx_datastore:getDataStore', 'property', 'steam:0123456789', function(store) - - local dressing = store.get('dressing') - - if dressing == nil then - dressing = {} - end - + local dressing = store.get('dressing') or {} end) ``` + +# Legal +### License +esx_datastore - datastore inventory for ESX + +Copyright (C) 2015-2018 Jérémie N'gadi + +This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. + +This program Is distributed In the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty Of MERCHANTABILITY Or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License For more details. + +You should have received a copy Of the GNU General Public License along with this program. If Not, see http://www.gnu.org/licenses/. diff --git a/__resource.lua b/__resource.lua index defcc2aa..f9f6fe26 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,11 +1,11 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' -description 'ESX DataStore' +description 'ESX Data Store' -version '1.0.1' +version '1.0.2' server_scripts { - '@mysql-async/lib/MySQL.lua', - 'server/classes/datastore.lua', - 'server/main.lua' + '@mysql-async/lib/MySQL.lua', + 'server/classes/datastore.lua', + 'server/main.lua' } diff --git a/esx_datastore.sql b/esx_datastore.sql index 9aae7b54..c8d8debf 100644 --- a/esx_datastore.sql +++ b/esx_datastore.sql @@ -1,17 +1,19 @@ USE `essentialmode`; CREATE TABLE `datastore` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `shared` int(11) NOT NULL, - PRIMARY KEY (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `shared` int(11) NOT NULL, + + PRIMARY KEY (`id`) ); CREATE TABLE `datastore_data` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `owner` varchar(255), - `data` longtext, - PRIMARY KEY (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `owner` varchar(255), + `data` longtext, + + PRIMARY KEY (`id`) ); diff --git a/server/classes/datastore.lua b/server/classes/datastore.lua index de95b2cf..2c31e541 100644 --- a/server/classes/datastore.lua +++ b/server/classes/datastore.lua @@ -1,103 +1,90 @@ function stringsplit(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 + 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 function CreateDataStore(name, owner, data) + local self = {} - local self = {} + self.name = name + self.owner = owner + self.data = data - self.name = name - self.owner = owner - self.data = data + local timeoutCallbacks = {} - local timeoutCallbacks = {} + self.set = function(key, val) + data[key] = val + self.save() + end - self.set = function(key, val) - data[key] = val - self.save() - end + self.get = function(key, i) + local path = stringsplit(key, '.') + local obj = self.data - self.get = function(key, i) + for i=1, #path, 1 do + obj = obj[path[i]] + end - local path = stringsplit(key, '.') - local obj = self.data + if i == nil then + return obj + else + return obj[i] + end + end - for i=1, #path, 1 do - obj = obj[path[i]] - end + self.count = function(key, i) + local path = stringsplit(key, '.') + local obj = self.data - if i == nil then - return obj - else - return obj[i] - end + for i=1, #path, 1 do + obj = obj[path[i]] + end - end + if i ~= nil then + obj = obj[i] + end - self.count = function(key, i) + if obj == nil then + return 0 + else + return #obj + end + end - local path = stringsplit(key, '.') - local obj = self.data + self.save = function() + for i=1, #timeoutCallbacks, 1 do + ESX.ClearTimeout(timeoutCallbacks[i]) + timeoutCallbacks[i] = nil + end - for i=1, #path, 1 do - obj = obj[path[i]] - 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) - 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 + table.insert(timeoutCallbacks, timeoutCallback) + end + return self end - diff --git a/server/main.lua b/server/main.lua index d5994f98..c80e3135 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,142 +1,114 @@ ESX = nil -Items = {} local DataStoresIndex = {} local DataStores = {} local SharedDataStores = {} - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -AddEventHandler('onMySQLReady', function() +MySQL.ready(function() + local result = MySQL.Sync.fetchAll('SELECT * FROM datastore') - local result = MySQL.Sync.fetchAll('SELECT * FROM datastore') + for i=1, #result, 1 do + local name = result[i].name + local label = result[i].label + local shared = result[i].shared - for i=1, #result, 1 do + local result2 = MySQL.Sync.fetchAll('SELECT * FROM datastore_data WHERE name = @name', { + ['@name'] = name + }) - local name = result[i].name - local label = result[i].label - local shared = result[i].shared + if shared == 0 then - local result2 = MySQL.Sync.fetchAll( - 'SELECT * FROM datastore_data WHERE name = @name', - { - ['@name'] = name - } - ) + table.insert(DataStoresIndex, name) + DataStores[name] = {} - if shared == 0 then + 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 = CreateDataStore(storeName, storeOwner, storeData) - table.insert(DataStoresIndex, name) + table.insert(DataStores[name], dataStore) + end - DataStores[name] = {} + else - for j=1, #result2, 1 do + local data = nil - local storeName = result2[j].name - local storeOwner = result2[j].owner - local storeData = (result2[j].data == nil and {} or json.decode(result2[j].data)) + if #result2 == 0 then + MySQL.Sync.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, NULL, \'{}\')', { + ['@name'] = name + }) - local dataStore = CreateDataStore(storeName, storeOwner, storeData) + data = {} + else + data = json.decode(result2[1].data) + end - table.insert(DataStores[name], dataStore) - - end - - else - - local data = nil - - 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 = CreateDataStore(name, nil, data) - SharedDataStores[name] = dataStore - - end - - end + local dataStore = CreateDataStore(name, nil, data) + SharedDataStores[name] = dataStore + end + end end) function GetDataStore(name, owner) - for i=1, #DataStores[name], 1 do - if DataStores[name][i].owner == owner then - return DataStores[name][i] - end - end + for i=1, #DataStores[name], 1 do + if DataStores[name][i].owner == owner then + return DataStores[name][i] + end + end end function GetDataStoreOwners(name) + local identifiers = {} - local identifiers = {} - - for i=1, #DataStores[name], 1 do - table.insert(identifiers, DataStores[name][i].owner) - end - - return identifiers + for i=1, #DataStores[name], 1 do + table.insert(identifiers, DataStores[name][i].owner) + end + return identifiers end function GetSharedDataStore(name) - return SharedDataStores[name] + return SharedDataStores[name] end AddEventHandler('esx_datastore:getDataStore', function(name, owner, cb) - cb(GetDataStore(name, owner)) + cb(GetDataStore(name, owner)) end) AddEventHandler('esx_datastore:getDataStoreOwners', function(name, cb) - cb(GetDataStoreOwners(name)) + cb(GetDataStoreOwners(name)) end) AddEventHandler('esx_datastore:getSharedDataStore', function(name, cb) - cb(GetSharedDataStore(name)) + cb(GetSharedDataStore(name)) end) AddEventHandler('esx:playerLoaded', function(source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local dataStores = {} - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - local dataStores = {} + for i=1, #DataStoresIndex, 1 do + local name = DataStoresIndex[i] + local dataStore = GetDataStore(name, xPlayer.identifier) - for i=1, #DataStoresIndex, 1 do + if dataStore == nil then + MySQL.Async.execute('INSERT INTO datastore_data (name, owner, data) VALUES (@name, @owner, @data)', + { + ['@name'] = name, + ['@owner'] = xPlayer.identifier, + ['@data'] = '{}' + }) - local name = DataStoresIndex[i] - local dataStore = GetDataStore(name, xPlayer.identifier) + dataStore = CreateDataStore(name, xPlayer.identifier, {}) + table.insert(DataStores[name], dataStore) + end - if dataStore == nil 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(DataStores[name], dataStore) - end - - table.insert(dataStores, dataStore) - - end - - xPlayer.set('dataStores', dataStores) + table.insert(dataStores, dataStore) + end + xPlayer.set('dataStores', dataStores) end) -