Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- https://github.com/danielga/gmod_luasocket/releases
- ad = ad or {}
- local id_seller = "»-- идентификатор продавца
- local password = "" --пароль
- local auth = {
- Host = "db1.myarena.ru", --здес укажи адрес бд
- Port = 3306, --здес укажи порт бд
- Username = "", --здес укажи имя пользователя бд
- Password = "", --здес укажи пароль пользователя бд
- Database = "vvbnnn_donatefust" --от"
- тово что мы в итемсторе поселимся ниче плохово не будет таблицы то разные
- }
- local sql = {}
- sql.Connected = false
- sql.Queries = {}
- file.CreateDir("autodonate")
- local function log(text, silent)
- text = text.."\n"
- if !silent then Msg("[autodonate] "..text) end
- file.Append(os.date("autodonate/%d-%m-%y.txt"), os.date("[%c] ")..text)
- end
- function sql:Log( text )
- print( "[autodonate MySQL] " .. text )
- end
- function sql:Initialize()
- require( "mysqloo" )
- sql.Database = mysqloo.connect( auth.Host, auth.Username, auth.Password, auth.Database, auth.Port )
- sql.Database.onConnected = function( )
- self.Connected = true
- self:Query( "CREATE TABLE IF NOT EXISTS ad_pdata ( infoid VARCHAR( 32 ) NOT NULL, value BLOB NULL, PRIMARY KEY ( infoid ) );" )
- --for _, v in ipairs( sql.Queries ) do
- while ( #sql.Queries > 0 ) do
- local query = table.remove( sql.Queries, 1 )
- self:Query( query[ 1 ], query[ 2 ], unpack( query[ 3 ] ) )
- end
- self:Log( "Connection succesful!" )
- end
- sql.Database.onConnectionFailed = function( db, err )
- sql:Log( "Connection failed: " .. err )
- self.Connected = false
- timer.Simple( 10, function()
- db:connect()
- end )
- end
- self:Log( "Connecting to database..." )
- sql.Database:connect()
- end
- function sql:Query( sql, callback, ... )
- if ( self.Database and self.Connected ) then
- local args = {}
- for _, val in ipairs( { ... } ) do
- val = tostring( val )
- val = self.Database:escape( val )
- table.insert( args, val )
- end
- local formatted = string.format( sql, unpack( args ) )
- local query = self.Database:query( formatted )
- query.onSuccess = function( _, data )
- if ( callback ) then
- callback( data )
- end
- end
- query.onError = function( _, err )
- if ( self.Database:status() == mysqloo.DATABASE_NOT_CONNECTED ) then
- table.insert( self.Queries, { formatted, callback, {} } )
- self.Database:connect()
- self.Connected = false
- self:Log( "Lost connection to server, reconnecting..." )
- else
- self:Log( "Query failed: " .. err )
- end
- end
- query:start()
- else
- self:Log( "Query attempted while disconnected." )
- table.insert( self.Queries, { sql, callback, { ... } } )
- end
- end
- function sql:GetPData(steamid, callback)
- if !isstring(steamid) then steamid = steamid:SteamID64() end
- self:Query( "SELECT value FROM ad_pdata WHERE infoid = '%s' LIMIT 1", callback, steamid )
- end
- local function retryRemove(steamid)
- sql:GetPData(steamid, function(a)
- if a or a[1] or a[1].value then
- log("БД не удалила значение, пробуем ещё раз через пол секунды", true)
- timer.Simple(0.5, function()
- sql:RemovePData(steamid)
- retryRemove(steamid)
- end)
- end
- end)
- end
- function sql:RemovePData( steamid )
- if !isstring(steamid) then steamid = steamid:SteamID64() end
- self:Query( "DELETE FROM ad_pdata WHERE infoid = '%s'", nil, steamid )
- timer.Simple(0.1, function() retryRemove(steamid) end)
- end
- local function retrySet(steamid, value)
- sql:GetPData(steamid, function(a)
- if !a or !a[1] or !a[1].value or a[1].value != value then
- timer.Simple(0.5, function()
- sql:SetPData(steamid, value)
- retrySet(steamid, value)
- end)
- end
- end)
- end
- function sql:SetPData( steamid, value )
- if !isstring(steamid) then steamid = steamid:SteamID64() end
- self:Query( "REPLACE INTO ad_pdata ( infoid, value ) VALUES ( '%s', '%s' )", nil, steamid, value )
- timer.Simple(0.1, function() retrySet(steamid, value) end)
- end
- sql:Initialize()
- ad.sql = sql
- ------------------------------------------------------------
- local md5 = include("ad_md5.lua")
- local red = Color(255, 0, 0)
- local function onError(reason, sid, code)
- reason = "\n============AUTODONATE ERROR============\n "..reason.."\n========================================\n SteamID: "..sid.." || code: "..code.."\n========================================\n\n"
- log(reason, true)
- MsgC(red, reason, color_white)
- end
- local invKeys = (file.Read("autodonate/invkeys.txt") or ""):Split("\n")
- local function processData(statuscode, body, sid, code)
- if statuscode != 200 then return onError("код ответа равен не 200 ("..statuscode..")", sid, code) end
- body = util.JSONToTable(body)
- if !body then return onError("ответ пришел не в JSON формате", sid, code) end
- if body.retval != "0" then return onError("запрос не выполнен!\n код: "..body.retval.."\n описание ошибки: "..body.retdesc, sid, code) end
- if util.SteamIDFrom64(sid) == "STEAM_0:0:0" then return onError("SteamID неверен!", sid, code) end
- body.inv = tostring(body.inv)
- for k in pairs(invKeys) do
- if tostring(k) == body.inv then return log("Ignoring duped inv key "..k) end
- end
- local val = math.floor(tonumber(body.cnt_goods:Replace(",", ".")))
- if !val then return onError("JOPA ERROR CNT_GOODS IS NIL:\n"..util.TableToJSON(body, true), sid, code) end
- log(sid.." byed "..val.."p")
- local ply = player.GetBySteamID64(sid)
- if ply then
- ad.add(ply, val, true)
- else
- log(sid.." is offline, adding "..val.."p to MySQL")
- sql:GetPData(sid, function(a)
- local data = util.JSONToTable(a and a[1] and a[1].value or "{\"balance\":0}")
- data.balance = data.balance+val
- sql:SetPData(sid, util.TableToJSON(data))
- end)
- end
- invKeys[body.inv] = true
- file.Append("autodonate/invkeys.txt", body.inv.."\n")
- log("writed inv key "..body.inv)
- end
- local b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
- function dec(data)
- data = string.gsub(data, '[^'..b..'=]', '')
- return (data:gsub('.', function(x)
- if (x == '=') then return '' end
- local r,f='',(b:find(x)-1)
- for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
- return r;
- end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
- if (#x ~= 8) then return '' end
- local c=0
- for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
- return string.char(c)
- end))
- end
- concommand.Add("ad_go", function(ply, _, req)
- if IsValid(ply) then return ply:Kick("net") end
- req = dec(req[1]):Split("&"..ad.config.param.."=")
- if !req[1] or !req[2] then
- log("wrong request: "..tostring(req[1]).." sid: "..tostring(req[2]))
- return
- end
- local code, sid = req[1], req[2]
- log("sending POST: code: ["..code.."] sid: ["..sid.."]")
- HTTP{
- method = "POST",
- url = "http://shop.digiseller.ru/xml/check_unique_code.asp",
- type = "application/json",
- body = [[{"id_seller":"]]..id_seller..[[","unique_code":"]]..code..[[","sign":"]]..md5.sumhexa(id_seller..":"..code..":"..password)..[["}]],
- failed = function(reason) onError(reason, sid, code) end,
- success = function(status, body) processData(status, body, sid, code) end
- }
- end)
- concommand.Add("ad_retry",function(ply, _, arg)
- if IsValid(ply) then return end
- local code, sid = arg[1], arg[2]
- if !code or !sid then return print("ad_retry wrong arguments") end
- log("sending POST: code: "..code.." sid: "..sid)
- HTTP{
- method = "POST",
- url = "http://shop.digiseller.ru/xml/check_unique_code.asp",
- type = "application/json",
- body = [[{"id_seller":"]]..id_seller..[[","unique_code":"]]..code..[[","sign":"]]..md5.sumhexa(id_seller..":"..code..":"..password)..[["}]],
- failed = function(reason) onError(reason, sid, code) end,
- success = function(status, body) processData(status, body, sid, code) end
- }
- end)
- ------------------------------------------------------
- local sip = "autodonate_error_what"
- timer.Simple(1, function()
- sip = game.GetIPAddress()
- ad.sip = sip
- if sip == "0.0.0.0:27015" then
- http.Fetch("https://api.ipify.org", function(ip)
- sip = ip..":27015"
- ad.sip = sip
- end)
- end
- end)
- util.AddNetworkString("autodonate")
- local function update(ply)
- local tbl = {balance = ply.ad.balance}
- if ply.ad[sip] then
- tbl.group = ply.ad[sip].group
- tbl.group_expires = ply.ad[sip].group_expires
- end
- net.Start("autodonate")
- net.WriteTable(tbl)
- net.WriteString(ply:GetPData("ad_weapons", ""))
- net.WriteBool(false)
- net.Send(ply)
- end
- function ad.save(ply, upd)
- sql:SetPData(ply, util.TableToJSON(ply.ad))
- if upd then update(ply) end
- end
- function ad.set(ply, value)
- ply = isentity(ply) and ply or false
- assert(ply, "игрок не на сервере!")
- log("изменение счёта "..ply:SteamID64()..", было "..ply.ad.balance.."p, стало: "..value, true)
- ply.ad.balance = value
- ad.save(ply, true)
- end
- function ad.add(ply, amount, msg)
- ply = isentity(ply) and ply or false
- assert(ply, "игрок не на сервере!")
- ad.set(ply, ply.ad.balance+amount)
- log(ply:SteamID64().." пополнил счет на "..amount.."р, счет равен "..ply.ad.balance.."p", true)
- if msg then ad.msg(ply, "Вы пополнили счет на "..amount.."р") end
- end
- function ad.msg(ply, msg, err)
- local tbl = {balance = ply.ad.balance}
- if ply.ad[sip] then
- tbl.group = ply.ad[sip].group
- tbl.group_expires = ply.ad[sip].group_expires
- end
- net.Start("autodonate")
- net.WriteTable(tbl)
- net.WriteString(ply:GetPData("ad_weapons", ""))
- net.WriteBool(true)
- net.WriteString(msg)
- net.WriteBool(err)
- net.Send(ply)
- end
- function ad.removeGroup(sid)
- if !isstring(sid) then sid = sid:SteamID64() end
- sql:GetPData(sid, function(a)
- local data = util.JSONToTable(a and a[1] and a[1].value or "{\"balance\":0}")
- data[sip] = nil
- sql:SetPData(sid, util.TableToJSON(data))
- end)
- end
- local function timedGroup(ply, group)
- ulx.adduser(NULL, ply, group)
- ply.ad[sip] = {}
- ply.ad[sip].group = group
- ply.ad[sip].group_expires = os.time()+2591999
- end
- hook.Add("PlayerInitialSpawn", "autodonate", function(ply)
- if !ply:IsBot() then
- sql:GetPData(ply, function(a)
- ply.ad = util.JSONToTable(a and a[1] and a[1].value or "{\"balance\":0}")
- update(ply)
- end)
- end
- end)
- timer.Create("ad.checkGroups", 1, 0, function()
- for _, ply in pairs(player.GetAll()) do
- if !ply:IsBot() and ply.ad and ply.ad[sip] and ply.ad[sip].group:gsub("_inf", "") != ply:GetUserGroup() then
- ply.ad[sip] = nil
- update(ply)
- elseif !ply:IsBot() and ply.ad and ply.ad[sip] and ply.ad[sip].group_expires and ply.ad[sip].group_expires-os.time() <= 0 then
- if ply.ad[sip].group == ply:GetUserGroup() then
- log(ply:SteamID64().." был снят с привелении "..ply.ad[sip].group, true)
- ulx.adduser(NULL, ply, "user")
- ad.msg(ply, "Месяц прошёл - донат группа снята")
- end
- ply.ad[sip] = nil
- if ply.ad.balance == 0 then
- sql:RemovePData(ply)
- else ad.save(ply) end
- update(ply)
- end
- end
- end)
- hook.Add("PostPlayerDeath", "ad_death", function(ply)
- ply.ad_weps = nil
- ply.ad_jmp = nil
- ply.ad_hp = nil
- ply.ad_ar = nil
- end)
- concommand.Add("ad_get", function(ply, _, arg)
- arg = arg[1]
- if table.HasValue(ply:GetPData("ad_weapons", ""):Split(" "), arg) then
- ply.ad_weps = ply.ad_weps or {}
- if arg == "_hp" and !ply.ad_hp then
- ply.ad_hp = true
- ply:SetHealth(250)
- ad.msg(ply, "Вы взяли 250 хп")
- elseif arg == "_ar" and !ply.ad_ar then
- ply.ad_ar = true
- ply:SetArmor(228)
- ad.msg(ply, "Вы взяли 228 брони")
- elseif arg == "_jmp" and !ply.ad_jmp then
- ply.ad_jmp = true
- ply:SetJumpPower(ply:GetJumpPower()*2)
- ad.msg(ply, "Вы активировали двойной прыжок")
- elseif !ply.ad_weps[arg] then
- ply:Give(arg)
- ply.ad_weps[arg] = true
- ad.msg(ply, "Вы взяли "..arg)
- end
- end
- end)
- concommand.Add("ad_buywep", function(ply, _, arg)
- arg = arg[1]
- for _, v in pairs(ad.categories) do
- local try = v[arg]
- if try then
- if ply.ad.balance < try.p then
- log(ply:SteamID64().." попытался наебать донат (PLUS) => Что: "..arg..", Баланс игрока:"..(ply.ad.balance.."p")..", Цена предмета: "..try.p)
- return ply:Kick("siebalsa")
- end
- if os.time()-(ply.ad_lastByed or 0) < 5 then return ad.msg(ply, "Подождите 5 секунд перед покупкой следующего предмета", true) end
- log(ply:SteamID64().." купил(PLUS) "..arg.." за "..try.p.."p", true)
- local err, msg = try.func(ply)
- ad.msg(ply, msg)
- if err then
- ply.ad_lastByed = os.time()
- return
- end
- ad.set(ply, ply.ad.balance-try.p)
- ply.ad_lastByed = os.time()
- end
- end
- end)
- concommand.Add("autodonate_buy", function(ply, _, arg)
- arg = arg[1]
- local try = ad.config.items[arg]
- if !try or ply.ad.balance < try.p or (ply.ad[sip] and ply.ad[sip].group == try) then
- log(ply:SteamID64().." попытался наебать донат => Что: "..arg..", Баланс игрока:"..(ply.ad.balance.."p")..(try and ", Цена предмета: "..try.p or "").." ещё инфа: "..(ply.ad[sip] and ply.ad[sip].group == try and " уже имеет эту привилегию" or "нет") , true)
- return ply:Kick("siebalsa")
- end
- if os.time()-(ply.ad_lastByed or 0) < 5 then return ad.msg(ply, "Подождите 5 секунд перед покупкой следующего предмета", true) end
- log(ply:SteamID64().." купил "..arg.." за "..try.p.."p", true)
- if try.func then
- local err, msg = try.func(ply)
- ad.msg(ply, msg)
- if err then
- ply.ad_lastByed = os.time()
- return
- end
- else
- timedGroup(ply, arg)
- ad.msg(ply, "Вы успешно купили привилегию "..try[1].." за "..try.p.."р")
- end
- ad.set(ply, ply.ad.balance-try.p)
- ply.ad_lastByed = os.time()
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement