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