dobrograd-13-06-2022/garrysmod/addons/util-other/lua/autorun/server/unban.lua

250 lines
9.1 KiB
Lua
Raw Normal View History

2023-11-16 15:01:19 +05:00
local maxFamilyDisplay = 20
local function notifyDiscord(admin, sid, ban, reason)
local permanent = ban.endTime <= 0
local console = not IsValid(admin)
octolib.func.chain({
function(nxt)
octolib.getDBVar(sid, 'family', {}):Then(nxt):Catch(ErrorNoHalt)
end,
function(nxt, family)
local toCheck = { util.SteamIDTo64(sid) }
if not console then toCheck[#toCheck + 1] = admin:SteamID64() end
local familySize = 1
for i, v in ipairs(family) do
if v ~= sid then
toCheck[#toCheck + 1] = util.SteamIDTo64(v)
familySize = familySize + 1
end
if familySize > maxFamilyDisplay then break end -- check only 10 first family members
end
octolib.getSteamData(toCheck, nxt)
end,
function(nxt, response)
local steamData = { -- change data format for convenience
target = response[1],
admin = not console and response[2] or nil,
family = {},
}
for i = (console and 2 or 3), #response do
steamData.family[#steamData.family + 1] = response[i]
end
local embed = {
author = {
name = steamData.admin and steamData.admin.name or 'Console',
icon_url = steamData.admin and steamData.admin.avatar or 'https://cdn.octothorp.team/img/logo/white.png',
url = steamData.admin and ('https://steamcommunity.com/profiles/' .. steamData.admin.steamid64) or 'https://panel.octothorp.team/',
},
title = steamData.target.name,
url = 'https://steamcommunity.com/profiles/' .. steamData.target.steamid64,
description = 'Игроку в ' .. (permanent and 'перманентной ' or '') .. 'блокировке выдан разбан',
thumbnail = { url = steamData.target.avatar },
fields = {
{
name = 'SteamID',
value = steamData.target.steamid,
}, {
name = 'Блокировку выдал',
value = ban.admin,
}, {
name = 'Причина блокировки',
value = ban.reason,
}, {
name = 'Причина снятия блокировки',
value = reason or 'Не указана',
}, {
name = 'Примерное время в блокировке',
value = octolib.time.formatDuration(os.time() - ban.startTime),
},
},
}
if not permanent then
table.insert(embed.fields, 3, {
name = 'Примерный срок блокировки',
value = octolib.time.formatDuration(ban.endTime - ban.startTime),
})
end
for i, member in ipairs(steamData.family) do
embed.fields[#embed.fields + 1] = {
name = 'Связанный аккаунт #' .. i,
value = '[' .. member.name .. '](https://steamcommunity.com/profiles/' .. member.steamid64 .. ')\n' .. member.steamid,
inline = true,
}
end
if #steamData.family == maxFamilyDisplay then
embed.footer = {
text = ('Отображаются только первые %s связанных аккаунтов. Полный список можно посмотреть на https://octothorp.team/admin/octolib-vars'):format(maxFamilyDisplay),
icon_url = 'https://img.icons8.com/color/48/asterisk.png',
}
end
if CFG.webhooks.unban then
octoservices:post('/discord/webhook/' .. CFG.webhooks.unban, {
content = permanent and CFG.adminMention or nil,
embeds = { embed },
}):Catch(function(err)
octolib.msg('Error getting Steam data: %s', err)
end)
end
end,
})
end
local function requestConsent(admin, sid, ban, reason)
octolib.getDBVar(sid, 'family', {}):Then(function(family)
if not IsValid(admin) then return end
netstream.Start(admin, 'dbg-unban.consent', {
target = sid,
admin = ban.admin,
reason = ban.reason,
length = ban.endTime > 0 and (ban.endTime - ban.startTime) or 0,
spent = os.time() - ban.startTime,
family = family,
unbanReason = reason or nil,
})
end)
end
local function requestConsoleConsent(sid, ban, reason)
octolib.func.chain({
function(nxt)
octolib.getDBVar(sid, 'family', {}):Then(nxt):Catch(ErrorNoHalt)
end,
function(nxt, family)
local toCheck = { util.SteamIDTo64(sid) }
local size = 1
for i, v in ipairs(family) do
if v ~= sid then
toCheck[#toCheck + 1] = util.SteamIDTo64(v)
size = size + 1
end
if size > maxFamilyDisplay then break end -- check only 10 first family members
end
octolib.getSteamData(toCheck, nxt)
end,
function(nxt, response)
local steamData = { -- change data format for convenience
target = response[1],
family = {},
}
for i = 2, #response do
steamData.family[#steamData.family + 1] = response[i]
end
octolib.msg('=================================')
octolib.msg('Ты собираешься разбанить игрока, находящегося в блокировке')
octolib.msg('Пожалуйста, проверь всю информацию о нем, чтобы убедиться в отсутствии последствий')
octolib.msg('Ник игрока: %s', steamData.target.name)
octolib.msg('SteamID: %s', steamData.target.steamid)
octolib.msg('Ссылка на профиль: https://steamcommunity.com/profiles/%s', steamData.target.steamid64)
octolib.msg('Блокировку выдавал админ: %s', ban.admin)
if ban.endTime > 0 then
octolib.msg('Примерная длительность блокировки: %s', octolib.time.formatDuration(ban.endTime - ban.startTime))
else
octolib.msg('БЛОКИРОВКА БЕССРОЧНАЯ! Особенно внимательно просмотри связанные аккаунты')
end
octolib.msg('Причина блокировки: %s', ban.reason)
octolib.msg('Причина снятия блокировки: %s', reason)
octolib.msg('Примерное время в блокировке: %s', octolib.time.formatDuration(os.time() - ban.startTime))
if steamData.family[1] then
octolib.msg('Связанные аккаунты:')
for _, member in ipairs(steamData.family) do
octolib.msg('- %s, %s, https://steamcommunity.com/profiles/%s', member.name, member.steamid, member.steamid64)
end
if #steamData.family == maxFamilyDisplay then
octolib.msg('(Отображаются только первые %s связанных аккаунтов, полный список на https://octothorp.team/admin/octolib-vars)', maxFamilyDisplay)
end
else octolib.msg('Связанные аккаунты: отсутствуют') end
octolib.msg('Введи эту команду еще раз, чтобы выдать разбан. Об этом будет уведомлена старшая администрация')
octolib.msg('sg unban "%s" "%s"', sid, reason)
octolib.msg('=================================')
end,
})
end
-- consents['admin steamid'] = 'last target steamid allowed to unban'
-- consoleConsents['target steamid allowed to unban'] = true
local consents, consoleConsents = {}, {}
hook.Add('serverguard.PreventPlayerUnban', 'dbg-security.unbanConfirmation', function(sid, admin, reason)
local ban = serverguard.banTable[sid]
local asid = IsValid(admin) and admin:SteamID() or false
if not ban or (ban.endTime > 0 and ban.endTime <= os.time()) then
consents[asid] = nil -- player is not banned permanently
if asid then admin:Notify('warning', 'Этот игрок не заблокирован')
else octolib.msg('Этот игрок не заблокирован') end
return
end
if IsValid(admin) then
if ban.endTime <= 0 and not admin:query('Unban permanently banned players') then
admin:Notify('warning', 'Обратись к старшей администрации, чтобы снять перманентные блокировки')
return true -- prevent unban
end
if consents[asid] ~= sid then
requestConsent(admin, sid, ban, reason)
return true -- prevent unban for now
end
consents[asid] = nil
notifyDiscord(admin, sid, ban, reason)
else
if not consoleConsents[sid] then
requestConsoleConsent(sid, ban, reason)
consoleConsents[sid] = true
timer.Simple(120, function() -- console has to re-enter unban command in 2 minutes
consoleConsents[sid] = nil
end)
return true -- prevent unban for now
else
notifyDiscord(nil, sid, ban, reason)
consoleConsents[sid] = nil
end
end
end)
hook.Add('serverguard.PlayerBannedBySteamID', 'dbg-security.rebanCheck', function(sid, len, reason, admin)
local ban = serverguard.banTable[sid]
if not ban then return end
if ban.endTime <= 0 or (ban.endTime - os.time()) >= (len - 1) * 60 then
if IsValid(admin) then
admin:Notify('warning', 'Сначала разбань этого игрока, затем выдай ему бан повторно')
else
octolib.msg('Сначала разбань этого игрока, затем выдай ему бан повторно')
end
return true
end
end)
netstream.Hook('dbg-unban.consent', function(ply, sid, reason)
if not (octolib.string.isSteamID(sid) and ply:query('Unban')) then return end
local ban = serverguard.banTable[sid]
if not ban then return end
if not (ban.endTime > 0 or ply:query('Unban permanently banned players')) then return end
consents[ply:SteamID()] = sid
ply:ConCommand(('sg unban "%s" "%s"'):format(sid, reason))
end)