· 6 years ago · Jul 11, 2019, 04:58 PM
1MySQL = module("vrp_mysql", "MySQL")
2
3local Proxy = module("lib/Proxy")
4local Tunnel = module("lib/Tunnel")
5local Lang = module("lib/Lang")
6Debug = module("lib/Debug")
7
8local config = module("cfg/base")
9local version = module("version")
10Debug.active = config.debug
11MySQL.debug = config.debug
12
13-- open MySQL connection
14MySQL.createConnection("vRP", config.db.host,config.db.user,config.db.password,config.db.database)
15
16vRP = {}
17Proxy.addInterface("vRP",vRP)
18
19tvRP = {}
20Tunnel.bindInterface("vRP",tvRP) -- listening for client tunnel
21
22-- load language
23local dict = module("cfg/lang/"..config.lang) or {}
24vRP.lang = Lang.new(dict)
25
26-- init
27vRPclient = Tunnel.getInterface("vRP","vRP") -- server -> client tunnel
28
29vRP.users = {} -- will store logged users (id) by first identifier
30vRP.rusers = {} -- store the opposite of users
31vRP.user_tables = {} -- user data tables (logger storage, saved to database)
32vRP.user_tmp_tables = {} -- user tmp data tables (logger storage, not saved)
33vRP.user_sources = {} -- user sources
34
35-- queries
36MySQL.createCommand("vRP/base_tables",[[
37CREATE TABLE IF NOT EXISTS vrp_users(
38 id INTEGER AUTO_INCREMENT,
39 last_login VARCHAR(100),
40 whitelisted BOOLEAN,
41 banned BOOLEAN,
42 CONSTRAINT pk_user PRIMARY KEY(id)
43);
44
45CREATE TABLE IF NOT EXISTS vrp_user_ids(
46 identifier VARCHAR(255),
47 user_id INTEGER,
48 CONSTRAINT pk_user_ids PRIMARY KEY(identifier),
49 CONSTRAINT fk_user_ids_users FOREIGN KEY(user_id) REFERENCES vrp_users(id) ON DELETE CASCADE
50);
51
52CREATE TABLE IF NOT EXISTS vrp_user_data(
53 user_id INTEGER,
54 dkey VARCHAR(255),
55 dvalue TEXT,
56 CONSTRAINT pk_user_data PRIMARY KEY(user_id,dkey),
57 CONSTRAINT fk_user_data_users FOREIGN KEY(user_id) REFERENCES vrp_users(id) ON DELETE CASCADE
58);
59
60CREATE TABLE IF NOT EXISTS vrp_srv_data(
61 dkey VARCHAR(100),
62 dvalue TEXT,
63 CONSTRAINT pk_srv_data PRIMARY KEY(dkey)
64);
65]])
66
67MySQL.createCommand("vRP/create_user","INSERT INTO vrp_users(whitelisted,banned) VALUES(false,false); SELECT LAST_INSERT_ID() AS id")
68MySQL.createCommand("vRP/add_identifier","INSERT INTO vrp_user_ids(identifier,user_id) VALUES(@identifier,@user_id)")
69MySQL.createCommand("vRP/userid_byidentifier","SELECT user_id FROM vrp_user_ids WHERE identifier = @identifier")
70
71MySQL.createCommand("vRP/set_userdata","REPLACE INTO vrp_user_data(user_id,dkey,dvalue) VALUES(@user_id,@key,@value)")
72MySQL.createCommand("vRP/get_userdata","SELECT dvalue FROM vrp_user_data WHERE user_id = @user_id AND dkey = @key")
73
74MySQL.createCommand("vRP/set_srvdata","REPLACE INTO vrp_srv_data(dkey,dvalue) VALUES(@key,@value)")
75MySQL.createCommand("vRP/get_srvdata","SELECT dvalue FROM vrp_srv_data WHERE dkey = @key")
76
77MySQL.createCommand("vRP/get_banned","SELECT banned FROM vrp_users WHERE id = @user_id")
78MySQL.createCommand("vRP/set_banned","UPDATE vrp_users SET banned = @banned, reason = @reason WHERE id = @user_id")
79MySQL.createCommand("vRP/get_whitelisted","SELECT whitelisted FROM vrp_users WHERE id = @user_id")
80MySQL.createCommand("vRP/set_whitelisted","UPDATE vrp_users SET whitelisted = @whitelisted WHERE id = @user_id")
81MySQL.createCommand("vRP/set_last_login","UPDATE vrp_users SET last_login = @last_login, last_date = @last_date WHERE id = @user_id")
82MySQL.createCommand("vRP/get_last_login","SELECT last_login FROM vrp_users WHERE id = @user_id")
83
84-- init tables
85print("[vRP] init base tables")
86MySQL.execute("vRP/base_tables")
87
88-- identification system
89
90--- sql.
91-- cbreturn user id or nil in case of error (if not found, will create it)
92function vRP.getUserIdByIdentifiers(ids, cbr)
93 local task = Task(cbr)
94
95 if ids ~= nil and #ids then
96 local i = 0
97 local validids = 0
98
99 -- search identifiers
100 local function search()
101 i = i+1
102 if i <= #ids then
103 if (not config.ignore_ip_identifier or (string.find(ids[i], "ip:") == nil)) and
104 (not config.ignore_license_identifier or (string.find(ids[i], "license:") == nil)) and
105 (not config.ignore_xbox_identifier or (string.find(ids[i], "xbl:") == nil)) and
106 (not config.ignore_discord_identifier or (string.find(ids[i], "discord:") == nil)) and
107 (not config.ignore_live_identifier or (string.find(ids[i], "live:") == nil))
108 then -- ignore ip & license
109 validids = validids + 1
110 MySQL.query("vRP/userid_byidentifier", {identifier = ids[i]}, function(rows, affected)
111 if #rows > 0 then -- found
112 task({rows[1].user_id})
113 else -- not found
114 search()
115 end
116 end)
117 else
118 search()
119 end
120 elseif validids > 0 then -- no ids found, create user
121 MySQL.query("vRP/create_user", {}, function(rows, affected)
122 if #rows > 0 then
123 local user_id = rows[1].id
124 -- add identifiers
125 for l,w in pairs(ids) do
126 if (not config.ignore_ip_identifier or (string.find(w, "ip:") == nil)) and
127 (not config.ignore_license_identifier or (string.find(w, "license:") == nil)) and
128 (not config.ignore_xbox_identifier or (string.find(w, "xbl:") == nil)) and
129 (not config.ignore_discord_identifier or (string.find(w, "discord:") == nil)) and
130 (not config.ignore_live_identifier or (string.find(w, "live:") == nil))
131 then -- ignore ip & license identifier
132 MySQL.execute("vRP/add_identifier", {user_id = user_id, identifier = w})
133 end
134 end
135 task({user_id})
136 else
137 task()
138 end
139 end)
140 end
141 end
142
143 search()
144 else
145 task()
146 end
147end
148
149-- return identification string for the source (used for non vRP identifications, for rejected players)
150function vRP.getSourceIdKey(source)
151 local ids = GetPlayerIdentifiers(source)
152 local idk = "idk_"
153 for k,v in pairs(ids) do
154 idk = idk..v
155 end
156
157 return idk
158end
159
160function vRP.getPlayerEndpoint(player)
161 return GetPlayerEP(player) or "0.0.0.0"
162end
163
164function vRP.getPlayerName(player)
165 return GetPlayerName(player) or "ukendt"
166end
167
168--- sql
169function vRP.isBanned(user_id, cbr)
170 local task = Task(cbr, {false})
171
172 MySQL.query("vRP/get_banned", {user_id = user_id}, function(rows, affected)
173 if #rows > 0 then
174 task({rows[1].banned})
175 else
176 task()
177 end
178 end)
179end
180
181--- sql
182function vRP.setBanned(user_id,banned,reason)
183 MySQL.execute("vRP/set_banned", {user_id = user_id, banned = banned, reason = reason})
184end
185
186--- sql
187function vRP.isWhitelisted(user_id, cbr)
188 local task = Task(cbr, {false})
189
190 MySQL.query("vRP/get_whitelisted", {user_id = user_id}, function(rows, affected)
191 if #rows > 0 then
192 task({rows[1].whitelisted})
193 else
194 task()
195 end
196 end)
197end
198
199--- sql
200function vRP.setWhitelisted(user_id,whitelisted)
201 MySQL.execute("vRP/set_whitelisted", {user_id = user_id, whitelisted = whitelisted})
202end
203
204--- sql
205function vRP.getLastLogin(user_id, cbr)
206 local task = Task(cbr,{""})
207 MySQL.query("vRP/get_last_login", {user_id = user_id}, function(rows, affected)
208 if #rows > 0 then
209 task({rows[1].last_login})
210 else
211 task()
212 end
213 end)
214end
215
216function vRP.setUData(user_id,key,value)
217 MySQL.execute("vRP/set_userdata", {user_id = user_id, key = key, value = value})
218end
219
220function vRP.getUData(user_id,key,cbr)
221 local task = Task(cbr,{""})
222
223 MySQL.query("vRP/get_userdata", {user_id = user_id, key = key}, function(rows, affected)
224 if #rows > 0 then
225 task({rows[1].dvalue})
226 else
227 task()
228 end
229 end)
230end
231
232function vRP.setSData(key,value)
233 MySQL.execute("vRP/set_srvdata", {key = key, value = value})
234end
235
236function vRP.getSData(key, cbr)
237 local task = Task(cbr,{""})
238
239 MySQL.query("vRP/get_srvdata", {key = key}, function(rows, affected)
240 if #rows > 0 then
241 task({rows[1].dvalue})
242 else
243 task()
244 end
245 end)
246end
247
248-- return user data table for vRP internal persistant connected user storage
249function vRP.getUserDataTable(user_id)
250 return vRP.user_tables[user_id]
251end
252
253function vRP.getUserTmpTable(user_id)
254 return vRP.user_tmp_tables[user_id]
255end
256
257function vRP.isConnected(user_id)
258 return vRP.rusers[user_id] ~= nil
259end
260
261function vRP.isFirstSpawn(user_id)
262 local tmp = vRP.getUserTmpTable(user_id)
263 return tmp and tmp.spawns == 1
264end
265
266function vRP.getUserId(source)
267 if source ~= nil then
268 local ids = GetPlayerIdentifiers(source)
269 if ids ~= nil and #ids > 0 then
270 return vRP.users[ids[1]]
271 end
272 end
273
274 return nil
275end
276
277-- return map of user_id -> player source
278function vRP.getUsers()
279 local users = {}
280 for k,v in pairs(vRP.user_sources) do
281 users[k] = v
282 end
283
284 return users
285end
286
287-- return source or nil
288function vRP.getUserSource(user_id)
289 return vRP.user_sources[user_id]
290end
291
292function vRP.ban(source,reason)
293 local user_id = vRP.getUserId(source)
294
295 if user_id ~= nil then
296 vRP.setBanned(user_id,true,reason)
297 vRP.kick(source,"[Banned] "..reason)
298 end
299end
300
301function vRP.kick(source,reason)
302 DropPlayer(source,reason)
303end
304
305-- tasks
306
307function task_save_datatables()
308 TriggerEvent("vRP:save")
309
310 Debug.pbegin("vRP save datatables")
311 for k,v in pairs(vRP.user_tables) do
312 vRP.setUData(k,"vRP:datatable",json.encode(v))
313 end
314
315 Debug.pend()
316 SetTimeout(config.save_interval*1000, task_save_datatables)
317end
318task_save_datatables()
319
320function tvRP.ping()
321 local user_id = vRP.getUserId(source)
322 if user_id ~= nil then
323 local tmpdata = vRP.getUserTmpTable(user_id)
324 tmpdata.pings = 0 -- reinit ping countdown
325 end
326end
327
328-- handlers
329
330AddEventHandler("playerConnecting",function(name,setMessage, deferrals)
331 deferrals.defer()
332
333 local source = source
334 Debug.pbegin("playerConnecting")
335 local ids = GetPlayerIdentifiers(source)
336 local playerip = vRP.getPlayerEndpoint(source)
337
338 if ids ~= nil and #ids > 0 then
339 deferrals.update("[vRP] Tjekker identitet...")
340 vRP.getUserIdByIdentifiers(ids, function(user_id)
341 -- if user_id ~= nil and vRP.rusers[user_id] == nil then -- check user validity and if not already connected (old way, disabled until playerDropped is sure to be called)
342 if user_id ~= nil then -- check user validity
343 deferrals.update("[vRP] Tjekker om du er banned...")
344 vRP.isBanned(user_id, function(banned)
345 if not banned then
346 deferrals.update("[vRP] Tjekker om du er whitelisted...")
347 vRP.isWhitelisted(user_id, function(whitelisted)
348 if not config.whitelist or whitelisted then
349 Debug.pbegin("playerConnecting_delayed")
350 if vRP.rusers[user_id] == nil then -- not present on the server, init
351 -- init entries
352 vRP.users[ids[1]] = user_id
353 vRP.rusers[user_id] = ids[1]
354 vRP.user_tables[user_id] = {}
355 vRP.user_tmp_tables[user_id] = {}
356 vRP.user_sources[user_id] = source
357
358 -- load user data table
359 deferrals.update("[vRP] Indlæser dine data...")
360 vRP.getUData(user_id, "vRP:datatable", function(sdata)
361 local data = json.decode(sdata)
362 if type(data) == "table" then vRP.user_tables[user_id] = data end
363
364 -- init user tmp table
365 local tmpdata = vRP.getUserTmpTable(user_id)
366
367 deferrals.update("[vRP] Tjekker seneste login...")
368 vRP.getLastLogin(user_id, function(last_login)
369 tmpdata.last_login = last_login or ""
370 tmpdata.spawns = 0
371
372 -- set last login
373 local ep = vRP.getPlayerEndpoint(source)
374 local last_login_stamp = ep
375 local last_login_date = os.date("%H:%M:%S %d/%m/%Y")
376 MySQL.execute("vRP/set_last_login", {user_id = user_id, last_login = last_login_stamp, last_date = last_login_date})
377
378 -- trigger join
379 print("[vRP] "..name.." ("..vRP.getPlayerEndpoint(source)..") tilsluttede (ID: "..user_id..")")
380 TriggerEvent("vRP:playerJoin", user_id, source, name, tmpdata.last_login)
381
382 local dname = "ByensRP #1 [Connect]"
383 local dato = os.date("**%d-%m-%Y** kl. **%X**")
384 local dmessage = "**"..name.." (ID: "..tostring(user_id)..")** tilsluttede sig til serveren: ("..dato..")"
385 PerformHttpRequest('https://discordapp.com/api/webhooks/534075522674720768/5y5i3it8RDic0Upj9YzCWdyHPNEeZcquaBqMxfclLwLNv3j5jZYOcjbLLwHCjFyJq5py', function(err, text, headers) end, 'POST', json.encode({username = dname, content = dmessage}), { ['Content-Type'] = 'application/json' })
386
387 deferrals.done()
388 end)
389 end)
390 else -- already connected
391 print("[vRP] "..name.." ("..vRP.getPlayerEndpoint(source)..") tilsluttede igen (ID: "..user_id..")")
392 TriggerEvent("vRP:playerRejoin", user_id, source, name)
393
394 local dname2 = "ByensRP #1 [Re-join]"
395 local dato2 = os.date("**%d-%m-%Y** kl. **%X**")
396 local dmessage2 = "**"..name.." (ID: "..tostring(user_id)..")** tilsluttede sig **igen** til serveren: ("..dato2..")"
397 PerformHttpRequest('https://discordapp.com/api/webhooks/534075522674720768/5y5i3it8RDic0Upj9YzCWdyHPNEeZcquaBqMxfclLwLNv3j5jZYOcjbLLwHCjFyJq5py', function(err, text, headers) end, 'POST', json.encode({username = dname2, content = dmessage2}), { ['Content-Type'] = 'application/json' })
398
399 deferrals.done()
400
401 -- reset first spawn
402 local tmpdata = vRP.getUserTmpTable(user_id)
403 tmpdata.spawns = 0
404 end
405
406 Debug.pend()
407 else
408 print("[vRP] "..name.." ("..vRP.getPlayerEndpoint(source)..") afvist: ikke whitelisted (ID: "..user_id..")")
409 deferrals.done("[vRP] Ansøg om whitelist og oprret din karakter på www.ByensRP.dk (ID: "..user_id..").")
410 end
411 end)
412 else
413 print("[vRP] "..name.." ("..vRP.getPlayerEndpoint(source)..") afvist: banned (ID: "..user_id..")")
414 deferrals.done("[vRP] Ansøg om unban via vores Discord (ID: "..user_id..").")
415 end
416 end)
417 else
418 print("[vRP] "..name.." ("..vRP.getPlayerEndpoint(source)..") afvist: identifikationsfejl")
419 deferrals.done("[vRP] Kunne ikke hente dit SteamID.")
420 end
421 end)
422 else
423 print("[vRP] "..name.." ("..vRP.getPlayerEndpoint(source)..") afvist: mangler steamid")
424 deferrals.done("[vRP] Du skal åbne Steam inden du åbner FiveM.")
425 end
426 Debug.pend()
427end)
428
429AddEventHandler("playerDropped",function(reason)
430 local source = source
431 Debug.pbegin("playerDropped")
432
433 -- remove player from connected clients
434 vRPclient.removePlayer(-1,{source})
435
436
437 local user_id = vRP.getUserId(source)
438
439 if user_id ~= nil then
440 TriggerEvent("vRP:playerLeave", user_id, source)
441
442 -- save user data table
443 vRP.setUData(user_id,"vRP:datatable",json.encode(vRP.getUserDataTable(user_id)))
444
445 print("[vRP] "..vRP.getPlayerEndpoint(source).." forlod (ID: "..user_id..")")
446
447 local dname3 = "ByensRP #1 [Disconnect]"
448 local dato3 = os.date("**%d-%m-%Y** kl. **%X**")
449 local dmessage3 = "**(ID: "..tostring(user_id)..")** forlod serveren: ("..dato3..")"
450 PerformHttpRequest('https://discordapp.com/api/webhooks/534075522674720768/5y5i3it8RDic0Upj9YzCWdyHPNEeZcquaBqMxfclLwLNv3j5jZYOcjbLLwHCjFyJq5py', function(err, text, headers) end, 'POST', json.encode({username = dname3, content = dmessage3}), { ['Content-Type'] = 'application/json' })
451
452 vRP.users[vRP.rusers[user_id]] = nil
453 vRP.rusers[user_id] = nil
454 vRP.user_tables[user_id] = nil
455 vRP.user_tmp_tables[user_id] = nil
456 vRP.user_sources[user_id] = nil
457 end
458 Debug.pend()
459end)
460
461RegisterServerEvent("vRPcli:playerSpawned")
462AddEventHandler("vRPcli:playerSpawned", function()
463 Debug.pbegin("playerSpawned")
464 -- register user sources and then set first spawn to false
465 local user_id = vRP.getUserId(source)
466 local player = source
467 if user_id ~= nil then
468 vRP.user_sources[user_id] = source
469 local tmp = vRP.getUserTmpTable(user_id)
470 tmp.spawns = tmp.spawns+1
471 local first_spawn = (tmp.spawns == 1)
472
473 if first_spawn then
474 -- first spawn, reference player
475 -- send players to new player
476 for k,v in pairs(vRP.user_sources) do
477 vRPclient.addPlayer(source,{v})
478 end
479 -- send new player to all players
480 vRPclient.addPlayer(-1,{source})
481 end
482
483 -- set client tunnel delay at first spawn
484 Tunnel.setDestDelay(player, config.load_delay)
485
486 -- show loading
487 vRPclient.setProgressBar(player,{"vRP:loading", "botright", "Indlæser...", 0,0,0, 100})
488
489 SetTimeout(2000, function() -- trigger spawn event
490 TriggerEvent("vRP:playerSpawn",user_id,player,first_spawn)
491
492 SetTimeout(config.load_duration*1000, function() -- set client delay to normal delay
493 Tunnel.setDestDelay(player, config.global_delay)
494 vRPclient.removeProgressBar(player,{"vRP:loading"})
495 end)
496 end)
497 end
498
499 Debug.pend()
500end)
501
502RegisterServerEvent("vRP:playerDied")