This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 0e770b2b49
commit 94063e4369
7342 changed files with 1718932 additions and 14 deletions

View File

@@ -0,0 +1,18 @@
--[[
| 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 netstream = sam.netstream
netstream.Hook("PlaySound", function(sound)
surface.PlaySound(sound)
end)

View File

@@ -0,0 +1,79 @@
--[[
| 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 netstream = sam.netstream
local nwvars = {}
if SERVER then
function sam.player.set_nwvar(ply, key, value, force)
local id = ply:EntIndex()
if force or nwvars[id][key] ~= value then
nwvars[id][key] = value
netstream.Start(nil, "SetNWVar", id, key, value)
end
end
end
if CLIENT then
function sam.player.set_nwvar(ply, key, value)
local id_vars = nwvars[ply:EntIndex()]
id_vars[key] = value
end
netstream.Hook("SetNWVar", function(id, key, value)
local id_vars = nwvars[id]
if id_vars == nil then
nwvars[id] = {
[key] = value
}
else
id_vars[key] = value
end
end)
netstream.Hook("SendNWVars", function(vars)
nwvars = vars
end)
netstream.Hook("RemoveNWVar", function(id)
nwvars[id] = nil
end)
end
function sam.player.get_nwvar(ply, key, default)
local value = nwvars[ply:EntIndex()]
if value then
value = value[key]
if value ~= nil then
return value
end
end
return default
end
if SERVER then
hook.Add("OnEntityCreated", "SAM.NWVars", function(ent)
if ent:IsPlayer() and ent:IsValid() then
nwvars[ent:EntIndex()] = {}
netstream.Start(ent, "SendNWVars", nwvars)
end
end)
hook.Add("EntityRemoved", "SAM.NWVars", function(ent)
if ent:IsPlayer() then
local id = ent:EntIndex()
nwvars[id] = nil
netstream.Start(nil, "RemoveNWVar", id)
end
end)
end

View File

@@ -0,0 +1,183 @@
--[[
| 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 config = sam.config
do
local _player = {}
sam.player = setmetatable(sam.player, {
__index = _player,
__newindex = function(_, k, v)
_player[k] = v
if sam.isfunction(v) and debug.getlocal(v, 1) == "ply" then
FindMetaTable("Player")["sam_" .. k] = v
sam.console["sam_" .. k] = v
end
end
})
end
function sam.player.find_by_name(name)
name = name:lower()
local current, players = nil, player.GetAll()
for i = 1, #players do
local ply = players[i]
local found = ply:Name():lower():find(name, 1, true)
if found then
if current then
if not sam.istable(current) then
current = {current, ply}
else
table.insert(current, ply)
end
else
current = ply
end
end
end
return current
end
do
if CLIENT then
config.add_menu_setting("Chat Prefix (Leave empty for no prefix)", function()
local entry = vgui.Create("SAM.TextEntry")
entry:SetPlaceholder("")
entry:SetNoBar(true)
entry:SetConfig("ChatPrefix", "")
return entry
end)
end
function sam.player.send_message(ply, msg, tbl)
if SERVER then
if sam.isconsole(ply) then
local result = sam.format_message(msg, tbl)
sam.print(unpack(result, 1, result.__cnt))
else
return sam.netstream.Start(ply, "send_message", msg, tbl)
end
else
local prefix_result = sam.format_message(config.get("ChatPrefix", ""))
local prefix_n = #prefix_result
local result = sam.format_message(msg, tbl, prefix_result, prefix_n)
chat.AddText(unpack(result, 1, result.__cnt))
end
end
if SERVER then
function sam.player.add_text(ply, ...)
if sam.isconsole(ply) then
sam.print(...)
else
sam.netstream.Start(ply, "add_text", ...)
end
end
end
if CLIENT then
sam.netstream.Hook("send_message", function(msg, tbl)
sam.player.send_message(nil, msg, tbl)
end)
sam.netstream.Hook("add_text", function(...)
chat.AddText(...)
end)
end
end
do
local PLAYER = FindMetaTable("Player")
function PLAYER:IsAdmin()
return self:CheckGroup("admin")
end
function PLAYER:IsSuperAdmin()
return self:CheckGroup("superadmin")
end
local inherits_from = sam.ranks.inherits_from
function PLAYER:CheckGroup(name)
return inherits_from(self:sam_getrank(), name)
end
local has_permission = sam.ranks.has_permission
function PLAYER:HasPermission(perm)
return has_permission(self:sam_getrank(), perm)
end
local can_target = sam.ranks.can_target
function PLAYER:CanTarget(ply)
return can_target(self:sam_getrank(), ply:sam_getrank())
end
function PLAYER:CanTargetRank(rank)
return can_target(self:sam_getrank(), rank)
end
local get_ban_limit = sam.ranks.get_ban_limit
function PLAYER:GetBanLimit(ply)
return get_ban_limit(self:sam_getrank())
end
function PLAYER:sam_get_play_time()
return self:sam_get_nwvar("play_time", 0) + self:sam_get_session_time()
end
function PLAYER:sam_get_session_time()
return os.time() - self:sam_get_nwvar("join_time", 0)
end
function PLAYER:sam_getrank()
return self:sam_get_nwvar("rank", "user")
end
function PLAYER:sam_setrank(name)
return self:sam_set_nwvar("rank", name)
end
if SERVER then
function PLAYER:Ban(length)
self:sam_ban(length)
end
hook.Remove("PlayerInitialSpawn", "PlayerAuthSpawn")
end
end
do
local set_cooldown = function(ply, name, time)
if not ply.sam_cool_downs then
ply.sam_cool_downs = {}
end
ply.sam_cool_downs[name] = SysTime() + time
return true
end
function sam.player.check_cooldown(ply, name, time)
if not ply.sam_cool_downs or not ply.sam_cool_downs[name] then
return set_cooldown(ply, name, time)
end
local current_time = SysTime()
local cool_down = ply.sam_cool_downs[name]
if cool_down > current_time then
return false, cool_down - current_time
else
return set_cooldown(ply, name, time)
end
end
end

139
lua/sam/player/sv_auth.lua Normal file
View File

@@ -0,0 +1,139 @@
--[[
| 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, SQL = sam, sam.SQL
local auth_player = function(data, ply)
if not ply:IsValid() then return end
if ply:sam_get_nwvar("is_authed") then return end
local steamid = ply:SteamID()
local rank, expiry_date, play_time
local first_join = false
if data then
rank, expiry_date, play_time = data.rank, tonumber(data.expiry_date), tonumber(data.play_time)
SQL.FQuery([[
UPDATE
`sam_players`
SET
`name` = {1},
`last_join` = {2}
WHERE
`steamid` = {3}
]], {ply:Name(), os.time(), steamid})
else
rank, expiry_date, play_time = "user", 0, 0
first_join = true
local time = os.time()
SQL.FQuery([[
INSERT INTO
`sam_players`(
`steamid`,
`name`,
`rank`,
`expiry_date`,
`first_join`,
`last_join`,
`play_time`
)
VALUES
({1}, {2}, {3}, {4}, {5}, {6}, {7})
]], {steamid, ply:Name(), rank, 0, time, time, 0})
end
ply:SetUserGroup(rank)
ply:sam_setrank(rank)
ply:sam_start_rank_timer(expiry_date)
ply:sam_set_nwvar("join_time", os.time())
ply:sam_set_nwvar("play_time", play_time)
ply:sam_set_nwvar("is_authed", true)
hook.Call("SAM.AuthedPlayer", nil, ply, steamid, first_join)
timer.Simple(0, function()
if IsValid(ply) then
sam.client_hook_call("SAM.AuthedPlayer", ply, steamid, first_join)
end
end)
end
hook.Add("PlayerInitialSpawn", "SAM.AuthPlayer", function(ply)
SQL.FQuery([[
SELECT
`rank`,
`expiry_date`,
`play_time`
FROM
`sam_players`
WHERE
`steamid` = {1}
]], {ply:SteamID()}, auth_player, true, ply)
end)
sam.player.auth = auth_player
hook.Add("SAM.AuthedPlayer", "SetSuperadminToListenServer", function(ply)
if game.SinglePlayer() or ply:IsListenServerHost() then
ply:sam_set_rank("superadmin")
end
end)
hook.Add("SAM.AuthedPlayer", "CheckIfFullyAuthenticated", function(ply)
timer.Simple(0, function()
if not IsValid(ply) then return end
if ply:IsBot() then return end
if not ply.IsFullyAuthenticated or ply:IsFullyAuthenticated() then return end
if game.SinglePlayer() or ply:IsListenServerHost() then return end
ply:Kick("Your SteamID wasn't fully authenticated, try restarting steam.")
end)
end)
do
local format = string.format
local floor = math.floor
local SysTime = SysTime
local last_save = SysTime()
local save_play_time = function(ply)
if not ply:sam_get_nwvar("is_authed") then return end
local query = format([[
UPDATE
`sam_players`
SET
`play_time` = %u
WHERE
`steamid` = '%s'
]], floor(ply:sam_get_play_time()), ply:SteamID())
SQL.Query(query)
end
hook.Add("Think", "SAM.Player.SaveTimes", function()
if SysTime() - last_save < 60 then return end
SQL.Begin()
local players = player.GetHumans()
for i = 1, #players do
save_play_time(players[i])
end
SQL.Commit()
sam.hook_call("SAM.UpdatedPlayTimes")
last_save = SysTime()
end)
hook.Add("PlayerDisconnected", "SAM.Player.SaveTime", save_play_time)
end

291
lua/sam/player/sv_bans.lua Normal file
View File

@@ -0,0 +1,291 @@
--[[
| 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

View File

@@ -0,0 +1,157 @@
--[[
| 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 netstream = sam.netstream
do
local connected_players = {}
function sam.player.kick_id(id, reason)
reason = sam.isstring(reason) and reason or sam.language.get("default_reason")
reason = reason:sub(1, 400)
game.KickID(id, reason)
end
function sam.player.is_connected(steamid)
return connected_players[steamid] and true or false
end
function sam.get_connected_players()
return connected_players
end
gameevent.Listen("player_connect")
hook.Add("player_connect", "SAM.ConnectedPlayers", function(data)
connected_players[data.networkid] = true
end)
gameevent.Listen("player_disconnect")
hook.Add("player_disconnect", "SAM.ConnectedPlayers", function(data)
connected_players[data.networkid] = nil
end)
end
function sam.player.set_exclusive(ply, reason)
ply.sam_exclusive_reason = reason
end
function sam.player.get_exclusive(ply, admin)
local reason = ply.sam_exclusive_reason
if reason then
if ply == admin then
return "You are " .. reason .. "!"
else
return ply:Name() .. " is " .. reason .. "!"
end
end
end
do
local hide_weapons = function(ply, should_hide)
for _, v in pairs(ply:GetWeapons()) do
v:SetNoDraw(should_hide)
end
local physgun_beams = ents.FindByClassAndParent("physgun_beam", ply)
if physgun_beams then
for i = 1, #physgun_beams do
physgun_beams[i]:SetNoDraw(should_hide)
end
end
end
local cloak = function(ply, should_cloak)
ply:SetNoDraw(should_cloak)
ply:DrawWorldModel(not should_cloak)
ply:SetRenderMode(should_cloak and RENDERMODE_TRANSALPHA or RENDERMODE_NORMAL)
ply:Fire("alpha", should_cloak and 0 or 255, 0)
ply:sam_set_nwvar("cloaked", should_cloak)
hide_weapons(ply, should_cloak)
end
function sam.player.cloak(ply)
cloak(ply, true)
end
function sam.player.uncloak(ply)
cloak(ply, false)
end
hook.Add("PlayerSpawn", "SAM.CloakPlayer", function(ply)
if ply:sam_get_nwvar("cloaked") then
cloak(ply, true)
end
end)
hook.Add("PlayerSwitchWeapon", "SAM.CloakPlayer", function(ply)
if ply:sam_get_nwvar("cloaked") then
timer.Create("SAM.HideWeapons" .. ply:SteamID(), 0, 1, function()
if IsValid(ply) and ply:sam_get_nwvar("cloaked") then
hide_weapons(ply, true)
end
end)
end
end)
end
do
local call_hook = function(ply)
local can_spawn = hook.Call("SAM.CanPlayerSpawn", nil, ply)
if can_spawn ~= nil then
return can_spawn
end
end
local spawn_hooks = {
"Effect", "NPC",
"Object", "Prop",
"Ragdoll", "SENT",
"SWEP", "Vehicle"
}
for k, v in ipairs(spawn_hooks) do
hook.Add("PlayerSpawn" .. v, "SAM.CanPlayerSpawn", call_hook)
end
end
do
local persistent_data = {}
function sam.player.set_pdata(ply, key, value)
local ply_pdata = persistent_data[ply:AccountID()]
if ply_pdata then
ply_pdata[key] = value
else
persistent_data[ply:AccountID()] = {
[key] = value
}
end
end
function sam.player.get_pdata(ply, key, default)
local ply_pdata = persistent_data[ply:AccountID()]
if ply_pdata then
local value = ply_pdata[key]
if value ~= nil then
return value
end
end
return default
end
end
function sam.player.play_sound(ply, sound)
netstream.Start(ply, "PlaySound", sound)
end
--[[/*953ed60e46bbecc33df4049c215b53951c0dfcb21fbe82bbeb63c201211c72dc*/]]

215
lua/sam/player/sv_ranks.lua Normal file
View File

@@ -0,0 +1,215 @@
--[[
| 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, Promise = sam.SQL, sam.Promise
function sam.player.set_rank(ply, rank, length)
if sam.type(ply) ~= "Player" or not ply:IsValid() then
error("invalid player")
elseif not sam.ranks.is_rank(rank) then
error("invalid rank")
end
if not sam.isnumber(length) or length < 0 then
length = 0
end
local expiry_date = 0
if length ~= 0 then
if rank == "user" then
expiry_date = 0
else
expiry_date = (math.min(length, 31536000) * 60) + os.time()
end
end
ply:sam_start_rank_timer(expiry_date)
SQL.FQuery([[
UPDATE
`sam_players`
SET
`rank` = {1},
`expiry_date` = {2}
WHERE
`steamid` = {3}
]], {rank, expiry_date, ply:SteamID()})
local old_rank = ply:sam_getrank()
ply:SetUserGroup(rank)
ply:sam_setrank(rank)
sam.hook_call("SAM.ChangedPlayerRank", ply, rank, old_rank, expiry_date)
end
do
local set_rank_id = function(player_data, arguments)
local old_rank = player_data and player_data.rank or false
local promise, steamid, rank, length = unpack(arguments, 1, 4)
local expiry_date = 0
if length ~= 0 then
if rank == "user" then
expiry_date = 0
else
expiry_date = (math.min(length, 31536000) * 60) + os.time()
end
end
local exists = true
if old_rank == false then
exists, old_rank = false, "user"
local time = os.time()
SQL.FQuery([[
INSERT INTO
`sam_players`(
`steamid`,
`name`,
`rank`,
`expiry_date`,
`first_join`,
`last_join`,
`play_time`
)
VALUES
({1}, {2}, {3}, {4}, {5}, {6}, {7})
]], {steamid, "", rank, 0, time, time, 0})
else
SQL.FQuery([[
UPDATE
`sam_players`
SET
`rank` = {1},
`expiry_date` = {2}
WHERE
`steamid` = {3}
]], {rank, expiry_date, steamid})
end
promise:resolve()
sam.hook_call("SAM.ChangedSteamIDRank", steamid, rank, old_rank, expiry_date, exists)
end
function sam.player.set_rank_id(steamid, rank, length)
sam.is_steamid(steamid, true)
if not sam.ranks.is_rank(rank) then
error("invalid rank")
end
local promise = Promise.new()
do
local ply = player.GetBySteamID(steamid)
if ply then
promise:resolve(ply:sam_set_rank(rank, length))
return promise
end
end
if not sam.isnumber(length) or length < 0 then
length = 0
end
SQL.FQuery([[
SELECT
`rank`
FROM
`sam_players`
WHERE
`steamid` = {1}
]], {steamid}, set_rank_id, true, {promise, steamid, rank, length})
return promise
end
end
do
local get_rank = function(data, callback)
if not data then
callback(false)
else
callback(data.rank)
end
end
function sam.player.get_rank(steamid, callback)
sam.is_steamid(steamid, true)
SQL.FQuery([[
SELECT
`rank`
FROM
`sam_players`
WHERE
`steamid` = {1}
]], {steamid}, get_rank, true, callback)
end
end
do
local remove_rank_timer = function(ply)
timer.Remove("SAM.RankTimer." .. ply:SteamID())
end
function sam.player.start_rank_timer(ply, expiry_date)
ply.sam_rank_expirydate = expiry_date
if expiry_date == 0 then -- permanent rank
return remove_rank_timer(ply)
end
expiry_date = expiry_date - os.time()
timer.Create("SAM.RankTimer." .. ply:SteamID(), expiry_date, 1, function()
sam.player.send_message(nil, "rank_expired", {
T = {ply, admin = sam.console}, V = ply:sam_getrank()
})
ply:sam_set_rank("user")
end)
end
hook.Add("PlayerDisconnected", "SAM.RemoveRankTimer", remove_rank_timer)
end
hook.Add("SAM.OnRankRemove", "ResetPlayerRank", function(name)
for _, ply in ipairs(player.GetAll()) do
if ply:sam_getrank() == name then
ply:sam_set_rank("user")
end
end
SQL.FQuery([[
UPDATE
`sam_players`
SET
`rank` = 'user',
`expiry_date` = 0
WHERE
`rank` = {1}
]], {name})
end)
hook.Add("SAM.RankNameChanged", "ChangePlayerRankName", function(old, new)
for _, ply in ipairs(player.GetAll()) do
if ply:sam_getrank() == old then
ply:sam_set_rank(new)
end
end
SQL.FQuery([[
UPDATE
`sam_players`
SET
`rank` = {1}
WHERE
`rank` = {2}
]], {new, old})
end)