mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
462
lua/sam/menu/tabs/players.lua
Normal file
462
lua/sam/menu/tabs/players.lua
Normal file
@@ -0,0 +1,462 @@
|
||||
--[[
|
||||
| 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 SUI = sam.SUI
|
||||
local netstream = sam.netstream
|
||||
|
||||
sam.permissions.add("manage_players", nil, "superadmin")
|
||||
|
||||
local get_pages_count = function(count)
|
||||
count = count / 35
|
||||
local i2 = math.floor(count)
|
||||
return count ~= i2 and i2 + 1 or count
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
local check = function(ply)
|
||||
return ply:HasPermission("manage_players") and ply:sam_check_cooldown("MenuViewPlayers", 0.1)
|
||||
end
|
||||
|
||||
local limit = 35
|
||||
|
||||
local get_page_count = function(callback, res, page, column, order_by, sort_by, keyword)
|
||||
local query = [[
|
||||
SELECT
|
||||
COUNT(`steamid`) AS `count`
|
||||
FROM
|
||||
`sam_players`]]
|
||||
if keyword then
|
||||
if column == "steamid" and sam.is_steamid64(keyword) then
|
||||
keyword = util.SteamIDFrom64(keyword)
|
||||
end
|
||||
|
||||
query = string.format("%s WHERE `%s` LIKE %s", query, column, SQL.Escape("%" .. keyword .. "%"))
|
||||
end
|
||||
SQL.Query(query, callback, true, {res, page, column, order_by, sort_by, keyword})
|
||||
end
|
||||
|
||||
local valid_columns = {
|
||||
steamid = true,
|
||||
name = true,
|
||||
rank = true
|
||||
}
|
||||
|
||||
local valid_sorts = {
|
||||
id = true,
|
||||
name = true,
|
||||
rank = true,
|
||||
play_time = true,
|
||||
last_join = true
|
||||
}
|
||||
|
||||
local resolve_promise = function(data, arguments)
|
||||
local res = arguments[1]
|
||||
arguments[1] = data
|
||||
res(arguments)
|
||||
end
|
||||
|
||||
local get_players = function(count_data, arguments)
|
||||
local res, page, column, order_by, sort_by, keyword = unpack(arguments)
|
||||
local count = count_data.count
|
||||
|
||||
local current_page
|
||||
if page < 1 then
|
||||
page, current_page = 1, 1
|
||||
end
|
||||
|
||||
local pages_count = get_pages_count(count)
|
||||
if page > pages_count then
|
||||
page, current_page = pages_count, pages_count
|
||||
end
|
||||
|
||||
local query = [[
|
||||
SELECT
|
||||
`steamid`,
|
||||
`name`,
|
||||
`rank`,
|
||||
`expiry_date`,
|
||||
`first_join`,
|
||||
`last_join`,
|
||||
`play_time`
|
||||
FROM
|
||||
`sam_players`
|
||||
]]
|
||||
|
||||
local args = {}
|
||||
|
||||
if keyword then
|
||||
args[1] = column
|
||||
args[2] = "%" .. keyword .. "%"
|
||||
|
||||
query = query .. [[
|
||||
WHERE
|
||||
`{1f}` LIKE {2}
|
||||
]]
|
||||
end
|
||||
|
||||
args[3] = sort_by
|
||||
if order_by == "DESC" then
|
||||
query = query .. [[
|
||||
ORDER BY `{3f}` DESC
|
||||
]]
|
||||
else
|
||||
query = query .. [[
|
||||
ORDER BY `{3f}` ASC
|
||||
]]
|
||||
end
|
||||
|
||||
args[4] = limit
|
||||
args[5] = math.abs(limit * (page - 1))
|
||||
|
||||
query = query .. [[
|
||||
LIMIT {4} OFFSET {5}
|
||||
]]
|
||||
|
||||
SQL.FQuery(query, args, resolve_promise, false, {res, count, current_page})
|
||||
end
|
||||
|
||||
netstream.async.Hook("SAM.GetPlayers", function(res, ply, page, column, order_by, sort_by, keyword)
|
||||
if not isnumber(page) then return end
|
||||
if not valid_columns[column] then return end
|
||||
if order_by ~= "ASC" and order_by ~= "DESC" then return end
|
||||
if not valid_sorts[sort_by] then return end
|
||||
if keyword ~= nil and not sam.isstring(keyword) then return end
|
||||
|
||||
get_page_count(get_players, res, page, column, order_by, sort_by, keyword)
|
||||
end, check)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local GetColor = SUI.GetColor
|
||||
local Line = sui.TDLib.LibClasses.Line
|
||||
|
||||
local COLUMN_FONT = SUI.CreateFont("Column", "Roboto", 18)
|
||||
local LINE_FONT = SUI.CreateFont("Line", "Roboto", 16)
|
||||
local NEXT_FONT = SUI.CreateFont("NextButton", "Roboto", 18)
|
||||
|
||||
local button_click = function(s)
|
||||
local v = s.v
|
||||
|
||||
local dmenu = vgui.Create("SAM.Menu")
|
||||
dmenu:SetInternal(s)
|
||||
if v.name and v.name ~= "" then
|
||||
dmenu:AddOption("Copy Name", function()
|
||||
SetClipboardText(v.name)
|
||||
end)
|
||||
end
|
||||
|
||||
dmenu:AddOption("Copy SteamID", function()
|
||||
SetClipboardText(v.steamid)
|
||||
end)
|
||||
|
||||
dmenu:AddOption("Copy Rank", function()
|
||||
SetClipboardText(v.rank)
|
||||
end)
|
||||
|
||||
dmenu:AddOption("Copy Play Time", function()
|
||||
SetClipboardText(sam.reverse_parse_length(tonumber(v.play_time) / 60))
|
||||
end)
|
||||
|
||||
dmenu:AddSpacer()
|
||||
|
||||
dmenu:AddOption("Change Rank", function()
|
||||
local querybox = vgui.Create("SAM.QueryBox")
|
||||
querybox:SetTitle(string.format("Change rank for '%s'", v.name or v.steamid))
|
||||
querybox:SetWide(360)
|
||||
|
||||
local ranks = querybox:Add("SAM.ComboBox")
|
||||
ranks:SetTall(28)
|
||||
|
||||
for rank_name in SortedPairsByMemberValue(sam.ranks.get_ranks(), "immunity", true) do
|
||||
if v.rank ~= rank_name then
|
||||
ranks:AddChoice(rank_name, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
querybox:Done()
|
||||
querybox.save:SetEnabled(true)
|
||||
|
||||
querybox:SetCallback(function()
|
||||
RunConsoleCommand("sam", "setrankid", v.steamid, ranks:GetValue())
|
||||
end)
|
||||
end)
|
||||
|
||||
dmenu:Open()
|
||||
end
|
||||
|
||||
sam.menu.add_tab("https://raw.githubusercontent.com/Srlion/Addons-Data/main/icons/sam/user.png", function(column_sheet)
|
||||
local refresh, pages
|
||||
local current_page, current_column, current_order, current_sort, keyword = nil, "steamid", "DESC", "id", nil
|
||||
|
||||
local players_body = column_sheet:Add("Panel")
|
||||
players_body:Dock(FILL)
|
||||
players_body:DockMargin(0, 1, 0, 0)
|
||||
players_body:DockPadding(10, 10, 10, 10)
|
||||
|
||||
local toggle_loading, is_loading = sam.menu.add_loading_panel(players_body)
|
||||
|
||||
local title = players_body:Add("SAM.Label")
|
||||
title:Dock(TOP)
|
||||
title:SetFont(SAM_TAB_TITLE_FONT)
|
||||
title:SetText("Players")
|
||||
title:SetTextColor(GetColor("menu_tabs_title"))
|
||||
title:SizeToContents()
|
||||
|
||||
local total = players_body:Add("SAM.Label")
|
||||
total:Dock(TOP)
|
||||
total:DockMargin(0, 6, 0, 0)
|
||||
total:SetFont(SAM_TAB_DESC_FONT)
|
||||
total:SetText("60 total players")
|
||||
total:SetTextColor(GetColor("menu_tabs_title"))
|
||||
total:SetPos(10, SUI.Scale(40))
|
||||
total:SizeToContents()
|
||||
|
||||
local search_entry
|
||||
do
|
||||
local container = players_body:Add("SAM.Panel")
|
||||
container:Dock(TOP)
|
||||
container:DockMargin(0, 6, 10, 0)
|
||||
container:SetTall(30)
|
||||
|
||||
local sort_by = container:Add("SAM.ComboBox")
|
||||
sort_by:Dock(RIGHT)
|
||||
sort_by:DockMargin(4, 0, 0, 0)
|
||||
sort_by:SetWide(106)
|
||||
sort_by:SetValue("Sort By (ID)")
|
||||
sort_by:AddChoice("ID")
|
||||
sort_by:AddChoice("Name")
|
||||
sort_by:AddChoice("Rank")
|
||||
sort_by:AddChoice("Play Time")
|
||||
|
||||
function sort_by:OnSelect(_, value)
|
||||
value = value:lower():gsub(" ", "_")
|
||||
if current_sort ~= value then
|
||||
current_sort = value
|
||||
refresh()
|
||||
end
|
||||
end
|
||||
|
||||
local sort_order = container:Add("SAM.ComboBox")
|
||||
sort_order:Dock(RIGHT)
|
||||
sort_order:SetWide(96)
|
||||
sort_order:SetValue("Desc")
|
||||
sort_order:AddChoice("Desc")
|
||||
sort_order:AddChoice("Asc")
|
||||
|
||||
function sort_order:OnSelect(_, value)
|
||||
value = value:upper()
|
||||
if current_order ~= value then
|
||||
current_order = value
|
||||
refresh()
|
||||
end
|
||||
end
|
||||
|
||||
local column = container:Add("SAM.ComboBox")
|
||||
column:Dock(RIGHT)
|
||||
column:DockMargin(0, 0, 4, 0)
|
||||
column:SetWide(140)
|
||||
|
||||
column:SetValue("Search (SteamID)")
|
||||
column:AddChoice("SteamID")
|
||||
column:AddChoice("Name")
|
||||
column:AddChoice("Rank")
|
||||
|
||||
function column:OnSelect(_, value)
|
||||
value = value:lower()
|
||||
if current_column ~= value then
|
||||
current_column = value
|
||||
refresh()
|
||||
end
|
||||
end
|
||||
|
||||
search_entry = container:Add("SAM.TextEntry")
|
||||
search_entry:Dock(LEFT)
|
||||
search_entry:SetNoBar(true)
|
||||
search_entry:SetPlaceholder("Search...")
|
||||
search_entry:SetRadius(4)
|
||||
search_entry:SetWide(220)
|
||||
|
||||
function search_entry:OnEnter(no_refresh)
|
||||
local value = self:GetValue()
|
||||
if keyword ~= value then
|
||||
keyword = value ~= "" and value or nil
|
||||
if not no_refresh then
|
||||
refresh()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Line(players_body, nil, -5, SUI.Scale(15), -5, 0)
|
||||
|
||||
do
|
||||
local columns = players_body:Add("Panel")
|
||||
columns:Dock(TOP)
|
||||
columns:DockMargin(0, 10, 0, 0)
|
||||
|
||||
local info = columns:Add("SAM.Label")
|
||||
info:Dock(LEFT)
|
||||
info:DockMargin(4, 0, 0, 0)
|
||||
info:SetFont(COLUMN_FONT)
|
||||
info:SetText("Player")
|
||||
info:SetTextColor(GetColor("player_list_titles"))
|
||||
info:SetWide(SUI.Scale(280) + SUI.Scale(34))
|
||||
info:SizeToContentsY(3)
|
||||
|
||||
local play_time = columns:Add("SAM.Label")
|
||||
play_time:Dock(LEFT)
|
||||
play_time:DockMargin(-4, 0, 0, 0)
|
||||
play_time:SetFont(COLUMN_FONT)
|
||||
play_time:SetText("Play Time")
|
||||
play_time:SetTextColor(GetColor("player_list_titles"))
|
||||
play_time:SetWide(SUI.Scale(180))
|
||||
play_time:SizeToContentsY(3)
|
||||
|
||||
local rank_expiry = columns:Add("SAM.Label")
|
||||
rank_expiry:Dock(LEFT)
|
||||
rank_expiry:DockMargin(-4, 0, 0, 0)
|
||||
rank_expiry:SetFont(COLUMN_FONT)
|
||||
rank_expiry:SetText("Rank Expiry")
|
||||
rank_expiry:SetTextColor(GetColor("player_list_titles"))
|
||||
rank_expiry:SetWide(SUI.Scale(280))
|
||||
rank_expiry:SizeToContentsY(3)
|
||||
|
||||
columns:SizeToChildren(false, true)
|
||||
end
|
||||
|
||||
local body = players_body:Add("SAM.ScrollPanel")
|
||||
body:Dock(FILL)
|
||||
body:DockMargin(0, 10, 0, 0)
|
||||
body:SetVBarPadding(6)
|
||||
|
||||
local set_data = function(data)
|
||||
body:GetCanvas():Clear()
|
||||
body.VBar.Scroll = 0
|
||||
|
||||
local players, players_count, current_page_2 = unpack(data)
|
||||
total:SetText(players_count .. " total players")
|
||||
|
||||
pages = get_pages_count(players_count)
|
||||
current_page.i = pages == 0 and 0 or current_page_2 or current_page.i
|
||||
current_page:SetText(current_page.i .. "/" .. pages)
|
||||
|
||||
body:Line()
|
||||
|
||||
for k, v in ipairs(players) do
|
||||
local line = body:Add("SAM.PlayerLine")
|
||||
line:DockMargin(0, 0, 0, 10)
|
||||
|
||||
local name = v.name ~= "" and v.name or nil
|
||||
line:SetInfo({
|
||||
steamid = v.steamid,
|
||||
name = name,
|
||||
rank = v.rank
|
||||
})
|
||||
|
||||
local play_time = line:Add("SAM.Label")
|
||||
play_time:Dock(LEFT)
|
||||
play_time:DockMargin(4, 0, 0, 0)
|
||||
play_time:SetFont(LINE_FONT)
|
||||
play_time:SetText(sam.reverse_parse_length(tonumber(v.play_time) / 60))
|
||||
play_time:SetTextColor(GetColor("player_list_data"))
|
||||
play_time:SetContentAlignment(4)
|
||||
play_time:SetWide(SUI.Scale(180))
|
||||
|
||||
local expiry_date = tonumber(v.expiry_date)
|
||||
local rank_expiry = line:Add("SAM.Label")
|
||||
rank_expiry:Dock(LEFT)
|
||||
rank_expiry:DockMargin(-3, 0, 0, 0)
|
||||
rank_expiry:SetFont(LINE_FONT)
|
||||
rank_expiry:SetText(expiry_date == 0 and "Never" or sam.reverse_parse_length((expiry_date - os.time()) / 60))
|
||||
rank_expiry:SetTextColor(GetColor("player_list_data"))
|
||||
rank_expiry:SetContentAlignment(4)
|
||||
rank_expiry:SizeToContents()
|
||||
|
||||
local but = line:Actions()
|
||||
but.v = v
|
||||
but:On("DoClick", button_click)
|
||||
|
||||
body:Line()
|
||||
end
|
||||
end
|
||||
|
||||
refresh = function()
|
||||
if not is_loading() and LocalPlayer():HasPermission("manage_players") then
|
||||
search_entry:OnEnter(true)
|
||||
local refresh_query = netstream.async.Start("SAM.GetPlayers", toggle_loading, current_page.i, current_column, current_order, current_sort, keyword)
|
||||
refresh_query:done(set_data)
|
||||
end
|
||||
end
|
||||
|
||||
local bottom_panel = players_body:Add("SAM.Panel")
|
||||
bottom_panel:Dock(BOTTOM)
|
||||
bottom_panel:DockMargin(0, 6, 0, 0)
|
||||
bottom_panel:SetTall(30)
|
||||
bottom_panel:Background(GetColor("page_switch_bg"))
|
||||
|
||||
local previous_page = bottom_panel:Add("SAM.Button")
|
||||
previous_page:Dock(LEFT)
|
||||
previous_page:SetWide(30)
|
||||
previous_page:SetText("<")
|
||||
previous_page:SetFont(NEXT_FONT)
|
||||
|
||||
previous_page:On("DoClick", function()
|
||||
if current_page.i <= 1 then return end
|
||||
|
||||
current_page.i = current_page.i - 1
|
||||
refresh()
|
||||
end)
|
||||
|
||||
current_page = bottom_panel:Add("SAM.Label")
|
||||
current_page:Dock(FILL)
|
||||
current_page:SetContentAlignment(5)
|
||||
current_page:SetFont(SAM_TAB_DESC_FONT)
|
||||
current_page:SetText("loading...")
|
||||
current_page.i = 1
|
||||
|
||||
local next_page = bottom_panel:Add("SAM.Button")
|
||||
next_page:Dock(RIGHT)
|
||||
next_page:SetWide(30)
|
||||
next_page:SetText(">")
|
||||
next_page:SetFont(NEXT_FONT)
|
||||
|
||||
next_page:On("DoClick", function()
|
||||
if current_page.i == pages then return end
|
||||
|
||||
current_page.i = current_page.i + 1
|
||||
refresh()
|
||||
end)
|
||||
|
||||
function bottom_panel:Think()
|
||||
next_page:SetEnabled(current_page.i ~= pages)
|
||||
previous_page:SetEnabled(current_page.i > 1)
|
||||
end
|
||||
|
||||
do
|
||||
local refresh_2 = function()
|
||||
timer.Simple(1, refresh)
|
||||
end
|
||||
|
||||
for k, v in ipairs({"SAM.AuthedPlayer", "SAM.ChangedPlayerRank", "SAM.ChangedSteamIDRank"}) do
|
||||
hook.Add(v, "SAM.MenuPlayers", refresh_2)
|
||||
end
|
||||
end
|
||||
|
||||
refresh()
|
||||
|
||||
return players_body
|
||||
end, function()
|
||||
return LocalPlayer():HasPermission("manage_players")
|
||||
end, 2)
|
||||
Reference in New Issue
Block a user