250 lines
9.1 KiB
Lua
250 lines
9.1 KiB
Lua
|
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)
|