Files
wnsrc/lua/sam/player/sv_bans.lua

291 lines
6.5 KiB
Lua
Raw Normal View History

2024-08-04 22:55:00 +03:00
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
if SAM_LOADED then return end
local sam = sam
local SQL = sam.SQL
local DEFAULT_REASON = sam.language.get("default_reason")
local set_cached, get_cached do
local cached_bans = {}
function set_cached(k, v)
cached_bans[k] = v
end
function get_cached(k)
return cached_bans[k]
end
timer.Create("SAM.ClearCachedBans", 60 * 2.5, 0, function()
table.Empty(cached_bans)
end)
end
function sam.format_ban_message(admin_name, admin_steamid, reason, unban_date)
unban_date = unban_date == 0 and "never" or sam.format_length((unban_date - os.time()) / 60)
local message_tbl
if admin_name == "" then
message_tbl = sam.format_message("ban_message", {
S = admin_steamid, S_2 = reason, S_3 = unban_date
})
else
message_tbl = sam.format_message("ban_message_2", {
S = admin_name, S_2 = admin_steamid, S_3 = reason, S_4 = unban_date
})
end
local message = ""
for i = 1, #message_tbl do
local v = message_tbl[i]
if sam.isstring(v) then
message = message .. v
end
end
return message
end
function sam.player.ban(ply, length, reason, admin_steamid)
if sam.type(ply) ~= "Player" or not ply:IsValid() then
error("invalid player")
end
if ply.sam_is_banned then return end
local unban_date
if not sam.isnumber(length) or length <= 0 then
unban_date = 0
else
unban_date = (math.min(length, 31536000) * 60) + os.time()
end
if not sam.isstring(reason) then
reason = DEFAULT_REASON
end
if ply:IsBot() then -- you can't ban bots!
return ply:Kick(reason)
end
if not sam.is_steamid(admin_steamid) then -- 4958fc64d974ee5657060aff5c15da1f4f4c5a3de14720e33e3dfbd4622d384a
admin_steamid = "Console"
end
local steamid = ply:SteamID()
SQL.FQuery([[
INSERT INTO
`sam_bans`(
`steamid`,
`reason`,
`admin`,
`unban_date`
)
VALUES
({1}, {2}, {3}, {4})
]], {steamid, reason, admin_steamid, unban_date})
local admin_name = ""
do
local admin = player.GetBySteamID(admin_steamid)
if admin then
admin_name = admin:Name()
end
end
ply.sam_is_banned = true
set_cached(steamid, nil)
sam.hook_call("SAM.BannedPlayer", ply, unban_date, reason, admin_steamid)
ply:Kick(sam.format_ban_message(admin_name, admin_steamid, reason, unban_date))
end
function sam.player.ban_id(steamid, length, reason, admin_steamid)
sam.is_steamid(steamid, true)
do
local ply = player.GetBySteamID(steamid)
if ply then
return ply:sam_ban(length, reason, admin_steamid)
end
end
local unban_date
if not sam.isnumber(length) or length <= 0 then
unban_date = 0
else
unban_date = (math.min(length, 31536000) * 60) + os.time()
end
if not sam.isstring(reason) then
reason = DEFAULT_REASON
end
local query
if SQL.IsMySQL() then
query = [[
INSERT INTO
`sam_bans`(
`steamid`,
`reason`,
`admin`,
`unban_date`
)
VALUES
({1}, {2}, {3}, {4}) ON DUPLICATE KEY
UPDATE
`reason` = VALUES(`reason`),
`admin` = VALUES(`admin`),
`unban_date` = VALUES(`unban_date`)
]]
else
query = [[
INSERT INTO
`sam_bans`(
`steamid`,
`reason`,
`admin`,
`unban_date`
)
VALUES
({1}, {2}, {3}, {4}) ON CONFLICT(`steamid`) DO
UPDATE SET
`reason` = excluded.`reason`,
`admin` = excluded.`admin`,
`unban_date` = excluded.`unban_date`
]]
end
SQL.FQuery(query, {steamid, reason, admin_steamid, unban_date})
local admin_name = ""
if sam.is_steamid(admin_steamid) then
local admin = player.GetBySteamID(admin_steamid)
if admin then
admin_name = admin:Name()
end
else
admin_steamid = "Console"
end
set_cached(steamid, nil)
sam.hook_call("SAM.BannedSteamID", steamid, unban_date, reason, admin_steamid)
sam.player.kick_id(steamid, sam.format_ban_message(admin_name, admin_steamid, reason, unban_date))
end
function sam.player.unban(steamid, admin)
sam.is_steamid(steamid, true)
if not sam.is_steamid(admin) then
admin = "Console"
end
SQL.FQuery([[
DELETE FROM
`sam_bans`
WHERE
`steamid` = {1}
]], {steamid})
set_cached(steamid, false)
sam.hook_call("SAM.UnbannedSteamID", steamid, admin)
end
local check_for_unban = function(steamid, ban_data, callback)
local to_return = ban_data
local unban_date = tonumber(ban_data.unban_date)
if unban_date ~= 0 and os.time() >= unban_date then
to_return = false
sam.player.unban(steamid)
end
if callback then
callback(to_return, steamid)
else
return to_return
end
end
do
local query_callback = function(data, arguments)
local steamid, callback = arguments[1], arguments[2]
if data then
set_cached(steamid, data)
check_for_unban(steamid, data, callback)
else
set_cached(steamid, false)
callback(false, steamid)
end
end
function sam.player.is_banned(steamid, callback)
sam.is_steamid(steamid, true)
local ban_data = get_cached(steamid)
if ban_data then
check_for_unban(steamid, ban_data, callback)
elseif ban_data == false then
callback(false, steamid)
else
local query = [[
SELECT
`sam_bans`.`steamid`,
`sam_bans`.`reason`,
`sam_bans`.`admin`,
`sam_bans`.`unban_date`,
IFNULL(`sam_players`.`name`, '') AS `admin_name`
FROM
`sam_bans`
LEFT OUTER JOIN
`sam_players`
ON
`sam_bans`.`admin` = `sam_players`.`steamid`
WHERE
`sam_bans`.`steamid` = ]] .. SQL.Escape(steamid)
SQL.Query(query, query_callback, true, {steamid, callback})
end
end
end
do
local steamids = {}
local query_callback = function(ban_data, steamid)
steamids[steamid] = nil
if ban_data then
sam.player.kick_id(steamid, sam.format_ban_message(ban_data.admin_name, ban_data.admin, ban_data.reason, tonumber(ban_data.unban_date)))
end
end
gameevent.Listen("player_connect")
hook.Add("player_connect", "SAM.CheckIfBanned", function(data)
local steamid = data.networkid
if data.bot == 0 and not steamids[steamid] then
steamids[steamid] = true
sam.player.is_banned(steamid, query_callback)
end
end)
hook.Add("CheckPassword", "SAM.CheckIfBanned", function(steamid64)
local steamid = util.SteamIDFrom64(steamid64)
local ban_data = get_cached(steamid)
if not ban_data then return end
ban_data = check_for_unban(steamid, ban_data)
if not ban_data then return end
return false, sam.format_ban_message(ban_data.admin_name, ban_data.admin, ban_data.reason, tonumber(ban_data.unban_date))
end)
end
sam.player.ban_set_cached, sam.player.ban_get_cached = set_cached, get_cached