264 lines
8.7 KiB
Lua
264 lines
8.7 KiB
Lua
|
local function updatePlayers()
|
|||
|
local members = {}
|
|||
|
for k, v in pairs(simpleOrgs.orgs) do
|
|||
|
members[k] = table.IsSequential(v.members) and octolib.array.toKeys(v.members) or table.GetKeys(v.members)
|
|||
|
end
|
|||
|
octolib.func.throttle(player.GetAll(), 10, 0.1, function(ply)
|
|||
|
if not IsValid(ply) then return end
|
|||
|
local sid, orgs = ply:SteamID(), {}
|
|||
|
for k, v in pairs(members) do
|
|||
|
if v[sid] then orgs[k] = true end
|
|||
|
end
|
|||
|
ply:SetLocalVar('dbg-orgs.member', orgs)
|
|||
|
end)
|
|||
|
end
|
|||
|
|
|||
|
local function reloadOrgs()
|
|||
|
octolib.db:RunQuery('SELECT * FROM `dbg_orgs`', function(q, st, res)
|
|||
|
if not istable(res) then return end
|
|||
|
|
|||
|
local members, owners, urls, flyers = {}, {}, {}, {}
|
|||
|
for _,v in ipairs(res) do
|
|||
|
members[v.id] = pon.decode(v.members)
|
|||
|
owners[v.id] = pon.decode(v.owners)
|
|||
|
urls[v.id] = v.url or ''
|
|||
|
flyers[v.id] = v.flyer or ''
|
|||
|
end
|
|||
|
|
|||
|
for k,v in pairs(simpleOrgs.orgs) do
|
|||
|
v.members = simpleOrgs.decompressMembers(members[k] or {})
|
|||
|
table.Empty(v.owners)
|
|||
|
for _, owner in ipairs(owners[k] or {}) do
|
|||
|
v.owners[#v.owners + 1] = owner
|
|||
|
end
|
|||
|
v.url = urls[k] or ''
|
|||
|
v.flyer = flyers[k] or ''
|
|||
|
end
|
|||
|
updatePlayers()
|
|||
|
end)
|
|||
|
end
|
|||
|
|
|||
|
hook.Add('octolib.event:reloadOrgs', 'dbg-orgs', reloadOrgs)
|
|||
|
|
|||
|
hook.Add('octolib.db.init', 'dbg-orgs', function()
|
|||
|
octolib.db:RunQuery([[
|
|||
|
CREATE TABLE IF NOT EXISTS `dbg_orgs` (
|
|||
|
`id` VARCHAR(10) NOT NULL,
|
|||
|
`members` TEXT NOT NULL,
|
|||
|
`owners` TEXT NOT NULL,
|
|||
|
`url` VARCHAR(128) NOT NULL DEFAULT '',
|
|||
|
`flyer` VARCHAR(128) NOT NULL DEFAULT '',
|
|||
|
PRIMARY KEY (`id`)
|
|||
|
) COLLATE='utf8_general_ci'
|
|||
|
]], function(q, st, res)
|
|||
|
local vals = ''
|
|||
|
for k,v in pairs(simpleOrgs.orgs) do
|
|||
|
if #vals ~= 0 then vals = vals .. ',' end
|
|||
|
vals = vals .. ('(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\')'):format(
|
|||
|
octolib.db:escape(k),
|
|||
|
octolib.db:escape(pon.encode(v.members)),
|
|||
|
octolib.db:escape(pon.encode(v.owners)),
|
|||
|
octolib.db:escape(v.url),
|
|||
|
octolib.db:escape(v.flyer))
|
|||
|
end
|
|||
|
octolib.db:RunQuery([[INSERT IGNORE INTO `dbg_orgs` VALUES ]] .. vals, reloadOrgs)
|
|||
|
end)
|
|||
|
end)
|
|||
|
|
|||
|
local function saveOrg(id)
|
|||
|
local org = id and simpleOrgs.orgs[id]
|
|||
|
if not org then return end
|
|||
|
local members = simpleOrgs.compressMembers(id)
|
|||
|
octolib.db:PrepareQuery([[UPDATE `dbg_orgs` SET `members` = ?, `url` = ?, `flyer` = ? WHERE `id` = ?]], {pon.encode(members), org.url, org.flyer, id}, function(q, st, res)
|
|||
|
octolib.sendCmdToOthers('reloadOrgs')
|
|||
|
updatePlayers()
|
|||
|
end)
|
|||
|
end
|
|||
|
simpleOrgs.saveOrg = saveOrg
|
|||
|
|
|||
|
|
|||
|
function simpleOrgs.compressMembers(membersOrID)
|
|||
|
membersOrID = membersOrID or {}
|
|||
|
local members = membersOrID
|
|||
|
if not istable(membersOrID) then members = simpleOrgs.orgs[membersOrID] and simpleOrgs.orgs[membersOrID].members end
|
|||
|
if not istable(members) then return {} end
|
|||
|
if table.IsSequential(members) then return octolib.table.mapSequential(members, octolib.string.compressSteamID) end
|
|||
|
local result = {}
|
|||
|
for k, v in pairs(members) do
|
|||
|
result[octolib.string.compressSteamID(k)] = v
|
|||
|
end
|
|||
|
return result
|
|||
|
end
|
|||
|
|
|||
|
function simpleOrgs.decompressMembers(membersOrID)
|
|||
|
membersOrID = membersOrID or {}
|
|||
|
if not istable(membersOrID) then return simpleOrgs.orgs[membersOrID] and table.Copy(simpleOrgs.orgs[membersOrID].members) or {} end
|
|||
|
if table.IsSequential(membersOrID) then return octolib.table.mapSequential(membersOrID, octolib.string.decompressSteamID) end
|
|||
|
local result = {}
|
|||
|
for k, v in pairs(membersOrID) do
|
|||
|
result[octolib.string.decompressSteamID(k)] = v
|
|||
|
end
|
|||
|
return result
|
|||
|
end
|
|||
|
|
|||
|
local allowedFlyerExts = octolib.array.toKeys {'.jpg', '.png'}
|
|||
|
netstream.Hook('simple-orgs.editor.save', function(ply, orgId, data, url, flyer)
|
|||
|
if not (istable(data) and isstring(url) and isstring(flyer) and orgId and simpleOrgs.orgs[orgId]) then
|
|||
|
return ply:Notify('Организация не найдена')
|
|||
|
end
|
|||
|
if not table.HasValue(simpleOrgs.orgs[orgId].owners, ply:SteamID()) and not ply:IsSuperAdmin() then
|
|||
|
return ply:Notify('Доступ запрещен')
|
|||
|
end
|
|||
|
|
|||
|
simpleOrgs.orgs[orgId].members = data
|
|||
|
simpleOrgs.orgs[orgId].url = url
|
|||
|
|
|||
|
if flyer ~= '' then
|
|||
|
if flyer:sub(1, 20) ~= 'https://i.imgur.com/' then
|
|||
|
return ply:Notify('warning', 'Можно использовать только ссылки с Imgur')
|
|||
|
end
|
|||
|
if not allowedFlyerExts[flyer:sub(-4)] then
|
|||
|
return ply:Notify('warning', 'Можно использовать только ссылки в формате .jpg или .png')
|
|||
|
end
|
|||
|
flyer = flyer:sub(21)
|
|||
|
end
|
|||
|
simpleOrgs.orgs[orgId].flyer = flyer
|
|||
|
|
|||
|
saveOrg(orgId)
|
|||
|
ply:Notify('Информация об организации обновлена')
|
|||
|
end)
|
|||
|
|
|||
|
netstream.Hook('simple-orgs.editor.saveOwners', function(ply, orgId, data)
|
|||
|
if not (istable(data) and orgId and simpleOrgs.orgs[orgId]) then
|
|||
|
return ply:Notify('Организация не найдена')
|
|||
|
end
|
|||
|
local org = simpleOrgs.orgs[orgId]
|
|||
|
if not ply:query('DBG: Редактировать организации') then
|
|||
|
return ply:Notify('Доступ запрещен')
|
|||
|
end
|
|||
|
org.owners = data
|
|||
|
octolib.db:PrepareQuery([[UPDATE `dbg_orgs` SET `owners` = ? WHERE `id` = ?]], {pon.encode(data), orgId}, function(q, st, res)
|
|||
|
octolib.sendCmdToOthers('reloadOrgs')
|
|||
|
end)
|
|||
|
ply:Notify('Информация об организации обновлена')
|
|||
|
end)
|
|||
|
|
|||
|
concommand.Add('dbg_orgs_edit', function(ply, cmd, args)
|
|||
|
local orgId = args[1]
|
|||
|
if not orgId then
|
|||
|
return ply:PrintMessage(HUD_PRINTCONSOLE, 'dbg_orgs_edit ID')
|
|||
|
end
|
|||
|
local _, msg = ply:OpenOrgEditor(orgId)
|
|||
|
if msg then ply:PrintMessage(HUD_PRINTCONSOLE, msg) end
|
|||
|
end)
|
|||
|
|
|||
|
hook.Add('PlayerFinishedLoading', 'simple-orgs', function(ply)
|
|||
|
local orgs = {}
|
|||
|
for k in pairs(simpleOrgs.orgs) do
|
|||
|
if ply:IsOrgMember(k) then orgs[k] = true end
|
|||
|
end
|
|||
|
ply:SetLocalVar('dbg-orgs.member', orgs)
|
|||
|
end)
|
|||
|
|
|||
|
hook.Add('playerCanChangeTeam', 'simple-orgs.multirank', function(ply, t, force)
|
|||
|
if force then return end
|
|||
|
local org = RPExtraTeams[t].orgID
|
|||
|
if org then org = simpleOrgs.orgs[org] end
|
|||
|
if org then
|
|||
|
return false, 'Это абстрактная профессия, которая используется участниками организации ' .. org.name .. '. Ты не можешь ее взять'
|
|||
|
end
|
|||
|
end)
|
|||
|
|
|||
|
CFG.use.ent_dbg_org_board = {
|
|||
|
function(ply, ent)
|
|||
|
if not ent.orgId then return end
|
|||
|
return 'Изучить', 'octoteam/icons/search.png', function(ply, ent)
|
|||
|
ent:Use(ply, ply, USE_TOGGLE, 1)
|
|||
|
end
|
|||
|
end,
|
|||
|
function(ply, ent)
|
|||
|
if not ent.orgId then return end
|
|||
|
|
|||
|
local org = simpleOrgs.orgs[ent.orgId]
|
|||
|
if not org or (not table.HasValue(org.owners, ply:SteamID()) and not ply:query('DBG: Редактировать организации')) then return end
|
|||
|
|
|||
|
return 'Управление', 'octoteam/icons/group3.png', function(ply, ent)
|
|||
|
local ok, msg = ply:OpenOrgEditor(ent.orgId)
|
|||
|
if msg then ply:Notify(ok and 'hint' or 'warning', msg) end
|
|||
|
end
|
|||
|
end,
|
|||
|
function(ply, ent)
|
|||
|
if not ply:IsSuperAdmin() then return end
|
|||
|
return 'Настроить', 'octoteam/icons/keypad.png', function(ply, ent)
|
|||
|
octolib.request.send(ply, {
|
|||
|
{
|
|||
|
name = 'Идентификатор организации',
|
|||
|
desc = 'Организации создаются через разработчиков',
|
|||
|
type = 'comboBox',
|
|||
|
opts = octolib.table.mapSequential(table.GetKeys(simpleOrgs.orgs), function(v) return {simpleOrgs.orgs[v].name, v, ent.orgId == v} end),
|
|||
|
required = true,
|
|||
|
}
|
|||
|
}, function(data)
|
|||
|
ent:SetOrgID(data[1])
|
|||
|
end)
|
|||
|
end
|
|||
|
end,
|
|||
|
}
|
|||
|
|
|||
|
local function simpleOrgAccess(ply, ent)
|
|||
|
|
|||
|
local data = dbgEstates.getData(ent:GetEstateID())
|
|||
|
if not data or not data.owners then return end
|
|||
|
for _,v in ipairs(data.owners) do
|
|||
|
if string.StartWith(v, 'g:') then
|
|||
|
if v == 'g:police' then
|
|||
|
for k, v in pairs(simpleOrgs.orgs) do
|
|||
|
if v.police and ply:IsOrgMember(k) then
|
|||
|
return true
|
|||
|
end
|
|||
|
end
|
|||
|
else
|
|||
|
local gID = v:sub(3)
|
|||
|
if ply:IsOrgMember(gID) then
|
|||
|
return true
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
end
|
|||
|
hook.Add('canKeysLock', 'dbg-orgs.doors', simpleOrgAccess)
|
|||
|
hook.Add('canKeysUnlock', 'dbg-orgs.doors', simpleOrgAccess)
|
|||
|
|
|||
|
hook.Add('dbg-winter.isWarm', 'dbg-orgs', function(ply)
|
|||
|
if ply.dbgPolice_citizenData then
|
|||
|
return true
|
|||
|
end
|
|||
|
end)
|
|||
|
|
|||
|
hook.Add('PlayerDisconnected', 'dbg-orgs.customClothes', function(ply)
|
|||
|
local clothes = ply.dbgPolice_citizenData and ply.dbgPolice_citizenData.cl
|
|||
|
if clothes then
|
|||
|
ply:SetDBVar('customClothes', clothes)
|
|||
|
end
|
|||
|
end)
|
|||
|
|
|||
|
local function getClothes(mdl, clothesData)
|
|||
|
for prefix, clothes in pairs(clothesData) do
|
|||
|
if string.StartWith(mdl, prefix) then return clothes end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
netstream.Hook('dbg-orgs.clothes', function(ply, clID, value)
|
|||
|
|
|||
|
if not (clID and value) then return end
|
|||
|
local org = ply.currentOrg and simpleOrgs.orgs[ply.currentOrg]
|
|||
|
if not (org and org.clothes) then return end
|
|||
|
|
|||
|
local clothes = getClothes(ply:GetModel(), org.clothes)
|
|||
|
if not (clothes and clothes[clID]) then return end
|
|||
|
local clothing = clothes[clID]
|
|||
|
if clothing.vals[value] then
|
|||
|
ply:SetBodygroup(clothing.bodygroup, value)
|
|||
|
end
|
|||
|
end)
|