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