· 9 years ago · Nov 19, 2016, 08:12 PM
1local DB_HOST = "db1.eu.serenityservers.net"
2local DB_USERNAME = "db2413"
3local DB_PASSWORD = "O55j0wODp0"
4local DB_DATABASE = "db2413"
5local SERVER_ID = "sandbox"
6
7local CHAT_CMD_ENABLE = true
8local CHAT_CMD_COMMANDS = {"!donate", "/donate", "!d", "!vip"}
9local CHAT_CMD_URL = "http://thekillzone.net/donate/index.php?page=packages&game=gmod&server=sandbox"
10
11---------------------------------------------------------------
12-- Leave everything bellow, unless you know what you're doing -
13---------------------------------------------------------------
14
15DonationSystem = { }
16local DS = DonationSystem
17
18---- Logs -----------------------------------------------------
19
20DS.Logs = { }
21
22local function addlog( str )
23 DS.Logs[ #DS.Logs + 1 ] = { os.date( ), str }
24 Msg( "[DonationSystem] " .. tostring( str ) .. "\n" )
25 file.Append( "donationsystem_logs.txt", os.date( ) .. "\t" .. str .. "\n" )
26end
27addlog( "Initiating DonationSystem v4.6" )
28
29---- Chat Commands --------------------------------------------
30
31local function donateCommand( pl, text, teamonly )
32 if table.HasValue( CHAT_CMD_COMMANDS, text ) then
33 pl:SendLua([[gui.OpenURL("]] .. CHAT_CMD_URL .. [[")]])
34 return ""
35 end
36end
37if CHAT_CMD_ENABLE then
38 hook.Add( "PlayerSay", "DonationSystemChat", donateCommand )
39end
40
41---- Console Commands -----------------------------------------------
42
43local function consolePrint( ply, msg )
44 if IsValid(ply) then
45 ply:PrintMessage(HUD_PRINTCONSOLE, msg )
46 else
47 print(msg)
48 end
49end
50
51concommand.Add( "ds_printlogs",function( ply, cmd, args, str )
52 if IsValid( ply ) and not ply:IsSuperAdmin() then return end
53 consolePrint( ply, "DonationSystem Logs:" )
54 for i=1, #DS.Logs do
55 consolePrint( ply, table.concat( DS.Logs[ i ], "\t" ) )
56 end
57end )
58
59concommand.Add( "ds_debuginfo",function( ply, cmd, args, str )
60 if IsValid( ply ) and not ply:IsSuperAdmin() then return end
61 consolePrint( ply, "DonationSystem Debug Info:" )
62 consolePrint( ply, "HOSTNAME: (".. #DB_HOST.. ")\t" .. DB_HOST )
63 consolePrint( ply, "USERNAME: (".. #DB_USERNAME.. ")\t" .. DB_USERNAME )
64 consolePrint( ply, "PASSWORD: (".. #DB_PASSWORD.. ")\t" .. string.rep("*",#DB_PASSWORD) )
65 consolePrint( ply, "DATABASE: (".. #DB_DATABASE.. ")\t" .. DB_DATABASE)
66 consolePrint( ply, "SERVER_ID: (".. #SERVER_ID.. ")\t" .. SERVER_ID )
67 consolePrint( ply, "MySQLOO:\t" .. (mysqloo and "LOADED" or "NOT LOADED") )
68
69end )
70
71concommand.Add( "ds_status", function( ply, cmd, args, str )
72 if IsValid( ply ) and not ply:IsSuperAdmin() then return end
73 consolePrint( ply, "Database Status: " .. DS.Database:status( ) )
74end )
75
76---- MySQLOO --------------------------------------------------
77local succ, err = pcall(require, "mysqloo" )
78if succ then
79 addlog( "Successfully loaded MySQLOO module!" )
80else
81 addlog( "Failed to load MySQLOO module: " .. err )
82 return nil
83end
84
85DS.Database = mysqloo.connect( DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE, 3306 )
86local db = DS.Database
87local queue = {}
88local function query( sql, callback )
89 local q = db:query( sql )
90 if not q then
91 table.insert( queue, { sql, callback } )
92 db:connect( )
93 return
94 end
95 function q:onSuccess( data )
96 if type( callback ) == "function" then
97 callback( data, q )
98 end
99 end
100 function q:onError( err )
101 if db:status() == mysqloo.DATABASE_NOT_CONNECTED then
102 table.insert( queue, { sql, callback } )
103 db:connect( )
104 return
105 else
106 DS.DatabaseCheck( )
107 addlog( "Query Error: " .. err .. " sql: " .. sql )
108 end
109 end
110 q:start()
111end
112
113function db:onConnected( )
114 addlog( "Connected to database" )
115 DS.DatabaseCheck( )
116 for k, v in pairs( queue ) do
117 query( v[ 1 ], v[ 2 ] )
118 end
119 queue = {}
120end
121
122function db:onConnectionFailed( err )
123 addlog( "Connection to database failed! Error: " .. err )
124end
125
126db:connect( )
127
128function DS.DatabaseCheck( )
129 query( [[
130 CREATE TABLE IF NOT EXISTS `commands` (
131 id MEDIUMINT NOT NULL AUTO_INCREMENT,
132 serverid varchar(40) NOT NULL,
133 packageid int(6) unsigned NOT NULL,
134 online TINYINT(1) UNSIGNED NOT NULL,
135 commandid int(6) unsigned NOT NULL,
136 delay INT UNSIGNED NOT NULL,
137 activatetime INT UNSIGNED NOT NULL,
138 command TEXT NOT NULL,
139 activated TINYINT(1) UNSIGNED NOT NULL,
140 transactionid varchar(125) NOT NULL,
141 playerid varchar(40) NOT NULL,
142 playername varchar(40) NOT NULL,
143 PRIMARY KEY (id))
144 ]] )
145end
146
147---- Commands -------------------------------------------------
148
149util.AddNetworkString( "DonationSystemColorChat" )
150util.AddNetworkString( "DonationSystemConCommand" )
151
152hook.Add( "PlayerInitialSpawn", "DonationSystemPlayerJoinSendLua", function(ply)
153 ply:SendLua( [[
154 net.Receive( "DonationSystemColorChat", function( len ) chat.AddText( unpack( net.ReadTable() ) ) end )
155 net.Receive( "DonationSystemCmd", function( len ) RunConsoleCommand( unpack( net.ReadTable() ) ) end )
156 ]] )
157end)
158
159DS.Commands = {
160 [ "gforum_smf_usergroup" ] = function( data, args, ply )
161 if Forum == nil then
162 error( "gForum is not installed" )
163 end
164 local steamid = data.playerid
165 local gid = args[1]
166 if tonumber( gid ) == nil then
167 error( "Invalid first argument. Got " .. type(gid) .. ", expected number.")
168 return nil
169 end
170 if Forum == "smf" then
171 local query1 = database:query("SELECT `id` FROM " .. Prefix .. "_link WHERE `steamid`='" .. steamid .. "'")
172 query1.onError = function( err, sql )
173 addlog( "Error executing gforum_smf_usergroup command.\nQuery1 errored!\nQuery:" .. sql .. "\nError: " .. err )
174 end
175 query1.onSuccess = function( query, data )
176 local id = query:getData()[1]['id'] or nil
177 if id then
178 local query2 = database:query("SELECT `id_member`, `member_name`, `id_group`, `personal_text` FROM " .. Prefix .. "_members WHERE `id_member`='" .. id .. "'")
179 query2.onError = function( err, sql )
180 addlog( "Error executing gforum_smf_usergroup command.\nQuery2 errored!\nQuery:" .. sql .. "\nError: " .. err )
181 end
182 query2.onSuccess = function( _query )
183 local Args1 = _query:getData()[1] or nil
184 if Args1['id_member'] then
185 database:query("UPDATE " .. Prefix .. "_members SET `id_group`='" .. gid .."' WHERE `id_member`='" ..Args1['id_member'] .. "'")
186 end
187 end
188 query2:start()
189 else
190 ServerLog("[gForum] Tried to set rank on unlinked user.")
191 addlog("[gForum] Tried to set rank on unlinked user.")
192 end
193 end
194 query1:start()
195 else
196 error( "Forum is not smf" )
197 end
198 end,
199 [ "darkrp_money" ] = function( data, args, ply )
200 if not IsValid( ply ) then
201 error( "Player is not valid" )
202 end
203 local succ, err = pcall( function( )
204 local PLAYER = FindMetaTable( "Player" )
205 if type( PLAYER.AddMoney ) == "function" then
206 ply:AddMoney( tonumber( args[ 1 ] ) )
207 elseif type( PLAYER.addMoney ) == "function" then
208 ply:addMoney( tonumber( args[ 1 ] ) )
209 else
210 error( "No functions were found" )
211 end
212 end )
213 if not succ then
214 error( err )
215 end
216 end,
217 [ "pointshop_points" ] = function( data, args, ply )
218 if not IsValid( ply ) then
219 error( "Player is not valid" )
220 end
221 local succ, err = pcall( function() ply:PS_GivePoints( tonumber( args[ 1 ] ) ) end )
222 if not succ then
223 error( err )
224 end
225 end,
226 ["print"] = function( data, args, ply )
227 if not IsValid( ply ) then
228 error( "Player is not valid" )
229 end
230 if type( args ) == "table" then
231 for i=1, #args do
232 if type( args[ i ] ) == "table" then
233 args[ i ] = Color( args[ i ][ 1 ], args[ i ][ 2 ], args[ i ][ 3 ] )
234 elseif type( args[ i ] ) == "string" then
235 args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) )
236 args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) )
237 args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) )
238 args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) )
239 args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Name( ) ) )
240 args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( ply:SteamID( ) ) )
241 args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) )
242 args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( ply:UniqueID( ) ) )
243 args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) )
244 end
245 end
246 net.Start( "DonationSystemColorChat" )
247 net.WriteTable( args )
248 net.Send( ply )
249 end
250 end,
251 [ "broadcast" ] = function( data, args, ply )
252 if type( args ) == "table" then
253 for i=1, #args do
254 if type( args[ i ] ) == "table" then
255 args[ i ] = Color( args[ i ][ 1 ], args[ i ][ 2 ], args[ i ][ 3 ] )
256 elseif type( args[ i ] ) == "string" then
257 args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) )
258 args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) )
259 args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) )
260 args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) )
261 args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) )
262 args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) )
263 if IsValid( ply ) then
264 args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) )
265 args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Nick( ) ) )
266 args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) )
267 end
268 end
269 end
270 net.Start( "DonationSystemColorChat" )
271 net.WriteTable( args )
272 net.Broadcast( )
273 end
274 end,
275 [ "broadcast_omit" ] = function( data, args, ply )
276 if type( args ) == "table" then
277 for i=1, #args do
278 if type( args[ i ] ) == "table" then
279 args[ i ] = Color( args[ i ][ 1 ], args[ i ][ 2 ], args[ i ][ 3 ] )
280 elseif type( args[ i ] ) == "string" then
281 args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) )
282 args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) )
283 args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) )
284 args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) )
285 args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) )
286 args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) )
287 if IsValid( ply ) then
288 args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) )
289 args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Nick( ) ) )
290 args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) )
291 end
292 end
293 end
294 net.Start( "DonationSystemColorChat" )
295 net.WriteTable( args )
296
297 if IsValid(ply) then
298 net.SendOmit( ply )
299 else
300 net.Broadcast( )
301 end
302 end
303 end,
304 [ "lua" ] = function( data, args, ply )
305 local oldPLAYER, oldSTEAMID, oldORDERDATA, oldQUERY = PLAYER, STEAMID, ORDERDATA, QUERY
306 PLAYER, STEAMID, ORDERDATA, QUERY = ply, data.playerid, data, query
307
308 local func = CompileString( args[ 1 ], "[DonationSystem] Lua", true )
309 if type(func) == "function" then
310 func()
311 else
312 PLAYER, STEAMID, ORDERDATA, QUERY = oldPLAYER, oldSTEAMID, oldORDERDATA, oldQUERY
313 error(func)
314 end
315
316 PLAYER, STEAMID, ORDERDATA, QUERY = oldPLAYER, oldSTEAMID, oldORDERDATA, oldQUERY
317 end,
318 [ "sv_cmd" ] = function( data, args, ply )
319 for i=1, #args do
320 args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) )
321 args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) )
322 args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) )
323 args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) )
324 args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) )
325 args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) )
326 if IsValid( ply ) then
327 args[i] = string.Replace( args[i], "%steamid64%", tostring( ply:SteamID64( ) ) )
328 args[i] = string.Replace( args[i], "%gamename%", tostring( ply:Nick( ) ) )
329 args[i] = string.Replace( args[i], "%userid%", tostring( ply:UserID( ) ) )
330 end
331 end
332 RunConsoleCommand( unpack( args ) )
333 end,
334 [ "disabled" ] = function( data, args, ply ) end,
335 [ "cl_cmd" ] = function( data, args, ply )
336 if not IsValid( ply ) then
337 error( "Player is not valid" )
338 end
339 for i=1, #args do
340 args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) )
341 args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) )
342 args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) )
343 args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) )
344 args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) )
345 args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) )
346
347 args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) )
348 args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Nick( ) ) )
349 args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) )
350 end
351 net.Start( "DonationSystemCmd" )
352 net.WriteTable( args )
353 net.Send( ply )
354 end,
355 [ "sql" ] = function( data, args, ply )
356 local querystring = args.query or args[ 1 ]
357 querystring = string.Replace( querystring, "%name%", tostring( data.playername ) )
358 querystring = string.Replace( querystring, "%orderid%", tostring( data.id ) )
359 querystring = string.Replace( querystring, "%transactionid%", tostring( data.transactionid ) )
360 querystring = string.Replace( querystring, "%packageid%", tostring( data.packageid ) )
361 querystring = string.Replace( querystring, "%steamid%", tostring( data.playerid ) )
362 querystring = string.Replace( querystring, "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) )
363 querystring = string.Replace( querystring, "%name_esc%", db:escape( tostring( data.playername ) ) )
364 querystring = string.Replace( querystring, "%ostime%", tostring( os.time( ) ) )
365
366 if IsValid( ply ) then
367 querystring = string.Replace( querystring, "%steamid64%", tostring( ply:SteamID64( ) ) )
368 querystring = string.Replace( querystring, "%gamename%", tostring( ply:Nick( ) ) )
369 querystring = string.Replace( querystring, "%gamename_esc%", db:escape( tostring( ply:Name( ) ) ) )
370 querystring = string.Replace( querystring, "%userid%", tostring( ply:UserID( ) ) )
371 end
372
373 query( querystring )
374 end,
375 [ "sql_ext" ] = function( data, args,ply )
376 local querystring = args.query
377 querystring = string.Replace( querystring, "%name%", tostring( data.playername ) )
378 querystring = string.Replace( querystring, "%orderid%", tostring( data.id ) )
379 querystring = string.Replace( querystring, "%transactionid%", tostring( data.transactionid ) )
380 querystring = string.Replace( querystring, "%packageid%", tostring( data.packageid ) )
381 querystring = string.Replace( querystring, "%steamid%", tostring( data.playerid ) )
382 querystring = string.Replace( querystring, "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) )
383 querystring = string.Replace( querystring, "%name_esc%", db:escape( tostring( data.playername ) ) )
384 querystring = string.Replace( querystring, "%ostime%", tostring( os.time( ) ) )
385
386 if IsValid(ply) then
387 querystring = string.Replace( querystring, "%steamid64%", tostring(ply:SteamID64()) )
388 querystring = string.Replace( querystring, "%gamename%", tostring(ply:Nick()) )
389 querystring = string.Replace( querystring, "%gamename_esc%", db:escape(tostring(ply:Name())) )
390 querystring = string.Replace( querystring, "%userid%", tostring(ply:UserID()) )
391 end
392
393 local db = mysqloo.connect( args.host, args.database, args.username, args.password, 3306 )
394
395 function db:onConnected( )
396 local q = self:query( querystring )
397 function q:onSuccess( data ) end
398 function q:onError( err, sql )
399 addlog( "Error executing 'sql_ext' command, error: " .. err .. " sql: " .. sql )
400 end
401 q:start( )
402 end
403 function db:onConnectionFailed( err )
404 addlog( "Error executing 'sql_ext' command, error: ", err )
405 end
406
407 db:connect( )
408 end,
409 [ "cancel" ] = function( data, args, ply )
410 local excludeself, serverid, packageid, online, delay, commandid
411
412 if type(args[1]) == "table" then
413 excludeself = args[1].excludeself
414 serverid = args[1].serverid
415 packageid = args[1].packageid
416 online = args[1].online
417 delay = args[1].delay
418 commandid = args[1].commandid
419 else
420 excludeself = args[ 1 ]
421 serverid = args[ 2 ]
422 packageid = args[ 3 ]
423 online = args[ 4 ]
424 delay = args[ 5 ]
425 commandid = args[ 6 ]
426 end
427
428 local querystr = "UPDATE commands SET activated = 1 WHERE playerid = \"" .. db:escape( data.playerid ) .. "\""
429 if excludeself then querystr = querystr .. " AND transactionid <> \"" .. db:escape( data.transactionid ) .. "\"" end
430 if serverid then querystr = querystr .. " AND serverid = \"" .. db:escape( serverid ) .. "\""end
431 if packageid then querystr = querystr .. " AND packageid = \"" .. db:escape( packageid ) .. "\"" end
432 if online then querystr = querystr .. " AND online = \"" .. ( online and 1 or 0 ) .. "\"" end
433 if delay then querystr = querystr .. " AND delay = \"" .. db:escape( delay ) .. "\"" end
434 if commandid then querystr = querystr .. " AND commandid = \"" .. db:escape( commandid ) .. "\"" end
435 query( querystr )
436 end
437}
438
439---- Main Timer -----------------------------------------------
440
441local activated = {}
442timer.Create( "DonationSystemCheck", 60, 0, function( ) -- Check database every 60 seconds
443 -- Store players to table, and add players conditions to sql query.
444 local plyEnts = { }
445 local sqlplayers = ""
446 for _, ply in pairs( player.GetAll( ) ) do
447 if (Forum != "smf" and ply:TimeConnected( ) > 60) or (Forum == "smf" and ply.Registered) then -- Making sure player is fully initialised
448 plyEnts[ ply:SteamID( ) ] = ply
449 sqlplayers = sqlplayers .. " OR playerid = \"" .. db:escape( ply:SteamID( ) ) .. "\""
450 end
451 end
452
453 -- Get all commands that should be activated in next 60 seconds
454 query("SELECT *, ( UNIX_TIMESTAMP() ) AS unixtime FROM `commands` WHERE serverid = \"" .. db:escape( SERVER_ID ) .. "\" AND activated = 0 AND activatetime <= (UNIX_TIMESTAMP()+59) AND ( online = 0 " .. sqlplayers .. ")", function( commands ) -- " AND delay <= 76561198000622892 - 279"
455 for _, cmddata in pairs( commands ) do
456 -- Delay the command
457 local timeoffset = math.max( 1, cmddata.activatetime - cmddata.unixtime )
458
459 timer.Simple( timeoffset, function( )
460 if cmddata.online == 0 or IsValid( plyEnts[ cmddata.playerid ] ) then -- Check if player still on the server
461 query("UPDATE `commands` SET activated='1' WHERE id=" .. cmddata.id, function( data, q ) -- Activate it
462 if q:affectedRows( ) > 0 and not activated[ cmddata.id ] then -- Making sure the command is not activated before to prevent duplicate execution
463 if cmddata.online == 0 or IsValid( plyEnts[ cmddata.playerid ] ) then
464 activated[ cmddata.id ] = true
465 local args = util.JSONToTable( cmddata.command )
466 local command = table.remove( args, 1 )
467
468 addlog( "Executing " .. ( cmddata.online == 1 and "online" or "offline" ) .. " command '" .. command .. "'(" .. cmddata.id .. ") for " .. cmddata.playername .. "(" .. cmddata.playerid .. ")\nCommand Data:" .. cmddata.command)
469
470 local succ, err = pcall( function( ) DS.Commands[ command ]( cmddata, args, plyEnts[ cmddata.playerid ] ) end )
471 if not succ then
472 addlog( "Error while executing command '" .. command .. "'(" .. cmddata.id .. "). Error: " .. err )
473 end
474
475 else
476 query("UPDATE `commands` SET activated='0' WHERE id=" .. cmddata.id) -- If player disconnect, we might want to deactivate the command
477 end
478 else
479 addlog( "Error executing command (" .. cmddata.id .. "). Failed to mark command as activated. " .. tostring( IsValid( plyEnts[ cmddata.playerid ] ) ) )
480 end
481 end )
482 end
483 end )
484 end
485 end )
486end )