· 9 years ago · Nov 19, 2016, 09:00 AM
1include("static_data.lua")
2
3local print, pairs, IsValid, tonumber = print, pairs, IsValid, tonumber
4
5/*
6 ---------------------------------------------------------
7 MySQL
8 ---------------------------------------------------------
9*/
10/*if file.Exists("../lua/includes/modules/gmsv_mysqloo.dll") or file.Exists("../lua/includes/modules/gmsv_mysqloo_i486.dll") then
11 require("mysqloo")
12end*/
13require("tmysql4")
14
15//require("mysql")
16
17//HRP_MYSQL_LOCAL = false
18//ForumDatabase = false
19
20//local LastMySQLConnect = 0
21//local LastForumConnect = 0
22
23local CONNECTED_TO_MYSQLOO = true // not really mysqloo but I cba to change every check for it
24
25tmysql.escape = function(str) // this was removed from module..
26 return GameDatabase:Escape(str)
27end
28
29function DB.Query(query, callback, qtype)
30
31 local cBackFunc = function(r)
32 if r[1].error then
33 local err = table.concat({"tMySQL query error: ", r[1].error, debug.Trace() or "", "Query: ", query, "\n"}, "")
34 DB.Log(err)
35 ErrorNoHalt(err)
36 r[1].data = nil
37 //return
38 end
39 // lua_run DB.Query("SELECT amount, steam, rpname FROM metrorp_wallets limit 3", PrintTable, 1)
40 if callback then
41 if qtype == 0 then
42 ErrorNoHalt("Query "..query.." used Type 0 in DB.Query!\n")
43 local tbl = {}
44 for i=1, #r[1].data do
45 local ind = 1
46 tbl[i] = {}
47 for a,b in pairs(r[1].data[i]) do
48 tbl[i][ind] = b
49 ind = ind + 1
50 end
51 end
52 callback(tbl, !r[1].error)
53 else
54 callback(r[1].data, !r[1].error)
55 end
56 end
57
58 end
59 GameDatabase:Query(query, cBackFunc)
60end
61
62/*function DB.MySQLQuery(String, Type)
63 local ostime = os.time()
64 if LastMySQLConnect < ostime then
65 DB.ConnectToNormalMySQL()
66 end
67 local R, S, E = mysql.query(HRP_MYSQL_LOCAL, String, Type)
68
69 if !S then
70 //ErrorNoHalt("MySQL Query Failed. " .. E .. "\n")
71 print("MySQL Query Failed. " .. E .. "\n")
72 if E == "MySQL server has gone away" or E == "Invalid connection!" then
73 DB.ConnectToNormalMySQL()
74 end
75 end
76
77 return R, S, E;
78end*/
79
80/*function DB.MySQLQueryForum(String, Type)
81 local ostime = os.time()
82
83 if LastForumConnect < ostime then
84 DB.ConnectToNormalMySQLForum()
85 print("Forum connection is over 25900s long, reconnecting\n")
86 end
87 local R, S, E = mysql.query(ForumDatabase, String, Type)
88
89 if !S then
90 //ErrorNoHalt("MySQL Query Failed. " .. E .. "\n")
91 print("Forum MySQL Query Failed. " .. E .. "\n")
92 if E == "MySQL server has gone away" or E == "Invalid connection!" then
93 DB.ConnectToNormalMySQLForum()
94 end
95 end
96
97 return R, S, E;
98end*/
99
100local GoodChars = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "@", "^", "=", "_", "-", "~", "[", "]", "{", "}", "(", ")", "\"", ":", ", ", ".", "*", "?", "&", "|", "ï", "¢", "£", "¤", "Â¥", "§", "¦", "«", "ª", "©", "¨", "¬", "Â", "®", "¯", "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "º", "»¼", "½", "¾", "¿", "À", "Ã", "Â", "Ã", "Ä", "Ã…", "Æ", "Ç", "È", "É", "Ê", "Ë", "ÃŒ", "Ã", "ÃŽ", "Ã", "Ã", "Ñ", "Ã’", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ã", "Þ", "ß", "à ", "á", "â", "ã", "ä", "Ã¥", "æ", "ç", "è", "é", "ê", "ë", "ì", "Ã", "î", "ï", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ", "Ã", ".", "ß", "µ", " ", "Å ", "Ž", "ž", "<", ">"}
101function DB.StripForHTTPForum(Name, Stop)
102 if !Name then return "N/A"; end
103
104 Name = tmysql.escape(Name);
105 //DB.ConnectToNormalMySQLForum()
106 //Name = mysql.escape(ForumDatabase, Name);
107 //mysql.disconnect(ForumDatabase)
108
109 local charSize = #GoodChars
110 Name = Name:gsub(".", function(a)
111 local found
112 for i=1, charSize do
113 if GoodChars[i] == a then
114 found = true
115 break
116 end
117 end
118 if !found then
119 return "?"
120 end
121 end)
122
123 return Name
124end
125
126function DB.StripForHTTP(Name, Stop)
127 if !Name then return "NA" end
128
129 Name = tmysql.escape(Name);
130
131 local charSize = #GoodChars
132 Name = Name:gsub(".", function(a)
133 local found
134 for i=1, charSize do
135 if GoodChars[i] == a then
136 found = true
137 break
138 end
139 end
140 if !found then
141 return "?"
142 end
143 end)
144
145 return Name
146end
147
148
149function DB.QueryValue(query, callback)
150 local function cBack(r)
151 if !r or !r[1].data or !r[1].data[1] then
152 callback(nil, !r[1].error)
153 return
154 end
155 local ind = next(r[1].data[1])
156 callback(r[1].data[1][ind], !r[1].error)
157 end
158 GameDatabase:Query(query, callback and cBack)
159
160end
161
162local function StopMySQLTimeOuts()
163 //DB.MySQLQueryForum("SET wait_timeout = 99999")
164 //DB.MySQLQuery("SET wait_timeout = 99999")
165end
166// total bs... connections timing out faster then 30 secs
167//local function IncreaseTimeOut() /*timer.Simple(1, function () */ timer.Create("MySQLTimeOutStop", 118, 0, StopMySQLTimeOuts); DB.ConnectToNormalMySQLForum(); DB.ConnectToNormalMySQL(); /* end)*/ end
168local lastConnectionRetry = 0
169function DB.ConnectToMySQL(host, username, password, database_name, database_port, reconnect)
170 //local e, Status
171 //Status, GameDatabase, e = pcall(tmysql.initialize, host, username, password, database_name, database_port)
172 DB.Log("tMySQL: [IF (DB)] Disconnecting old database")
173 OLD_DB__ = GameDatabase
174 GameDatabase = nil
175 //if GameDatabase then GameDatabase:Disconnect() end
176
177 DB.Log("tMySQL: Making a new connection")
178 GameDatabase, DB_ERROR = tmysql.initialize(host, username, password, database_name, database_port)
179
180 DB.Log("tMySQL: Connected [probably].")
181 /*if Status then
182 DB.Log("tMySQL: Connection to external database "..host.." succeeded!")
183 print("tMySQL connected sucessfully.")
184 else
185 DB.Log("Can't connect to MySQL using tMySQL! "..e)
186 print("Can't connect to MySQL using tMySQL!", e)
187 end*/
188 //CONNECTED_TO_MYSQLOO = Status
189 //if !reconnect then
190 // DB.Init()
191 //end
192end
193
194
195/*---------------------------------------------------------
196 Database initialize
197 ---------------------------------------------------------*/
198function DB.Init()
199 /*
200 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_cvars(var char(20) NOT NULL, value INTEGER NOT NULL, PRIMARY KEY(var));")
201 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_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));")
202 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_salaries(steam char(20) NOT NULL, salary INTEGER NOT NULL, PRIMARY KEY(steam));")
203 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_wallets(steam char(20) NOT NULL, amount INTEGER NOT NULL, donation_benefits TEXT(128) NOT NULL, PRIMARY KEY(steam));")
204 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_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));")
205 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_rpnames(steam char(20) NOT NULL, name char(35) NOT NULL, PRIMARY KEY(steam));")
206 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_zspawns(map char(30) NOT NULL, x NUMERIC NOT NULL, y NUMERIC NOT NULL, z NUMERIC NOT NULL);")
207 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_disableddoors(map char(30) NOT NULL, idx char(50) NOT NULL, title char(25) NOT NULL, PRIMARY KEY(map, idx));")
208 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_groupdoors(map char(30) NOT NULL, idx char(50) NOT NULL, teams char(50) NOT NULL, title char(25) NOT NULL, PRIMARY KEY(map, idx));")
209 DB.Query("CREATE TABLE IF NOT EXISTS metrorp_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);")
210 */
211
212 DB.CreateJailPos()
213 DB.CreateSpawnPos()
214 DB.CreateZombiePos()
215 DB.SetUpNonOwnableDoors()
216 DB.SetUpGroupOwnableDoors()
217 DB.LoadConsoles()
218
219 DB.Query("SELECT * FROM metrorp_cvars;", function(settings)
220 if settings then
221 for k,v in pairs(settings) do
222 RunConsoleCommand(v.var, v.value)
223 end
224 end
225 end)
226
227 -- Set the lastused of all jailpositions to 0 because the server just started
228 DB.Query("UPDATE metrorp_jailpositions SET lastused = 0;")
229
230 DB.JailPos = {}
231 DB.Query("SELECT * FROM metrorp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
232
233 DB.TeamSpawns = {}
234 DB.Query("SELECT * FROM metrorp_tspawns;", function(data) DB.TeamSpawns = data or {} end)
235
236 /*if CONNECTED_TO_MYSQLOO then -- In a listen server, the connection with the external database is often made AFTER the listen server host has joined,
237 --so he walks around with the settings from the SQLite database
238 for k,v in pairs(player.GetAll()) do
239 local SteamID = sql.SQLStr(v:SteamID())
240 DB.Query([[SELECT amount, salary, name, admin, mayor, cp, tool, phys, prop FROM metrorp_wallets
241 LEFT OUTER JOIN metrorp_salaries ON metrorp_wallets.steam = metrorp_salaries.steam
242 LEFT OUTER JOIN metrorp_rpnames ON metrorp_wallets.steam = metrorp_rpnames.steam
243 WHERE metrorp_wallets.steam = ]].. SteamID ..[[
244 ;]], function(data)
245 local Data = data[1]
246 if Data.name then
247 v:SetMetroRPVar("rpname", Data.name)
248 end
249 if Data.salary then
250 v:SetMetroRPVar("salary", Data.salary)
251 end
252 if Data.amount then
253 v:SetMetroRPVar("money", Data.amount)
254 end
255 end)
256 end
257 end*/
258end
259
260/*---------------------------------------------------------
261 positions
262 ---------------------------------------------------------*/
263function DB.CreateSpawnPos()
264 local map = string.lower(game.GetMap())
265 if not team_spawn_positions then return end
266
267 for k, v in pairs(team_spawn_positions) do
268 if v[1] == map then
269 DB.StoreTeamSpawnPos(v[2], Vector(v[3], v[4], v[5]))
270 end
271 end
272end
273
274function DB.CreateZombiePos()
275 if not zombie_spawn_positions then return end
276 local map = string.lower(game.GetMap())
277
278 local once = false
279
280 for k, v in pairs(zombie_spawn_positions) do
281 if map == string.lower(v[1]) then
282 if not once then
283 DB.Query("DELETE FROM metrorp_zspawns;")
284 once = true
285 end
286 DB.Query("INSERT INTO metrorp_zspawns VALUES(" .. sql.SQLStr(map) .. ", " .. v[2] .. ", " .. v[3] .. ", " .. v[4] .. ");")
287 end
288 end
289
290end
291
292function DB.StoreZombies()
293 local map = string.lower(game.GetMap())
294
295 DB.Query("DELETE FROM metrorp_zspawns WHERE map = " .. sql.SQLStr(map) .. ";", function()
296 for k, v in pairs(zombieSpawns) do
297 local s = string.Explode(" ", v)
298 DB.Query("INSERT INTO metrorp_zspawns VALUES(" .. sql.SQLStr(map) .. ", " .. s[1] .. ", " .. s[2] .. ", " .. s[3] .. ");")
299 end
300 end)
301
302end
303
304local FirstZombieSpawn = true
305function DB.RetrieveZombies(callback)
306 if zombieSpawns and table.Count(zombieSpawns) > 0 and not FirstZombieSpawn then callback() return zombieSpawns end
307 FirstZombieSpawn = false
308 zombieSpawns = {}
309 DB.Query("SELECT * FROM metrorp_zspawns WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";", function(r)
310 if not r then callback() return end
311 for map, row in pairs(r) do
312 zombieSpawns[map] = tostring(Vector(row.x, row.y, row.z))
313 end
314 callback()
315 end)
316end
317
318local function IsEmpty(vector)
319 local point = util.PointContents(vector)
320 local a = point ~= CONTENTS_SOLID
321 and point ~= CONTENTS_MOVEABLE
322 and point ~= CONTENTS_LADDER
323 and point ~= CONTENTS_PLAYERCLIP
324 and point ~= CONTENTS_MONSTERCLIP
325 local b = true
326
327 for k,v in pairs(ents.FindInSphere(vector, 35)) do
328 if v:IsNPC() or v:IsPlayer() or v:GetClass() == "prop_physics" then
329 b = false
330 end
331 end
332 return a and b
333end
334
335function DB.RetrieveRandomZombieSpawnPos()
336 if #zombieSpawns < 1 then return end
337 local r = string.Explode(" ", table.Random(zombieSpawns))
338 r = Vector(r[1], r[2], r[3])
339 if not IsEmpty(Vector(r.x, r.y, r.z)) then
340 local found = false
341 for i = 40, 200, 10 do
342 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(i, 0, 0)) then
343 found = true
344 return Vector(r.x, r.y, r.z) + Vector(i, 0, 0)
345 end
346 end
347
348 if not found then
349 for i = 40, 200, 10 do
350 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(0, i, 0)) then
351 found = true
352 return Vector(r.x, r.y, r.z) + Vector(0, i, 0)
353 end
354 end
355 end
356
357 if not found then
358 for i = 40, 200, 10 do
359 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(-i, 0, 0)) then
360 found = true
361 return Vector(r.x, r.y, r.z) + Vector(-i, 0, 0)
362 end
363 end
364 end
365
366 if not found then
367 for i = 40, 200, 10 do
368 if IsEmpty(Vector(r.x, r.y, r.z) + Vector(0, -i, 0)) then
369 found = true
370 return Vector(r.x, r.y, r.z) + Vector(0, -i, 0)
371 end
372 end
373 end
374 else
375 return Vector(r.x, r.y, r.z)
376 end
377
378 return Vector(r.x, r.y, r.z) + Vector(0,0,70)
379end
380
381function DB.CreateJailPos()
382 if not jail_positions then return end
383 local map = string.lower(game.GetMap())
384
385 local once = false
386
387 for k, v in pairs(jail_positions) do
388 if map == string.lower(v[1]) then
389 if not once then
390 DB.Query("DELETE FROM metrorp_jailpositions;", function()
391 DB.Query("INSERT INTO metrorp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. v[2] .. ", " .. v[3] .. ", " .. v[4] .. ", " .. 0 .. ");")
392 end)
393 DB.JailPos = {}
394 once = true
395 return
396 end
397 DB.Query("INSERT INTO metrorp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. v[2] .. ", " .. v[3] .. ", " .. v[4] .. ", " .. 0 .. ");")
398 end
399 end
400
401end
402
403function DB.StoreJailPos(ply, addingPos)
404 local map = string.lower(game.GetMap())
405 local pos = string.Explode(" ", tostring(ply:GetPos()))
406 DB.QueryValue("SELECT COUNT(*) FROM metrorp_jailpositions WHERE map = " .. sql.SQLStr(map) .. ";", function(already)
407 if not already or already == 0 then
408 DB.Query("INSERT INTO metrorp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ", " .. 0 .. ");", function()
409 DB.Query("SELECT * FROM metrorp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
410 end)
411 Notify(ply, 1, 4, LANGUAGE.created_first_jailpos)
412 else
413 if addingPos then
414 DB.Query("INSERT INTO metrorp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ", " .. 0 .. ");", function()
415 DB.Query("SELECT * FROM metrorp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
416 end)
417 Notify(ply, 1, 4, LANGUAGE.added_jailpos)
418 else
419
420 DB.Query("DELETE FROM metrorp_jailpositions WHERE map = " .. sql.SQLStr(map) .. ";")
421 DB.Query("INSERT INTO metrorp_jailpositions VALUES(" .. sql.SQLStr(map) .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ", " .. 0 .. ");", function()
422 DB.Query("SELECT * FROM metrorp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
423 end)
424
425 Notify(ply, 1, 5, LANGUAGE.reset_add_jailpos)
426 end
427 end
428 end)
429end
430
431function DB.RetrieveJailPos()
432 local map = string.lower(game.GetMap())
433 local r = DB.JailPos
434 if not r then return Vector(0,0,0) end
435
436 -- Retrieve the least recently used jail position
437 local now = CurTime()
438 local oldest = 0
439 local ret
440
441 for k, row in pairs(r) do
442 if row.map == map and (now - tonumber(row.lastused)) > oldest then
443 oldest = (now - tonumber(row.lastused))
444 ret = row
445 elseif row.map == map and oldest == 0 then
446 ret = row
447 end
448 end
449 -- Mark that position as having been used just now
450 if ret then DB.Query("UPDATE metrorp_jailpositions SET lastused = " .. CurTime() .. " WHERE map = " .. sql.SQLStr(map) .. " AND x = " .. ret.x .. " AND y = " .. ret.y .. " AND z = " .. ret.z .. ";", function()
451 DB.Query("SELECT * FROM metrorp_jailpositions;", function(jailpos) DB.JailPos = jailpos end)
452 end) end
453 return ret and Vector(ret.x, ret.y, ret.z)
454end
455
456function DB.SaveSetting(setting, value)
457 DB.Query("SELECT value FROM metrorp_cvars WHERE var = "..sql.SQLStr(setting)..";", function(Data)
458 if Data then
459 DB.Query("UPDATE metrorp_cvars set Value = " .. sql.SQLStr(value) .." WHERE var = " .. sql.SQLStr(setting)..";")
460 else
461 DB.Query("INSERT INTO metrorp_cvars VALUES("..sql.SQLStr(setting)..","..sql.SQLStr(value)..");")
462 end
463 end)
464end
465
466function DB.CountJailPos()
467 return table.Count(DB.JailPos or {})
468end
469
470local function FixDarkRPTspawnsTable() -- SQLite only
471 local FixTable = sql.Query("SELECT * FROM metrorp_tspawns;")
472 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
473 sql.Query("DROP TABLE IF EXISTS metrorp_tspawns;") -- remove the table and remake it
474 sql.Query("CREATE TABLE IF NOT EXISTS metrorp_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));")
475 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
476 sql.Query("INSERT INTO metrorp_tspawns VALUES(NULL, "..sql.SQLStr(v.map)..", "..v.team..", "..v.x..", "..v.y..", "..v.z..");")
477 end
478 end
479end
480
481function DB.StoreTeamSpawnPos(t, pos)
482 if not CONNECTED_TO_MYSQLOO then FixDarkRPTspawnsTable() end -- Check if the server doesn't use an out of date version of this table
483 local map = string.lower(game.GetMap())
484 DB.QueryValue("SELECT COUNT(*) FROM metrorp_tspawns WHERE team = " .. t .. " AND map = " .. sql.SQLStr(map) .. ";", function(already)
485 already = tonumber(already)
486 local ID = 0
487 local found = false
488 for k,v in SortedPairs(DB.TeamSpawns or {}) do
489 if tonumber(v.id) == ID + 1 then
490 ID = tonumber(v.id)
491 found = true
492 else
493 ID = ID + 1
494 found = false
495 break
496 end
497 end
498 if found or ID == 0 then ID = ID + 1 end
499
500 if not already or already == 0 then
501 DB.Query("INSERT INTO metrorp_tspawns VALUES(".. ID .. ", ".. sql.SQLStr(map) .. ", " .. t .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ");", function()
502 DB.Query("SELECT * FROM metrorp_tspawns;", function(data) DB.TeamSpawns = data or {} end) end)
503 print(string.format(LANGUAGE.created_spawnpos, team.GetName(t)))
504 else
505 DB.RemoveTeamSpawnPos(t, function() -- remove everything and create new
506 DB.Query("INSERT INTO metrorp_tspawns VALUES(".. ID .. ", ".. sql.SQLStr(map) .. ", " .. t .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ");", function()
507 DB.Query("SELECT * FROM metrorp_tspawns;", function(data) DB.TeamSpawns = data or {} end) end)
508 end)
509 print(string.format(LANGUAGE.updated_spawnpos, team.GetName(t)))
510 end
511 end)
512end
513
514function DB.AddTeamSpawnPos(t, pos)
515 if not CONNECTED_TO_MYSQLOO then FixDarkRPTspawnsTable() end--Check if the server doesn't use an out of date version of this table
516 local map = string.lower(game.GetMap())
517 local ID = 0
518 local found = false
519 for k,v in SortedPairs(DB.TeamSpawns or {}) do
520 if tonumber(v.id) == ID + 1 then
521 ID = tonumber(v.id)
522 found = true
523 else
524 ID = ID + 1
525 found = false
526 break
527 end
528 end
529 if found or ID == 0 then ID = ID + 1 end
530
531 DB.Query("INSERT INTO metrorp_tspawns VALUES(".. ID .. ", " .. sql.SQLStr(map) .. ", " .. t .. ", " .. pos[1] .. ", " .. pos[2] .. ", " .. pos[3] .. ");", function()
532 DB.Query("SELECT * FROM metrorp_tspawns;", function(data) DB.TeamSpawns = data or {} end) end)
533end
534
535function DB.RemoveTeamSpawnPos(t, callback)
536 local map = string.lower(game.GetMap())
537 DB.Query("DELETE FROM metrorp_tspawns WHERE team = "..t..";", function()
538 DB.Query("SELECT * FROM metrorp_tspawns;", function(data) DB.TeamSpawns = data or {} end)
539 if callback then callback() end
540 end)
541end
542
543function DB.RetrieveTeamSpawnPos(ply)
544 local map = string.lower(game.GetMap())
545 local t = ply:Team()
546
547 local returnal = {}
548
549 if DB.TeamSpawns then
550 for k,v in pairs(DB.TeamSpawns) do
551 if v.map == map and tonumber(v.team) == t then
552 table.insert(returnal, Vector(v.x, v.y, v.z))
553 end
554 end
555 return (table.Count(returnal) > 0 and returnal) or nil
556 end
557end
558
559/*---------------------------------------------------------
560Players
561 ---------------------------------------------------------*/
562
563function DB.StoreRPName(ply, name)
564 //if not name or string.len(name) < 2 then return end
565 ply:SetMetroRPVar("rpname", name)
566 DB.Query("UPDATE metrorp_wallets SET rpname = " .. sql.SQLStr(name) .. " WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";")
567end
568
569//local rpnameslist --Make sure the DB doesn't get checked for ALL RPnames when someone InitialSpawns
570function DB.RetrieveRPNames(Name, callback)
571 /*if rpnameslist then
572 return callback(rpnameslist)
573 end*/
574 DB.QueryValue("SELECT `rpname` FROM `metrorp_wallets` WHERE `rpname`='"..Name.."';", callback)
575
576end
577
578function DB.RetrieveRPName(ply, callback)
579 /*for k,v in pairs(rpnameslist or {}) do
580 if v.steam == ply:SteamID() then return callback(v.rpname) end -- First check the cache for RP names
581 end*/
582 DB.QueryValue("SELECT rpname FROM metrorp_wallets WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";", callback)
583end
584
585function DB.StoreMoney(ply, amount)
586 if not IsValid(ply) then return end
587 if amount < 0 then return end
588 ply:SetMetroRPVar("money", math.floor(amount))
589
590 local steamID = ply:SteamID()
591 DB.QueryValue("SELECT amount FROM metrorp_wallets WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(r)
592 if r then
593 DB.Query("UPDATE metrorp_wallets SET amount = " .. math.floor(amount) .. " WHERE steam = " .. sql.SQLStr(steamID) .. ";")
594 else
595 DB.Query("INSERT INTO metrorp_wallets (`steam`, `amount`, `donation_benefits`, `playerdata`) VALUES(" .. sql.SQLStr(steamID) .. ", " .. math.floor(amount) .. ", 'GOLD.false;VIP.false', '');")
596 end
597 end)
598end
599
600function DB.RetrieveMoney(ply) -- This is only run once when the player joins, there's no need for a cache unless the player keeps rejoining.
601 if not IsValid(ply) then return 0 end
602 local steamID = ply:SteamID()
603
604 DB.QueryValue("SELECT amount FROM metrorp_wallets WHERE steam = " .. sql.SQLStr(ply:SteamID()) .. ";", function(r)
605 if !ply:IsValid() then return end
606 if r then
607 ply:SetMetroRPVar("money", math.floor(r))
608 else
609 -- No record yet, setting starting cash to 500
610 DB.StoreMoney(ply, GetConVarNumber("startingmoney") or 500)
611 end
612 end)
613end
614
615function DB.ResetAllMoney(ply,cmd,args)
616 if not ply:IsSuperAdmin() then return end
617 DB.Query("DELETE FROM metrorp_wallets;")
618 for k,v in pairs(player.GetAll()) do
619 v:SetMetroRPVar("money", GetConVarNumber("startingmoney") or 500)
620 end
621 if ply:IsPlayer() then
622 NotifyAll(1,4, string.format(LANGUAGE.reset_money, ply:Nick()))
623 else
624 NotifyAll(1,4, string.format(LANGUAGE.reset_money, "Console"))
625 end
626end
627//concommand.Add("rp_resetallmoney", DB.ResetAllMoney)
628
629function DB.PayPlayer(ply1, ply2, amount)
630 if not IsValid(ply1) or not IsValid(ply2) then return end
631 ply1:AddMoney(-amount)
632 ply2:AddMoney(amount)
633end
634
635function DB.StoreSalary(ply, amount)
636 //local steamID = ply:SteamID()
637 amount = math.floor(amount)
638
639 ply.MetroRPVars.salary = amount
640 net.Start("MetroRP_PlayerVar")
641 net.WriteEntity(ply)
642 net.WriteString("salary")
643 net.WriteType(amount)
644 net.Send(ply)
645
646 //ply:SetMetroRPVar("salary", math.floor(amount))
647 /*DB.QueryValue("SELECT COUNT(*) FROM metrorp_salaries WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(already)
648 if not already or already == 0 then
649 DB.Query("INSERT INTO metrorp_salaries VALUES(" .. sql.SQLStr(steamID) .. ", " .. math.floor(amount) .. ");")
650 else
651 DB.Query("UPDATE metrorp_salaries SET salary = " .. math.floor(amount) .. " WHERE steam = " .. sql.SQLStr(steamID) .. ";")
652 end
653 end)*/
654
655 return amount
656end
657
658function DB.RetrieveSalary(ply, callback)
659 if not IsValid(ply) then return 0 end
660 local steamID = ply:SteamID()
661 local normal = GetConVarNumber("normalsalary")
662
663 if ply.MetroRPVars.salary then return callback and callback(ply.MetroRPVars.salary) end -- First check the cache.
664
665 DB.QueryValue("SELECT salary FROM metrorp_salaries WHERE steam = " .. sql.SQLStr(steamID) .. ";", function(r)
666 if not r then
667 ply:SetMetroRPVar("salary", normal)
668 callback(normal)
669 else
670 callback(r)
671 end
672 end)
673end
674
675/*---------------------------------------------------------
676 Doors
677 ---------------------------------------------------------*/
678function DB.StoreDoorOwnability(ent)
679 local map = string.lower(game.GetMap())
680 ent.DoorData = ent.DoorData or {}
681 local nonOwnable = ent.DoorData.NonOwnable
682
683 local entStr = ent:GetPos()
684 entStr = sql.SQLStr(table.concat({entStr.x, entStr.y, entStr.Z}, ";"))
685
686 DB.QueryValue("SELECT COUNT(*) FROM metrorp_disableddoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. entStr .. ";", function(r)
687 r = tonumber(r)
688 if not r then return end
689
690 if r > 0 and not nonOwnable then
691 DB.Query("DELETE FROM metrorp_disableddoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. entStr .. ";")
692 elseif r == 0 and nonOwnable then
693 DB.Query("INSERT INTO metrorp_disableddoors VALUES(" .. sql.SQLStr(map) .. ", " .. entStr .. ", " .. sql.SQLStr("Non-Ownable Door") .. ");")
694 end
695 end)
696end
697
698function DB.StoreNonOwnableDoorTitle(ent, text)
699 ent.DoorData = ent.DoorData or {}
700 ent.DoorData.title = text
701
702 local entStr = ent:GetPos()
703 entStr = sql.SQLStr(table.concat({entStr.x, entStr.y, entStr.Z}, ";"))
704
705 DB.Query("UPDATE metrorp_disableddoors SET title = " .. sql.SQLStr(text) .. " WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. " AND idx = " .. entStr .. ";")
706end
707
708function DB.SetUpNonOwnableDoors()
709 DB.Query("SELECT idx, title FROM metrorp_disableddoors WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";", function(r)
710 if !r then return end
711
712
713 local tbl = ents.GetAll()
714 for _, row in pairs(r) do
715 local e
716 for i=1, #tbl do
717 if tbl[i]:IsValid() then
718 local entStr = tbl[i]:GetPos()
719 entStr = table.concat({entStr.x, entStr.y, entStr.Z}, ";")
720 if entStr == row.idx then
721 e = tbl[i]
722 end
723 end
724 end
725 if IsValid(e) then
726 e.DoorData = e.DoorData or {}
727 e.DoorData.NonOwnable = true
728 e.DoorData.title = row.title
729 end
730 end
731
732 end)
733end
734
735
736function DB.StoreGroupDoorOwnability(ent)
737 local map = string.lower(game.GetMap())
738 ent.DoorData = ent.DoorData or {}
739
740 local entStr = ent:GetPos()
741 entStr = sql.SQLStr(table.concat({entStr.x, entStr.y, entStr.Z}, ";"))
742
743 DB.QueryValue("SELECT COUNT(*) FROM metrorp_groupdoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. entStr .. ";", function(r)
744 r = tonumber(r)
745 if not r then return end
746
747 if r > 0 and not ent.DoorData.GroupOwn then
748 DB.Query("DELETE FROM metrorp_groupdoors WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. entStr .. ";")
749 elseif r == 0 and ent.DoorData.GroupOwn then
750 DB.Query("INSERT INTO metrorp_groupdoors VALUES(" .. sql.SQLStr(map) .. ", " .. entStr .. ", " .. sql.SQLStr(ent.DoorData.GroupOwn) .. ", " .. sql.SQLStr(ent.DoorData.title or "") .. ");")
751 elseif r == 1 then
752 DB.Query("UPDATE metrorp_groupdoors SET teams = "..sql.SQLStr(ent.DoorData.GroupOwn) .. " WHERE map = " .. sql.SQLStr(map) .. " AND idx = " .. entStr .. ";")
753 end
754 end)
755end
756
757function DB.StoreGroupOwnableDoorTitle(ent, text)
758 local entStr = ent:GetPos()
759 entStr = sql.SQLStr(table.concat({entStr.x, entStr.y, entStr.Z}, ";"))
760
761 DB.Query("UPDATE metrorp_groupdoors SET title = " .. sql.SQLStr(text) .. " WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. " AND idx = " .. entStr .. ";")
762 e.DoorData = e.DoorData or {}
763 ent.DoorData.title = text
764end
765
766function DB.SetUpGroupOwnableDoors()
767 DB.Query("SELECT idx, title, teams FROM metrorp_groupdoors WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";", function(r)
768 if !r then return end
769
770
771 local tbl = ents.GetAll()
772 for _, row in pairs(r) do
773 local e
774 for i=1, #tbl do
775 if tbl[i]:IsValid() then
776 local entStr = tbl[i]:GetPos()
777 entStr = table.concat({entStr.x, entStr.y, entStr.Z}, ";")
778 if entStr == row.idx then
779 e = tbl[i]
780 end
781 end
782 end
783 if IsValid(e) then
784 e.DoorData = e.DoorData or {}
785 e.DoorData.title = row.title
786 e.DoorData.GroupOwn = row.teams
787 end
788 end
789
790 end)
791end
792
793function DB.LoadConsoles()
794 local map = string.lower(game.GetMap())
795 DB.Query("SELECT * FROM metrorp_consolespawns WHERE map = " .. sql.SQLStr(map) .. ";", function(data)
796 if data then
797 for k, v in pairs(data) do
798 local console = ents.Create("metrorp_console")
799 console:SetPos(Vector(tonumber(v.x), tonumber(v.y), tonumber(v.z)))
800 console:SetAngles(Angle(tonumber(v.pitch), tonumber(v.yaw), tonumber(v.roll)))
801 console:Spawn()
802 console.ID = v.id
803 end
804 else--If there are no custom positions in the database, use the presets.
805 for k,v in pairs(RP_ConsolePositions) do
806 if v[1] == map then
807 local console = ents.Create("metrorp_console")
808 console:SetPos(Vector(RP_ConsolePositions[k][2], RP_ConsolePositions[k][3], RP_ConsolePositions[k][4]))
809 console:SetAngles(Angle(RP_ConsolePositions[k][5], RP_ConsolePositions[k][6], RP_ConsolePositions[k][7]))
810 console:Spawn()
811 console:Activate()
812
813 console.ID = "0"
814 end
815 end
816 end
817 end)
818end
819
820function DB.CreateConsole(ply, cmd, args)
821 if not ply:IsSuperAdmin() then return end
822
823 local tr = {}
824 tr.start = ply:EyePos()
825 tr.endpos = ply:EyePos() + 95 * ply:GetAimVector()
826 tr.filter = ply
827 local trace = util.TraceLine(tr)
828
829 local console = ents.Create("metrorp_console")
830 console:SetPos(trace.HitPos)
831 console:Spawn()
832 console:Activate()
833
834 DB.QueryValue("SELECT MAX(id) FROM metrorp_consolespawns;", function(Data)
835 console.ID = (tonumber(Data) and tostring(tonumber(Data) + 1)) or "1"
836 end)
837
838 ply:ChatPrint("Console spawned, move and freeze it to save it!")
839end
840concommand.Add("rp_CreateConsole", DB.CreateConsole)
841
842function DB.RemoveConsoles(ply, cmd, args)
843 if not ply:IsSuperAdmin() then return end
844 DB.Query("DELETE FROM metrorp_consolespawns WHERE map = " .. sql.SQLStr(string.lower(game.GetMap())) .. ";")
845end
846concommand.Add("rp_removeallconsoles", DB.RemoveConsoles)
847
848/*---------------------------------------------------------
849 Logging - recoded by TOMASAS, it's now about 181% faster then it used to be (Fixed by Casavant for Linux)
850 ---------------------------------------------------------*/
851local os, file, concat = os, file, table.concat
852//if (not util.tobool(GetConVarNumber("logging")) or not text) and not force then return end
853if !file.IsDir("harborrp_logs", "DATA") then
854 file.CreateDir("harborrp_logs")
855end
856if !file.IsDir("harborrp_logs2", "DATA") then
857 file.CreateDir("harborrp_logs2")
858end
859if !File then
860 File = "harborrp_logs/"..os.date("%m_%d_%Y %I_%M %p")..".txt"
861 File = file.Open(File, "w", "DATA")
862 File:Write(concat({os.date(), "\t", "Server Logging Started"}, ""))
863end
864function DB.Log(text, force)
865 File:Skip(File:Size())
866 File:Write(concat({"\n", os.date(), "\t", text or ""}, ""))
867 File:Flush()
868end