Last active
March 14, 2017 07:07
-
-
Save moonexpr/f973b57365c1597dd6eb8ac90becbd51 to your computer and use it in GitHub Desktop.
A few essential ULX commands
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --[[ | |
| Configuration Table | |
| =============== | |
| Desc: Allows for easy configuration of missing chapters | |
| Definations: | |
| - ULib.ACCESS_SUPERADMIN: All superadmins may access this command. | |
| - ULib.ACCESS_ADMIN: All administrators and higher may access this command. | |
| - ULib.ACCESS_OPERATOR: All operators and higher may access this command. | |
| - ULib.ACCESS_ALL: All users may access this command. | |
| ]]-- | |
| -- to hide | |
| -- add "--" before CreateConvar | |
| CreateConVar ("soundcloud", "1", "tracker variable - used as an SEO enhancer by associating your server with this word.") | |
| CreateConVar ("missing chapter", "1", "tracker variable - used as an SEO enhancer by associating your server with this word.") | |
| if ulx.missing_chapter then | |
| ulx.missing_chapter.m_bRefreshProtect = true | |
| else | |
| ulx.missing_chapter = {} | |
| ulx.missing_chapter.m_bRefreshProtect = false | |
| end | |
| ulx.missing_chapter = { | |
| soundcloud = { | |
| category = "Chat", | |
| console = "ulx soundcloud", | |
| chat = "!sc", | |
| permission = ULib.ACCESS_ALL, | |
| }, | |
| subscribe = { | |
| category = "Chat", | |
| console = "ulx subscribe", | |
| chat = "!sub", | |
| permission = ULib.ACCESS_ALL, | |
| subscribers = {}, -- DO NOT TOUCH | |
| }, | |
| tune = { | |
| category = "Chat", | |
| console = "ulx tune", | |
| chat = "!tune", | |
| permission = ULib.ACCESS_ALL, | |
| }, | |
| smite = { | |
| category = "Fun", | |
| console = "ulx smite", | |
| chat = "!smite", | |
| permission = ULib.ACCESS_ADMIN, | |
| }, | |
| fly = { | |
| category = "Utility", | |
| console = "ulx fly", | |
| chat = "!fly", | |
| permission = ULib.ACCESS_ADMIN, | |
| }, | |
| eject = { | |
| category = "Utility", | |
| console = "ulx eject", | |
| chat = "!eject", | |
| permission = ULib.ACCESS_SUPERADMIN, | |
| }, | |
| closeserver = { | |
| category = "Rcon", | |
| console = "ulx closeserver", | |
| chat = "!closeserver", | |
| permission = ULib.ACCESS_SUPERADMIN, | |
| }, | |
| } | |
| local missing_chapter = ulx.missing_chapter | |
| local const_strHelperWriteChat = "WriteChat" | |
| local const_strHelperWriteConsole = "WriteConsole" | |
| local const_strHelperConCommand = "ConCommandOverride" | |
| local const_strNetSmite = "particlePlayerSmite" | |
| --[[ | |
| Helper Functions | |
| =============== | |
| Desc: Helps make coding easier. | |
| Usage: - | |
| *** Please don"t change unless you know what you"re doing. | |
| ]]-- | |
| math.mean = function (tbl) | |
| total = 0 | |
| for _, int in pairs (tbl) do | |
| total = total + int | |
| end | |
| return total / #tbl | |
| end | |
| math.outlier = function (tbl) | |
| av = math.mean (tbl) | |
| w = { int = 0, diff = 0 } | |
| for _, int in pairs (tbl) do | |
| if math.abs (int - av) > math.abs (w ["int"]) then | |
| w ["int"] = int | |
| w ["diff"] = math.abs (int - av) | |
| end | |
| end | |
| return w ["int"], w ["diff"] | |
| end | |
| -- Easylua Module by CapsAdmin | |
| -- | |
| -- https://github.com/CapsAdmin/fast_addons/blob/master/lua/helpers/easylua.lua | |
| local function FindEntity(str) | |
| if not str then return NULL end | |
| str = tostring(str) | |
| if str == "#this" and IsEntity(this) and this:IsValid() then | |
| return this | |
| end | |
| if str == "#me" and IsEntity(me) and me:IsPlayer() then | |
| return me | |
| end | |
| if str == "#all" then | |
| return all | |
| end | |
| if str == "#randply" then | |
| return table.Random(player.GetAll()) | |
| end | |
| if str:sub(1,1) == "#" then | |
| local str = str:sub(2) | |
| if #str > 0 then | |
| str = str:lower() | |
| local found | |
| for key, data in pairs(team.GetAllTeams()) do | |
| if data.Name:lower() == str then | |
| found = data.Name:lower() | |
| break | |
| end | |
| end | |
| if not found then | |
| local classes = {} | |
| for key, ent in pairs(ents.GetAll()) do | |
| classes [ent:GetClass():lower()] = true | |
| end | |
| for class in pairs(classes) do | |
| if class:lower() == str then | |
| print("found", class) | |
| found = class | |
| end | |
| end | |
| end | |
| if found then | |
| local func = CreateAllFunction(function(v) return v:GetClass():lower() == class end) | |
| print(func:GetName()) | |
| return func | |
| end | |
| end | |
| end | |
| -- unique id | |
| local ply = player.GetByUniqueID(str) | |
| if ply and ply:IsPlayer() then | |
| return ply | |
| end | |
| -- steam id | |
| if str:find("STEAM") then | |
| for key, _ply in pairs(player.GetAll()) do | |
| if _ply:SteamID() == str then | |
| return _ply | |
| end | |
| end | |
| end | |
| if str:sub(1,1) == "_" and tonumber(str:sub(2)) then | |
| str = str:sub(2) | |
| end | |
| if tonumber(str) then | |
| ply = Entity(tonumber(str)) | |
| if ply:IsValid() then | |
| return ply | |
| end | |
| end | |
| -- community id | |
| if #str == 17 then | |
| end | |
| -- ip | |
| if SERVER then | |
| if str:find("%d+%.%d+%.%d+%.%d+") then | |
| for key, _ply in pairs(player.GetAll()) do | |
| if _ply:IPAddress():find(str) then | |
| return _ply | |
| end | |
| end | |
| end | |
| end | |
| -- search in sensible order | |
| -- search exact | |
| for _,ply in pairs(player.GetAll()) do | |
| if ply:Nick()==str then | |
| return ply | |
| end | |
| end | |
| -- Search bots so we target those first | |
| for key, ply in pairs(player.GetBots()) do | |
| if comparenick(ply:Nick(), str) then | |
| return ply | |
| end | |
| end | |
| -- search from beginning of nick | |
| for _,ply in pairs(player.GetHumans()) do | |
| if ply:Nick():lower():find(str,1,true)==1 then | |
| return ply | |
| end | |
| end | |
| -- Search normally and search with colorcode stripped | |
| for key, ply in pairs(player.GetAll()) do | |
| if comparenick(ply:Nick(), str) then | |
| return ply | |
| end | |
| if comparenick(ply:Nick():gsub("%^%d", ""), str) then | |
| return ply | |
| end | |
| end | |
| for key, ent in pairs(ents.GetAll()) do | |
| if compareentity(ent, str) then | |
| return ent | |
| end | |
| end | |
| do -- class | |
| local _str, idx = str:match("(.-)(%d+)$") | |
| if idx then | |
| idx = tonumber(idx) | |
| str = _str | |
| else | |
| str = str | |
| idx = (me and me.easylua_iterator) or 0 | |
| end | |
| local found = {} | |
| for key, ent in pairs(ents.GetAll()) do | |
| if compare(ent:GetClass(), str) then | |
| table.insert(found, ent) | |
| end | |
| end | |
| return found [math.Clamp(idx%#found, 1, #found)] or NULL | |
| end | |
| end | |
| if SERVER then | |
| util.AddNetworkString (const_strHelperWriteChat) | |
| util.AddNetworkString (const_strHelperWriteConsole) | |
| util.AddNetworkString (const_strHelperConCommand) | |
| function httpEncode(str) | |
| if (str) then | |
| str = string.gsub (str, "\n", "\r\n") | |
| str = string.gsub (str, "( [^%w ])", function (c) return string.format ("%%%02X", string.byte (c)) end) | |
| str = string.gsub (str, " ", "+") | |
| end | |
| return str | |
| end | |
| local meta = FindMetaTable ("Player") | |
| function meta:WriteChat (...) | |
| local tbl = { Color (250, 250, 250) } | |
| local tbl2 = { ... } | |
| for _, v in pairs (tbl2) do | |
| tbl [#tbl + 1] = v | |
| end | |
| table.insert (tbl, "\n") | |
| net.Start (const_strHelperWriteChat) | |
| net.WriteTable (tbl) | |
| net.Send (self) | |
| end | |
| function WriteChat (...) | |
| local tbl = { Color (250, 250, 250) } | |
| local tbl2 = { ... } | |
| for _, v in pairs (tbl2) do | |
| tbl [#tbl + 1] = v | |
| end | |
| table.insert (tbl, "\n") | |
| net.Start (const_strHelperWriteChat) | |
| net.WriteTable (tbl) | |
| net.Broadcast () | |
| end | |
| function meta:WriteConsole (...) | |
| net.Start (const_strHelperWriteConsole) | |
| net.WriteTable ({Color (250, 250, 250), ..., "\n"}) | |
| net.Send (self) | |
| end | |
| function WriteConsole (...) | |
| net.Start (const_strHelperWriteConsole) | |
| net.WriteTable ({Color (250, 250, 250), ..., "\n"}) | |
| net.Broadcast () | |
| end | |
| if not ulx.missing_chapter.m_bRefreshProtect then | |
| -- Override this because normal ConCommand has a blacklist server-side | |
| -- Let's ensure that we only set this variable once. | |
| meta.OldConCommand = meta.ConCommand | |
| end | |
| function meta:ConCommand (strCommand) | |
| net.Start (const_strHelperConCommand) | |
| net.WriteString (strCommand) | |
| net.Send (self) | |
| end | |
| end | |
| if CLIENT then | |
| net.Receive (const_strHelperWriteChat, function () | |
| local tblMessage = net.ReadTable () | |
| if not istable (tblMessage) then return end | |
| chat.AddText (unpack (tblMessage)) | |
| end) | |
| net.Receive (const_strHelperWriteConsole, function () | |
| local tblMessage = net.ReadTable () | |
| if not istable (tblMessage) then return end | |
| MsgC (unpack (tblMessage)) | |
| end) | |
| net.Receive (const_strHelperConCommand, function () | |
| local strCommand = net.ReadString () | |
| if not isstring (strCommand) then return end | |
| LocalPlayer ():ConCommand (string.format ("%s\n", strCommand)) | |
| end) | |
| end | |
| --[[ | |
| SoundCloud | |
| =============== | |
| Desc: Allows users to listen to music | |
| Usage: | |
| - ulx soundcloud {search} | |
| - ulx tune {song id} | |
| - ulx tune @{player name} | |
| ]]-- | |
| ulx.soundcloud = { songs = {}, players = {}, currentSong = nil } | |
| local constrAPIKey = "" | |
| if SERVER then | |
| util.AddNetworkString ("ulxSoundCloudPlay") | |
| util.AddNetworkString ("ulxSoundCloudToggle") | |
| function ProcessSong (calling_ply, json) | |
| if constrAPIKey == "" then | |
| ULib.tsayError (calling_ply, "Please inform the gameserver manager to aquire an API key (more: https://forums.pococraft.org/threads/46/)") | |
| return | |
| end | |
| local tblSong = util.JSONToTable (json) | |
| tblSong = type(tblSong [1]) == "table" and tblSong [1] or tblSong | |
| if tblSong ["errors"] or table.Count (tblSong) == 0 then | |
| ULib.tsayError (calling_ply, "This song does not exist!") | |
| return | |
| end | |
| if not ulx.soundcloud ["players"] [calling_ply:SteamID ()] then | |
| ulx.soundcloud ["players"] [calling_ply:SteamID ()] = {} | |
| calling_ply:WriteChat (Color (255, 96, 0), "Soundcloud: ", Color (250, 250, 250), "To hide the top duration bar, type in developer's console: ui_soundcloud 0") | |
| end | |
| local tblPlyHistory = ulx.soundcloud ["players"] [calling_ply:SteamID ()] | |
| ulx.soundcloud ["players"] [calling_ply:SteamID ()] [#tblPlyHistory + 1] = tblSong | |
| ulx.soundcloud.songs [tblSong ["id"]] = tblSong | |
| ulx.soundcloud.songs [tblSong ["id"]].queue = {} | |
| ulx.soundcloud.songs [tblSong ["id"]].queue ["queue_steamid"] = calling_ply:SteamID () | |
| ulx.soundcloud.songs [tblSong ["id"]].queue ["queue_player"] = calling_ply | |
| ulx.soundcloud.songs [tblSong ["id"]].queue ["queue_time"] = CurTime () | |
| for _, ply in pairs (player.GetAll ()) do | |
| if missing_chapter.subscribe.subscribers [calling_ply:SteamID ()] and missing_chapter.subscribe.subscribers [calling_ply:SteamID ()] [ply:SteamID ()] then | |
| ply:WriteChat (Color (250, 250, 250), "Your DJ, ", team.GetColor (calling_ply:Team ()), Color (250, 250, 250), calling_ply:Nick (), " has started listening to \"" .. tblSong ["title"] .. "\"", Color (200, 0, 100), " (@" .. tblSong ["user"] ["username"] .. ") ", Color (150, 150, 0), "+" .. tblSong ["likes_count"] .. "\n", Color(250, 250, 250), "#" .. tblSong ["id"]) | |
| elseif ply ~= calling_ply then | |
| ply:WriteChat (team.GetColor (calling_ply:Team ()), calling_ply:Nick(), Color (250, 250, 250), " has started listening to \"" .. tblSong ["title"] .. "\"", Color (200, 0, 100), " (@" .. tblSong ["user"] ["username"] .. ") ", Color (150, 150, 0), "+" .. tblSong ["likes_count"] .. "\n", Color(250, 250, 250), "#" .. tblSong ["id"]) | |
| end | |
| end | |
| --PrintTable (tblSong) | |
| net.Start ("ulxSoundCloudPlay") | |
| net.WriteTable(tblSong) | |
| if missing_chapter.subscribe.subscribers [calling_ply:SteamID ()] and table.Count (missing_chapter.subscribe.subscribers [calling_ply:SteamID ()]) ~= 0 then | |
| for sid, listener in pairs (missing_chapter.subscribe.subscribers [calling_ply:SteamID ()]) do | |
| if IsValid (listener) then | |
| net.Send (listener) | |
| else | |
| -- remove disconnected players | |
| missing_chapter.subscribe.subscribers [calling_ply:SteamID ()][sid] = nil | |
| end | |
| end | |
| else | |
| net.Send (calling_ply) | |
| end | |
| end | |
| end | |
| if CLIENT then | |
| local cvarSoundcloud = CreateClientConVar ("ui_soundcloud", "1", true, false) | |
| hook.Add("HUDPaint", "VisualizeSoundcloud", function () | |
| local song = ulx.soundcloud.currentSong | |
| if not cvarSoundcloud:GetBool () or not song or not song:IsValid () or not song:GetState () == GMOD_CHANNEL_STALLED then | |
| return | |
| end | |
| song:SetVolume (GetConVar ("snd_musicvolume"):GetInt ()) | |
| local fDuration = song:GetLength() | |
| local fNow = song:GetTime() | |
| local fRatio = fNow / fDuration | |
| local strDuration = os.date ("%M:%S", fNow) | |
| if fRatio == 1 then | |
| return | |
| end | |
| -- Background | |
| surface.SetDrawColor (150, 150, 150, 255) | |
| surface.DrawRect (0, 0, ScrW (), 3) | |
| -- Foreground | |
| surface.SetDrawColor (255, 96, 0, 255) | |
| surface.DrawRect (0, 0, ScrW () * fRatio, 3) | |
| -- Duration Text | |
| surface.SetFont ("Trebuchet18") | |
| local w, h = surface.GetTextSize (strDuration) | |
| surface.SetTextColor (240, 240, 240) | |
| surface.SetTextPos ((ScrW () * fRatio) - w, 5) | |
| surface.DrawText (strDuration) | |
| end) | |
| -- Removed due many issues with downloading | |
| -- sound.PlayURL (string.format (strFormatURL, tblSong ["stream_url"], constrAPIKey), tblSong ["SetTime"] and "noblock" or "mono", function (station) | |
| -- station:Play () | |
| -- station:SetVolume (1) | |
| -- if tblSong ["SetTime"] then | |
| -- station:SetTime(tblSong ["SetTime"]) | |
| -- end | |
| -- ulx.soundcloud.currentSong = station | |
| -- end) | |
| function PlayMusic (strLocation, tblSong) | |
| sound.PlayFile (strLocation, tblSong ["SetTime"] and "noblock" or "mono", function (station) | |
| station:Play () | |
| station:SetVolume (GetConVar ("snd_musicvolume"):GetInt ()) | |
| if tblSong ["SetTime"] then | |
| station:SetTime(tblSong ["SetTime"]) | |
| end | |
| ulx.soundcloud.currentSong = station | |
| end) | |
| if not tblSong ["likes_count"] then | |
| tblSong ["likes_count"] = "n/a" | |
| end | |
| if tblSong ["SetTime"] then | |
| chat.AddText (Color(250, 250, 250), tblSong ["title"], Color (200, 0, 100), " (@" .. tblSong ["user"] ["username"] .. ") ", Color (150, 150, 0), "+" .. tblSong ["likes_count"], Color (100, 100, 100), " + " .. os.date("%M:%S", tblSong ["duration"] - tblSong ["SetTime"])) | |
| else | |
| chat.AddText (Color(250, 250, 250), tblSong ["title"], Color (200, 0, 100), " (@" .. tblSong ["user"] ["username"] .. ") ", Color (150, 150, 0), "+" .. tblSong ["likes_count"]) | |
| end | |
| end | |
| function InitializeLoading () | |
| if ulx.soundcloud.currentSong then | |
| ulx.soundcloud.currentSong:Stop () | |
| end | |
| local strFormatURL = "%s?client_id=%s" | |
| local tblSong = net.ReadTable () | |
| strFName = util.CRC (tblSong ["stream_url"]) | |
| strFullFName = ("soundcloud/nstatic/%s.dat"):format (strFName) | |
| if file.Exists (strFullFName, "DATA") then | |
| PlayMusic (("data/%s"):format (strFullFName), tblSong) | |
| else | |
| http.Fetch (strFormatURL:format (tblSong ["stream_url"], constrAPIKey), | |
| function (data) | |
| if not file.Exists ("soundcloud/nstatic", "DATA") then | |
| file.CreateDir ("soundcloud/nstatic") | |
| end | |
| file.Write (strFullFName, data) | |
| PlayMusic (("data/%s"):format (strFullFName), tblSong) | |
| end, | |
| function (strError) | |
| error (("failed to download music :( (%s)"):format (strError)) | |
| end | |
| ) | |
| end | |
| end | |
| function Toggle () | |
| if not ulx.soundcloud.currentSong or not IsValid (ulx.soundcloud.currentSong) then | |
| return | |
| end | |
| song = ulx.soundcloud.currentSong | |
| state = song:GetState () | |
| if state == GMOD_CHANNEL_PAUSED then | |
| chat.AddText ("Resuming song...") | |
| elseif state == GMOD_CHANNEL_STOPPED then | |
| chat.AddText ("Restarting song... (stopped)") | |
| elseif state == GMOD_CHANNEL_PLAYING then | |
| song:Pause () | |
| end | |
| end | |
| net.Receive ("ulxSoundCloudPlay", InitializeLoading) | |
| net.Receive ("ulxSoundCloudToggle", Toggle) | |
| -- TTT Hotfixes | |
| hook.Add ("TTTPrepareRound", "MissingChapter", function () | |
| if not ulx.soundcloud.currentSong or not IsValid (ulx.soundcloud.currentSong) then | |
| return | |
| end | |
| -- long variable too long | |
| song = ulx.soundcloud.currentSong | |
| print (song:GetTime ()) | |
| print (song:GetLength ()) | |
| if math.floor (song:GetTime ()) != math.floor (song:GetLength ()) then | |
| sound.PlayFile (song:GetFileName (), "noblock", function (station) | |
| station:Play () | |
| station:SetTime (song:GetTime ()) | |
| song:Stop () | |
| ulx.soundcloud.currentSong = station | |
| end) | |
| end | |
| end) | |
| end | |
| function ulx.tune (calling_ply, id) | |
| tblSong = {} | |
| if id:sub (1, 1) == "@" then | |
| local queue_ply = FindEntity (id:sub (2, id:len ())) | |
| if not IsValid (queue_ply) or not queue_ply:IsPlayer () then | |
| ULib.tsayError (calling_ply, "Could not find player!") return | |
| elseif not ulx.soundcloud ["players"] [queue_ply:SteamID ()] then | |
| ULib.tsayError (calling_ply, "Player has not played any song recently!") return | |
| end | |
| local tblPlyHistory = ulx.soundcloud ["players"] [queue_ply:SteamID ()] | |
| tblSong = tblPlyHistory [#tblPlyHistory] | |
| elseif id:find("http://soundcloud.com") or id:find("https://soundcloud.com") or id:find("http://www.soundcloud.com") or id:find("https://www.soundcloud.com") then | |
| local strFormatURL = "https://api.soundcloud.com/resolve.json?url=%s&client_id=%s" | |
| http.Fetch (string.format (strFormatURL, id, constrAPIKey), | |
| function (json) | |
| ProcessSong (calling_ply, json) | |
| end, | |
| function (err) | |
| error ("souncloud api [api/resolve] error: " .. err) | |
| end | |
| ) | |
| return | |
| else | |
| bSuccess, output = pcall(tonumber, id) | |
| id = bSuccess and output or 0 | |
| if ulx.soundcloud [id] then | |
| tblSong = table.Copy (ulx.soundcloud [id]) | |
| else | |
| local strFormatURL = "https://api.soundcloud.com/tracks/%i?client_id=%s" | |
| http.Fetch (string.format (strFormatURL, id, constrAPIKey), | |
| function (json) | |
| ProcessSong (calling_ply, json) | |
| end, | |
| function (err) | |
| error ("souncloud api [api/tracks] error: " .. err) | |
| end | |
| ) | |
| return | |
| end | |
| end | |
| if tblSong ["queue"] ["queue_time"] + tblSong ["duration"] > CurTime () then | |
| tblSong ["SetTime"] = tblSong ["queue"] ["queue_time"] + tblSong ["duration"] - CurTime () | |
| end | |
| for _, ply in pairs (player.GetAll ()) do | |
| if ply ~= calling_ply then | |
| ply:WriteChat (Color(250, 250, 250), calling_ply:Nick() .. " has tuned into \"" .. tblSong ["title"] .. "\"", Color (200, 0, 100), " (@" .. tblSong ["user"] ["username"] .. ") ", Color (150, 150, 0), "+" .. tblSong ["likes_count"] .. "\n", Color(250, 250, 250), "created by " .. (IsValid (tblSong ["queue"] ["queue_player"]) and tblSong ["queue"] ["queue_player"]:Nick () or tblSong ["queue"] ["queue_steamid"])) | |
| end | |
| end | |
| net.Start ("ulxSoundCloudPlay") | |
| net.WriteTable(tblSong) | |
| net.Send (calling_ply) | |
| end | |
| function ulx.sc (calling_ply, query) | |
| if query:find("http://soundcloud.com") or query:find("https://soundcloud.com") or query:find("http://www.soundcloud.com") or query:find("https://www.soundcloud.com") then | |
| ulx.tune (calling_ply, query) | |
| return | |
| end | |
| local strFormatURL = "http://api.soundcloud.com/tracks.json?client_id=%s&q=%s&limit=50" | |
| http.Fetch (string.format (strFormatURL, constrAPIKey, httpEncode (query)), | |
| function (json) | |
| ProcessSong (calling_ply, json) | |
| end, | |
| function (error) | |
| ULib.tsayError (calling_ply, "We failed to load the soundcloud URL : ((error code: " .. error .. ")") | |
| end) | |
| end | |
| function ulx.sub (calling_ply, target_ply, bUnsubscribe) | |
| if bUnsubscribe then | |
| if calling_ply.ulxCurSubscriber then | |
| target_ply = calling_ply.ulxCurSubscriber | |
| missing_chapter.subscribe.subscribers [target_ply:SteamID ()] [calling_ply:SteamID ()] = nil | |
| calling_ply.ulxCurSubscriber = nil | |
| else | |
| ULib.tsayError (calling_ply, "You are not subscribed to anyone at the moment.") | |
| end | |
| else | |
| if calling_ply == target_ply then | |
| ULib.tsayError (calling_ply, "No. Stop being so narcissistic.") | |
| return | |
| end | |
| calling_ply.ulxCurSubscriber = target_ply | |
| missing_chapter.subscribe.subscribers [target_ply:SteamID ()] = missing_chapter.subscribe.subscribers [target_ply:SteamID ()] and missing_chapter.subscribe.subscribers [target_ply:SteamID ()] or {} | |
| missing_chapter.subscribe.subscribers [target_ply:SteamID ()] [calling_ply:SteamID ()] = calling_ply | |
| ulx.fancyLogAdmin (calling_ply, "#A subscribed to #T", target_ply) | |
| end | |
| end | |
| function ulx.toggle (calling_ply) | |
| net.Start ("ulxSoundCloudToggle") | |
| net.Send (calling_ply) | |
| end | |
| local instTune = ulx.command (missing_chapter.tune.category, missing_chapter.tune.console, ulx.tune, missing_chapter.tune.chat) | |
| instTune:help ("Plays a station created by someone") | |
| instTune:defaultAccess (missing_chapter.tune.permission) | |
| instTune:addParam ({ | |
| type = ULib.cmds.StringArg, | |
| hint = "id", | |
| ULib.cmds.takeRestOfLine | |
| }) | |
| local instSoundcloud = ulx.command (missing_chapter.soundcloud.category, missing_chapter.soundcloud.console, ulx.sc, missing_chapter.soundcloud.chat) | |
| instSoundcloud:help ("Plays a soundcloud song") | |
| instSoundcloud:defaultAccess (missing_chapter.soundcloud.permission) | |
| instSoundcloud:addParam ({ | |
| type = ULib.cmds.StringArg, | |
| hint = "query", | |
| ULib.cmds.takeRestOfLine | |
| }) | |
| local instSubscribe = ulx.command (missing_chapter.subscribe.category, missing_chapter.subscribe.console, ulx.sub, missing_chapter.subscribe.chat) | |
| instSubscribe:setOpposite ('ulx unsubscribe', {_, game.GetWorld (), true}, '!unsub') | |
| instSubscribe:help ("Subscribe to a player to listen their new songs") | |
| instSubscribe:defaultAccess (missing_chapter.subscribe.permission) | |
| instSubscribe:addParam ({ | |
| type = ULib.cmds.PlayerArg, | |
| hint = "player", | |
| }) | |
| instSubscribe:addParam ({ | |
| type = ULib.cmds.BoolArg, | |
| invisible = true | |
| }) | |
| local instPause = ulx.command (missing_chapter.soundcloud.category, "toggle", ulx.toggle, "toggle") | |
| instPause:help ("Toggles your song.") | |
| instPause:defaultAccess (missing_chapter.soundcloud.permission) | |
| --[[ | |
| Smite | |
| =============== | |
| Desc: Used to smite down moral players | |
| Usage: | |
| - ulx smite {player name} | |
| ]]-- | |
| if SERVER then | |
| util.AddNetworkString (const_strNetSmite) | |
| end | |
| if CLIENT then | |
| net.Receive (const_strNetSmite, function() | |
| local plys = net.ReadTable () | |
| for _, ply in pairs (plys) do | |
| if not IsValid (ply) then return end | |
| for i = 1, 10 do | |
| sound.Play ("npc/scanner/scanner_electric1.wav", ply:GetPos (), math.random (75, 100), math.random (80, 200)) | |
| end | |
| sound.Play ("ambient/explosions/explode_" .. math.random (1, 9) .. ".wav", ply:GetPos ()) | |
| local entPoint1 = ClientsideModel ("models/props_junk/popcan01a.mdl" ,RENDERGROUP_OPAQUE) | |
| local entPoint2 = ClientsideModel ("models/props_junk/popcan01a.mdl", RENDERGROUP_OPAQUE) | |
| entPoint1:SetNoDraw (true) | |
| entPoint2:SetNoDraw (true) | |
| local tblControl1 = { | |
| ["entity"] = entPoint1, | |
| ["attachtype"] = PATTACH_ABSORIGIN_FOLLOW, | |
| } | |
| local tblControl2 = { | |
| ["entity"] = entPoint2, | |
| ["attachtype"] = PATTACH_ABSORIGIN_FOLLOW, | |
| } | |
| for i = 1,10 do | |
| local a = ((i * 36) * math.pi) / 180 | |
| local t = Vector(math.sin (a), math.cos (a), 0) * 2 | |
| entPoint1:SetPos (ply:GetPos () + Vector (0, 0, 1000) + t) | |
| entPoint2:SetPos (ply:GetPos () + t) | |
| ply:CreateParticleEffect ("Weapon_Combine_Ion_Cannon",{tblControl2, tblControl1}) | |
| end | |
| ParticleEffectAttach ("Weapon_Combine_Ion_Cannon_Explosion", 1, ply, 0) | |
| end | |
| end) | |
| end | |
| function ulx.smite (calling_ply, target_plys) | |
| net.Start (const_strNetSmite) | |
| net.WriteTable (target_plys) | |
| net.Broadcast () | |
| timer.Simple (.1, function() | |
| for _, ply in pairs (target_plys) do | |
| ply:Kill () | |
| playerpos = ply:GetPos () | |
| local traceworld = {} | |
| traceworld.start = playerpos | |
| traceworld.endpos = traceworld.start + (Vector (0, 0, -1) * 250) | |
| local trw = util.TraceLine (traceworld) | |
| local worldpos1 = trw.HitPos + trw.HitNormal | |
| local worldpos2 = trw.HitPos - trw.HitNormal | |
| util.Decal ("Scorch", worldpos1, worldpos2) | |
| end | |
| end) | |
| ulx.fancyLogAdmin (calling_ply, "#A smited down #T", target_plys) | |
| end | |
| local instSmite = ulx.command (missing_chapter.smite.category, missing_chapter.smite.console, ulx.smite, missing_chapter.smite.chat) | |
| instSmite:help ("Smites down mortal men.") | |
| instSmite:defaultAccess (missing_chapter.smite.permission) | |
| instSmite:addParam ({ | |
| type = ULib.cmds.PlayersArg | |
| }) | |
| --[[ | |
| Fly | |
| =============== | |
| Desc: Much like noclip except you may not go through walls | |
| Usage: | |
| - ulx fly | |
| - ulx fly {player name} | |
| ]]-- | |
| local tblPlyNotify = {} | |
| function ulx.fly (calling_ply, target_plys) | |
| if not target_plys [ 1 ]:IsValid() then | |
| Msg ("You are god, you are not constrained by walls built by mere mortals.\n") | |
| return | |
| end | |
| local affected_plys = {} | |
| for i=1, #target_plys do | |
| local v = target_plys [ i ] | |
| if v:GetMoveType() == MOVETYPE_WALK then | |
| local vecAvailableSpace = math.Clamp ( | |
| util.QuickTrace (v:GetPos (), v:GetPos () + Vector (0, 0, 1e5), v).HitPos.Z - v:GetPos ().Z, | |
| 0, | |
| 750 | |
| ) | |
| v:SetVelocity (v:GetForward () * vecAvailableSpace * 2 + Vector (0, 0, vecAvailableSpace)) | |
| v:EmitSound ("weapons/rpg/rocketfire1.wav") | |
| if not tblPlyNotify [v] then | |
| v:WriteChat (Color (200, 200, 0), "Tip: ", Color (250, 250, 250), "Press forward key where you're looking to move forward.") | |
| end | |
| timer.Simple (.5, function () | |
| v:SetMoveType (MOVETYPE_FLY) | |
| end) | |
| table.insert (affected_plys, v) | |
| elseif v:GetMoveType() == MOVETYPE_FLY then | |
| v:SetMoveType (MOVETYPE_WALK) | |
| table.insert (affected_plys, v) | |
| else | |
| ULib.tsayError (calling_ply, v:Nick () .. " can't fly right now.", true) | |
| end | |
| end | |
| end | |
| local instFly = ulx.command (missing_chapter.fly.permission, missing_chapter.fly.console, ulx.fly, missing_chapter.fly.chat) | |
| instFly:help ("Toggles fly mode on target(s).") | |
| instFly:defaultAccess (missing_chapter.fly.permission) | |
| instFly:addParam ({ | |
| type = ULib.cmds.PlayersArg, | |
| ULib.cmds.optional | |
| }) | |
| --[[ | |
| Drop Connection | |
| =============== | |
| Desc: Essentially silently forces the client to drop the connection without a disconnect message | |
| Usage: | |
| - ulx drop {player name} | |
| - chat example: "!eject Potatofactory" | |
| - chat example: "!eject *" | |
| ]]-- | |
| function ulx.conndrop (calling_ply, target_ply) | |
| target_ply:WriteConsole (string.format ("Disconnect: Forced server connection drop by \"%s\".", calling_ply:Nick ())) | |
| target_ply:ConCommand ("disconnect") | |
| end | |
| local instEject = ulx.command (missing_chapter.eject.category, missing_chapter.eject.console, ulx.conndrop, missing_chapter.eject.chat) | |
| instEject:help ("Drops a client's connection client-side") | |
| instEject:defaultAccess (missing_chapter.eject.permission) | |
| instEject:addParam ({ | |
| type = ULib.cmds.PlayerArg, | |
| ULib.cmds.optional | |
| }) | |
| --[[ | |
| Close Server | |
| =============== | |
| Desc: Blocks clients from establishing an Ad-Hoc connection with the gameserver | |
| Usage: | |
| - ulx closeserver "developers" "go away" | |
| ]]-- | |
| ulx.closeserver = {} | |
| ulx.closeserver.osession = | |
| { | |
| ['m_bEnabled'] = false, | |
| ['m_funcOption'] = function () return true end, | |
| ['m_strReason'] = 'Generic Reason', | |
| ['m_strUserGroupAuth'] = ULib.ACCESS_SUPERADMIN, | |
| ['m_strSteamIDAuth'] = 'STEAM_0:0:0', | |
| -- ['m_strSteamIDAuth'] = 'STEAM_0:1:56987503', | |
| } | |
| ulx.closeserver.session = table.Copy (ulx.closeserver.osession) | |
| function checkInheritance (tblGroup, strCheck) | |
| if strCheck == ULib.ACCESS_SUPERADMIN then | |
| return tblGroup.name == ULib.ACCESS_SUPERADMIN or tblGroup.inherit_from == ULib.ACCESS_SUPERADMIN | |
| elseif strCheck == ULib.ACCESS_ADMIN then | |
| return (tblGroup.name == ULib.ACCESS_ADMIN or tblGroup.inherit_from == ULib.ACCESS_ADMIN) or (tblGroup.name == ULib.ACCESS_SUPERADMIN or tblGroup.inherit_from == ULib.ACCESS_SUPERADMIN) | |
| elseif strCheck == ULib.ACCESS_OPERATOR then | |
| return (tblGroup.name == ULib.ACCESS_OPERATOR or tblGroup.inherit_from == ULib.ACCESS_OPERATOR) or (tblGroup.name == ULib.ACCESS_ADMIN or tblGroup.inherit_from == ULib.ACCESS_ADMIN) or (tblGroup.name == ULib.ACCESS_SUPERADMIN or tblGroup.inherit_from == ULib.ACCESS_SUPERADMIN) | |
| else | |
| if strCheck == ULib.ACCESS_ALL then | |
| return true | |
| else | |
| return tblGroup.name == strCheck or tblGroup.inherit_from == strCheck | |
| end | |
| end | |
| end | |
| ulx.closeserver.options = | |
| { | |
| ['0'] = function () | |
| return false, ulx.closeserver.session ['m_strReason'] | |
| end, | |
| ['1'] = function (strSteamID64) | |
| local strSteamID32 = util.SteamIDFrom64 (strSteamID64) | |
| local strGroup = ULib.ucl.users [strSteamID32] | |
| local tblGroupAccess = ULib.ucl.groups [strGroup] | |
| tblGroupAccess.name = strGroup | |
| if checkInheritance (tblGroupAccess, ULib.ACCESS_SUPERADMIN) then | |
| return true | |
| else | |
| return false, ulx.closeserver.session ['m_strReason'] | |
| end | |
| end, | |
| ['2'] = function (strSteamID64) | |
| local strSteamID32 = util.SteamIDFrom64 (strSteamID64) | |
| local strGroup = ULib.ucl.users [strSteamID32] | |
| local tblGroupAccess = ULib.ucl.groups [strGroup] | |
| if checkInheritance (tblGroupAccess, ULib.ACCESS_ADMIN) then | |
| return true | |
| else | |
| return false, ulx.closeserver.session ['m_strReason'] | |
| end | |
| end, | |
| ['3'] = function (strSteamID64) | |
| local strSteamID32 = util.SteamIDFrom64 (strSteamID64) | |
| local strGroup = ULib.ucl.users [strSteamID32] | |
| local tblGroupAccess = ULib.ucl.groups [strGroup] | |
| if checkInheritance (tblGroupAccess, ULib.ACCESS_OPERATOR) then | |
| return true | |
| else | |
| return false, ulx.closeserver.session ['m_strReason'] | |
| end | |
| end, | |
| ['usergroup'] = function (strSteamID64) | |
| local strSteamID32 = util.SteamIDFrom64 (strSteamID64) | |
| local strGroup = ULib.ucl.users [strSteamID32] | |
| local tblGroupAccess = ULib.ucl.groups [strGroup] | |
| if checkInheritance (tblGroupAccess, ulx.closeserver.session ['m_strUserGroupAuth']) then | |
| return true | |
| else | |
| return false, ulx.closeserver.session ['m_strReason'] | |
| end | |
| end, | |
| ['steamid'] = function (strSteamID64) | |
| return (strSteamID64 == ulx.closeserver.session ['m_strSteamIDAuth'] or util.SteamIDFrom64 (strSteamID64) == ulx.closeserver.session ['m_strSteamIDAuth']), ulx.closeserver.session ['m_strReason'] | |
| end, | |
| } | |
| ulx.closeserver.ifunc = function (calling_ply) | |
| if not ulx.closeserver.session ['m_bEnabled'] then | |
| ULib.tsayError( calling_ply, 'The gameserver is not closed right now!', true ) | |
| return | |
| end | |
| ulx.fancyLogAdmin (calling_ply, '#A has re-opened the gameserver to the public!') | |
| WriteChat (string.format ('We\'re now live @ %s', game.GetIPAddress())) | |
| ulx.closeserver.session = table.Copy (ulx.closeserver.osession) | |
| end | |
| ulx.closeserver.func = function (calling_ply, strOption, strReason, bOpen) | |
| if bOpen then | |
| ulx.closeserver.ifunc (calling_ply) | |
| return | |
| end | |
| if ulx.closeserver.session ['m_bEnabled'] then | |
| ULib.tsayError( calling_ply, 'The gameserver is already closed!', true ) | |
| return | |
| end | |
| -- Safety | |
| strOption = tostring (strOption) | |
| if ulx.closeserver.options [strOption] then | |
| if strOption == 0 and calling_ply ~= game.GetWorld () then | |
| ULib.tsayError (calling_ply, 'As a failsafe, You may only use option 0 if you are running it though RCON!', true) | |
| return | |
| end | |
| ulx.closeserver.session ['m_funcOption'] = ulx.closeserver.options [strOption] | |
| else | |
| if strOption:sub (1, 6) == 'STEAM_' then | |
| ulx.closeserver.session ['m_strSteamIDAuth'] = strOption | |
| ulx.closeserver.session ['m_funcOption'] = ulx.closeserver.options ['steamid'] | |
| elseif ULib.ucl.groups [strOption] then | |
| ulx.closeserver.session ['m_strUserGroupAuth'] = strOption | |
| ulx.closeserver.session ['m_funcOption'] = ulx.closeserver.options ['usergroup'] | |
| else | |
| ULib.tsayError (calling_ply, 'Invalid option: ' .. strOption, true) | |
| return | |
| end | |
| end | |
| ulx.fancyLogAdmin (calling_ply, string.format ('#A has closed the gameserver:\n"%s"', strReason)) | |
| ulx.closeserver.session ['m_strReason'] = strReason | |
| ulx.closeserver.session ['m_bEnabled'] = true | |
| end | |
| local instCloseserver = ulx.command (missing_chapter.closeserver ['category'], missing_chapter.closeserver ['console'], ulx.closeserver.func, missing_chapter.closeserver ['chat']) | |
| instCloseserver:help ( | |
| [[Prevents users from connecting to the server. | |
| STEAMID_32: Only one specific person | |
| - Example: STEAM_0:1:56987503 (Potatofactory) | |
| - Example 2: STEAM_0:1:56196170 (Jck123) | |
| CUSTOM GROUP: Only people in that specific group and higher | |
| - Example: developers | |
| - Example 2: vip | |
| 0: no one, | |
| 1: superadmin and inherited only, | |
| 2: admin, inherited and + only, | |
| 3: operators, inherited and + only,]] | |
| ) | |
| instCloseserver:defaultAccess (missing_chapter.closeserver ['permission']) | |
| instCloseserver:setOpposite ('ulx openserver', { _, '0', '0', true }, '!openserver') | |
| instCloseserver:addParam ({ | |
| type = ULib.cmds.StringArg, | |
| hint = 'option' | |
| }) | |
| instCloseserver:addParam ({ | |
| type = ULib.cmds.StringArg, | |
| hint = 'reason', | |
| ULib.cmds.takeRestOfLine | |
| }) | |
| instCloseserver:addParam ({ | |
| type = ULib.cmds.BoolArg, | |
| invisible = true | |
| }) | |
| hook.Add ('CheckPassword', missing_chapter.closeserver ['console'], ulx.closeserver.session ['m_funcOption']) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment