local DB_HOST = "" local DB_USERNAME = "" local DB_PASSWORD = "" local DB_DATABASE = "" local SERVER_ID = "darkrp" ------------------------------------------------------------- -- Leave everything bellow ---------------------------------- ------------------------------------------------------------- DonationSystem = { } ---- Logs --------------------------------------------------- DonationSystem.Logs = { } local function addlog( str ) DonationSystem.Logs[ #DonationSystem.Logs + 1 ] = { os.date( ), str } ServerLog( "[DonationSystem] " .. tostring( str ) .. "\n" ) end concommand.Add( "ds_printlogs",function( ply, cmd, args, str ) if IsValid( ply ) then return end print( "DonationSystem Logs:" ) for i=1, #DonationSystem.Logs do print( unpack( DonationSystem.Logs[ i ] ) ) end end ) ---- MySQLOO ------------------------------------------------ require( "mysqloo" ) if not mysqloo then addlog( "No mysqloo module was found" ) return nil end DonationSystem.Database = mysqloo.connect( DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE, 3306 ) local db = DonationSystem.Database local queue = {} local function query( sql, callback ) local q = db:query( sql ) if not q then table.insert( queue, { sql, callback } ) db:connect( ) return end function q:onSuccess( data ) if type( callback ) == "function" then callback( data, q ) end end function q:onError( err ) if db:status() == mysqloo.DATABASE_NOT_CONNECTED then table.insert( queue, { sql, callback } ) db:connect( ) return else DonationSystem.DatabaseCheck( ) addlog( "Query Error: " .. err .. " sql: " .. sql ) end end q:start() end function db:onConnected( ) addlog( "Connected to database" ) DonationSystem.DatabaseCheck( ) for k, v in pairs( queue ) do query( v[ 1 ], v[ 2 ] ) end queue = {} end function db:onConnectionFailed( err ) addlog( "Connection to database failed! Error: " .. err ) end db:connect( ) function DonationSystem.DatabaseCheck( ) query( [[ CREATE TABLE IF NOT EXISTS `commands` ( id MEDIUMINT NOT NULL AUTO_INCREMENT, serverid varchar(40) NOT NULL, packageid int(6) unsigned NOT NULL, online TINYINT(1) UNSIGNED NOT NULL, commandid int(6) unsigned NOT NULL, delay INT UNSIGNED NOT NULL, activatetime INT UNSIGNED NOT NULL, command TEXT NOT NULL, activated TINYINT(1) UNSIGNED NOT NULL, transactionid varchar(125) NOT NULL, playerid varchar(40) NOT NULL, playername varchar(40) NOT NULL, PRIMARY KEY (id)) ]] ) end concommand.Add( "ds_status", function( ply, cmd, args, str ) addlog( db:status( ) ) end ) ---- Commands ----------------------------------------------- util.AddNetworkString( "DonationSystemColorChat" ) util.AddNetworkString( "DonationSystemConCommand" ) hook.Add( "PlayerInitialSpawn", "DonationSystemPlayerJoinSendLua", function(ply) ply:SendLua( [[ net.Receive( "DonationSystemColorChat", function( len ) chat.AddText( unpack( net.ReadTable() ) ) end ) ]] ) ply:SendLua( [[ net.Receive( "DonationSystemCmd", function( len ) RunConsoleCommand( unpack( net.ReadTable() ) ) end ) ]] ) end) DonationSystem.Commands = { [ "darkrp_money" ] = function( data, args, ply ) if not IsValid( ply ) then addlog( "Error executing darkrp_money command, Error: player is not valid" ) return nil end local succ, err = pcall( function( ) local PLAYER = FindMetaTable( "Player" ) if type( PLAYER.AddMoney ) == "function" then ply:AddMoney( tonumber( args[ 1 ] ) ) elseif type( PLAYER.addMoney ) == "function" then ply:addMoney( tonumber( args[ 1 ] ) ) else addlog( "Error executing darkrp_money command, Error: No functions were found" ) end end ) if not succ then addlog( "Error executing darkrp_money command, Error: " .. err ) end end, [ "pointshop_points" ] = function( data, args, ply ) if not IsValid( ply ) then addlog( "Error executing pointshop_points command, Error: player is not valid" ) return nil end local succ, err = pcall( function() ply:PS_GivePoints( tonumber( args[ 1 ] ) ) end ) if not succ then addlog( "Error executing pointshop_points command, Error: " .. err ) end end, ["print"] = function( data, args, ply ) if not IsValid( ply ) then addlog( "Error executing print command, Error: player is not valid" ) return nil end if type( args ) == "table" then for i=1, #args do if type( args[ i ] ) == "table" then args[ i ] = Color( args[ i ][ 1 ], args[ i ][ 2 ], args[ i ][ 3 ] ) elseif type( args[ i ] ) == "string" then args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) ) args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) ) args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) ) args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) ) args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Name( ) ) ) args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( ply:SteamID( ) ) ) args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) ) args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( ply:UniqueID( ) ) ) args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) ) end end net.Start( "DonationSystemColorChat" ) net.WriteTable( args ) net.Send( ply ) end end, [ "broadcast" ] = function( data, args, ply ) if type( args ) == "table" then for i=1, #args do if type( args[ i ] ) == "table" then args[ i ] = Color( args[ i ][ 1 ], args[ i ][ 3 ], args[ i ][ 5 ] ) elseif type( args[ i ] ) == "string" then args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) ) args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) ) args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) ) args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) ) args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) ) args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) ) if IsValid( ply ) then args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) ) args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Nick( ) ) ) args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) ) end end end net.Start( "DonationSystemColorChat" ) net.WriteTable( args ) net.Broadcast( ) end end, [ "broadcast_omit" ] = function( data, args, ply ) if type( args ) == "table" then for i=1, #args do if type( args[ i ] ) == "table" then args[ i ] = Color( args[ i ][ 1 ], args[ i ][ 3 ], args[ i ][ 5 ] ) elseif type( args[ i ] ) == "string" then args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) ) args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) ) args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) ) args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) ) args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) ) args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) ) if IsValid( ply ) then args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) ) args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Nick( ) ) ) args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) ) end end end net.Start( "DonationSystemColorChat" ) net.WriteTable( args ) if IsValid(ply) then net.SendOmit( ply ) else net.Broadcast( ) end end end, [ "lua" ] = function( data, args, ply ) local oldPLAYER = PLAYER local oldSTEAMID = STEAMID local oldORDERDATA = ORDERDATA local oldQUERY = QUERY PLAYER = ply STEAMID = data.playerid ORDERDATA = data QUERY = query RunStringEx( args[ 1 ], "[DonationSystem] Lua: " ) PLAYER = oldPLAYER STEAMID = oldSTEAMID ORDERDATA = oldORDERDATA QUERY = oldQUERY end, [ "sv_cmd" ] = function( data, args, ply ) for i=1, #args do args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) ) args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) ) args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) ) args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) ) args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) ) args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) ) if IsValid( ply ) then args[i] = string.Replace( args[i], "%steamid64%", tostring( ply:SteamID64( ) ) ) args[i] = string.Replace( args[i], "%gamename%", tostring( ply:Nick( ) ) ) args[i] = string.Replace( args[i], "%userid%", tostring( ply:UserID( ) ) ) end end RunConsoleCommand( unpack( args ) ) end, [ "disabled" ] = function( data, args, ply ) end, [ "cl_cmd" ] = function( data, args, ply ) if not IsValid( ply ) then addlog( "Error executing cl_cmd command, Error: player is not valid" ) return nil end for i=1, #args do args[ i ] = string.Replace( args[ i ], "%name%", tostring( data.playername ) ) args[ i ] = string.Replace( args[ i ], "%orderid%", tostring( data.id ) ) args[ i ] = string.Replace( args[ i ], "%transactionid%", tostring( data.transactionid ) ) args[ i ] = string.Replace( args[ i ], "%packageid%", tostring( data.packageid ) ) args[ i ] = string.Replace( args[ i ], "%steamid%", tostring( data.playerid ) ) args[ i ] = string.Replace( args[ i ], "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) ) args[ i ] = string.Replace( args[ i ], "%steamid64%", tostring( ply:SteamID64( ) ) ) args[ i ] = string.Replace( args[ i ], "%gamename%", tostring( ply:Nick( ) ) ) args[ i ] = string.Replace( args[ i ], "%userid%", tostring( ply:UserID( ) ) ) end net.Start( "DonationSystemCmd" ) net.WriteTable( args ) net.Send( ply ) end, [ "sql" ] = function( data, args, ply ) local querystring = args.query or args[ 1 ] querystring = string.Replace( querystring, "%name%", tostring( data.playername ) ) querystring = string.Replace( querystring, "%orderid%", tostring( data.id ) ) querystring = string.Replace( querystring, "%transactionid%", tostring( data.transactionid ) ) querystring = string.Replace( querystring, "%packageid%", tostring( data.packageid ) ) querystring = string.Replace( querystring, "%steamid%", tostring( data.playerid ) ) querystring = string.Replace( querystring, "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) ) querystring = string.Replace( querystring, "%name_esc%", db:escape( tostring( data.playername ) ) ) querystring = string.Replace( querystring, "%ostime%", tostring( os.time( ) ) ) if IsValid( ply ) then querystring = string.Replace( querystring, "%steamid64%", tostring( ply:SteamID64( ) ) ) querystring = string.Replace( querystring, "%gamename%", tostring( ply:Nick( ) ) ) querystring = string.Replace( querystring, "%gamename_esc%", db:escape( tostring( ply:Name( ) ) ) ) querystring = string.Replace( querystring, "%userid%", tostring( ply:UserID( ) ) ) end query( querystring ) end, [ "sql_ext" ] = function( data, args,ply ) local querystring = args.query querystring = string.Replace( querystring, "%name%", tostring( data.playername ) ) querystring = string.Replace( querystring, "%orderid%", tostring( data.id ) ) querystring = string.Replace( querystring, "%transactionid%", tostring( data.transactionid ) ) querystring = string.Replace( querystring, "%packageid%", tostring( data.packageid ) ) querystring = string.Replace( querystring, "%steamid%", tostring( data.playerid ) ) querystring = string.Replace( querystring, "%uniqueid%", tostring( util.CRC( "gm_" .. data.playerid .. "_gm" ) ) ) querystring = string.Replace( querystring, "%name_esc%", db:escape( tostring( data.playername ) ) ) querystring = string.Replace( querystring, "%ostime%", tostring( os.time( ) ) ) if IsValid(ply) then querystring = string.Replace( querystring, "%steamid64%", tostring(ply:SteamID64()) ) querystring = string.Replace( querystring, "%gamename%", tostring(ply:Nick()) ) querystring = string.Replace( querystring, "%gamename_esc%", db:escape(tostring(ply:Name())) ) querystring = string.Replace( querystring, "%userid%", tostring(ply:UserID()) ) end local db = mysqloo.connect( args.host, args.database, args.username, args.password, 3306 ) function db:onConnected( ) local q = self:query( querystring ) function q:onSuccess( data ) end function q:onError( err, sql ) addlog( "Error executing 'sql_ext' command, error: " .. err .. " sql: " .. sql ) end q:start( ) end function db:onConnectionFailed( err ) addlog( "Error executing 'sql_ext' command, error: ", err ) end db:connect( ) end, [ "cancel" ] = function( data, args, ply ) local excludeself = args.excludeself or args[ 1 ] local serverid = args.serverid or args[ 2 ] local packageid = args.packageid or args[ 3 ] local online = args.online or args[ 4 ] local delay = args.delay or args[ 5 ] local commandid = args.commandid or args[ 6 ] if #args > 6 then addlog( "Error executing 'cancel' command, Error: Arguments can't exceed 6" ) elseif #args >= 2 and type(excludeself) ~= "boolean" then addlog( "Error executing 'cancel' command, Error: Invalid 'excludeself' argument(1). Expected boolean, got " .. type( excludeself ) .. ": " .. excludeself ) elseif type( serverid ) ~= "string" then addlog( "Error executing 'cancel' command, Error: Invalid 'serverid' argument(2). Expected string, got " .. type( serverid ) .. ": " .. serverid ) elseif #args >= 3 and tonumber( packageid ) == nil then addlog( "Error executing 'cancel' command, Error: Invalid 'packageid' argument(3). Expected number, got " .. type( packageid ) .. ": " .. packageid ) elseif #args >= 4 and type( online ) ~= "boolean" then addlog( "Error executing 'cancel' command, Error: Invalid 'online' argument(4). Expected boolean, got " .. type( online ) .. ": " .. online ) elseif #args >= 5 and tonumber( delay ) == nil then addlog( "Error executing 'cancel' command, Error: Invalid 'delay' argument(5). Expected number, got " .. type( delay ) .. ": " .. delay ) elseif #args >= 6 and tonumber( commandid ) == nil then addlog( "Error executing 'cancel' command, Error: Invalid 'commandid' argument(6). Expected number, got " .. type( commandid ) .. ": " .. commandid ) else -- All arguments are validated local querystr = "UPDATE commands SET activated = 1 WHERE playerid = \"" .. db:escape( data.playerid ) .. "\"" if #args>=1 and excludeself then querystr = querystr .. " AND transactionid <> \"" .. db:escape( data.transactionid ) .. "\"" end if #args>=2 then querystr = querystr .. " AND serverid = \"" .. db:escape( serverid ) .. "\""end if #args>=3 then querystr = querystr .. " AND packageid = \"" .. db:escape( packageid ) .. "\"" end if #args>=4 then querystr = querystr .. " AND online = \"" .. ( online and 1 or 0 ) .. "\"" end if #args>=5 then querystr = querystr .. " AND delay = \"" .. db:escape( delay ) .. "\"" end if #args>=6 then querystr = querystr .. " AND commandid = \"" .. db:escape( commandid ) .. "\"" end query( querystr ) end end } ---- Main Timer --------------------------------------------- local activated = {} timer.Create( "DonationSystemCheck", 60, 0, function( ) -- Check database every 60 seconds -- Store players to table, and add players conditions to query. local plyEnts = { } local sqlplayers = "" for _, ply in pairs( player.GetAll( ) ) do if ply:TimeConnected( ) > 60 then -- Making sure player is fully initialised plyEnts[ ply:SteamID( ) ] = ply sqlplayers = sqlplayers .. " OR playerid = \"" .. db:escape( ply:SteamID( ) ) .. "\"" end end -- Get all commands that should be activated in next 60 seconds 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 ) for _, cmddata in pairs( commands ) do -- Delay the command local timeoffset = math.max( 1, cmddata.activatetime - cmddata.unixtime ) timer.Simple( timeoffset, function( ) query("UPDATE `commands` SET activated='1' WHERE id=" .. cmddata.id, function( data, q ) -- Activate it if q:affectedRows( ) > 0 and not activated[ cmddata.id ] and ( cmddata.online == 0 or IsValid( plyEnts[ cmddata.playerid ] ) ) then -- Making sure the command is not activated before to prevent duplicate execution activated[ cmddata.id ] = true local args = util.JSONToTable( cmddata.command ) local command = table.remove( args, 1 ) local succ, err = pcall( function( ) DonationSystem.Commands[ command ]( cmddata, args, plyEnts[ cmddata.playerid ] ) end ) if not succ then addlog( "Error executing command '" .. command .. "'(" .. cmddata.id .. "). Error: " .. err ) end addlog( "Activated command '" .. command .. "' for " .. cmddata.playername .. "(" .. cmddata.playerid .. ")(cmdid = " .. cmddata.id .. ")") else addlog( "Error executing command (" .. cmddata.id .. "). Conditions failed. " .. tostring( IsValid( plyEnts[ cmddata.playerid ] ) ) ) end end ) end ) end end ) end )