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,58 @@
--[[
| 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, command = sam, sam.command
command.new_argument("dropdown")
:OnExecute(function(arg, input, ply, _, result)
if not arg.options or table.Empty(arg.options) then
ply:sam_send_message("no data", {S = "dropdown", S_2 = input})
return
end
table.insert(result, input)
end)
:Menu(function(set_result, body, buttons, arg)
local default = arg.hint or "select"
local cbo = buttons:Add("SAM.ComboBox")
cbo:SetValue(default)
cbo:SetTall(25)
function cbo:OnSelect(_, value)
set_result(value)
default = value
end
function cbo:DoClick()
if self:IsMenuOpen() then
return self:CloseMenu()
end
self:Clear()
self:SetValue(default)
if not arg.options then
LocalPlayer():sam_send_message("dropdown has no options data")
return
end
for k, v in pairs(arg.options) do
self:AddChoice(v)
end
self:OpenMenu()
end
return cbo
end)
:End()

View File

@@ -0,0 +1,72 @@
--[[
| 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, command = sam, sam.command
local get_length = function(arg, input)
if (input == "" or input == nil) and arg.optional then
if arg.default ~= nil then
return arg.default
end
return ""
end
return sam.parse_length(input)
end
command.new_argument("length")
:OnExecute(function(arg, input, ply, _, result, i)
local length = get_length(arg, input)
if length == "" then
result[i] = nil
elseif not length then
ply:sam_send_message("invalid", {
S = "length", S_2 = input
})
return false
else
if arg.min and length ~= 0 then
length = math.max(length, arg.min)
end
if arg.max then
if length == 0 then
length = arg.max
else
length = math.min(length, arg.max)
end
end
result[i] = length
end
end)
:Menu(function(set_result, body, buttons, argument)
local length_input = buttons:Add("SAM.TextEntry")
length_input:SetTall(25)
length_input:SetCheck(function(new_limit)
new_limit = get_length(argument, new_limit) or nil
set_result(new_limit)
return new_limit or false
end)
local hint = argument.hint or "length"
if argument.default then
hint = hint .. " = " .. tostring(argument.default)
end
length_input:SetPlaceholder(hint)
return length_input
end)
:End()

View File

@@ -0,0 +1,60 @@
--[[
| 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, command = sam, sam.command
command.new_argument("map")
:OnExecute(function(argument, input, ply, _, result)
local map_name = sam.is_valid_map(input)
if not map_name and not (argument.optional and input == "None") then
ply:sam_send_message("invalid", {
S = "map", S_2 = input
})
return false
end
table.insert(result, map_name)
end)
:Menu(function(set_result, _, buttons, argument)
local maps = buttons:Add("SAM.ComboBox")
maps:SetTall(25)
if argument.optional then
maps:AddChoice("None", nil, true)
end
for _, map_name in ipairs(sam.get_global("Maps")) do
if not (argument.exclude_current and map_name == game.GetMap()) then
maps:AddChoice(map_name)
end
end
function maps:OnSelect(_, value)
set_result(value)
end
local value = argument.optional and "None" or maps:GetOptionText(1)
maps:SetValue(value)
maps:OnSelect(nil, value)
return maps
end)
:AutoComplete(function(_, result, name)
for _, map_name in ipairs(sam.get_global("Maps")) do
if map_name:lower():find(name, 1, true) then
table.insert(result, map_name)
end
end
end)
:End()

View File

@@ -0,0 +1,77 @@
--[[
| 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, command = sam, sam.command
local get_number = function(argument, input, gsub)
if (input == "" or input == nil) and argument.optional then
if argument.default ~= nil then
return argument.default
end
return ""
end
local number = tonumber(input)
if gsub ~= false and not isnumber(number) then
number = tonumber(input:gsub("%D", ""), 10 /*gsub returns two args*/)
end
return number
end
command.new_argument("number")
:OnExecute(function(argument, input, ply, _, result, i)
local number = get_number(argument, input)
if number == "" then
result[i] = nil
elseif not number then
ply:sam_send_message("invalid", {
S = argument.hint or "number", S_2 = input
})
return false
else
if argument.min then
number = math.max(number, argument.min)
end
if argument.max then
number = math.min(number, argument.max)
end
if argument.round then
number = math.Round(number)
end
result[i] = number
end
end)
:Menu(function(set_result, body, buttons, argument)
local number_entry = buttons:Add("SAM.TextEntry")
number_entry:SetUpdateOnType(true)
number_entry:SetNumeric(true)
number_entry:SetTall(25)
number_entry:SetCheck(function(number)
number = get_number(argument, number, false)
set_result(number)
return number or false
end)
local hint = argument.hint or "number"
if argument.default then
hint = hint .. " = " .. tostring(argument.default)
end
number_entry:SetPlaceholder(hint)
return number_entry
end)
:End()

View File

@@ -0,0 +1,456 @@
--[[
| 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, command = sam, sam.command
local can_target_player = function(arg, admin, target, cmd, input)
if not IsValid(target) or not target:IsPlayer() or not target:sam_get_nwvar("is_authed") then
if input then
admin:sam_send_message("cant_find_target", {
S = input
})
end
return false
end
if not arg.allow_higher_target and not admin:CanTarget(target) then
if cmd then
admin:sam_send_message("cant_target_player", {
S = target:Name()
})
end
return false
end
if arg.cant_target_self and admin == target then
if cmd then
admin:sam_send_message("cant_target_self", {
S = cmd.name
})
end
return false
end
return true
end
local check_text_match = function(text, ply)
if ply:Name():lower():find(text, 1, true) then return true end
if ply:sam_getrank():lower():find(text, 1, true) then return true end
if team.GetName(ply:Team()):lower():find(text, 1, true) then return true end
if not ply:IsBot() then
return ply:SteamID():lower():find(text, 1, true) or ply:SteamID64():lower():find(text, 1, true)
end
return false
end
command.new_argument("player")
:OnExecute(function(arg, input, ply, cmd, result, n)
if input == nil and arg.optional then
if sam.isconsole(ply) then
ply:sam_send_message("cant_target_self", {
S = cmd.name
})
return false
end
result[n] = {ply, admin = ply, input = input}
return
end
local single_target = arg.single_target
local targets = {admin = ply, input = input}
if input == "*" then
if single_target then
ply:sam_send_message("cant_target_multi_players")
return false
end
local players = player.GetAll()
for i = 1, #players do
local v = players[i]
if can_target_player(arg, ply, v) then
table.insert(targets, v)
end
end
elseif input:sub(1, 1) == "#" and not single_target then
local tmp = {}
for _, v in ipairs(input:sub(2):Trim():Split(",")) do
v = tonumber(v)
if not sam.isnumber(v) then continue end
local target = Entity(v)
if not tmp[target] and IsValid(target) and target:IsPlayer() then
tmp[target] = true
if can_target_player(arg, ply, target) then
table.insert(targets, target)
end
end
end
else
local target
if input == "^" then
target = ply
elseif input == "@" and not sam.isconsole(ply) then
target = ply:GetEyeTrace().Entity
elseif sam.is_steamid(input) then
target = player.GetBySteamID(input)
elseif sam.is_steamid64(input) then
target = player.GetBySteamID64(input)
elseif input:sub(1, 1) == "#" then
local index = input:sub(2):Trim()
index = tonumber(index)
if not isnumber(index) then
ply:sam_send_message("invalid_id", {
S = input
})
return false
end
target = Entity(index)
if not IsValid(target) or not target:IsPlayer() then
ply:sam_send_message("player_id_not_found", {
S = index
})
return false
end
else
if input:sub(1, 1) == "%" and #input > 1 then
input = input:sub(2)
end
target = sam.player.find_by_name(input)
if sam.istable(target) then
if single_target then
ply:sam_send_message("found_multi_players", {T = target})
return false
else
for k, v in ipairs(target) do
if can_target_player(arg, ply, v) then
table.insert(targets, v)
end
end
goto _end
end
end
end
if not can_target_player(arg, ply, target, cmd, input) then
return false
end
table.insert(targets, target)
end
::_end::
if #targets == 0 then
ply:sam_send_message("cant_find_target", {
S = input
})
return false
end
result[n] = targets
end)
-- Do NOT ask me about this code at all please because I feel shit about it but I'm not gonna make
-- a file specially for this one
:Menu(function(set_result, body, buttons, argument, childs)
if body.ply_list then
local ply_list = body.ply_list
ply_list.argument = argument
ply_list.set_result = set_result
ply_list.multi_select = argument.single_target ~= true
if argument.single_target == true and #ply_list:GetSelected() > 1 then
ply_list:ClearSelection()
end
ply_list:OnRowSelected()
ply_list:GetParent():Show()
return
end
local SUI = sam.SUI
local SetVisible = FindMetaTable("Panel").SetVisible
local left_body = body:Add("SAM.Panel")
left_body:Dock(LEFT)
left_body:DockMargin(0, 0, 5, 0)
left_body:SetWide(0)
left_body.no_remove = true
left_body.no_change = "player"
SetVisible(left_body, false)
left_body.SetVisible = function(s, visible)
if visible == s:IsVisible() or visible == s.visible_state then return end
if visible then
SetVisible(s, true)
s:InvalidateLayout(true)
end
s.visible_state = visible
s:Stop()
s:SizeTo(visible and SUI.Scale(320) or 0, -1, 0.2, 0, 0, function()
SetVisible(s, visible)
s:InvalidateParent(true)
end)
end
left_body:Show()
table.insert(childs, left_body)
local ply_list = left_body:Add("SAM.ScrollPanel")
ply_list:Dock(FILL)
ply_list:Background(Color(34, 34, 34), 3)
ply_list.argument = argument
ply_list.set_result = set_result
ply_list.multi_select = argument.single_target ~= true
ply_list.Paint = function(s, w, h)
s:RoundedBox("Background", 3, 0, 0, w, h, SUI.GetColor("text_entry_bg"))
end
local lines = {}
function ply_list:OnClickLine(line, clear)
local multi_select = ply_list.multi_select
if not multi_select and not clear then return end
if multi_select and input.IsKeyDown(KEY_LCONTROL) then
if line.Selected then
line.Selected = false
self.main_selected_line = nil
self:OnRowSelected()
return
end
clear = false
end
if multi_select and input.IsKeyDown(KEY_LSHIFT) then
local selected = self:GetSelectedLine()
if selected then
self.main_selected_line = self.main_selected_line or selected
if clear then
self:ClearSelection()
end
local first = math.min(self.main_selected_line.id, line.id)
local last = math.max(self.main_selected_line.id, line.id)
for id = first, last do
local line_2 = lines[id]
local was_selected = line_2.Selected
line_2.Selected = true
if not was_selected then
self:OnRowSelected(line_2.id, line_2)
end
end
return
end
end
if not multi_select or clear then
self:ClearSelection()
end
line.Selected = true
self.main_selected_line = line
self:OnRowSelected(line.id, line)
end
function ply_list:GetSelected()
local ret = {}
for _, v in ipairs(lines) do
if v.Selected then
table.insert(ret, v)
end
end
return ret
end
function ply_list:GetSelectedLine()
for _, line in ipairs(lines) do
if line.Selected then return line end
end
end
function ply_list:ClearSelection()
for _, line in ipairs(lines) do
line.Selected = false
end
self:OnRowSelected()
end
function ply_list:OnRowSelected()
local plys = {}
for k, v in ipairs(ply_list:GetSelected()) do
plys[k] = v.ply:EntIndex()
end
if #plys == 0 then
self.set_result(nil)
else
self.set_result("#" .. table.concat(plys, ","))
end
end
function ply_list:OnRowRightClick(_, line)
local dmenu = vgui.Create("SAM.Menu")
dmenu:SetInternal(line)
local name = line.ply:Name()
dmenu:AddOption("Copy Name", function()
SetClipboardText(name)
end)
dmenu:AddSpacer()
local steamid = line.ply:SteamID()
dmenu:AddOption("Copy SteamID", function()
SetClipboardText(steamid)
end)
dmenu:AddOption("Copy SteamID64", function()
SetClipboardText(util.SteamIDTo64(steamid))
end)
dmenu:Open()
dmenu:SetPos(input.GetCursorPos())
end
local item_click = function(s)
ply_list:OnClickLine(s, true)
end
local item_rightclick = function(s)
if not s.Selected then
ply_list:OnClickLine(s, true)
end
ply_list:OnRowRightClick(s.id, s)
end
local item_cursor = function(s)
if input.IsMouseDown(MOUSE_LEFT) then
ply_list:OnClickLine(s)
end
end
local added_players = {}
local add_player = function(ply, i)
if can_target_player(ply_list.argument, LocalPlayer(), ply) then
local player_button = ply_list:Add("SAM.Button")
player_button:Dock(TOP)
player_button:DockMargin(0, 0, 0, 2)
player_button:DockPadding(4, 4, 4, 4)
player_button:SetContained(false)
player_button:SetText("")
player_button:SetZPos(i)
player_button.DoClick = item_click
player_button.DoRightClick = item_rightclick
player_button.OnCursorMoved = item_cursor
local line = player_button:Add("SAM.PlayerLine")
line:SetMouseInputEnabled(false)
line:SetInfo({
steamid = ply:IsBot() and "BOT" or ply:SteamID(),
name = ply:Name(),
rank = ply:sam_getrank()
})
player_button:InvalidateLayout(true)
player_button:SizeToChildren(false, true)
player_button.ply = ply
player_button.line = line
player_button.id = table.insert(lines, player_button)
body.search_entry:OnValueChange()
added_players[ply] = true
end
end
ply_list:On("Think", function()
local players = player.GetAll()
for i = 1, #players do
local ply = players[i]
if not added_players[ply] then
add_player(ply, i)
end
end
local argument = ply_list.argument
for i = 1, #lines do
local line = lines[i]
local ply = line.ply
if not can_target_player(argument, LocalPlayer(), ply) then
line:Remove()
table.remove(lines, i)
added_players[ply] = nil
ply_list:OnRowSelected()
break
end
line = line.line
line:SetName(ply:Name())
line:SetRank(ply:sam_getrank())
end
end)
local search_entry = left_body:Add("SAM.TextEntry")
search_entry:Dock(TOP)
search_entry:DockMargin(0, 0, 0, 5)
search_entry:SetPlaceholder("Search... (name/steamid/rank/job)")
search_entry:SetBackground(Color(34, 34, 34))
search_entry:SetTall(25)
search_entry:SetNoBar(true)
function search_entry:OnValueChange(text)
if text == nil then
text = self:GetValue()
end
if text ~= "" then
ply_list:ClearSelection()
end
text = text:lower()
for i, line in ipairs(lines) do
local ply = line.ply
if IsValid(ply) then
line:SetVisible(check_text_match(text, ply))
end
end
ply_list:GetCanvas():InvalidateLayout(true)
end
body.ply_list = ply_list
body.search_entry = search_entry
end)
:AutoComplete(function(arg, result, name)
local ply = LocalPlayer()
for k, v in ipairs(player.GetAll()) do
if can_target_player(arg, ply, v) and v:Name():lower():find(name, 1, true) then
table.insert(result, "%" .. v:Name())
end
end
end)
:End()

View File

@@ -0,0 +1,78 @@
--[[
| 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, command = sam, sam.command
local is_good_rank = function(rank, arg, ply)
if arg.check and not arg.check(rank, ply) then
return false
end
return true
end
command.new_argument("rank")
:OnExecute(function(arg, input, ply, _, result, i)
if not input and arg.optional then
result[i] = nil
return
end
if not sam.ranks.is_rank(input) or not is_good_rank(input, arg, ply) then
ply:sam_send_message("invalid", {
S = arg.hint or "rank", S_2 = input
})
return false
end
result[i] = input
end)
:Menu(function(set_result, body, buttons, arg)
local current_rank = arg.hint or "select rank"
local ranks = buttons:Add("SAM.ComboBox")
ranks:SetValue(current_rank)
ranks:SetTall(25)
function ranks:OnSelect(_, value)
set_result(value)
current_rank = value
end
function ranks:DoClick()
if self:IsMenuOpen() then
return self:CloseMenu()
end
self:Clear()
self:SetValue(current_rank)
for rank_name in SortedPairsByMemberValue(sam.ranks.get_ranks(), "immunity", true) do
if is_good_rank(rank_name, arg, LocalPlayer()) then
self:AddChoice(rank_name)
end
end
self:OpenMenu()
end
return ranks
end)
:AutoComplete(function(arg, result, name)
for rank_name in SortedPairsByMemberValue(sam.ranks.get_ranks(), "immunity", true) do
if rank_name:lower():find(name, 1, true) and is_good_rank(rank_name, arg, LocalPlayer()) then
table.insert(result, rank_name)
end
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/
--]]
if SAM_LOADED then return end
local sam, command = sam, sam.command
local cached_ranks = {}
local targeting_offline = {}
local check_steamid = function(steamid)
if not sam.is_steamid(steamid) then
if sam.is_steamid64(steamid) then
return util.SteamIDFrom64(steamid)
else
return nil
end
end
return steamid
end
local can_target_steamid_callback = function(data, promise)
local ply, steamid = promise.ply, promise.steamid
if not data or sam.ranks.can_target(promise.rank, data.rank) then
promise:resolve({steamid})
elseif IsValid(ply) then
ply:sam_send_message("cant_target_player", {
S = steamid
})
end
targeting_offline[ply] = nil
cached_ranks[steamid] = data ~= nil and data or false
end
command.new_argument("steamid")
:OnExecute(function(argument, input, ply, _, result, i)
local steamid = check_steamid(input)
if not steamid then
ply:sam_send_message("invalid", {
S = "steamid/steamid64", S_2 = input
})
return false
end
if argument.allow_higher_target then
result[i] = steamid
return
end
local promise = sam.Promise.new()
promise.ply = ply
promise.rank = ply:sam_getrank()
promise.steamid = steamid
local target = player.GetBySteamID(steamid)
if sam.isconsole(ply) then
promise:resolve({steamid})
elseif target then
if ply:CanTarget(target) then
promise:resolve({steamid, target})
else
ply:sam_send_message("cant_target_player", {
S = steamid
})
end
elseif cached_ranks[steamid] ~= nil then
can_target_steamid_callback(cached_ranks[steamid], promise)
else
targeting_offline[ply] = true
sam.SQL.FQuery([[
SELECT
`rank`
FROM
`sam_players`
WHERE
`steamid` = {1}
]], {steamid}, can_target_steamid_callback, true, promise)
end
result[i] = promise
end)
:Menu(function(set_result, body, buttons, argument)
local steamid_entry = buttons:Add("SAM.TextEntry")
steamid_entry:SetTall(25)
steamid_entry:SetUpdateOnType(true)
steamid_entry:SetPlaceholder("steamid/steamid64")
steamid_entry:SetCheck(function(steamid)
steamid = check_steamid(steamid)
set_result(steamid)
return steamid or false
end)
return steamid_entry
end)
:End()
timer.Create("SAM.ClearCachedRanks", 60 * 2.5, 0, function()
table.Empty(cached_ranks)
end)
hook.Add("SAM.ChangedSteamIDRank", "RemoveIfCached", function(steamid)
cached_ranks[steamid] = nil
end)
hook.Add("SAM.CanRunCommand", "StopIfTargetingOffline", function(ply)
if targeting_offline[ply] then
return false
end
end)

View File

@@ -0,0 +1,70 @@
--[[
| 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, command = sam, sam.command
command.new_argument("text")
:OnExecute(function(argument, input, ply, _, result, i)
if sam.isstring(input) then
input = input:sub(1, 255)
end
local invalid = false
if input == nil then
if not argument.optional then
invalid = true
end
elseif argument.check and not argument.check(input, ply) then
invalid = true
end
if invalid then
ply:sam_send_message("invalid", {
S = argument.hint or "text", S_2 = input
})
return false
end
result[i] = input
end)
:Menu(function(set_result, body, buttons, argument)
local text_entry = buttons:Add("SAM.TextEntry")
text_entry:SetTall(25)
local default = argument.default
text_entry:SetCheck(function(text)
local valid = true
if text == "" then
if default then
text = default
elseif not argument.optional then
valid = false
end
elseif argument.check and not argument.check(text, LocalPlayer()) then
valid = false
end
set_result(valid and text or nil)
return valid
end)
local hint = argument.hint or "text"
if default then
hint = hint .. " = " .. tostring(default)
end
text_entry:SetPlaceholder(hint)
return text_entry
end)
:End()