This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 0e770b2b49
commit ba1fc01b16
7084 changed files with 2173495 additions and 14 deletions

View File

@@ -0,0 +1 @@
NjHJUTU-YA9iKMrNPeqbYNtVSMnBrAXn

View File

@@ -0,0 +1 @@
KzPJMvyH09mq9Tyx1pHh4NbolbW3cL3W

View File

@@ -0,0 +1,246 @@
--[[
| 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) then return end
local ix = ix
ix.xenforo = ix.xenforo or {}
ix.xenforo.stored = ix.xenforo.stored or {}
ix.xenforo.restrictedWhitelists = ix.xenforo.restrictedWhitelists or {}
function ix.xenforo:RegisterForumGroup(name, id, data)
self.stored[id] = {id = id, name = name,
premiumTier = data.premiumTier or 0,
camiGroup = data.camiGroup,
inherits = data.inherits,
priority = data.priority,
flags = data.flags,
whitelists = data.whitelists,
}
if (!self.stored[id].premiumTier) then
self.stored[id].premiumTier = 0
end
if (!self.stored[id].priority) then
self.stored[id].priority = -1
end
end
function ix.xenforo:RegisterRestrictedWhitelist(whitelist)
self.restrictedWhitelists[whitelist] = true
end
function ix.xenforo:IsValidGroupID(id)
id = tostring(id)
return self.stored[id] != nil
end
function ix.xenforo:FindGroup(group)
local targetGroup
if (string.find(group, "^%d+$") and self.stored[group]) then
targetGroup = group
else
group = string.lower(group)
for k, v in pairs(self.stored) do
if (string.find(string.utf8lower(v.name), group, 1, true) and (!targetGroup or string.utf8len(targetGroup) > string.utf8len(v.name))) then
targetGroup = k
end
end
end
return targetGroup
end
function ix.xenforo:AddGroup(client, id, duration)
if (!self.stored[id]) then return false end
local groups = client:GetData("xenforoGroups", {})
if (duration) then
local time = math.Clamp(duration, 30, 2880)
groups[id] = os.time() + time * 60
else
groups[id] = -1
end
client:SetData("xenforoGroups", groups)
self:ApplyInGameGroups(client)
return self.stored[id].name, groups[id] - os.time()
end
function ix.xenforo:RemoveGroup(client, id)
if (!self.stored[id]) then return false end
local groups = client:GetData("xenforoGroups", {})
groups[id] = nil
if (table.IsEmpty(groups)) then
client:SetData("xenforoGroups", nil)
else
client:SetData("xenforoGroups", groups)
end
self:ApplyInGameGroups(client)
return self.stored[id].name
end
function ix.xenforo:ClearTempGroups(client)
local tempGroups = client:GetData("xenforoGroups", {})
local bRemoved = false
for k, v in pairs(tempGroups) do
if (v >= 0 and v < os.time()) then
tempGroups[k] = nil
bRemoved = true
end
end
local bHasTempGroups = !table.IsEmpty(tempGroups)
if (bRemoved) then
if (!table.IsEmpty(tempGroups)) then
client:SetData("xenforoGroups", tempGroups)
else
client:SetData("xenforoGroups", nil)
end
end
return tempGroups, bHasTempGroups
end
local inherits_from = sam.ranks.inherits_from
function ix.xenforo:ApplyInGameGroups(client)
local ranks = {}
local prio = 0
local primaryRank = "user"
local flags = ""
local tier = 0
local toRemove = table.Copy(self.restrictedWhitelists)
if (client.ixXenforoGroups or client:GetData("xenforoGroups")) then
local tempGroups, bHasTempGroups = self:ClearTempGroups(client)
-- copy table so we don't modify it when adding the temp groups
local forumGroups = table.Copy(client.ixXenforoGroups or {})
if (bHasTempGroups) then
forumGroups = table.Add(forumGroups, table.GetKeys(tempGroups))
end
-- Allow other plugins to add xenforo groups manually
hook.Run("ModifyXenforoGroups", client, forumGroups)
for _, v in ipairs(forumGroups) do
local data = self.stored[tostring(v)]
if (!data) then continue end
if (data.camiGroup) then
ranks[#ranks + 1] = data.camiGroup
if (data.priority > prio) then
prio = data.priority
primaryRank = data.camiGroup
end
end
-- Give flags
if (data.flags) then
for i = 1, #data.flags do
local flag = data.flags[i]
if (!string.find(flags, flag, 1, true)) then
flags = flags..flag
end
end
end
-- Set Premium tier
if (data.premiumTier > tier) then
tier = data.premiumTier
end
-- Give whitelists
if (ix.config.Get("whitelistForumLink") and data.whitelists) then
for faction in pairs(data.whitelists) do
toRemove[faction] = nil --don't remove this whitelist
if (!client:HasWhitelist(faction)) then
client:SetWhitelisted(faction, true)
end
end
end
end
end
-- Allow other plugins to add CAMI ranks to the list
hook.Run("ModifyClientCAMIGroups", client, ranks)
-- Network ranks
if (#ranks > 0) then
client:SetLocalVar("xenforoRanks", ranks)
else
client:SetLocalVar("xenforoRanks", nil)
end
-- Network flags
local oldFlags = client:GetLocalVar("xenforoFlags", "")
if (flags != "") then
client:SetLocalVar("xenforoFlags", flags)
for i = 1, #flags do
local flag = flags[i]
local info = ix.flag.list[flag]
if (info and info.callback) then
info.callback(client, true)
end
string.gsub(oldFlags, flag, "")
end
else
client:SetLocalVar("xenforoFlags", nil)
end
-- Remove old flags that haven't been given again
if (client:GetCharacter() and #oldFlags > 0) then
for i = 1, #oldFlags do
local flag = oldFlags[i]
local info = ix.flag.list[flag]
if (!client:GetCharacter():HasFlags(flag) and info and info.callback) then
info.callback(client, false)
end
end
end
-- Network Premium tier
if (tier > 0) then
client:SetNetVar("xenforoTier", tier)
else
client:SetNetVar("xenforoTier", nil)
end
-- Set primary rank
if (client:GetUserGroup() == "superadmin" and
(inherits_from(primaryRank, "admin") or inherits_from(primaryRank, "superadmin"))) then
primaryRank = "superadmin"
end
client:sam_set_rank(primaryRank)
-- Remove whitelists
if (ix.config.Get("whitelistForumLink")) then
-- remove whitelists
for k in pairs(toRemove) do
if (client:HasWhitelist(k)) then
client:SetWhitelisted(k, false)
end
end
end
hook.Run("PostPlayerXenforoGroupsUpdate", client)
end

View File

@@ -0,0 +1,233 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
ix.command.Add("LinkAccount", {
description = "Link your steam account to your forum account. Please provide your forum profile link, user ID, username or e-mail.",
arguments = {
ix.type.string
},
OnCheckAccess = function(self, client)
return !client:GetLocalVar("xenforoLink")
end,
OnRun = function(self, client, forumID)
PLUGIN:FindUser(client, forumID)
end
})
ix.command.Add("LinkComplete", {
description = "Link your steam account to your forum account.",
arguments = {
ix.type.text
},
OnCheckAccess = function(self, client)
return client:GetLocalVar("xenforoLinkStart", 0) + PLUGIN.TOKEN_VALID * 60 > os.time() and !client:GetLocalVar("xenforoLink")
end,
OnRun = function(self, client, code)
if (!code) then return end
PLUGIN:FinishLink(client, code)
end
})
ix.command.Add("LinkRemove", {
description = "Link your steam account to your forum account.",
OnCheckAccess = function(self, client)
return client:GetLocalVar("xenforoLink")
end,
OnRun = function(self, client)
PLUGIN:RemoveLink(client)
end
})
ix.command.Add("ForceGroupUpdate", {
description = "Link your steam account to your forum account.",
arguments = {
ix.type.player
},
superAdminOnly = true,
OnRun = function(self, client, target)
PLUGIN:GetXenforoGroups(target, client)
end
})
ix.command.Add("PlyGiveTempGroup", {
description = "Give a player a temporary (admin) group.",
arguments = {
ix.type.player,
ix.type.string,
ix.type.number
},
argumentNames = {"target", "SAM groupName", "duration (minutes)"},
privilege = "Manage Temp Admin",
OnRun = function(self, client, target, group, duration)
local targetGroup = ix.xenforo:FindGroup(group)
if (!targetGroup) then
client:NotifyLocalized("xenforoNoGroupFound", group)
return
end
local groupName, time = ix.xenforo:AddGroup(target, targetGroup, duration)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target) then
v:NotifyLocalized("xenforoTempGroup", target:Name(), groupName, math.ceil(time / 60))
end
end
end
})
ix.command.Add("PlyRemoveTempGroup", {
description = "Remove a player a temporary (admin) group.",
arguments = {
ix.type.player,
ix.type.string
},
argumentNames = {"target", "forum groupID/SAM groupName"},
privilege = "Manage Temp Admin",
OnRun = function(self, client, target, group)
local targetGroup = ix.xenforo:FindGroup(group)
if (!targetGroup) then
client:NotifyLocalized("xenforoNoGroupFound", group)
return
end
local groupName = ix.xenforo:RemoveGroup(target, targetGroup)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target) then
v:NotifyLocalized("xenforoTempGroupRemove", target:Name(), groupName)
end
end
end
})
ix.command.Add("PlyClearTempGroups", {
description = "Clear a player a temporary (admin) groups.",
arguments = {
ix.type.player
},
argumentNames = {"target"},
privilege = "Manage Temp Admin",
OnRun = function(self, client, target)
target:SetData("xenforoGroups", nil)
ix.xenforo:ApplyInGameGroups(client)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target) then
v:NotifyLocalized("xenforoTempGroupClear", target:Name())
end
end
end
})
ix.command.Add("PlyGetXenforoGroups", {
description = "Get all Xenforo Groups set on a player.",
arguments = {
ix.type.player
},
argumentNames = {"target"},
privilege = "Manage Temp Admin",
OnRun = function(self, client, target)
if (target.ixXenforoID) then
client:ChatNotifyLocalized("xenforoTargetForumID", target:Name(), target.ixXenforoID)
else
client:ChatNotifyLocalized("xenforoTargetNoForumID", target:Name())
end
if (target.ixXenforoGroups) then
local groupNames = {}
for k, v in ipairs(target.ixXenforoGroups) do
if (!ix.xenforo.stored[v]) then continue end
groupNames[#groupNames + 1] = ix.xenforo.stored[v].name
end
if (#groupNames > 0) then
client:ChatNotifyLocalized("xenforoTargetGroups", table.concat(groupNames, ", "))
else
client:ChatNotifyLocalized("xenforoTargetNoGroups", target:Name())
end
else
client:ChatNotifyLocalized("xenforoTargetNoGroups", target:Name())
end
if (target:GetData("xenforoGroups")) then
local groupNames = {}
for k, v in pairs(target:GetData("xenforoGroups")) do
if (!ix.xenforo.stored[tostring(k)]) then continue end
groupNames[#groupNames + 1] = ix.xenforo.stored[tostring(k)].name..(v < 0 and " (P)" or " (T: "..math.ceil((v - os.time())/60).."m)")
end
if (#groupNames > 0) then
client:ChatNotifyLocalized("xenforoTargetDynGroups", table.concat(groupNames, ", "))
else
client:ChatNotifyLocalized("xenforoTargetDynNoGroups", target:Name())
end
else
client:ChatNotifyLocalized("xenforoTargetDynNoGroups", target:Name())
end
if (target:GetLocalVar("xenforoRanks")) then
local ranks = {}
for k, v in ipairs(target:GetLocalVar("xenforoRanks")) do
ranks[#ranks + 1] = v
end
client:ChatNotifyLocalized("xenforoRanks", table.concat(ranks, ", "))
else
client:ChatNotifyLocalized("xenforoNoRanks", target:Name())
end
if (target:GetLocalVar("xenforoFlags")) then
client:ChatNotifyLocalized("xenforoFlags", target:GetLocalVar("xenforoFlags"))
else
client:ChatNotifyLocalized("xenforoNoFlags", target:Name())
end
if (target:GetNetVar("xenforoTier", 0) > 0) then
client:ChatNotifyLocalized("xenforoPremium", target:GetLocalVar("xenforoTier"))
else
client:ChatNotifyLocalized("xenforoNoPremium", target:Name())
end
end
})
ix.command.Add("ToggleGM", {
description = "Toggle your GM rank on and off. Will notify all admins about it.",
OnCheckAccess = function(self, client)
return table.HasValue(client:GetLocalVar("xenforoRanks", {}), "gamemaster_inactive") or
(table.HasValue(client:GetLocalVar("xenforoRanks", {}), "gamemaster") and client:GetLocalVar("GMToggledOn") == true)
end,
OnRun = function(self, client)
client:SetLocalVar("GMToggledOn", !client:GetLocalVar("GMToggledOn"))
ix.xenforo:ApplyInGameGroups(client)
for k, v in ipairs(player.GetAll()) do
if (v == client or v:IsAdmin()) then
v:NotifyLocalized("gamemasterToggle", client:Name(), client:GetLocalVar("GMToggledOn") and "on" or "off")
end
end
end
})
ix.command.Add("ToggleMentor", {
description = "Toggle your mentor rank on and off. Will notify all admins about it",
OnCheckAccess = function(self, client)
return table.HasValue(client:GetLocalVar("xenforoRanks", {}), "mentor_inactive") or
(table.HasValue(client:GetLocalVar("xenforoRanks", {}), "mentor") and client:GetLocalVar("MentorActive") == true)
end,
OnRun = function(self, client)
client:SetLocalVar("MentorActive", !client:GetLocalVar("MentorActive"))
ix.xenforo:ApplyInGameGroups(client)
for k, v in ipairs(player.GetAll()) do
if (v == client or v:IsAdmin()) then
v:NotifyLocalized("mentorToggle", client:Name(), client:GetLocalVar("MentorActive") and "on" or "off")
end
end
end
})

View File

@@ -0,0 +1,113 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
do
local PLAYER = FindMetaTable("Player")
local inherits_from = sam.ranks.inherits_from
function PLAYER:IsAdmin()
return self:CheckGroup("admin")
end
function PLAYER:IsSuperAdmin()
return self:CheckGroup("superadmin")
end
function PLAYER:CheckGroup(name)
local ranks = self:GetLocalVar("xenforoRanks")
if (ranks) then
for _, v in ipairs(ranks) do
if (inherits_from(v, name)) then
return true
end
end
end
return inherits_from(self:GetUserGroup(), name)
end
local has_permission = sam.ranks.has_permission
function PLAYER:HasPermission(perm)
local ranks = self:GetLocalVar("xenforoRanks")
if (ranks) then
for _, v in ipairs(ranks) do
if (has_permission(v, perm)) then
return true
end
end
end
return has_permission(self:GetUserGroup(), perm)
end
end
function PLUGIN:InitializedPlugins()
if (SERVER) then
self:InitAPIKey()
end
hook.Run("RegisterGroups", self)
end
hook.Add("CAMI.PlayerHasAccess", "ixXenforo.CAMI.PlayerHasAccess", function(ply, privilege, callback, target)
if sam.type(ply) ~= "Player" then return end
local ranks = ply:GetLocalVar("xenforoRanks")
local bTargetIsPlayer = sam.type(target) == "Player"
local bCanTarget = bTargetIsPlayer and ply:CanTarget(target)
if (ranks) then
for _, v in ipairs(ranks) do
local has_permission = sam.ranks.has_permission(v, privilege)
if (has_permission and (!bTargetIsPlayer or bCanTarget)) then
callback(true)
return true
end
end
end
local has_permission = ply:HasPermission(privilege)
if (bTargetIsPlayer) then
callback(has_permission and bCanTarget)
else
callback(has_permission)
end
return true
end)
hook.Remove("CAMI.PlayerHasAccess", "SAM.CAMI.PlayerHasAccess")
function PLUGIN:CharacterHasFlags(character, flags)
local client = character:GetPlayer()
if (!IsValid(client)) then return end
local flagList = client:GetLocalVar("xenforoFlags")
if (!flagList) then return end
for i = 1, #flags do
if (flagList:find(flags[i], 1, true)) then
return true
end
end
end
if (CLIENT) then
function PLUGIN:GetPlayerESPText(client, toDraw, distance, alphaFar, alphaMid, alphaClose)
local tier = client:GetNetVar("xenforoTier")
if (tier and PLUGIN.tiers[tier]) then
toDraw[#toDraw + 1] = {alpha = alphaClose, priority = 29, text = PLUGIN.tiers[tier]}
end
end
end

View File

@@ -0,0 +1,121 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
PLUGIN.name = "Xenforo Link"
PLUGIN.author = "Gr4Ss"
PLUGIN.description = "Links the in-game ranks and factions to the forums."
if (!sam) then return end
if (SERVER and !CHTTP) then
pcall(require, "chttp")
end
PLUGIN.TOKEN_VALID = 60
PLUGIN.NEW_ATTEMPT_WAIT = 1
PLUGIN.tiers = {
"A True Citizen",
"Protector",
"Galunga Prince"
}
CAMI.RegisterPrivilege({
Name = "Helix - Manage Temp Admin",
MinAccess = "superadmin"
})
ix.config.Add("whitelistForumLink", true, "Whether or not some whitelists should be linked to forum groups.", nil, {
category = "server"
})
ix.util.Include("sh_commands.lua")
ix.util.Include("sh_hooks.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_link.lua")
ix.util.Include("sv_plugin.lua")
ix.lang.AddTable("english", {
xenforoFailsPause = "You entered the wrong code too many times. Please try again in %d minutes.",
xenforoStartWait = "Please wait 1 minute before starting a new linking attempt.",
xenforoFailedFindUser = "Something went wrong trying to find the user '%s'.",
xenforoFindUserNoExactMatch = "We did not manage to find an exact match for the user '%s'.",
xenforoFailedCreatePM = "Something went wrong trying to send the private message with the token.",
xenforoFailedCreatePMError = "Received an error when trying to send the private message with the token.",
xenforoCodeSend = "Private message with link token was successfully send. Please check your PM's on the forums. Do not disconnect from the server: your token will become invalid.",
xenoforoNoLinkActive = "Cannot finishing linking as no link attempt is active. Please use /LinkAccount first.",
xenoforoLinkNotValid = "Token is no longer valid. Please start again with /LinkAccount.",
xenforoLinkSuccess = "Your account was successfully linked with your forum account!",
xenforoFailsPauseStart = "You entered a wrong token too many times. Please wait 1 hour before making a new attempt.",
xenforoWrongCode = "You entered a wrong token. You have %d attempts left.",
xenforoNotLinked = "%s does not have their forum account linked.",
xenforoGroupsUpdateSelf = "Your forum groups have been updated. %d valid groups were found.",
xenforoGroupsUpdate = "%s their forum groups have been updated. %d valid groups were found.",
xenforoLinkRemoved = "Your link to your forum has been removed.",
xenforoNoGroupFound = "Couldn't find the target group '%s'.",
xenforoTempGroup = "%s was temporarily given '%s' for '%d' minutes.",
xenforoTempGroupRemove = "%s was removed from the temporary group '%s'.",
xenforoTempGroupClear = "%s their temporary groups were cleared.",
xenforoWhitelistForumLink = "This faction whitelist is managed via the forums. Use /LinkAccount instead!",
xenforoTargetForumID = "%s is linked to forum account ID '%d'.",
xenforoTargetNoForumID = "%s does not have a forum account linked!",
xenforoTargetGroups = "Forum groups: %s",
xenforoTargetNoGroups = "%s has no Xenforo groups!",
xenforoTargetDynGroups = "Dynamic groups: %s",
xenforoTargetDynNoGroups = "%s has no dynamic groups!",
xenforoRanks = "SAM ranks: %s",
xenforoNoRanks = "%s has no ranks!",
xenforoFlags = "Flags: %s",
xenforoNoFlags = "%s has no forum-group flags!",
xenforoPremium = "Premium tier: %d",
xenforoNoPremium = "%s has no premium subscription!",
gamemasterToggle = "%s has toggled their gamemaster admin-powers %s!",
mentorToggle = "%s has toggled their mentor admin-powers %s!",
})
ix.lang.AddTable("spanish", {
xenoforoNoLinkActive = "No se puede linkear al no haber intento de link activo. Por favor, usa /LinkAccount primero.",
xenforoNoGroupFound = "No se pudo encontrar el grupo objetivo \"%s\".",
xenforoNotLinked = "%s no tiene su cuenta del foro linkeada.",
xenforoTempGroupClear = "Grupos temporales de %s removidos.",
xenoforoLinkNotValid = "El token ya no es válido. Por favor, empieza de nuevo con /LinkAccount.",
xenforoLinkRemoved = "Tu link a tu foro han sido removidos.",
xenforoGroupsUpdateSelf = "Tus grupos del foro han sido actualizados. %d grupos válidos fueron encontrados.",
xenforoLinkSuccess = "¡Tu cuenta ha sido linkeada exitosamente con tu cuenta del foro!",
xenforoCodeSend = "Mensaje privado con el token linkeado fue enviado con éxito. Por favor, revisa tus MPs en el foro. No te desconectes del servidor: Tu token se volverá inválido.",
xenforoGroupsUpdate = "%s sus grupos han sido actualizados. %d grupos válidos encontrados.",
xenforoFailedCreatePMError = "Error recibido al intentar enviar el mensaje con el token.",
xenforoTempGroupRemove = "%s ha sido echado del grupo temporal \"%s\".",
xenforoWrongCode = "Introdujiste un token erróneo. Tienes %d intentos más.",
xenforoTempGroup = "A %s se le dio temporalmente \"%s\" por \"%d\" minutos.",
xenforoFailsPauseStart = "Has introducido un token erróneo demasiadas veces. Por favor, espera 1 hora antes de hacer otro intento.",
xenforoWhitelistForumLink = "La whitelist de esta facción es manejada a través del foro ¡Usa /LinkAccount en lugar de eso!",
xenforoFindUserNoExactMatch = "No conseguimos encontrar una coincidencia exacta para el usuario '%s'.",
xenforoFailedFindUser = "Algo fue mal al intentar buscar al usuario '%s'.",
xenforoFailsPause = "Has introducido el código erróneo demasiadas veces. Por favor prueba otra vez en %d minutos.",
xenforoFailedCreatePM = "Algo fue mal al intentar enviar el mensaje privado con el token.",
xenforoStartWait = "Por favor espera 1 minuto antes de intentar otro intento de enlace.",
})
function PLUGIN:RegisterForumGroup(name, id, data)
id = isstring(id) and id or tostring(id)
if (!id or id == "") then return end
if (data.camiGroup) then
CAMI.RegisterUsergroup({Name = data.camiGroup, Inherits = data.inherits or "user"}, "helix")
end
if (SERVER) then
ix.xenforo:RegisterForumGroup(name, id, data)
end
end

View File

@@ -0,0 +1,75 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
function PLUGIN:PlayerLoadedCharacter(client, character)
self:GetXenforoGroups(client)
end
function PLUGIN:PlayerInitialSpawn(client)
local query = mysql:Select("xenforo_link")
query:Where("steamid", client:SteamID64())
query:Callback(function(result)
if (result and #result > 0) then
client.ixXenforoID = result[1]["forum_id"]
client.ixXenforoGroups = result[1]["groups"] and util.JSONToTable(result[1]["groups"]) or nil
for i = #client.ixXenforoGroups, 1, -1 do
if (!ix.xenforo.stored[tostring(client.ixXenforoGroups[i])]) then
table.remove(client.ixXenforoGroups, i)
end
end
end
end)
query:Execute()
end
function PLUGIN:PostPlayerLoadout(client)
if (!client:GetCharacter()) then return end
local flags = client:GetLocalVar("xenforoFlags", "")
if (flags == "") then return end
for i = 1, #flags do
local flag = flags[i]
local info = ix.flag.list[flag]
if (info and info.callback) then
info.callback(client, true)
end
end
end
function PLUGIN:CanWhitelistPlayer(target, faction)
if (ix.config.Get("whitelistForumLink") and ix.xenforo.restrictedWhitelists[faction.index]) then
return false, "xenforoWhitelistForumLink"
end
end
function PLUGIN:ModifyXenforoGroups(client, groups)
if (client:GetLocalVar("MentorActive")) then
groups[#groups + 1] = "mentor_active"
end
if (client:GetLocalVar("GMToggledOn")) then
groups[#groups + 1] = "gamemaster_active"
end
end
function PLUGIN:PlayerDataRestored(client)
local groups = client:GetData("xenforoGroups", {})
local newGroups = {}
for k, v in pairs(groups) do
newGroups[tostring(k)] = v
end
client:SetData("xenforoGroups", newGroups)
end

View File

@@ -0,0 +1,267 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
PLUGIN.MAX_ATTEMPTS = 3
PLUGIN.FAILS_WAIT = 60 -- wait in minutes after entering the wrong code too often
PLUGIN.messageText = [[Hello!
%s is trying to link their steam account to your forum account. If this is you, please follow the below instructions:
The token to link your account is: %s
Please use '/LinkComplete <token>' in-game to complete the link. This token is valid for 1 hour.
If you did not do this, please ignore this message.
-ServerBot]]
function PLUGIN:DatabaseConnected()
local query = mysql:Create("xenforo_link")
query:Create("steamid", "VARCHAR(20) NOT NULL")
query:Create("forum_id", "VARCHAR(20) NOT NULL")
query:Create("groups", "TEXT DEFAULT NULL")
query:PrimaryKey("forum_id")
query:Execute()
end
function PLUGIN.GenerateCode(length)
local result = {}
while (#result != 12) do
local char = string.char(math.random(32, 126))
if (string.find(char, "%w")) then
result[#result + 1] = char
end
end
return table.concat(result)
end
function PLUGIN:CheckClientWait(client)
if (client:GetData("xenforoLinkFailPause", 0) > os.time()) then
client:NotifyLocalized("xenforoFailsPause", math.ceil((client:GetData("xenforoLinkFailPause", 0) - os.time()) / 60))
return false
end
if (client.ixXenforoLink and client:GetLocalVar("xenforoLinkStart", 0) * self.NEW_ATTEMPT_WAIT * 15 <= os.time()) then
client:NotifyLocalized("xenforoStartWait")
return false
end
return true
end
function PLUGIN:FindUser(client, name)
if (!self.API_KEY) then return end
if (!self:CheckClientWait(client)) then return end
if (string.find(name, "willard.network/forums/members/[^%.]+%.%d+/")) then
PLUGIN:CheckLinkExists(client, string.match(name, "willard.network/forums/members/[^%.]+%.(%d+)/"))
return
elseif (string.find(name, "$%d+^") and tonumber(name) and tonumber(name) > 0) then
PLUGIN:CheckLinkExists(client, name)
return
end
local steamName = client:SteamName()
local endpoint = "https://willard.network/forums/api/users/find-name?username="
if (string.find(name, "@")) then
endpoint = "https://willard.network/forums/api/users/find-email?email="
end
endpoint = endpoint..name
local request = {
failed = function(error)
print("[XENFORO-LINK] Failed to find user: "..error)
print("[XENFORO-LINK] Client: "..steamName.."; endpoint: "..endpoint)
if (IsValid(client)) then
client:NotifyLocalized("xenforoFailedFindUser", name)
end
end,
success = function(code, body, headers)
if (!IsValid(client)) then return end
local httpResult = util.JSONToTable(body)
if (!httpResult) then
print("[XENFORO-LINK] Received invalid response; endpoint: "..endpoint, code)
file.Write("xenforoError.html", body)
client:NotifyLocalized("xenforoFailedFindUser", name)
return
end
if (!httpResult.exact) then
client:NotifyLocalized("xenforoFindUserNoExactMatch", name)
return
end
self:CheckLinkExists(client, httpResult.exact.user_id)
end,
url = endpoint,
method = "GET",
headers = {
["XF-Api-Key"] = self.API_KEY
}
}
CHTTP(request)
end
function PLUGIN:CheckLinkExists(client, forumID)
local query = mysql:Select("xenforo_link")
query:Where("forum_id", forumID)
query:Callback(function(result)
if (!IsValid(client)) then return end
if (result and #result > 0) then
client:NotifyLocalized("xenforoUserAlreadyLinked")
return
else
PLUGIN:StartLink(client, forumID)
end
end)
query:Execute()
end
function PLUGIN:StartLink(client, forumID)
if (!self.API_KEY) then return end
if (!self:CheckClientWait(client)) then return end
--TODO: add link start log
client.ixXenforoLink = {
id = tostring(forumID),
code = PLUGIN.GenerateCode(),
validUntil = os.time() + self.TOKEN_VALID * 60,
fails = 0
}
client:SetLocalVar("xenforoLinkStart", os.time())
local steamName = client:SteamName()
local messageText = string.format(self.messageText, steamName, client.ixXenforoLink.code)
local endpoint = string.format("https://willard.network/forums/api/conversations/")
local request = {
failed = function(error)
print("[XENFORO-LINK] Failed to send message: "..error)
print("[XENFORO-LINK] Client: "..steamName)
if (IsValid(client)) then
client:NotifyLocalized("xenforoFailedCreatePM")
end
end,
success = function(code, body, headers)
if (!IsValid(client)) then return end
local httpResult = util.JSONToTable(body)
if (!httpResult) then
print("[XENFORO-LINK] Received invalid response; endpoint: "..endpoint)
client:NotifyLocalized("xenforoFailedCreatePM")
return
end
if (httpResult.errors) then
print("[XENFORO-LINK] Failed to send PM")
ix.log.AddRaw("[XENFORO-LINK] Send message error: "..util.TableToJSON(httpResult))
client:NotifyLocalized("xenforoFailedCreatePMError")
return
end
client:ChatNotifyLocalized("xenforoCodeSend")
end,
url = endpoint,
parameters = {
["recipient_ids[]"] = tostring(client.ixXenforoLink.id),
["title"] = "Account Link Token",
["message"] = messageText,
["conversation_open"] = "0",
["open_invite"] = "0",
},
method = "POST",
type = "application/x-www-form-urlencoded",
headers = {["XF-Api-Key"] = self.API_KEY}
}
CHTTP(request)
end
function PLUGIN:FinishLink(client, code)
if (!self:CheckClientWait(client)) then return end
if (!client.ixXenforoLink) then
client:NotifyLocalized("xenoforoNoLinkActive")
return
end
if (client.ixXenforoLink.validUntil < os.time()) then
client:SetLocalVar("xenforoLinkStart", nil)
client.ixXenforoLink = nil
client:NotifyLocalized("xenoforoLinkNotValid")
return
end
code = string.Trim(code)
if (code == "") then
return
end
if (client.ixXenforoLink.code == code) then
self:FinalCheckLinkExists(client, client.ixXenforoLink.id)
else
client.ixXenforoLink.fails = client.ixXenforoLink.fails + 1
if (client.ixXenforoLink.fails >= self.MAX_ATTEMPTS) then
client:SetData("xenforoLinkFailPause", os.time() + self.FAILS_WAIT * 60)
client:SetLocalVar("xenforoLinkStart", nil)
client.ixXenforoLink = nil
client:NotifyLocalized("xenforoFailsPauseStart")
else
client:NotifyLocalized("xenforoWrongCode", self.MAX_ATTEMPTS - client.ixXenforoLink.fails)
end
end
end
function PLUGIN:FinalCheckLinkExists(client, forumID)
local query = mysql:Select("xenforo_link")
query:Where("forum_id", forumID)
query:Callback(function(result)
if (!IsValid(client)) then return end
if (result and #result > 0) then
client:NotifyLocalized("xenforoUserAlreadyLinked")
return
else
local insert = mysql:Insert("xenforo_link")
insert:Insert("steamid", client:SteamID64())
insert:Insert("forum_id", forumID)
insert:Execute()
client.ixXenforoID = forumID
client.ixXenforoLink = nil
client:NotifyLocalized("xenforoLinkSuccess")
self:GetXenforoGroups(client, client)
end
end)
query:Execute()
end
function PLUGIN:RemoveLink(client)
local query = mysql:Delete("xenforo_link")
query:Where("steamid", client:SteamID64())
query:Execute()
client.ixXenforoID = nil
client.ixXenforoGroups = nil
client:SetLocalVar("xenforoLink", false)
client:SetLocalVar("xenforoLinkStart", nil)
ix.xenforo:ApplyInGameGroups(client)
client:NotifyLocalized("xenforoLinkRemoved")
end

View File

@@ -0,0 +1,103 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
function PLUGIN:InitAPIKey()
if (!CHTTP) then return end
self.API_KEY = file.Read("gamemodes/helix/plugins/xenforolink/apikey.txt", "GAME")
if (self.API_KEY) then
self.API_KEY = string.gsub(self.API_KEY, "[^%w%-]", "")
end
end
function PLUGIN:GetXenforoGroups(client, notify)
if (!self.API_KEY) then return end
if (client.ixXenforoID) then
client:SetLocalVar("xenforoLink", true)
local steamName = client:SteamName()
local endpoint = string.format("https://willard.network/forums/api/users/%s/?with_posts=0", tostring(client.ixXenforoID))
local request = {
failed = function(error)
print("[XENFORO-LINK] Failed to find user: "..error)
print("[XENFORO-LINK] Client: "..steamName.."; endpoint: "..endpoint)
if (IsValid(client)) then
ix.xenforo:ApplyInGameGroups(client)
end
end,
success = function(code, body, headers)
if (!IsValid(client)) then return end
local httpResult = util.JSONToTable(body)
if (!httpResult) then
print("[XENFORO-LINK] Received invalid response; endpoint: "..endpoint)
ix.xenforo:ApplyInGameGroups(client)
return
end
if (!httpResult.user) then
print("[XENFORO-LINK] Received invalid response (no user); endpoint: "..endpoint)
ix.xenforo:ApplyInGameGroups(client)
return
end
local groups = {}
if (ix.xenforo:IsValidGroupID(httpResult.user["user_group_id"])) then
groups[#groups + 1] = tostring(httpResult.user["user_group_id"])
end
for _, v in ipairs(httpResult.user["secondary_group_ids"]) do
if (ix.xenforo:IsValidGroupID(v)) then
groups[#groups + 1] = tostring(v)
end
end
if (#groups > 0) then
client.ixXenforoGroups = groups
else
client.ixXenforoGroups = nil
end
local query = mysql:Update("xenforo_link")
query:Update("groups", groups and util.TableToJSON(groups) or nil)
query:Where("steamid", client:SteamID64())
query:Execute()
ix.xenforo:ApplyInGameGroups(client)
if (IsValid(notify)) then
if (client == notify) then
notify:NotifyLocalized("xenforoGroupsUpdateSelf", #groups)
else
notify:NotifyLocalized("xenforoGroupsUpdate", steamName, #groups)
end
end
end,
url = endpoint,
method = "GET",
headers = {
["XF-Api-Key"] = self.API_KEY
}
}
if (!CHTTP(request)) then
ix.xenforo:ApplyInGameGroups(client)
end
else
client:SetLocalVar("xenforoLink", false)
ix.xenforo:ApplyInGameGroups(client)
if (notify) then
notify:NotifyLocalized("xenforoNotLinked", client:SteamName())
end
end
end