· 8 years ago · Jan 19, 2018, 09:46 AM
1include("static_data.lua")
2DB.privcache = {}
3/*
4 ---------------------------------------------------------
5 MySQL
6 ---------------------------------------------------------
7*/
8if file.Exists("../lua/includes/modules/gmsv_mysqloo.dll") or file.Exists("../lua/includes/modules/gmsv_mysqloo_i486.dll") then
9 require("mysqloo")
10end
11
12local CONNECTED_TO_MYSQL = false
13DB.MySQLDB = nil
14
15function DB.Begin()
16 if not CONNECTED_TO_MYSQL then sql.Begin() end
17end
18function DB.Commit()
19 if not CONNECTED_TO_MYSQL then sql.Commit() end
20end
21
22function DB.Query(query, callback)
23 if CONNECTED_TO_MYSQL then
24 local query = DB.MySQLDB:query(query)
25 local data
26 query.onData = function(Q, D)
27 data = data or {}
28 table.insert(data, D)
29 end
30
31 query.onError = function(Q, E) Error(E) callback() DB.Log("MySQL Error: ".. E) end
32 query.onSuccess = function()
33 if callback then callback(data) end
34 end
35 query:start()
36 return
37 end
38 sql.Begin()
39 local Result = DB.QueryValue(query)
40 sql.Commit() -- otherwise it won't save, don't ask me why
41 if callback then callback(Result) end
42 return Result
43end
44
45function DB.Select(query)
46 if CONNECTED_TO_MYSQL then
47 local query = DB.MySQLDB:query(query)
48 local data
49 query.onData = function(Q, D)
50 data = D
51 end
52 sql.Begin()
53 sql.Commit() -- otherwise it won't save, don't ask me why
54 return data;
55 end
56end
57
58function DB.QueryValue(query, callback)
59 if CONNECTED_TO_MYSQL then
60 local query = DB.MySQLDB:query(query)
61 local data
62 query.onData = function(Q, D)
63 data = D
64 end
65 query.onSuccess = function()
66 for k,v in pairs(data or {}) do
67 callback(v)
68 return
69 end
70 callback()
71 end
72 query.onError = function(Q, E) Error(E) callback() DB.Log("MySQL Error: ".. E) end
73 query:start()
74 return
75 end
76 callback(sql.QueryValue(query))
77
78end
79
80function DB.ConnectToMySQL(host, username, password, database_name, database_port)
81 if not mysqloo then Error("MySQL modules aren't installed properly!") DB.Log("MySQL Error: MySQL modules aren't installed properly!") end
82 local databaseObject = mysqloo.connect(host, username, password, database_name, database_port)
83
84 databaseObject.onConnectionFailed = function(msg)
85 Error("Connection failed! " ..tostring(msg))
86 DB.Log("MySQL Error: Connection failed! "..tostring(msg))
87 end
88
89 databaseObject.onConnected = function()
90 DB.Log("MySQL: Connection to external database "..host.." succeeded!")
91 CONNECTED_TO_MYSQL = true
92
93 DB.Init() -- Initialize database
94 end
95 databaseObject:connect()
96 DB.MySQLDB = databaseObject
97end
98
99/*---------------------------------------------------------
100 Database initialize
101 ---------------------------------------------------------*/
102function DB.Init()
103 DB.Begin()
104 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_cvars(var char(20) NOT NULL, value INTEGER NOT NULL, PRIMARY KEY(var));")
105 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_tspawns(id INTEGER NOT NULL, map char(30) NOT NULL, team INTEGER NOT NULL, x NUMERIC NOT NULL, y NUMERIC NOT NULL, z NUMERIC NOT NULL, PRIMARY KEY(id));")
106 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_privs(steam char(20) NOT NULL, admin INTEGER NOT NULL, mayor INTEGER NOT NULL, cp INTEGER NOT NULL, tool INTEGER NOT NULL, phys INTEGER NOT NULL, prop INTEGER NOT NULL, PRIMARY KEY(steam));")
107 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_salaries(steam char(20) NOT NULL, salary INTEGER NOT NULL, PRIMARY KEY(steam));")
108 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_wallets(steam char(20) NOT NULL, amount INTEGER NOT NULL, PRIMARY KEY(steam));")
109 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_level(steam char(20) NOT NULL, level INTEGER NOT NULL, currentxp INTEGER NOT NULL, xpforlevel INTEGER NOT NULL, PRIMARY KEY(steam));")
110 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_jailpositions(map char(30) NOT NULL, x NUMERIC NOT NULL, y NUMERIC NOT NULL, z NUMERIC NOT NULL, lastused NUMERIC NOT NULL, PRIMARY KEY(map, x, y, z));")
111 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_rpnames(steam char(20) NOT NULL, name char(35) NOT NULL, PRIMARY KEY(steam));")
112 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_zspawns(map char(30) NOT NULL, x NUMERIC NOT NULL, y NUMERIC NOT NULL, z NUMERIC NOT NULL);")
113 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_disableddoors(map char(30) NOT NULL, idx INTEGER NOT NULL, title char(25) NOT NULL, PRIMARY KEY(map, idx));")
114 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_groupdoors(map char(30) NOT NULL, idx INTEGER NOT NULL, teams char(50) NOT NULL, title char(25) NOT NULL, PRIMARY KEY(map, idx));")
115 DB.Query("CREATE TABLE IF NOT EXISTS darkrp_consolespawns(id INTEGER NOT NULL PRIMARY KEY, map char(30) NOT NULL, x NUMERIC NOT NULL, y NUMERIC NOT NULL, z NUMERIC NOT NULL, pitch NUMERIC NOT NULL, yaw NUMERIC NOT NULL, roll NUMERIC NOT NULL);")
116 DB.Commit()
117
118 DB.CreatePrivs()
119 DB.CreateJailPos()
120 DB.CreateSpawnPos()
121 DB.CreateZombiePos()
122 DB.SetUpNonOwnableDoors()
123 DB.SetUpGroupOwnableDoors()
124 DB.LoadConsoles()
125
126 DB.Query("SELECT * FROM darkrp_cvars;", function(settings)
127 if settings then
128 local reset = false -- For the old SQLite Databases that had the "key" column instead of "var"
129 for k,v in pairs(settings) do
130 if v.key then reset = true end
131 RunConsoleCommand(v.var or v.key, v.value)
132 end
133 if reset then -- Renaming the column is impossible in SQLite, so do it the hard way
134 DB.Begin()
135 DB.Query("ALTER TABLE darkrp_cvars RENAME TO darkrp_cvars2;")
136 DB.Query("CREATE TABLE darkrp_cvars (var char(20) NOT NULL, value INTEGER NOT NULL, PRIMARY KEY(var));")
137 DB.Query("INSERT INTO darkrp_cvars SELECT * FROM darkrp_cvars2;")
138 DB.Query("DROP TABLE darkrp_cvars2;")
139 DB.Commit()
140 end
141 end
142 end)
143
144 -- Set the lastused of all jailpositions to 0 because the server just started
145 DB.Query("UPDATE darkrp_jailpositions SET lastused = 0;")
146
147 DB.JailPos = {}
148 DB.Query("SELECT * FROM darkrp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
149
150 DB.TeamSpawns = {}
151 DB.Query("SELECT * FROM darkrp_tspawns;", function(data) DB.TeamSpawns = data or {} end)
152
153 if CONNECTED_TO_MYSQL then -- In a listen server, the connection with the external database is often made AFTER the listen server host has joined,
154 --so he walks around with the settings from the SQLite database
155 for k,v in pairs(player.GetAll()) do
156 local SteamID = sql.SQLStr(v:SteamID())
157 DB.Query([[SELECT amount, salary, name, admin, mayor, cp, tool, phys, prop FROM darkrp_wallets
158 LEFT OUTER JOIN darkrp_salaries ON darkrp_wallets.steam = darkrp_salaries.steam
159 LEFT OUTER JOIN darkrp_rpnames ON darkrp_wallets.steam = darkrp_rpnames.steam
160 LEFT OUTER JOIN darkrp_privs ON darkrp_wallets.steam = darkrp_privs.steam
161 WHERE darkrp_wallets.steam = ]].. SteamID ..[[
162 ;]], function(data)
163 local Data = data[1]
164 if Data.name then
165 v:SetDarkRPVar("rpname", Data.name)
166 end
167 if Data.salary then
168 v:SetDarkRPVar("salary", Data.salary)
169 end
170 if Data.amount then
171 v:SetDarkRPVar("money", Data.amount)
172 end
173
174 local steamID = v:SteamID()
175 if DB.privcache[steamID] == nil then
176 DB.privcache[steamID] = {}
177 end
178
179 v:SetDarkRPVar("Privadmin", Data.admin)
180 DB.privcache[steamID]["admin"] = (Data.admin and 1) or 0
181
182 v:SetDarkRPVar("Privmayor", Data.mayor)
183 DB.privcache[steamID]["mayor"] = (Data.mayor and 1) or 0
184
185 v:SetDarkRPVar("Privcp", Data.cp)
186 DB.privcache[steamID]["cp"] = (Data.cp and 1) or 0
187
188 v:SetDarkRPVar("Privtool", Data.tool)
189 DB.privcache[steamID]["tool"] = (Data.tool and 1) or 0
190
191 v:SetDarkRPVar("Privphys", Data.phys)
192 DB.privcache[steamID]["phys"] = (Data.phys and 1) or 0
193
194 v:SetDarkRPVar("Privprop", Data.prop)
195 DB.privcache[steamID]["prop"] = (Data.prop and 1) or 0
196 end)
197 end
198 end
199end
200
201/*---------------------------------------------------------
202Leveling system
203----------------------------------------------------------*/
204
205local function saveStat ( ply )
206 local level = ply:GetNWInt("level")
207 local currentxp = ply:GetNWInt("currentxp")
208 local unique_id = ply:GetNWString ("steamID")
209 local levelxp = ply:GetNWInt ("levelxp")
210
211 DB.Query("UPDATE darkrp_level SET level = "..level.." WHERE unique_id = '"..unique_id.."'")
212 DB.Query("UPDATE darkrp_level SET currentxp = "..currentxp.." WHERE unique_id = '"..unique_id.."'")
213 ply:ChatPrint("Stats updated!")
214end
215
216/*local function load_stats ( ply )
217
218
219 steamID = ply:SteamID()
220 local result = DB.Query( "SELECT unique_id, level FROM darkrp_level WHERE unique_id = '"..steamID.."'" )
221 Msg("result1 is: " .. tostring(result))
222
223 if (result) then
224 Msg("result2 is: " .. tostring(result))
225
226 Msg("Player Already Exists!\n")
227 Msg("Loading Stats!\n")
228
229 local level = DB.QueryValue("SELECT level FROM darkrp_level WHERE unique_id = '"..steamID.."'")
230 local currentxp = DB.QueryValue("SELECT currentxp FROM darkrp_level WHERE unique_id = '"..steamID.."'")
231 local levelxp = DB.QueryValue("SELECT levelxp FROM darkrp_xpforlevel WHERE level = '"..level.."'")
232
233 ply:SetNWInt("currentxp", currentxp)
234 ply:SetNWInt("levelxp", levelxp)
235 ply:SetNWInt("level", level)
236
237 else
238 Msg("result3 is: " .. tostring(result))
239 Msg("Player Doesnt exist!\n")
240 DB.Query( "INSERT INTO darkrp_level (`unique_id`, `level`)VALUES ('"..steamID.."', '1')" )
241 ply:SetNWInt("level", 1)
242 ply:SetNWInt("currentxp", 1)
243 ply:SetNWInt("levelxp", 2500)
244
245end
246end*/
247
248local function load_stats ( ply )
249
250 steamID = ply:SteamID()
251 local result = DB.Select("SELECT level FROM darkrp_level WHERE unique_id = '"..steamID.."'")
252
253 Msg("result1 is: " .. tonumber(result))
254
255 if (result) then
256 Msg("result2 is: " .. tostring(result))
257
258 Msg("Player Already Exists!\n")
259 Msg("Loading Stats!\n")
260
261 local currentxp = DB.QueryValue("SELECT currentxp FROM darkrp_level WHERE unique_id = '"..steamID.."'")
262 local levelxp = DB.QueryValue("SELECT levelxp FROM darkrp_xpforlevel WHERE level = '"..level.."'")
263
264 ply:SetNWInt("currentxp", currentxp)
265 ply:SetNWInt("levelxp", levelxp)
266 ply:SetNWInt("level", level)
267 else
268 Msg("result3 is: " .. tostring(result))
269 Msg("Player Doesnt exist!\n")
270 DB.Query( "INSERT INTO darkrp_level (`unique_id`, `level`)VALUES ('"..steamID.."', '1')" )
271 ply:SetNWInt("level", 1)
272 ply:SetNWInt("currentxp", 1)
273 ply:SetNWInt("levelxp", 2500)
274
275 end
276end
277
278local function PlayerInitialSpawn( ply )
279 timer.Create("Steam_id_delay", 5, 1, function()
280 steamID = ply:SteamID()
281 ply:SetNWString("steamID", steamID)
282 timer.Create("SaveStat", 10, 0, function() saveStat( ply ) end)
283 load_stats( ply )
284 end)
285end
286
287hook.Add( "PlayerInitialSpawn", "PlayerInitialSpawn", PlayerInitialSpawn )
288
289
290
291/*---------------------------------------------------------
292 The privileges
293 ---------------------------------------------------------*/
294function DB.CreatePrivs()
295 DB.Begin()
296 if reset_all_privileges_to_these_on_startup then
297 DB.Query("DELETE FROM darkrp_privs;")
298 end
299 local already_inserted = {}
300 for k, v in pairs(RPAdmins) do
301 local admin = 0
302 local mayor = 0
303 local cp = 0
304 local tool = 0
305 local phys = 0
306 local prop = 0
307 for a, b in pairs(RPAdmins[k]) do
308 if b == ADMIN then admin = 1 end
309 if b == MAYOR then mayor = 1 end
310 if b == CP then cp = 1 end
311 if b == PTOOL then tool = 1 end
312 if b == PHYS then phys = 1 end
313 if b == PROP then prop = 1 end
314 end
315 if already_inserted[RPAdmins[k]] then
316 DB.Query("UPDATE darkrp_privs SET admin = " .. admin .. ", mayor = " .. mayor .. ", cp = " .. cp .. ", tool = " .. tool .. ", phys = " .. phys .. ", prop = " .. prop .. " WHERE steam = " .. sql.SQLStr(RPAdmins[k]) .. ";")
317 else
318 DB.Query("INSERT INTO darkrp_privs VALUES(" .. sql.SQLStr(k) .. ", " .. admin .. ", " .. mayor .. ", " .. cp .. ", " .. tool .. ", " .. phys .. ", " .. prop .. ");")
319 already_inserted[RPAdmins[k]] = true
320 end
321 end
322 DB.Commit()
323end
324
325function DB.Priv2Text(priv)
326 if priv == ADMIN then
327 return "admin"
328 elseif priv == MAYOR then
329 return "mayor"
330 elseif priv == CP then
331 return "cp"
332 elseif priv == PTOOL then
333 return "tool"
334 elseif priv == PHYS then
335 return "phys"
336 elseif priv == PROP then
337 return "prop"
338 else
339 return nil
340 end
341end
342
343function DB.HasPriv(ply, priv)
344 local SteamID = ply:SteamID()
345 if priv == ADMIN and (ply:EntIndex() == 0 or ply:IsAdmin()) then return true end
346
347 local p = DB.Priv2Text(priv)
348 if not p then return false end
349
350 -- If there is a current cache of priveleges
351 if DB.privcache[SteamID] and DB.privcache[SteamID][p] ~= nil then
352 if DB.privcache[SteamID][p] == 1 then
353 return true
354 else
355 return false
356 end
357 -- If there is no cache for this user
358 else
359 DB.QueryValue("SELECT " .. sql.SQLStr(p) .. " FROM darkrp_privs WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";", function(result)
360 result = tonumber(result)
361 if not DB.privcache[SteamID] then
362 DB.privcache[SteamID] = {}
363 end
364
365 if result == 1 then
366 DB.privcache[SteamID][p] = 1
367 return true
368 else
369 DB.privcache[SteamID][p] = 0
370 return false
371 end
372 end)
373 end
374end
375
376function DB.GrantPriv(ply, priv)
377 local steamID = ply:SteamID()
378 local p = DB.Priv2Text(priv)
379 if not p then return false end
380 DB.QueryValue("SELECT COUNT(*) FROM darkrp_privs WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(count)
381 if count and tonumber(count) > 0 then
382 DB.Query("UPDATE darkrp_privs SET " .. p .. " = 1 WHERE steam = " .. sql.SQLStr(steamID) .. ";")
383 else
384 DB.Begin()
385 DB.Query("INSERT INTO darkrp_privs VALUES(" .. sql.SQLStr(steamID) .. ", 0, 0, 0, 0, 0, 0);")
386 DB.Query("UPDATE darkrp_privs SET " .. sql.SQLStr(p) .. " = 1 WHERE steam = " .. sql.SQLStr(steamID) .. ";")
387
388 DB.Commit()
389 end
390 end)
391 -- privelege structure altered, fix the goddamn cache
392
393 if DB.privcache[steamID] == nil then
394 DB.privcache[steamID] = {}
395 end
396 ply:SetDarkRPVar("Priv"..p, true)
397 DB.privcache[steamID][p] = 1
398 return true
399end
400
401function DB.RevokePriv(ply, priv)
402 local steamID = ply:SteamID()
403 local p = DB.Priv2Text(priv)
404 DB.QueryValue("SELECT COUNT(*) FROM darkrp_privs WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(val)
405 val = tonumber(Val) or 0
406 if not p or val < 1 then return end
407 DB.Query("UPDATE darkrp_privs SET " .. p .. " = 0 WHERE steam = " .. sql.SQLStr(steamID) .. ";")
408 end)
409
410 -- privelege structure altered, alter the cache
411 if DB.privcache[steamID] == nil then
412 DB.privcache[steamID] = {}
413 end
414 DB.privcache[steamID][p] = 0
415 if ply.DarkRPVars["Priv"..p] then
416 ply:SetDarkRPVar("Priv"..p, false)
417 end
418 return true
419end
420
421/*---------------------------------------------------------
422 positions
423 ---------------------------------------------------------*/
424function DB.CreateSpawnPos()
425 local map = string.lower(game.GetMap())
426 if not team_spawn_positions then return end
427
428 for k, v in pairs(team_spawn_positions) do
429 if v[1] == map then
430 DB.StoreTeamSpawnPos(v[2], Vector(v[3], v[4], v[5]))
431 end
432 end
433end
434
435function DB.CreateZombiePos()
436 if not zombie_spawn_positions then return end
437 local map = string.lower(game.GetMap())
438
439 local once = false
440 DB.Begin()
441 for k, v in pairs(zombie_spawn_positions) do
442 if map == string.lower(v[1]) then
443 if not once then
444 DB.Query("DELETE FROM darkrp_zspawns;")
445 once = true
446 end
447 DB.Query("INSERT INTO darkrp_zspawns VALUES(" .. sql.SQLStr(map) .. ", " .. v[2] .. ", " .. v[3] .. ", " .. v[4] .. ");")
448 end
449 end
450 DB.Commit()
451end
452
453function DB.StoreZombies()
454 local map = string.lower(game.GetMap())
455 DB.Begin()
456 DB.Query("DELETE FROM darkrp_zspawns WHERE map = " .. sql.SQLStr(map) .. ";", function()
457 for k, v in pairs(zombieSpawns) do
458 local s = string.Explode(" ", v)
459 DB.Query("INSERT INTO darkrp_zspawns VALUES(" .. sql.SQLStr(map) .. ", " .. s[1] .. ", " .. s[2] .. ", " .. s[3] .. ");")
460 end
461 end)
462 DB.Commit()
463end
464
465local FirstZombieSpawn = true
466function DB.RetrieveZombies(callback)
467 if zombieSpawns and table.Count(zombieSpawns) > 0 and not FirstZombieSpawn then callback() return zombieSpawns end
468 FirstZombieSpawn = false
469 zombieSpawns = {}
470 DB.Query("SELECT * FROM darkrp_zspawns WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";", function(r)
471 if not r then callback() return end
472 for map, row in pairs(r) do
473 zombieSpawns[map] = tostring(Vector(row.x, row.y, row.z))
474 end
475 callback()
476 end)
477end
478
479local function IsEmpty(vector)
480 local point = util.PointContents(vector)
481 local a = point ~= CONTENTS_SOLID
482 and point ~= CONTENTS_MOVEABLE
483 and point ~= CONTENTS_LADDER
484 and point ~= CONTENTS_PLAYERCLIP
485 and point ~= CONTENTS_MONSTERCLIP
486 local b = true
487
488 for k,v in pairs(ents.FindInSphere(vector, 35)) do
489 if v:IsNPC() or v:IsPlayer() or v:GetClass() == "prop_physics" then
490 b = false
491 end
492 end
493 return a and b
494end
495
496function DB.RetrieveRandomZombieSpawnPos()
497 if #zombieSpawns < 1 then return end
498 local r = string.Explode(" ", table.Random(zombieSpawns))
499 r = Vector(r[1], r[2], r[3])
500 if not IsEmpty(Vector(r.x, r.y, r.z)) then
501 local found = false
502 for i = 40, 200, 10 do
503 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(i, 0, 0)) then
504 found = true
505 return Vector(r.x, r.y, r.z) + Vector(i, 0, 0)
506 end
507 end
508
509 if not found then
510 for i = 40, 200, 10 do
511 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(0, i, 0)) then
512 found = true
513 return Vector(r.x, r.y, r.z) + Vector(0, i, 0)
514 end
515 end
516 end
517
518 if not found then
519 for i = 40, 200, 10 do
520 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(-i, 0, 0)) then
521 found = true
522 return Vector(r.x, r.y, r.z) + Vector(-i, 0, 0)
523 end
524 end
525 end
526
527 if not found then
528 for i = 40, 200, 10 do
529 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(0, -i, 0)) then
530 found = true
531 return Vector(r.x, r.y, r.z) + Vector(0, -i, 0)
532 end
533 end
534 end
535 else
536 return Vector(r.x, r.y, r.z)
537 end
538
539 return Vector(r.x, r.y, r.z) + Vector(0,0,70)
540end
541
542function DB.CreateJailPos()
543 if not jail_positions then return end
544 local map = string.lower(game.GetMap())
545
546 local once = false
547 DB.Begin()
548 for k, v in pairs(jail_positions) do
549 if map == string.lower(v[1]) then
550 if not once then
551 DB.Query("DELETE FROM darkrp_jailpositions;", function()
552 DB.Query("INSERT INTO darkrp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. v[2] .. ", " .. v[3] .. ", " .. v[4] .. ", " .. 0 .. ");")
553 end)
554 DB.JailPos = {}
555 once = true
556 return
557 end
558 DB.Query("INSERT INTO darkrp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. v[2] .. ", " .. v[3] .. ", " .. v[4] .. ", " .. 0 .. ");")
559 end
560 end
561 DB.Commit()
562end
563
564function DB.StoreJailPos(ply, addingPos)
565 local map = string.lower(game.GetMap())
566 local pos = string.Explode(" ", tostring(ply:GetPos()))
567 DB.QueryValue("SELECT COUNT(*) FROM darkrp_jailpositions WHERE map = " .. sql.SQLStr(map) .. ";", function(already)
568 if not already or already == 0 then
569 DB.Query("INSERT INTO darkrp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ", " .. 0 .. ");", function()
570 DB.Query("SELECT * FROM darkrp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
571 end)
572 Notify(ply, 1, 4, LANGUAGE.created_first_jailpos)
573 else
574 if addingPos then
575 DB.Query("INSERT INTO darkrp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ", " .. 0 .. ");", function()
576 DB.Query("SELECT * FROM darkrp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
577 end)
578 Notify(ply, 1, 4, LANGUAGE.added_jailpos)
579 else
580 DB.Begin()
581 DB.Query("DELETE FROM darkrp_jailpositions WHERE map = " .. sql.SQLStr(map) .. ";")
582 DB.Query("INSERT INTO darkrp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ", " .. 0 .. ");", function()
583 DB.Query("SELECT * FROM darkrp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
584 end)
585 DB.Commit()
586 Notify(ply, 1, 5, LANGUAGE.reset_add_jailpos)
587 end
588 end
589 end)
590end
591
592function DB.RetrieveJailPos()
593 local map = string.lower(game.GetMap())
594 local r = DB.JailPos
595 if not r then return Vector(0,0,0) end
596
597 -- Retrieve the least recently used jail position
598 local now = CurTime()
599 local oldest = 0
600 local ret
601
602 for k, row in pairs(r) do
603 if row.map == map and (now - tonumber(row.lastused)) > oldest then
604 oldest = (now - tonumber(row.lastused))
605 ret = row
606 elseif row.map == map and oldest == 0 then
607 ret = row
608 end
609 end
610 -- Mark that position as having been used just now
611 if ret then DB.Query("UPDATE darkrp_jailpositions SET lastused = " .. CurTime() .. " WHERE map = " .. sql.SQLStr(map) .. " AND x = " .. ret.x .. " AND y = " .. ret.y .. " AND z = " .. ret.z .. ";", function()
612 DB.Query("SELECT * FROM darkrp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
613 end) end
614 return ret and Vector(ret.x, ret.y, ret.z)
615end
616
617function DB.SaveSetting(setting, value)
618 DB.Query("SELECT value FROM darkrp_cvars WHERE var = "..sql.SQLStr(setting)..";", function(Data)
619 if Data then
620 DB.Query("UPDATE darkrp_cvars set Value = " .. sql.SQLStr(value) .." WHERE var = " .. sql.SQLStr(setting)..";")
621 else
622 DB.Query("INSERT INTO darkrp_cvars VALUES("..sql.SQLStr(setting)..","..sql.SQLStr(value)..");")
623 end
624 end)
625end
626
627function DB.CountJailPos()
628 return table.Count(DB.JailPos or {})
629end
630
631local function FixDarkRPTspawnsTable() -- SQLite only
632 local FixTable = DB.QueryValue("SELECT * FROM darkrp_tspawns;")
633 if not FixTable or (FixTable and FixTable[1] and not FixTable[1].id) then -- The old tspawns table didn't have an 'id' column, this checks if the table is out of date
634 DB.QueryValue("DROP TABLE IF EXISTS darkrp_tspawns;") -- remove the table and remake it
635 DB.QueryValue("CREATE TABLE IF NOT EXISTS darkrp_tspawns(id INTEGER NOT NULL, map TEXT NOT NULL, team INTEGER NOT NULL, x NUMERIC NOT NULL, y NUMERIC NOT NULL, z NUMERIC NOT NULL, PRIMARY KEY(id));")
636 for k,v in pairs(FixTable or {}) do -- Put back the old data in the new format so the end user will not notice any changes, if there was nothing in the old table then loop through nothing
637 DB.QueryValue("INSERT INTO darkrp_tspawns VALUES(NULL, "..sql.SQLStr(v.map)..", "..v.team..", "..v.x..", "..v.y..", "..v.z..");")
638 end
639 end
640end
641
642function DB.StoreTeamSpawnPos(t, pos)
643 if not CONNECTED_TO_MYSQL then FixDarkRPTspawnsTable() end -- Check if the server doesn't use an out of date version of this table
644 local map = string.lower(game.GetMap())
645 DB.QueryValue("SELECT COUNT(*) FROM darkrp_tspawns WHERE team = " .. t .. " AND map = " .. sql.SQLStr(map) .. ";", function(already)
646 already = tonumber(already)
647 local ID = 0
648 local found = false
649 for k,v in SortedPairs(DB.TeamSpawns or {}) do
650 if tonumber(v.id) == ID + 1 then
651 ID = tonumber(v.id)
652 found = true
653 else
654 ID = ID + 1
655 found = false
656 break
657 end
658 end
659 if found or ID == 0 then ID = ID + 1 end
660
661 if not already or already == 0 then
662 DB.Query("INSERT INTO darkrp_tspawns VALUES(".. ID .. ", ".. sql.SQLStr(map) .. ", " .. t .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ");", function()
663 DB.Query("SELECT * FROM darkrp_tspawns;", function(data) DB.TeamSpawns = data or {} end) end)
664 print(string.format(LANGUAGE.created_spawnpos, team.GetName(t)))
665 else
666 DB.RemoveTeamSpawnPos(t, function() -- remove everything and create new
667 DB.Query("INSERT INTO darkrp_tspawns VALUES(".. ID .. ", ".. sql.SQLStr(map) .. ", " .. t .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ");", function()
668 DB.Query("SELECT * FROM darkrp_tspawns;", function(data) DB.TeamSpawns = data or {} end) end)
669 end)
670 print(string.format(LANGUAGE.updated_spawnpos, team.GetName(t)))
671 end
672 end)
673end
674
675function DB.AddTeamSpawnPos(t, pos)
676 if not CONNECTED_TO_MYSQL then FixDarkRPTspawnsTable() end--Check if the server doesn't use an out of date version of this table
677 local map = string.lower(game.GetMap())
678 local ID = 0
679 local found = false
680 for k,v in SortedPairs(DB.TeamSpawns or {}) do
681 if tonumber(v.id) == ID + 1 then
682 ID = tonumber(v.id)
683 found = true
684 else
685 ID = ID + 1
686 found = false
687 break
688 end
689 end
690 if found or ID == 0 then ID = ID + 1 end
691
692 DB.Query("INSERT INTO darkrp_tspawns VALUES(".. ID .. ", " .. sql.SQLStr(map) .. ", " .. t .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ");", function()
693 DB.Query("SELECT * FROM darkrp_tspawns;", function(data) DB.TeamSpawns = data or {} end) end)
694end
695
696function DB.RemoveTeamSpawnPos(t, callback)
697 local map = string.lower(game.GetMap())
698 DB.Query("DELETE FROM darkrp_tspawns WHERE team = "..t..";", function()
699 DB.Query("SELECT * FROM darkrp_tspawns;", function(data) DB.TeamSpawns = data or {} end)
700 if callback then callback() end
701 end)
702end
703
704function DB.RetrieveTeamSpawnPos(ply)
705 local map = string.lower(game.GetMap())
706 local t = ply:Team()
707
708 local returnal = {}
709
710 if DB.TeamSpawns then
711 for k,v in pairs(DB.TeamSpawns) do
712 if v.map == map and tonumber(v.team) == t then
713 table.insert(returnal, Vector(v.x, v.y, v.z))
714 end
715 end
716 return (table.Count(returnal) > 0 and returnal) or nil
717 end
718end
719
720/*---------------------------------------------------------
721Players
722 ---------------------------------------------------------*/
723function DB.StoreRPName(ply, name)
724 if not name or string.len(name) < 2 then return end
725 ply:SetDarkRPVar("rpname", name)
726 DB.QueryValue("SELECT name FROM darkrp_rpnames WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";", function(r)
727 if r then
728 DB.Query("UPDATE darkrp_rpnames SET name = " .. sql.SQLStr(name) .. " WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";")
729 else
730 DB.Query("INSERT INTO darkrp_rpnames VALUES(" .. sql.SQLStr(ply:SteamID()) .. ", " .. sql.SQLStr(name) .. ");")
731 end
732 end)
733end
734
735local rpnameslist --Make sure the DB doesn't get checked for ALL RPnames when someone InitialSpawns
736function DB.RetrieveRPNames(callback)
737 if rpnameslist then
738 return callback(rpnameslist)
739 end
740
741 DB.Query("SELECT * FROM darkrp_rpnames;", function(r)
742 if r then
743 rpnameslist = r
744 callback(rpnameslist)
745 else
746 rpnameslist = {}
747 callback(rpnameslist)
748 end
749 end)
750end
751
752function DB.RetrieveRPName(ply, callback)
753 for k,v in pairs(rpnameslist or {}) do
754 if v.steam == ply:SteamID() then return callback(v.name) end -- First check the cache for RP names
755 end
756 DB.QueryValue("SELECT name FROM darkrp_rpnames WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";", callback)
757end
758
759function DB.StoreMoney(ply, amount)
760 if not ValidEntity(ply) then return end
761 if amount < 0 then return end
762 ply:SetDarkRPVar("money", math.floor(amount))
763
764 local steamID = ply:SteamID()
765 DB.QueryValue("SELECT amount FROM darkrp_wallets WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(r)
766 if r then
767 DB.Query("UPDATE darkrp_wallets SET amount = " .. math.floor(amount) .. " WHERE steam = " .. sql.SQLStr(steamID) .. ";")
768 else
769 DB.Query("INSERT INTO darkrp_wallets VALUES(" .. sql.SQLStr(steamID) .. ", " .. math.floor(amount) .. ");")
770 end
771 end)
772end
773
774function DB.RetrieveMoney(ply) -- This is only run once when the player joins, there's no need for a cache unless the player keeps rejoining.
775 if not ValidEntity(ply) then return 0 end
776 local steamID = ply:SteamID()
777 local startingAmount = GetConVarNumber("startingmoney") or 500
778
779 DB.QueryValue("SELECT amount FROM darkrp_wallets WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";", function(r)
780 if r then
781 ply:SetDarkRPVar("money", math.floor(r))
782 else
783 -- No record yet, setting starting cash to 500
784 DB.StoreMoney(ply, startingAmount)
785 end
786 end)
787end
788
789function DB.ResetAllMoney(ply,cmd,args)
790 if not ply:IsSuperAdmin() then return end
791 DB.Query("DELETE FROM darkrp_wallets;")
792 for k,v in pairs(player.GetAll()) do
793 v:SetDarkRPVar("money", GetConVarNumber("startingmoney") or 500)
794 end
795 if ply:IsPlayer() then
796 NotifyAll(1,4, string.format(LANGUAGE.reset_money, ply:Nick()))
797 else
798 NotifyAll(1,4, string.format(LANGUAGE.reset_money, "Console"))
799 end
800end
801concommand.Add("rp_resetallmoney", DB.ResetAllMoney)
802
803function DB.PayPlayer(ply1, ply2, amount)
804 if not ValidEntity(ply1) or not ValidEntity(ply2) then return end
805 ply1:AddMoney(-amount)
806 ply2:AddMoney(amount)
807end
808
809function DB.StoreSalary(ply, amount)
810 local steamID = ply:SteamID()
811 ply:SetDarkRPVar("salary", math.floor(amount))
812 DB.QueryValue("SELECT COUNT(*) FROM darkrp_salaries WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(already)
813 if not already or already == 0 then
814 DB.Query("INSERT INTO darkrp_salaries VALUES(" .. sql.SQLStr(steamID) .. ", " .. math.floor(amount) .. ");")
815 else
816 DB.Query("UPDATE darkrp_salaries SET salary = " .. math.floor(amount) .. " WHERE steam = " .. sql.SQLStr(steamID) .. ";")
817 end
818 end)
819
820 return amount
821end
822
823function DB.RetrieveSalary(ply, callback)
824 if not ValidEntity(ply) then return 0 end
825 local steamID = ply:SteamID()
826 local normal = GetConVarNumber("normalsalary")
827 if ply.DarkRPVars.salary then return callback and callback(ply.DarkRPVars.salary) end -- First check the cache.
828
829 DB.QueryValue("SELECT salary FROM darkrp_salaries WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(r)
830 if not r then
831 ply:SetDarkRPVar("salary", normal)
832 callback(normal)
833 else
834 callback(r)
835 end
836 end)
837end
838
839/*---------------------------------------------------------
840 Doors
841 ---------------------------------------------------------*/
842function DB.StoreDoorOwnability(ent)
843 local map = string.lower(game.GetMap())
844 ent.DoorData = ent.DoorData or {}
845 local nonOwnable = ent.DoorData.NonOwnable
846 DB.QueryValue("SELECT COUNT(*) FROM darkrp_disableddoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. ent:EntIndex() .. ";", function(r)
847 r = tonumber(r)
848 if not r then return end
849
850 if r > 0 and not nonOwnable then
851 DB.Query("DELETE FROM darkrp_disableddoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. ent:EntIndex() .. ";")
852 elseif r == 0 and nonOwnable then
853 DB.Query("INSERT INTO darkrp_disableddoors VALUES(" .. sql.SQLStr(map) .. ", " .. ent:EntIndex() .. ", " .. sql.SQLStr("Non-Ownable Door") .. ");")
854 end
855 end)
856end
857
858function DB.StoreNonOwnableDoorTitle(ent, text)
859 ent.DoorData = ent.DoorData or {}
860 ent.DoorData.title = text
861 DB.Query("UPDATE darkrp_disableddoors SET title = " .. sql.SQLStr(text) .. " WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. " AND idx = " .. ent:EntIndex() .. ";")
862end
863
864function DB.SetUpNonOwnableDoors()
865 DB.Query("SELECT idx, title FROM darkrp_disableddoors WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";", function(r)
866 if not r then return end
867
868 for _, row in pairs(r) do
869 local e = ents.GetByIndex(tonumber(row.idx))
870 if ValidEntity(e) then
871 e.DoorData = e.DoorData or {}
872 e.DoorData.NonOwnable = true
873 e.DoorData.title = row.title
874 end
875 end
876 end)
877end
878
879
880function DB.StoreGroupDoorOwnability(ent)
881 local map = string.lower(game.GetMap())
882 ent.DoorData = ent.DoorData or {}
883
884 DB.QueryValue("SELECT COUNT(*) FROM darkrp_groupdoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. ent:EntIndex() .. ";", function(r)
885 r = tonumber(r)
886 if not r then return end
887
888 if r > 0 and not ent.DoorData.GroupOwn then
889 DB.Query("DELETE FROM darkrp_groupdoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. ent:EntIndex() .. ";")
890 elseif r == 0 and ent.DoorData.GroupOwn then
891 DB.Query("INSERT INTO darkrp_groupdoors VALUES(" .. sql.SQLStr(map) .. ", " .. ent:EntIndex() .. ", " .. sql.SQLStr(ent.DoorData.GroupOwn) .. ", " .. sql.SQLStr(ent.DoorData.title or "") .. ");")
892 elseif r == 1 then
893 DB.Query("UPDATE darkrp_groupdoors SET teams = "..sql.SQLStr(ent.DoorData.GroupOwn) .. " WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. ent:EntIndex() .. ";")
894 end
895 end)
896end
897
898function DB.StoreGroupOwnableDoorTitle(ent, text)
899 DB.Query("UPDATE darkrp_groupdoors SET title = " .. sql.SQLStr(text) .. " WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. " AND idx = " .. ent:EntIndex() .. ";")
900 e.DoorData = e.DoorData or {}
901 ent.DoorData.title = text
902end
903
904function DB.SetUpGroupOwnableDoors()
905 DB.Query("SELECT idx, title, teams FROM darkrp_groupdoors WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";", function(r)
906 if not r then return end
907
908 for _, row in pairs(r) do
909 local e = ents.GetByIndex(tonumber(row.idx))
910 if ValidEntity(e) then
911 e.DoorData = e.DoorData or {}
912 e.DoorData.title = row.title
913 e.DoorData.GroupOwn = row.teams
914 end
915 end
916 end)
917end
918
919function DB.LoadConsoles()
920 local map = string.lower(game.GetMap())
921 DB.Query("SELECT * FROM darkrp_consolespawns WHERE map = " .. sql.SQLStr(map) .. ";", function(data)
922 if data then
923 for k, v in pairs(data) do
924 local console = ents.Create("darkrp_console")
925 console:SetPos(Vector(tonumber(v.x), tonumber(v.y), tonumber(v.z)))
926 console:SetAngles(Angle(tonumber(v.pitch), tonumber(v.yaw), tonumber(v.roll)))
927 console:Spawn()
928 console.ID = v.id
929 end
930 else--If there are no custom positions in the database, use the presets.
931 for k,v in pairs(RP_ConsolePositions) do
932 if v[1] == map then
933 local console = ents.Create("darkrp_console")
934 console:SetPos(Vector(RP_ConsolePositions[k][2], RP_ConsolePositions[k][3], RP_ConsolePositions[k][4]))
935 console:SetAngles(Angle(RP_ConsolePositions[k][5], RP_ConsolePositions[k][6], RP_ConsolePositions[k][7]))
936 console:Spawn()
937 console:Activate()
938
939 console.ID = "0"
940 end
941 end
942 end
943 end)
944end
945
946function DB.CreateConsole(ply, cmd, args)
947 if not ply:IsSuperAdmin() then return end
948
949 local tr = {}
950 tr.start = ply:EyePos()
951 tr.endpos = ply:EyePos() + 95 * ply:GetAimVector()
952 tr.filter = ply
953 local trace = util.TraceLine(tr)
954
955 local console = ents.Create("darkrp_console")
956 console:SetPos(trace.HitPos)
957 console:Spawn()
958 console:Activate()
959
960 DB.QueryValue("SELECT MAX(id) FROM darkrp_consolespawns;", function(Data)
961 console.ID = (tonumber(Data) and tostring(tonumber(Data) + 1)) or "1"
962 end)
963
964 ply:ChatPrint("Console spawned, move and freeze it to save it!")
965end
966concommand.Add("rp_CreateConsole", DB.CreateConsole)
967
968function DB.RemoveConsoles(ply, cmd, args)
969 if not ply:IsSuperAdmin() then return end
970 DB.Query("DELETE FROM darkrp_consolespawns WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";")
971end
972concommand.Add("rp_removeallconsoles", DB.RemoveConsoles)
973
974/*---------------------------------------------------------
975 Logging
976 ---------------------------------------------------------*/
977function DB.Log(text, force)
978 if (not util.tobool(GetConVarNumber("logging")) or not text) and not force then return end
979 if not DB.File then -- The log file of this session, if it's not there then make it!
980 if not file.IsDir("DarkRP_logs") then
981 file.CreateDir("DarkRP_logs")
982 end
983 DB.File = "DarkRP_logs/"..os.date("%m_%d_%Y %I_%M %p")..".txt"
984 file.Write(DB.File, os.date().. "\t".. text)
985 return
986 end
987 file.Write(DB.File, (file.Read(DB.File) or "").."\n"..os.date().. "\t"..(text or ""))
988end