From 81241506df0b761c54a0570b1217fc408579bf2f Mon Sep 17 00:00:00 2001 From: GalacticInspired <73362346+GalacticInspired@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:40:25 +0100 Subject: [PATCH 01/60] Partially revert PR-1673 due to unhandled error --- MainModule/Server/Dependencies/TrelloAPI.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Dependencies/TrelloAPI.luau b/MainModule/Server/Dependencies/TrelloAPI.luau index 7d9721993d..e00b2101ba 100644 --- a/MainModule/Server/Dependencies/TrelloAPI.luau +++ b/MainModule/Server/Dependencies/TrelloAPI.luau @@ -10,8 +10,8 @@ ------------------------------------------------------------------------------------------------------------------------------------------------------------------- local print = function(...) warn("[Adonis TrelloAPI]: INFO:", ...) end +local error = function(...) warn("[Adonis TrelloAPI]: ERROR:", ...) end local warn = function(...) warn("[Adonis TrelloAPI]: WARN:", ...) end -local error = function(message, level) warn("[Adonis TrelloAPI]: ERROR:", message) return error("[Adonis TrelloAPI]: ERROR:"..message, level == 0 and 0 or 1 + (level or 1)) end local HttpService = game:GetService("HttpService") local Weeks = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} From 66d8d26737b66ac12e761837cb518209d70729b4 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:47:03 +0300 Subject: [PATCH 02/60] Update Changelog v261.3 --- MainModule/Server/Shared/Changelog.luau | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 7493692ffc..e6b4f6aaeb 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -1,8 +1,11 @@ return { - "Version: 261.2"; + "Version: 261.3"; "*Drag edges to expand*"; "*Report bugs/issues on our GitHub repository*"; ""; + "[Patch v261.3 2024-12-30 16:46 UTC] @Dimenpsyonal"; + "Fix trello erroring instead of warning (#1805)"; + ""; "[Patch v261.2 2024-12-21 20:23 UTC] @Dimenpsyonal"; "ACTUALLY fix argument handling"; ""; @@ -497,7 +500,7 @@ return { "(Git/DaRealGandhi20) [Add Text Selectable + New Text Format] :selectplayers/:count (#1132)"; "Git/Dimenpsyonal) Add atmosphere support (#1139)"; "(Git/Deniernal354) Add myself to credits (#1144)"; - "Git/wilsontultus) Update Moderators.lua - :invisible and :visible command... (#1146)"; + "(Git/wilsontultus) Update Moderators.lua - :invisible and :visible command... (#1146)"; "(Git/wilsontulus) Update !playerinfo command - Mail & Phone/ID Verified Status (#1147)"; "(Git/Dimenpsyonal) Add age restriction settings (#1149)"; "(Git/Dimenpsyonal) Remove GitHub link (#1150)"; From 66fdb87cbad54c1e9a8cf039ee4af347f0a2b341 Mon Sep 17 00:00:00 2001 From: fxe Date: Fri, 3 Jan 2025 12:25:04 +0000 Subject: [PATCH 03/60] Fixed TextBox capability warning (#1812) Resolves bug where if the TextBox wasn't accessible (Usually CoreGui instances) it would error due to not having the correct capabilities to access the instance. --- MainModule/Client/Core/Process.luau | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MainModule/Client/Core/Process.luau b/MainModule/Client/Core/Process.luau index 540a1ccb13..0b868b7ed2 100644 --- a/MainModule/Client/Core/Process.luau +++ b/MainModule/Client/Core/Process.luau @@ -169,7 +169,7 @@ return function(Vargs, GetEnv) end local textbox = service.UserInputService:GetFocusedTextBox() - if textbox then + if textbox and service.CheckProperty(textbox, "ReleaseFocus") then textbox:ReleaseFocus() end @@ -179,7 +179,7 @@ return function(Vargs, GetEnv) HandleTextChatCommands = function() local data = Remote.Get("PlayerData") local adminLevel, isDonor = data.AdminLevel, data.isDonor - + if service.TextChatService and service.TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then local function onCommandAdded(command) if not command:IsA("TextChatCommand") then From d71b97a4c5269f8bcfe53e899d53af818ede7694 Mon Sep 17 00:00:00 2001 From: kaiserandaxl <122803145+kaiserandaxl@users.noreply.github.com> Date: Fri, 3 Jan 2025 06:27:48 -0600 Subject: [PATCH 04/60] Fix indexing nil tab (#1800) * Fix indexing nil tab * Move the LogAdded event into the if statement --- MainModule/Server/Core/Logs.luau | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/MainModule/Server/Core/Logs.luau b/MainModule/Server/Core/Logs.luau index 311492d0c2..8d36db06a3 100644 --- a/MainModule/Server/Core/Logs.luau +++ b/MainModule/Server/Core/Logs.luau @@ -88,16 +88,18 @@ return function(Vargs, GetEnv) log.Time = os.time() end - if tab.__meta == "DLL" then - tab:AddToStartAndRemoveEndIfEnd(log, Logs.MaxLogs) - else - table.insert(tab, 1, log) - if #tab > tonumber(Logs.MaxLogs) then - table.remove(tab, #tab) + if tab then + if tab.__meta == "DLL" then + tab:AddToStartAndRemoveEndIfEnd(log, Logs.MaxLogs) + else + table.insert(tab, 1, log) + if #tab > tonumber(Logs.MaxLogs) then + table.remove(tab, #tab) + end end + + service.Events.LogAdded:Fire(Logs.TabToType(tab), log, tab) end - - service.Events.LogAdded:Fire(Logs.TabToType(tab), log, tab) end; -- // Preliminary support for oldlog encryption From 71b63366b61429eb295cc92a9e6547f56ce3bb3a Mon Sep 17 00:00:00 2001 From: fxe Date: Fri, 3 Jan 2025 12:28:23 +0000 Subject: [PATCH 05/60] Fix BrickColor typo inside sing command (#1811) Changed from incorrect "Lily White" to "Lily white" --- MainModule/Server/Commands/Fun.luau | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/MainModule/Server/Commands/Fun.luau b/MainModule/Server/Commands/Fun.luau index 3343588c6e..bc8a76aba6 100644 --- a/MainModule/Server/Commands/Fun.luau +++ b/MainModule/Server/Commands/Fun.luau @@ -154,7 +154,7 @@ return function(Vargs, env) --// Apparently Rojo doesn't handle mesh parts very well, so I'm loading this remotely (using require to bypass insertservice restrictions) --// The model is free to take so feel free to that 👍 --// Here's the URL https://www.roblox.com/library/7679952474/Adonis-Assets-Module - if not gerald then -- TODO: Add gerald to deps and remove require, I think the Rojo plugin (up to date) now supports loading + if not gerald then -- TODO: Add gerald to deps and remove require, I think the Rojo plugin (up to date) now supports loading warn("Requiring Assets Module by ID; Expand for module URL > ", {URL = "https://www.roblox.com/library/7679952474/Adonis-Assets-Module"}) gerald = require(7679952474).Gerald --// This apparently caches, so don't delete anything else future usage breaks end @@ -626,7 +626,7 @@ return function(Vargs, env) TorsoColor = BrickColor.new("Artichoke").Color, Face = math.random(1, 3) == 3 and 173789114 or 133360789, } - + local ActionProperties = { Speed = args[2] or nil, Health = args[3] or nil, @@ -644,7 +644,7 @@ return function(Vargs, env) end task.defer(humanoid.ApplyDescription, humanoid, description, Enum.AssetTypeVerification.Always) - + if ActionProperties.Speed then humanoid.WalkSpeed = ActionProperties.Speed end if ActionProperties.Jumppower then humanoid.JumpPower = ActionProperties.Jumppower end if ActionProperties.Health then humanoid.MaxHealth = ActionProperties.Health; humanoid.Health = ActionProperties.Health end @@ -3326,29 +3326,29 @@ return function(Vargs, env) torso.Anchored = true torso.BottomSurface = 0 torso.TopSurface = 0 - + for _, v in char:GetChildren() do if v:IsA("BasePart") then v.Anchored = true end end - + local function size(part) for _, v in part:GetChildren() do if (v:IsA("Weld") or v:IsA("Motor") or v:IsA("Motor6D")) and v.Part1 and v.Part1:IsA("Part") then local p1 = v.Part1 local c0 = {v.C0:components()} local c1 = {v.C1:components()} - + c0[3] = c0[3]*num c1[3] = c1[3]*num - + p1.Anchored = true v.Part1 = nil - + v.C0 = CFrame.new(unpack(c0)) v.C1 = CFrame.new(unpack(c1)) - + if p1.Name ~= "Head" and p1.Name ~= "Torso" then p1.Size = Vector3.new(p1.Size.X, p1.Size.Y, num) elseif p1.Name ~= "Torso" then @@ -3359,9 +3359,9 @@ return function(Vargs, env) m.Part1.Anchored = true end end - + p1.Size = Vector3.new(p1.Size.X, p1.Size.Y, num) - + for _, m in p1:GetChildren() do if m:IsA("Weld") then m.Part0 = p1 @@ -3369,15 +3369,15 @@ return function(Vargs, env) end end end - + if v.Parent == torso then p1.BottomSurface = 0 p1.TopSurface = 0 end - + p1.Anchored = false v.Part1 = p1 - + if v.Part0 == torso then table.insert(welds, v) p1.Anchored = true @@ -3389,24 +3389,24 @@ return function(Vargs, env) size(v) end end - + size(char) - + torso.Size = Vector3.new(torso.Size.X, torso.Size.Y, num) - + for i, v in welds do v.Part0 = torso v.Part1.Anchored = false end - + for i, v in char:GetChildren() do if v:IsA("BasePart") then v.Anchored = false end end - + Functions.MakeWeld(root, torso, CFrame.new(), CFrame.new()) - + local cape = char:FindFirstChild("ADONIS_CAPE") if cape then cape.Size = cape.Size*num @@ -5029,7 +5029,7 @@ return function(Vargs, env) local humanoid = character:FindFirstChildOfClass("Humanoid") local isR15 = humanoid and humanoid.RigType == Enum.HumanoidRigType.R15 or false local relativeSize = head.Size / (isR15 and Vector3.new(1.2, 1.2, 1.2) or Vector3.new(2, 1, 1)) - local partsColor = ({head.Color:ToHSV()})[3] < 0.26 and BrickColor.new("Lily White") or BrickColor.new("Black") + local partsColor = ({head.Color:ToHSV()})[3] < 0.26 and BrickColor.new("Lily white") or BrickColor.new("Black") local sound = head:FindFirstChild("ADONIS_SOUND") or Instance.new("Sound") sound.SoundId = `rbxassetid://{id}` From 8e557b39e2a87b75dab8ae1a7c3d3538f66a8982 Mon Sep 17 00:00:00 2001 From: kaiserandaxl <122803145+kaiserandaxl@users.noreply.github.com> Date: Fri, 3 Jan 2025 06:30:33 -0600 Subject: [PATCH 06/60] Add override for TShirt Asset Type (#1799) --- MainModule/Server/Commands/Moderators.luau | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Moderators.luau b/MainModule/Server/Commands/Moderators.luau index 28ac795b70..af76d904f4 100644 --- a/MainModule/Server/Commands/Moderators.luau +++ b/MainModule/Server/Commands/Moderators.luau @@ -5414,7 +5414,8 @@ return function(Vargs, env) assert(success and productInfo, "Invalid item ID") local AssetTypeNameDescriptionOverides = { - DynamicHead = "Head" + DynamicHead = "Head"; + TShirt = "GraphicTShirt" } --local typeEnum = Enum.AvatarAssetType:FromValue(productInfo.AssetTypeId) local typeId = productInfo.AssetTypeId From 5f18af773c27811a128a1974cb95b58cc6109fcf Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Fri, 3 Jan 2025 12:35:16 +0000 Subject: [PATCH 07/60] v262 prelim changelog --- MainModule/Server/Shared/Changelog.luau | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index e6b4f6aaeb..0e3b3be59a 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -1,8 +1,15 @@ return { - "Version: 261.3"; + "Version: 262"; "*Drag edges to expand*"; "*Report bugs/issues on our GitHub repository*"; ""; + "[v262 2025-01-03 12:35 UTC] @Dimenpsyonal"; + "*First update of 2025 (!!!)"; + "(Git/kaiserandaxl) Add override for TShirt Asset Type (#1799)"; + "(Git/kaiserandaxl) Fix indexing nil tab (#1800)"; + "(Git/fxeP1) Fix BrickColor typo inside sing command (#1811)"; + "(Git/fxeP1) Fixed TextBox capability warning (#1812)"; + ""; "[Patch v261.3 2024-12-30 16:46 UTC] @Dimenpsyonal"; "Fix trello erroring instead of warning (#1805)"; ""; From 463e105fab34051de281c5ac1b77b1b4f83fb58d Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Sat, 4 Jan 2025 15:47:46 +0000 Subject: [PATCH 08/60] Fix non-extant log logging --- MainModule/Server/Plugins/Server-SoftShutdown.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Plugins/Server-SoftShutdown.luau b/MainModule/Server/Plugins/Server-SoftShutdown.luau index 4c5cc16f3d..2e6b95f180 100644 --- a/MainModule/Server/Plugins/Server-SoftShutdown.luau +++ b/MainModule/Server/Plugins/Server-SoftShutdown.luau @@ -30,7 +30,7 @@ return function(Vargs, GetEnv) TeleportService:Teleport(game.PlaceId, player, {[PARAMETER_2_NAME] = true}) else Logs:AddLog("Script", `Failed to teleport {player.Name} {isReservedServer and "back to the main game" or "to a temporary softshutdown server"} due to {result.Name}. Details: {message}`) - Logs:AddLog("Error", `Failed to teleport {player.Name} {isReservedServer and "back to the main game" or "to a temporary softshutdown server"} to {result.Name}. Details: {message}`) + Logs:AddLog("Errors", `Failed to teleport {player.Name} {isReservedServer and "back to the main game" or "to a temporary softshutdown server"} to {result.Name}. Details: {message}`) Functions.Notification("Teleport failed", `SoftShutdown failed to teleport {isReservedServer and "back to the main game" or "to a temporary softshutdown server"}. Details {message}`, {player}, 35, "MatIcon://Error") end end From 80754b15437aaed748b534cc80e8a7704efce3ae Mon Sep 17 00:00:00 2001 From: Bargain Bucket <122705147+NoobBucket@users.noreply.github.com> Date: Sat, 4 Jan 2025 15:48:32 +0000 Subject: [PATCH 09/60] Fix ServerNewDex not logging correctly (#1814) Fix a typo that caused an error --- MainModule/Server/Plugins/ServerNewDex.rbxmx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Plugins/ServerNewDex.rbxmx b/MainModule/Server/Plugins/ServerNewDex.rbxmx index a6ff9ffaad..5f9e16528b 100644 --- a/MainModule/Server/Plugins/ServerNewDex.rbxmx +++ b/MainModule/Server/Plugins/ServerNewDex.rbxmx @@ -61,7 +61,7 @@ Logs:AddLog("Script", "Successfully loaded reflection metadata to Dex") else Logs:AddLog("Script", "Access to HttpService is not enabled! Dex api dump could not be fetched!") - Logs:AddLog("Error", "Access to HttpService is not enabled! Dex api dump could not be fetched!") + Logs:AddLog("Errors", "Access to HttpService is not enabled! Dex api dump could not be fetched!") --logError("Access to HttpService is not enabled! Dex api dump could not be fetched!") end end) From f16549c79b07cfdcd5ea23eda603544075c81855 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Sat, 4 Jan 2025 15:49:12 +0000 Subject: [PATCH 10/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 1 + 1 file changed, 1 insertion(+) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 0e3b3be59a..49beabc0a7 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -9,6 +9,7 @@ return { "(Git/kaiserandaxl) Fix indexing nil tab (#1800)"; "(Git/fxeP1) Fix BrickColor typo inside sing command (#1811)"; "(Git/fxeP1) Fixed TextBox capability warning (#1812)"; + "(Git/NoobBucket) Fix ServerNewDex not logging correctly (#1814)"; ""; "[Patch v261.3 2024-12-30 16:46 UTC] @Dimenpsyonal"; "Fix trello erroring instead of warning (#1805)"; From 2616b83adc50725cae3a796269ba87b58bb2fbb9 Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Wed, 8 Jan 2025 05:07:36 -0500 Subject: [PATCH 11/60] Fix :oddliest (#1775) Fixes #1762 --- MainModule/Server/Commands/Fun.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Fun.luau b/MainModule/Server/Commands/Fun.luau index bc8a76aba6..ed910455e6 100644 --- a/MainModule/Server/Commands/Fun.luau +++ b/MainModule/Server/Commands/Fun.luau @@ -4733,7 +4733,7 @@ return function(Vargs, env) AdminLevel = "Moderators"; Function = function(plr: Player, args: {string}) for i, v in service.GetPlayers(plr, args[1]) do - Admin.RunCommand(`{Settings.Prefix}char`, v.Name, "userid-51310503") + Admin.RunCommand(`{Settings.Prefix}char`, v.Name, "id-51310503") end end }; From 1e2c3607feed66ddf5415f88e2937df1fb47532f Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:09:49 +0000 Subject: [PATCH 12/60] Convert test case to nightly mode (#1669) --- MainModule/Server/Plugins/Anti_Cheat.luau | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MainModule/Server/Plugins/Anti_Cheat.luau b/MainModule/Server/Plugins/Anti_Cheat.luau index 8b7b40d60c..fe74aedf5c 100644 --- a/MainModule/Server/Plugins/Anti_Cheat.luau +++ b/MainModule/Server/Plugins/Anti_Cheat.luau @@ -1,4 +1,3 @@ - --// Anti-Exploit return function(Vargs, GetEnv) local server = Vargs.Server; @@ -27,7 +26,7 @@ return function(Vargs, GetEnv) player.CharacterAdded:Wait() end - if Admin.GetLevel(player) < Settings.Ranks.Moderators.Level or Core.DebugMode then + if Admin.GetLevel(player) < Settings.Ranks.Moderators.Level or server.Data.NightlyMode then Anti.CharacterCheck(player) end end From ca5d04fd0948005aa38b4fc5fb987aa3bef9c21e Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:10:41 +0000 Subject: [PATCH 13/60] Update urgent messages module on publish (#1697) * Create alerts.deploy.project.json * Publish alerts module too --- .github/alerts.deploy.project.json | 6 ++++++ .github/workflows/publish.yml | 13 +++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 .github/alerts.deploy.project.json diff --git a/.github/alerts.deploy.project.json b/.github/alerts.deploy.project.json new file mode 100644 index 0000000000..c15a3de83d --- /dev/null +++ b/.github/alerts.deploy.project.json @@ -0,0 +1,6 @@ +{ + "name": "MainModule", + "tree": { + "$path": "../MainModule/Server/Dependencies/__URGENT_MESSAGES.luau" + } +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d91694631e..2e334559bb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -71,6 +71,9 @@ jobs: - name: Build MainModule run: rojo build -o module.rbxm .github/module.deploy.project.json + + - name: Build Alerts Module + run: rojo build -o alertsmodule.rbxm .github/alerts.deploy.project.json - name: Send Standalone Release to Discord channel uses: tsickert/discord-webhook@v6.0.0 @@ -97,3 +100,13 @@ jobs: files: '{ "file": "module.rbxm" }' customHeaders: '{ "upload-secret": "${{ secrets.PUBURL2_SECRET }}" }' timeout: 10000 + + - name: Publish Alerts Module + uses: fjogeleit/http-request-action@v1.16.1 + with: + url: "${{ secrets.PUBURL2 }}/?assetId=${{ secrets.ALERTS_MODULE_ID }}" + method: "POST" + contentType: "multipart/form-data" + files: '{ "file": "alertsmodule.rbxm" }' + customHeaders: '{ "upload-secret": "${{ secrets.PUBURL2_SECRET }}" }' + timeout: 10000 From 31934980cfe01095f826698095dae180384f56f8 Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:11:42 +0000 Subject: [PATCH 14/60] Update Roblox StandardLib before lint (#1764) * Generate Roblox standard library before lint * Generate Roblox standard library before lint * Update build.sh * Update build.bat --- build.bat | 7 +++++-- build.sh | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/build.bat b/build.bat index a1023dba8c..1d299b378f 100644 --- a/build.bat +++ b/build.bat @@ -15,10 +15,13 @@ IF %ERRORLEVEL% NEQ 0 ( SET ROJO_COMMAND=rojo ) +echo Updating Roblox standard library with %SELENE_COMMAND% +%SELENE_COMMAND% generate-roblox-std + echo Checking for lint errors with %SELENE_COMMAND% from ./Loader and ./MainModule %SELENE_COMMAND% ./MainModule ./Loader -echo Running %ROJO_COMMAND% build -o Adonis.rbxm -%ROJO_COMMAND% build -o Adonis.rbxm +echo Running %ROJO_COMMAND% build -o Adonis.rbxl +%ROJO_COMMAND% build -o Adonis.rbxl ENDLOCAL diff --git a/build.sh b/build.sh index c6733cbc4e..5da0cb392a 100644 --- a/build.sh +++ b/build.sh @@ -1,7 +1,10 @@ #!/bin/bash +printf "Updating Roblox standard library" +selene generate-roblox-std + printf "Checking for lint errors from ./Loader and ./MainModule" selene ./Loader ./MainModule -printf "Running rojo build -o Adonis.rbxm" -rojo build -o Adonis.rbxm +printf "Running rojo build -o Adonis.rbxl" +rojo build -o Adonis.rbxl From b78a5e4b4beaf88c670024baf31cec3b187bf7a6 Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:12:32 +0000 Subject: [PATCH 15/60] Use JIT for Visualizer and Slider and use optimization level 2 for Visualizer (#1774) * Use native and optimize for visualizer * Use native for slider --- MainModule/Client/UI/Default/Music/Slider.luau | 1 + MainModule/Client/UI/Default/Music/Visualizer.luau | 2 ++ 2 files changed, 3 insertions(+) diff --git a/MainModule/Client/UI/Default/Music/Slider.luau b/MainModule/Client/UI/Default/Music/Slider.luau index f24cc2065b..6dcd7d7722 100644 --- a/MainModule/Client/UI/Default/Music/Slider.luau +++ b/MainModule/Client/UI/Default/Music/Slider.luau @@ -1,3 +1,4 @@ +--!native -------------------------------------------------------------------------------------------- -------------------------------------- Slider Module --------------------------------------- -- [Adonis Maintainer]: P3tray diff --git a/MainModule/Client/UI/Default/Music/Visualizer.luau b/MainModule/Client/UI/Default/Music/Visualizer.luau index 6772f56c24..7c089564cf 100644 --- a/MainModule/Client/UI/Default/Music/Visualizer.luau +++ b/MainModule/Client/UI/Default/Music/Visualizer.luau @@ -1,3 +1,5 @@ +--!native +--!optimize 2 local RunService = game:GetService("RunService") local module = {} From cf15da50b8f49207a0ff3b4fef16f3922c01f51f Mon Sep 17 00:00:00 2001 From: TheSkout001 Date: Wed, 8 Jan 2025 13:14:14 +0300 Subject: [PATCH 16/60] add !sit command (#1776) * add !sit command yes * add * move !sit command from Players to Donors * Sit -> DonorSit --- MainModule/Server/Commands/Donors.luau | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Donors.luau b/MainModule/Server/Commands/Donors.luau index 855c5603f4..bdf434c22f 100644 --- a/MainModule/Server/Commands/Donors.luau +++ b/MainModule/Server/Commands/Donors.luau @@ -390,5 +390,19 @@ return function(Vargs, env) end }; + DonorSit = { + Prefix = Settings.PlayerPrefix; + Commands = {"sit"}; + Args = {}; + Description = "Makes your character sit"; + Donors = true; + AdminLevel = "Players"; + Function = function(plr: Player, args: {string}) + local humanoid = plr.Character and plr.Character:FindFirstChildOfClass("Humanoid") + if humanoid then + humanoid.Sit = true + end + end + }; } -end +end \ No newline at end of file From 03e233dd21013ba5c50d7b395865ff041ffc1a72 Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Wed, 8 Jan 2025 05:15:02 -0500 Subject: [PATCH 17/60] Add a way to define cameras in settings (#1777) * Update Settings.luau * Update DefaultSettings.luau * Update Variables.luau --- Loader/Config/Settings.luau | 12 ++++++++++++ MainModule/Server/Core/Variables.luau | 15 +++++++++++++++ .../Server/Dependencies/DefaultSettings.luau | 13 +++++++++++++ 3 files changed, 40 insertions(+) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index 04a748438c..88b54846dd 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -210,6 +210,16 @@ settings.Aliases = { [":examplealias "] = ":ff | :fling | :fire " --// Order arguments appear in alias string determines their required order in the command message when ran later }; +settings.Cameras = { +--[[ + "Camera Name" would be the name of your camera + { + Name = "Camera Name"; + Position = Vector3.new(0, 0, 0) + } +]] +} + settings.Banned = {} -- List of people banned from the game Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} settings.Muted = {} -- List of people muted (cannot send chat messages) Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} settings.Blacklist = {} -- List of people banned from running commands Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} @@ -406,6 +416,7 @@ descs.Creators = [[ Anyone to be identified as a place owner; Format: {"Username descs.Permissions = [[ Command permissions; Format: {"Command:NewLevel";} ]] descs.Aliases = [[ Command aliases; Format: {[":alias ..."] = ":command ..."} ]] +descs.Cameras = [[ Cameras; Format: {Name = "CamName", Position = Vector3.new(X, Y, Z)} ]] descs.Commands = [[ Custom commands ]] descs.Banned = [[ List of people banned from the game; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] @@ -523,6 +534,7 @@ order = { " "; "Permissions"; "Aliases"; + "Cameras"; " "; "Commands"; "Banned"; diff --git a/MainModule/Server/Core/Variables.luau b/MainModule/Server/Core/Variables.luau index f7243ea007..dc5132804d 100644 --- a/MainModule/Server/Core/Variables.luau +++ b/MainModule/Server/Core/Variables.luau @@ -32,6 +32,21 @@ return function(Vargs, GetEnv) Variables.ChatCreateRobloxCommands = Settings.ChatCreateRobloxCommands == nil and Variables.ChatCreateRobloxCommands or Settings.ChatCreateRobloxCommands Variables.DisableRejoinAtMaxPlayers = Settings.DisableRejoinAtMaxPlayers or Variables.DisableRejoinAtMaxPlayers + for _, v in Settings.Cameras or {} do + local cam = service.New("Part", { + Parent = workspace; + Name = `Camera: {v.Name}`; + Position = v.Position; + Anchored = true; + CanCollide = false; + Locked = true; + Size = Vector3.new(1, 1, 1); + Transparency = 1; + }) + + table.insert(Variables.Cameras, {Brick = cam, Name = v.Name}) + end + for _, v in Settings.MusicList or {} do table.insert(Variables.MusicList, v) end for _, v in Settings.InsertList or {} do table.insert(Variables.InsertList, v) end for _, v in Settings.CapeList or {} do table.insert(Variables.Capes, v) end diff --git a/MainModule/Server/Dependencies/DefaultSettings.luau b/MainModule/Server/Dependencies/DefaultSettings.luau index c19cbef1d6..8bde88b275 100644 --- a/MainModule/Server/Dependencies/DefaultSettings.luau +++ b/MainModule/Server/Dependencies/DefaultSettings.luau @@ -211,6 +211,17 @@ settings.Aliases = { [":examplealias "] = ":ff | :fling | :fire " --// Order arguments appear in alias string determines their required order in the command message when ran later }; +--// Use the below table to define pre-set cameras +settings.Cameras = { +--[[ + "Camera Name" would be the name of your camera + { + Name = "Camera Name"; + Position = Vector3.new(0, 0, 0) + } +]] +} + settings.Banned = {} -- List of people banned from the game Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} settings.Muted = {} -- List of people muted (cannot send chat messages) Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} settings.Blacklist = {} -- List of people banned from running commands Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} @@ -407,6 +418,7 @@ descs.Creators = [[ Anyone to be identified as a place owner; Format: {"Username descs.Permissions = [[ Command permissions; Format: {"Command:NewLevel";} ]] descs.Aliases = [[ Command aliases; Format: {[":alias ..."] = ":command ..."} ]] +descs.Cameras = [[ Cameras; Format: {Name = "CamName", Position = Vector3.new(X, Y, Z)} ]] descs.Commands = [[ Custom commands ]] descs.Banned = [[ List of people banned from the game; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] @@ -524,6 +536,7 @@ order = { " "; "Permissions"; "Aliases"; + "Cameras"; " "; "Commands"; "Banned"; From 082769ef97649670d9193daa8fd477cc2bc630d2 Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Wed, 8 Jan 2025 05:15:40 -0500 Subject: [PATCH 18/60] Allow team names with spaced to be created via :teams (#1778) --- MainModule/Client/UI/Default/Teams.luau | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MainModule/Client/UI/Default/Teams.luau b/MainModule/Client/UI/Default/Teams.luau index 957c721914..000b102175 100644 --- a/MainModule/Client/UI/Default/Teams.luau +++ b/MainModule/Client/UI/Default/Teams.luau @@ -85,7 +85,7 @@ return function(data, env) self.Active = false self.AutoButtonColor = false self.Text = "..." - client.Remote.Send("ProcessCommand", string.format("%snewteam%s%s%s%s", data.CmdPrefix, data.CmdSplitKey, teamName.Text, data.CmdSplitKey, teamColor.Text)); + client.Remote.Send("ProcessCommand", string.format("%snewteam%s%s%s%s", data.CmdPrefix, data.CmdSplitKey, `"{teamName.Text}"`, data.CmdSplitKey, teamColor.Text)); teamName.Text = "" teamColor.Text = "" wait(1.2) @@ -98,9 +98,6 @@ return function(data, env) end; }) - teamName:GetPropertyChangedSignal("Text"):Connect(function() - teamName.Text = string.gsub(teamName.Text, data.CmdSplitKey, "") - end) teamColor:GetPropertyChangedSignal("Text"):Connect(function() teamColor.TextColor3 = BrickColor.new(teamColor.Text).Color --teamColor.TextColor3 = `{BrickColor.new(teamColor.Text:sub(1, 1):upper()}{teamColor.Text:sub(2):lower()).Color}` -- unfortunately we have BrickColors with names like "New Yeller" From 2998ebf749eff75dd936e22047d5e32e30201790 Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Wed, 8 Jan 2025 05:16:23 -0500 Subject: [PATCH 19/60] Add R15 support for :dog (#1781) --- MainModule/Server/Commands/Fun.luau | 51 ++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Fun.luau b/MainModule/Server/Commands/Fun.luau index ed910455e6..dd67eec326 100644 --- a/MainModule/Server/Commands/Fun.luau +++ b/MainModule/Server/Commands/Fun.luau @@ -2707,7 +2707,56 @@ return function(Vargs, env) end end elseif human.RigType == Enum.HumanoidRigType.R15 then - Remote.MakeGui(plr, "Output", {Title = "Nonfunctional"; Message = `This command does not yet support R15.`; Color = Color3.new(1,1,1)}) + if plr.Character:FindFirstChild("Shirt") then + plr.Character.Shirt.Parent = plr.Character.HumanoidRootPart + end + if plr.Character:FindFirstChild("Pants") then + plr.Character.Pants.Parent = plr.Character.HumanoidRootPart + end + local char, uppertorso, lowertorso, ca1, ca2 = plr.Character, plr.Character:FindFirstChild("UpperTorso"), plr.Character:FindFirstChild("LowerTorso"), CFrame.Angles(0, 0, 0), CFrame.Angles(0, 0, 0) + local head = char:FindFirstChild("Head") + + uppertorso.Transparency = 1 + lowertorso.Transparency = 1 + + for _, v in uppertorso:GetChildren() do + if v:IsA("Motor6D") then + local lc0 = service.New("CFrameValue", {Name = "LastC0";Value = v.C0;Parent = v}) + end + end + + for _, v in lowertorso:GetChildren() do + if v:IsA("Motor6D") then + local lc0 = service.New("CFrameValue", {Name = "LastC0";Value = v.C0;Parent = v}) + end + end + + head.Neck.C0 = CFrame.new(0, -.5, -2) * CFrame.Angles(0, 0, 0) + + char.RightUpperArm["RightShoulder"].C0 = CFrame.new(.5, -1, -1.5) * ca1 + char.LeftUpperArm["LeftShoulder"].C0 = CFrame.new(-.5, -1, -1.5) * ca2 + char.RightUpperLeg["RightHip"].C0 = CFrame.new(1, -0.3, 1.5) * ca1 + char.LeftUpperLeg["LeftHip"].C0 = CFrame.new(-1, -0.3, 1.5) * ca2 + local st = service.New("Seat", { + Name = "Adonis_Torso", + TopSurface = 0, + BottomSurface = 0, + Size = Vector3.new(3, 1, 4), + }) + + local attachment = service.New("Attachment", {Parent = st}) + local bf = service.New("VectorForce", {Force = Vector3.new(0, 2e3, 0), Parent = st, Attachment0 = attachment}) + + st.CFrame = uppertorso.CFrame + st.Parent = char + + Functions.MakeWeld(uppertorso, st, CFrame.new(), CFrame.new(0, .5, 0)) + + for _, v in char:GetDescendants() do + if v:IsA("BasePart") then + v.BrickColor = BrickColor.new("Brown") + end + end end end end From 88bcd0f231b5761fa9618ed67a6ac7249c89dd7f Mon Sep 17 00:00:00 2001 From: Wilson Simanjuntak Date: Wed, 8 Jan 2025 17:18:48 +0700 Subject: [PATCH 20/60] [Core.luau] Add task.wait workaround for loading large data in Studio (#1803) * [Core.luau] Add task.wait workaround for Studio if the table length exceeds 1000 This will mitigate the extreme lag at the first 5-10 seconds caused by huge amounts of stored data such as BannedList. * [Server.Core.luau] Optimize a bit and increase the length requirement Sorry for the mistake - constantly getting table length each iteration is also a bad idea though --- MainModule/Server/Core/Core.luau | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Core/Core.luau b/MainModule/Server/Core/Core.luau index f8b8fcdd38..5f191d1429 100644 --- a/MainModule/Server/Core/Core.luau +++ b/MainModule/Server/Core/Core.luau @@ -1289,9 +1289,11 @@ return function(Vargs, GetEnv) local data = GetData(tData.TableKey) if data then --// TODO: Possibly find a better way to "batch" TableUpdates to prevent script exhaustion + local isStudio = service.RunService:IsStudio() -- Studio lag workaround for loading larger data such as BannedList + local isHugeTable = #data > 1000 for i = 1, #data do LoadData("TableUpdate", data[i]) - if i % 250 == 0 then + if (isStudio and isHugeTable and i % 25 == 0) or i % 250 == 0 then task.wait() end end From a8ffdd16c0053d15fbec102141ead4161921384b Mon Sep 17 00:00:00 2001 From: GalacticInspired <73362346+GalacticInspired@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:19:58 +0100 Subject: [PATCH 21/60] New "clear" sub-command on "whitelist" for easy whitelist clearing (#1805) * Create a new sub-command on whitelist called "wipe" * a * actualy change to clear lol * Partially revert PR-1673 due to unhandled error * nuh uh --- MainModule/Server/Commands/Admins.luau | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MainModule/Server/Commands/Admins.luau b/MainModule/Server/Commands/Admins.luau index 000c532f70..dd10d2f70d 100644 --- a/MainModule/Server/Commands/Admins.luau +++ b/MainModule/Server/Commands/Admins.luau @@ -348,8 +348,8 @@ return function(Vargs, env) Whitelist = { Prefix = Settings.Prefix; Commands = {"wl", "enablewhitelist", "whitelist"}; - Args = {"on/off/add/remove/list", "optional player"}; - Description = "Enables/disables the whitelist; :wl username to add them to the whitelist"; + Args = {"on/off/add/remove/list/clear", "optional player"}; + Description = "Enables/disables the server whitelist; :wl username to add them to the whitelist"; AdminLevel = "Admins"; Function = function(plr: Player, args: {string}) local sub = string.lower(args[1]) @@ -399,8 +399,11 @@ return function(Vargs, env) end end Remote.MakeGui(plr, "List", {Title = "Whitelist List"; Tab = Tab;}) + elseif sub == "clear" then + Variables.Whitelist.Lists.Settings = {} + Functions.Hint("Cleared server whitelist", service.Players:GetPlayers()) else - error("Invalid subcommand (on/off/add/remove/list)") + error("Invalid subcommand (on/off/add/remove/list/clear)") end end }; From e1c0bcc38bf738d4c3532dcad8b7dafd0d0cb29a Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:21:15 +0000 Subject: [PATCH 22/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 49beabc0a7..73a893e337 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -5,6 +5,17 @@ return { ""; "[v262 2025-01-03 12:35 UTC] @Dimenpsyonal"; "*First update of 2025 (!!!)"; + "(Git/TheSkout001) Add donor !sit command (#1776)"; + "(Git/WalkerOfBacon) Add a way to define cameras in settings (#1777)"; + "(Git/WalkerOfBacon) Allow team names with spaced to be created via :teams (#1778)"; + "(Git/WalkerOfBacon) Add R15 support for :dog (#1781)"; + "(Git/ccuser44) Convert test case to nightly mode (#1669)"; + "(Git/ccuser44) Update urgent messages module on publish (#1697)"; + "(Git/ccuser44) Update Roblox StandardLib before lint (#1764)"; + "(Git/ccuser44) Use JIT for Visualizer and Slider (#1774)"; + "(Git/wilsontulus) Fix for loading large data in Studio (#1803)"; + "(Git/GalacticInspired) New "clear" sub-command on "whitelist" for easy whitelist clearing (#1805)"; + "(Git/WalkerOfBacon) Fix :oddliest (#1775)"; "(Git/kaiserandaxl) Add override for TShirt Asset Type (#1799)"; "(Git/kaiserandaxl) Fix indexing nil tab (#1800)"; "(Git/fxeP1) Fix BrickColor typo inside sing command (#1811)"; From 258b376c6ad68db023dd748113bde542cee423e8 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:21:39 +0000 Subject: [PATCH 23/60] Fix quotation --- MainModule/Server/Shared/Changelog.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 73a893e337..d67eb8977b 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -14,7 +14,7 @@ return { "(Git/ccuser44) Update Roblox StandardLib before lint (#1764)"; "(Git/ccuser44) Use JIT for Visualizer and Slider (#1774)"; "(Git/wilsontulus) Fix for loading large data in Studio (#1803)"; - "(Git/GalacticInspired) New "clear" sub-command on "whitelist" for easy whitelist clearing (#1805)"; + "(Git/GalacticInspired) New 'clear' sub-command on :whitelist (#1805)"; "(Git/WalkerOfBacon) Fix :oddliest (#1775)"; "(Git/kaiserandaxl) Add override for TShirt Asset Type (#1799)"; "(Git/kaiserandaxl) Fix indexing nil tab (#1800)"; From 3f21e395086795debc6c5d766585f5f9dcfbeed1 Mon Sep 17 00:00:00 2001 From: fxe Date: Thu, 9 Jan 2025 20:59:40 +0000 Subject: [PATCH 24/60] Attempt to fix unbanning on changed player names (#1819) * Attempt to fix unbanning on changed player names * Proactive fix for Banning API plugin GetUserIdFromNameAsync & GetNameFromUserIdAsync returns the UserId/Name if a player Instance is passed. --- MainModule/Server/Commands/Admins.luau | 2 +- MainModule/Server/Commands/HeadAdmins.luau | 4 ++-- MainModule/Server/Core/Functions.luau | 14 +++++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/MainModule/Server/Commands/Admins.luau b/MainModule/Server/Commands/Admins.luau index dd10d2f70d..fae7da28af 100644 --- a/MainModule/Server/Commands/Admins.luau +++ b/MainModule/Server/Commands/Admins.luau @@ -1402,7 +1402,7 @@ return function(Vargs, env) UseFakePlayer = true; }) do - if Admin.RemoveBan(v.Name) then + if Admin.RemoveBan(v) then Functions.LogAdminAction(plr, "Unban", v.Name, "User has been unbanned.") Functions.Hint(`{service.FormatPlayer(v, true)} has been unbanned`, {plr}) else diff --git a/MainModule/Server/Commands/HeadAdmins.luau b/MainModule/Server/Commands/HeadAdmins.luau index acddf436f0..b1dea981cf 100644 --- a/MainModule/Server/Commands/HeadAdmins.luau +++ b/MainModule/Server/Commands/HeadAdmins.luau @@ -102,7 +102,7 @@ return function(Vargs, env) do Functions.LogAdminAction(plr, "Un-Time Ban", v.Name, "Removed from timeban list") Functions.Hint( - if Admin.RemoveTimeBan(v.Name) + if Admin.RemoveTimeBan(v) then `{service.FormatPlayer(v, true)} has been un-time-banned` else `{service.FormatPlayer(v, true)} is not currently time-banned`, {plr} @@ -153,7 +153,7 @@ return function(Vargs, env) do Functions.LogAdminAction(plr, "Unbanned", v.Name, "N/A") Functions.Hint( - if Admin.RemoveBan(v.Name, true) + if Admin.RemoveBan(v, true) then `{service.FormatPlayer(v, true)} has been unbanned from the game` else `{service.FormatPlayer(v, true)} is not currently banned`, {plr} diff --git a/MainModule/Server/Core/Functions.luau b/MainModule/Server/Core/Functions.luau index 3cfb23da83..5f3b0d3d8f 100644 --- a/MainModule/Server/Core/Functions.luau +++ b/MainModule/Server/Core/Functions.luau @@ -1337,7 +1337,7 @@ return function(Vargs, GetEnv) table.insert(tab,result) end end - + return tab end; @@ -1405,7 +1405,11 @@ return function(Vargs, GetEnv) return AllGrabbedPlayers end; - GetUserIdFromNameAsync = function(name) + GetUserIdFromNameAsync = function(name: string | Player) + if type(name) == "userdata" and name:IsA("Player") then + return name.UserId + end + local cache = Admin.UserIdCache[name] if not cache then local success, UserId = pcall(service.Players.GetUserIdFromNameAsync, service.Players, name) @@ -1419,7 +1423,11 @@ return function(Vargs, GetEnv) return cache end; - GetNameFromUserIdAsync = function(id) + GetNameFromUserIdAsync = function(id: number | Player) + if type(id) == "userdata" and id:IsA("Player") then + return id.Name + end + local cache = Admin.UsernameCache[id] if not cache then local success, Username = pcall(service.Players.GetNameFromUserIdAsync, service.Players, id) From 071e1487106a919a28f9628305f8a75758302004 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Thu, 9 Jan 2025 21:00:17 +0000 Subject: [PATCH 25/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index d67eb8977b..106e21aa21 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -5,7 +5,7 @@ return { ""; "[v262 2025-01-03 12:35 UTC] @Dimenpsyonal"; "*First update of 2025 (!!!)"; - "(Git/TheSkout001) Add donor !sit command (#1776)"; + "(Git/fxeP1) Attempt to fix unbanning on changed player names (#1819)"; "(Git/WalkerOfBacon) Add a way to define cameras in settings (#1777)"; "(Git/WalkerOfBacon) Allow team names with spaced to be created via :teams (#1778)"; "(Git/WalkerOfBacon) Add R15 support for :dog (#1781)"; From 7aceaaf31a8aa8b9164e274962c71eaf1b4e2318 Mon Sep 17 00:00:00 2001 From: connor <85421634+ScriptedConnor@users.noreply.github.com> Date: Fri, 10 Jan 2025 18:08:30 -0500 Subject: [PATCH 26/60] Fixed friends tab on the !profile command. (#1821) --- MainModule/Client/UI/Default/Profile.luau | 33 +++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/MainModule/Client/UI/Default/Profile.luau b/MainModule/Client/UI/Default/Profile.luau index b1105632bf..1abefa1804 100644 --- a/MainModule/Client/UI/Default/Profile.luau +++ b/MainModule/Client/UI/Default/Profile.luau @@ -162,29 +162,40 @@ return function(data, env) window:Ready() do --// Friends Tab + local function pagesToTable(pages) + local items = {} + while true do + table.insert(items, pages:GetCurrentPage()) + if pages.IsFinished then + break + end + pages:AdvanceToNextPageAsync() + end + return items + end local function iterPageItems(pages) + local contents = pagesToTable(pages) + local pagenum = 1 + local lastpagenum = #contents return coroutine.wrap(function() local pagenum = 1 - while true do - for _, item in ipairs(pages:GetCurrentPage()) do + while pagenum <= lastpagenum do + for _, item in ipairs(contents[pagenum]) do coroutine.yield(item, pagenum) end - if pages.IsFinished then - break - end - pages:AdvanceToNextPageAsync() + pagenum += 1 end end) end - local LOCATION_TYPE = {"Mobile Website", "Mobile InGame", "Webpage", "Studio", "InGame", "Xbox", "Team Create"} + local LOCATION_TYPE = {"Mobile Website", "Mobile In-Game", "Webpage", "Studio", "In-Game", "Xbox", "Team Create"} local ACTIVITY_COLOR_CODES = { ["Mobile Website"] = Color3.fromRGB(50, 140, 231); - ["Mobile InGame"] = Color3.fromRGB(55, 200, 55); + ["Mobile In-Game"] = Color3.fromRGB(55, 200, 55); ["Webpage"] = Color3.fromRGB(50, 140, 231); ["Studio"] = Color3.fromRGB(231, 112, 0); - ["InGame"] = Color3.fromRGB(55, 200, 55); + ["In-Game"] = Color3.fromRGB(55, 200, 55); ["Xbox"] = Color3.fromRGB(127, 0, 127); ["Team Create"] = Color3.fromRGB(231, 112, 0); } @@ -210,7 +221,7 @@ return function(data, env) Routine(function() for item, pageNo in iterPageItems(friendPages) do table.insert(sortedFriends, item.Username) - local userId = item.id + local userId = item.Id local activity = onlineFriends[userId] friendInfoRef[item.Username] = { id = userId; @@ -467,4 +478,4 @@ return function(data, env) else gametab:Disable() end -end +end \ No newline at end of file From 74cff736fe3364ed385573f1ae730b6d07dc84b5 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Sat, 11 Jan 2025 02:10:27 +0300 Subject: [PATCH 27/60] Revert "add !sit command (#1776)" (#1820) This reverts commit cf15da50b8f49207a0ff3b4fef16f3922c01f51f. --- MainModule/Server/Commands/Donors.luau | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/MainModule/Server/Commands/Donors.luau b/MainModule/Server/Commands/Donors.luau index bdf434c22f..855c5603f4 100644 --- a/MainModule/Server/Commands/Donors.luau +++ b/MainModule/Server/Commands/Donors.luau @@ -390,19 +390,5 @@ return function(Vargs, env) end }; - DonorSit = { - Prefix = Settings.PlayerPrefix; - Commands = {"sit"}; - Args = {}; - Description = "Makes your character sit"; - Donors = true; - AdminLevel = "Players"; - Function = function(plr: Player, args: {string}) - local humanoid = plr.Character and plr.Character:FindFirstChildOfClass("Humanoid") - if humanoid then - humanoid.Sit = true - end - end - }; } -end \ No newline at end of file +end From f93b7118b0b708f5ddf7def3fb4d8d47364bdc26 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Fri, 10 Jan 2025 23:29:19 +0000 Subject: [PATCH 28/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 1 + 1 file changed, 1 insertion(+) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 106e21aa21..9ede01a5c0 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -21,6 +21,7 @@ return { "(Git/fxeP1) Fix BrickColor typo inside sing command (#1811)"; "(Git/fxeP1) Fixed TextBox capability warning (#1812)"; "(Git/NoobBucket) Fix ServerNewDex not logging correctly (#1814)"; + "(Git/ScriptedConnor) Fixed friends tab on the !profile command (#1821)"; ""; "[Patch v261.3 2024-12-30 16:46 UTC] @Dimenpsyonal"; "Fix trello erroring instead of warning (#1805)"; From 3608b08995bce944fd7b7e011cc2a72b02b3425d Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Sat, 11 Jan 2025 02:05:16 -0500 Subject: [PATCH 29/60] Fix :pchat glitching (#1809) --- MainModule/Client/UI/Default/PrivateChat.luau | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MainModule/Client/UI/Default/PrivateChat.luau b/MainModule/Client/UI/Default/PrivateChat.luau index a60b8db2bd..f4312fe6fc 100644 --- a/MainModule/Client/UI/Default/PrivateChat.luau +++ b/MainModule/Client/UI/Default/PrivateChat.luau @@ -321,7 +321,7 @@ return function(data, env) Parent = chatlog; FillDirection = "Vertical"; HorizontalAlignment = "Left"; - VerticalAlignment = "Bottom"; + VerticalAlignment = "Top"; SortOrder = "LayoutOrder"; }) @@ -358,7 +358,6 @@ return function(data, env) local p = vargs[1] local message = vargs[2] if newMessage then - print('sdf') newMessage({ PlayerName = p.Name; PlayerDisplayName = p.DisplayName; From c367391e36c4cda7b8016eaf0f1220f072b5ef92 Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Sat, 11 Jan 2025 07:29:29 +0000 Subject: [PATCH 30/60] Use standardized naming for build files that respects gitignore (#1817) Co-authored-by: Expertcoderz --- .github/workflows/publish.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2e334559bb..71780ea74e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -67,14 +67,14 @@ jobs: path: ${{ steps.naming.outputs.output_name }}.rbxm - name: Build Loader - run: rojo build -o loader.rbxm .github/loader.deploy.project.json + run: rojo build -o Adonis_Loader.rbxm .github/loader.deploy.project.json - name: Build MainModule - run: rojo build -o module.rbxm .github/module.deploy.project.json + run: rojo build -o Adonis_MainModule.rbxm .github/module.deploy.project.json - name: Build Alerts Module - run: rojo build -o alertsmodule.rbxm .github/alerts.deploy.project.json - + run: rojo build -o Adonis_AlertsModule.rbxm .github/alerts.deploy.project.json + - name: Send Standalone Release to Discord channel uses: tsickert/discord-webhook@v6.0.0 with: @@ -87,7 +87,7 @@ jobs: url: "${{ secrets.PUBURL2 }}/?assetId=${{ secrets.LOADER_ID }}" method: "POST" contentType: "multipart/form-data" - files: '{ "file": "loader.rbxm" }' + files: '{ "file": "Adonis_Loader.rbxm" }' customHeaders: '{ "upload-secret": "${{ secrets.PUBURL2_SECRET }}" }' timeout: 10000 @@ -97,7 +97,7 @@ jobs: url: "${{ secrets.PUBURL2 }}/?assetId=${{ secrets.MODULE_ID }}" method: "POST" contentType: "multipart/form-data" - files: '{ "file": "module.rbxm" }' + files: '{ "file": "Adonis_MainModule.rbxm" }' customHeaders: '{ "upload-secret": "${{ secrets.PUBURL2_SECRET }}" }' timeout: 10000 @@ -107,6 +107,6 @@ jobs: url: "${{ secrets.PUBURL2 }}/?assetId=${{ secrets.ALERTS_MODULE_ID }}" method: "POST" contentType: "multipart/form-data" - files: '{ "file": "alertsmodule.rbxm" }' + files: '{ "file": "Adonis_AlertsModule.rbxm" }' customHeaders: '{ "upload-secret": "${{ secrets.PUBURL2_SECRET }}" }' timeout: 10000 From 4aff151701921256e4b466a6da36fce11dbf9c57 Mon Sep 17 00:00:00 2001 From: ImFirstPlace <38781655+ImFirstPlace@users.noreply.github.com> Date: Sat, 11 Jan 2025 18:38:49 +1100 Subject: [PATCH 31/60] Update TextField PlaceholderColor3 (#1806) --- MainModule/Client/UI/Windows XP/Window.rbxmx | 159 +++++++++++-------- 1 file changed, 91 insertions(+), 68 deletions(-) diff --git a/MainModule/Client/UI/Windows XP/Window.rbxmx b/MainModule/Client/UI/Windows XP/Window.rbxmx index cd162b580f..3439b8f3b3 100644 --- a/MainModule/Client/UI/Windows XP/Window.rbxmx +++ b/MainModule/Client/UI/Windows XP/Window.rbxmx @@ -2,7 +2,7 @@ true null nil - + false @@ -25,7 +25,7 @@ 0 - + false @@ -69,6 +69,7 @@ null null null + 0 0 @@ -118,7 +119,7 @@ false 2 - + true @@ -164,6 +165,7 @@ null null null + 0.699999988 0.699999988 @@ -222,7 +224,7 @@ 2 - + 0 @@ -234,7 +236,7 @@ - + false @@ -297,7 +299,7 @@ false 2 - + 0 @@ -308,7 +310,7 @@ 0 - + false @@ -372,7 +374,7 @@ 2 - + false @@ -469,7 +471,7 @@ 2 - + false @@ -567,7 +569,7 @@ - + false @@ -630,7 +632,7 @@ false 999999 - + false @@ -674,6 +676,7 @@ null null null + 0 5 @@ -725,7 +728,7 @@ - + false @@ -788,7 +791,7 @@ false 1 - + true @@ -834,6 +837,7 @@ null null null + 0 0 @@ -886,7 +890,7 @@ 1 - + true @@ -989,7 +993,7 @@ 1 - + false @@ -1054,7 +1058,7 @@ - + 0 @@ -1063,7 +1067,7 @@ -1 - + 0 @@ -1074,14 +1078,14 @@ true - + 0 false Code.OLD - {0506ffb7-ad3b-489a-9bef-cfd7dbff8f3e} + {31a3c2a2-a077-40a7-9010-52f827d566fa} - + 0 @@ -2713,14 +2717,14 @@ end]]> true - + 0 false NoEnv-Modifier - {9840b665-71ba-4ed0-acd6-04d535842c43} + {396ac619-0995-414c-a5c6-7c78f71f014a} - + false @@ -2879,6 +2887,7 @@ end]]> null null null + 0 0 @@ -2928,7 +2937,7 @@ end]]> false 2 - + true @@ -2974,6 +2983,7 @@ end]]> null null null + 1 -50 @@ -3026,7 +3036,7 @@ end]]> 2 - + 0 @@ -3038,7 +3048,7 @@ end]]> - + false @@ -3082,6 +3092,7 @@ end]]> null null null + 0 0 @@ -3131,7 +3142,7 @@ end]]> false 2 - + true @@ -3177,6 +3188,7 @@ end]]> null null null + 1 -100 @@ -3229,7 +3241,7 @@ end]]> 2 - + 0 @@ -3241,7 +3253,7 @@ end]]> - + true @@ -3273,7 +3285,7 @@ end]]> rbxasset://fonts/families/LegacyArial.json 400 - rbxasset://fonts/arial.ttf + rbxasset://fonts/Arimo-Regular.ttf true 0 @@ -3287,6 +3299,7 @@ end]]> null null null + 0 400 @@ -3338,7 +3351,7 @@ end]]> true 1 - + true @@ -3441,7 +3454,7 @@ end]]> 2 - + false @@ -3485,6 +3498,7 @@ end]]> null null null + 0 34 @@ -3535,7 +3549,7 @@ end]]> 9 - + false @@ -3631,7 +3645,7 @@ end]]> true 1 - + true @@ -3702,7 +3716,7 @@ end]]> 0 0 0 - false + true null 0 @@ -3721,7 +3735,7 @@ end]]> 1 - + false @@ -3824,7 +3838,7 @@ end]]> 1 - + false @@ -3927,7 +3941,7 @@ end]]> 1 - + false @@ -4030,7 +4044,7 @@ end]]> 1 - + false @@ -4133,7 +4147,7 @@ end]]> 1 - + false @@ -4236,7 +4250,7 @@ end]]> 1 - + false @@ -4339,7 +4353,7 @@ end]]> 1 - + false @@ -4442,7 +4456,7 @@ end]]> 1 - + false @@ -4545,7 +4559,7 @@ end]]> 1 - + false @@ -4642,7 +4656,7 @@ end]]> 1 - + false @@ -4740,7 +4754,7 @@ end]]> - + true @@ -4786,6 +4800,7 @@ end]]> null null null + 1 -52 @@ -4837,7 +4852,7 @@ end]]> true 2 - + true @@ -4941,7 +4956,7 @@ end]]> - + true @@ -4987,6 +5002,7 @@ end]]> null null null + 1 -76 @@ -5038,7 +5054,7 @@ end]]> true 2 - + true @@ -5141,7 +5157,7 @@ end]]> 1 - + false @@ -5239,7 +5255,7 @@ end]]> - + true @@ -5285,6 +5301,7 @@ end]]> null null null + 1 -28 @@ -5336,7 +5353,7 @@ end]]> true 2 - + false @@ -5380,6 +5397,7 @@ end]]> null null null + 0.5 0 @@ -5430,7 +5448,7 @@ end]]> 10 - + true @@ -5534,7 +5552,7 @@ end]]> - + false @@ -5632,7 +5650,7 @@ end]]> - + 0 @@ -5643,7 +5661,7 @@ end]]> true - + false @@ -5706,7 +5724,7 @@ end]]> false 1 - + false @@ -5777,7 +5795,7 @@ end]]> 0 0 0 - false + true null 0 @@ -5796,7 +5814,7 @@ end]]> 1 - + false @@ -5861,7 +5879,7 @@ end]]> - + false @@ -5905,6 +5923,7 @@ end]]> null null null + 0 0 @@ -5954,7 +5973,7 @@ end]]> false 2 - + true @@ -6000,6 +6019,7 @@ end]]> null null null + 1 -100 @@ -6052,7 +6072,7 @@ end]]> 2 - + 0 @@ -6064,7 +6084,7 @@ end]]> - + false @@ -6127,7 +6147,7 @@ end]]> false 2 - + 0 @@ -6138,7 +6158,7 @@ end]]> TestDesc - + false @@ -6182,6 +6202,7 @@ end]]> null null null + 0 5 @@ -6232,7 +6253,7 @@ end]]> 2 - + false @@ -6276,6 +6297,7 @@ end]]> null null null + 1 -10 @@ -6327,7 +6349,7 @@ end]]> - + true @@ -6373,6 +6395,7 @@ end]]> null null null + 1 -100 @@ -6426,4 +6449,4 @@ end]]> - + \ No newline at end of file From c6a288435bdf6eb4a4735b4805d47d6ac933adb5 Mon Sep 17 00:00:00 2001 From: Jacob <147295502+Jgard12521@users.noreply.github.com> Date: Sat, 11 Jan 2025 03:35:52 -0600 Subject: [PATCH 32/60] Update the Licence Date (#1815) * Update LICENSE.luau * Update LICENSE.md --- LICENSE.luau | 2 +- LICENSE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.luau b/LICENSE.luau index 1c2b089369..a81c1f3dbe 100644 --- a/LICENSE.luau +++ b/LICENSE.luau @@ -2,7 +2,7 @@ MIT License - Copyright (c) 2016-2024 Sceleratis (https://github.com/Sceleratis), Epix Incorporated, and the Adonis Community. + Copyright (c) 2016-2025 Sceleratis (https://github.com/Sceleratis), Epix Incorporated, and the Adonis Community. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/LICENSE.md b/LICENSE.md index cca960237f..f35d57aa81 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016-2024 Sceleratis (https://github.com/Sceleratis), Epix Incorporated, and the Adonis Community. +Copyright (c) 2016-2025 Sceleratis (https://github.com/Sceleratis), Epix Incorporated, and the Adonis Community. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 0cf0aa0b9c7382c4e320830483c28088d0a3d643 Mon Sep 17 00:00:00 2001 From: Speeder323 <61844671+Speeder323@users.noreply.github.com> Date: Sat, 11 Jan 2025 10:46:25 +0100 Subject: [PATCH 33/60] Fix debounce for antiexploit notifications (#1783) * Fix notification debounce not being utilized The debounce was being set to 1 if the value was set, but other than that, it was not being increased, hence the debounce never kicked in. * off by one; make it 3 notifications again * Debounce table gets cleared within 60 seconds, not after --- MainModule/Server/Core/Anti.luau | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Core/Anti.luau b/MainModule/Server/Core/Anti.luau index accd3a746d..fbdb70ebd4 100644 --- a/MainModule/Server/Core/Anti.luau +++ b/MainModule/Server/Core/Anti.luau @@ -187,7 +187,7 @@ return function(Vargs, GetEnv) if Settings.AENotifs == true or Settings.ExploitNotifications == true then -- AENotifs for old loaders local debounceIndex = `{action}{player}{info}` - if os.clock() < antiNotificationResetTick then + if os.clock() > antiNotificationResetTick then antiNotificationDebounce = {} antiNotificationResetTick = os.clock() + 60 end @@ -201,6 +201,8 @@ return function(Vargs, GetEnv) return end + antiNotificationDebounce[debounceIndex] += 1 + for _, plr in service.Players:GetPlayers() do if Admin.GetLevel(plr) >= Settings.Ranks.Moderators.Level then Functions.Notification("Notification", string.format( From 559683dd88cbd783f1df57b158701bf36a472b08 Mon Sep 17 00:00:00 2001 From: Expertcoderz Date: Sat, 11 Jan 2025 13:28:25 +0000 Subject: [PATCH 34/60] Set argument range limits on :lowres (#1823) Prevents severe lag issues. --- MainModule/Server/Commands/Fun.luau | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Fun.luau b/MainModule/Server/Commands/Fun.luau index dd67eec326..93715fec68 100644 --- a/MainModule/Server/Commands/Fun.luau +++ b/MainModule/Server/Commands/Fun.luau @@ -429,7 +429,9 @@ return function(Vargs, env) AdminLevel = "Admins"; Function = function(plr: Player, args: {string}) local size = tonumber(args[2]) or 19 + assert(size >= 10, "Pixel size too small (< 10)") local dist = tonumber(args[3]) or 100 + assert(dist <= 10_000, "Render distance too large (> 10,000)") for i, v in service.GetPlayers(plr, args[1]) do Remote.MakeGui(v, "Effect", { Mode = "Pixelize"; @@ -2724,7 +2726,7 @@ return function(Vargs, env) local lc0 = service.New("CFrameValue", {Name = "LastC0";Value = v.C0;Parent = v}) end end - + for _, v in lowertorso:GetChildren() do if v:IsA("Motor6D") then local lc0 = service.New("CFrameValue", {Name = "LastC0";Value = v.C0;Parent = v}) From 5ef191afb65cabca4c4498a9cf4702ef37523367 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Sat, 11 Jan 2025 17:13:59 +0000 Subject: [PATCH 35/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 9ede01a5c0..abb535de75 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -5,6 +5,7 @@ return { ""; "[v262 2025-01-03 12:35 UTC] @Dimenpsyonal"; "*First update of 2025 (!!!)"; + "Set argument range limits on :lowres"; "(Git/fxeP1) Attempt to fix unbanning on changed player names (#1819)"; "(Git/WalkerOfBacon) Add a way to define cameras in settings (#1777)"; "(Git/WalkerOfBacon) Allow team names with spaced to be created via :teams (#1778)"; @@ -22,6 +23,9 @@ return { "(Git/fxeP1) Fixed TextBox capability warning (#1812)"; "(Git/NoobBucket) Fix ServerNewDex not logging correctly (#1814)"; "(Git/ScriptedConnor) Fixed friends tab on the !profile command (#1821)"; + "(Git/WalkerOfBacon) Fix :pchat glitching (#1809)"; + "(Git/ImFirstPlace) Update TextField PlaceholderColor3 (#1806)"; + "(Git/Speeder323) Fix debounce for antiexploit notifications (#1783)"; ""; "[Patch v261.3 2024-12-30 16:46 UTC] @Dimenpsyonal"; "Fix trello erroring instead of warning (#1805)"; From 07c77c49954028b2b8395ad928b12527e895de88 Mon Sep 17 00:00:00 2001 From: connor <85421634+convxors@users.noreply.github.com> Date: Sun, 12 Jan 2025 01:13:48 -0500 Subject: [PATCH 36/60] Github Username Changed (#1825) * Fixed friends tab on the !profile command. * Update Changelog.luau Github username changes from ScriptedConnor to convxors * Update Credits.luau Github username change from ScriptedConnor to convxors --------- Co-authored-by: connor <85421634+ScriptedConnor@users.noreply.github.com> --- MainModule/Server/Shared/Changelog.luau | 6 +++--- MainModule/Server/Shared/Credits.luau | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index abb535de75..14dfc25792 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -22,7 +22,7 @@ return { "(Git/fxeP1) Fix BrickColor typo inside sing command (#1811)"; "(Git/fxeP1) Fixed TextBox capability warning (#1812)"; "(Git/NoobBucket) Fix ServerNewDex not logging correctly (#1814)"; - "(Git/ScriptedConnor) Fixed friends tab on the !profile command (#1821)"; + "(Git/convxors) Fixed friends tab on the !profile command (#1821)"; "(Git/WalkerOfBacon) Fix :pchat glitching (#1809)"; "(Git/ImFirstPlace) Update TextField PlaceholderColor3 (#1806)"; "(Git/Speeder323) Fix debounce for antiexploit notifications (#1783)"; @@ -47,9 +47,9 @@ return { "(Git/Mars7383) Fix typo in Loadstring dependency affecting :ss (#1587)"; "(Git/PurpleCreativity) Remove ;cut command (#1590)"; "(Git/EasternBloxxer) Make dex fetch api dump on server start (#1591)"; - "(Git/ScriptedConnor) Fix TopBarShift for :setmessage (#1593)"; + "(Git/convxors) Fix TopBarShift for :setmessage (#1593)"; "(Git/jun022222222) Replace Coords.luau (#1595)"; - "(Git/ScriptedConnor) Add Text Selections to the :players Command (#1597)"; + "(Git/convxors) Add Text Selections to the :players Command (#1597)"; "(Git/omwot) Improve Modern theme (#1598)"; "(Git/jun022222222) Make mats & colors list selectable (#1599)"; "(Git/24rr) Add a search player bar for :privatechat (#1594)"; diff --git a/MainModule/Server/Shared/Credits.luau b/MainModule/Server/Shared/Credits.luau index e38134a0e3..413a1bc2f1 100644 --- a/MainModule/Server/Shared/Credits.luau +++ b/MainModule/Server/Shared/Credits.luau @@ -96,7 +96,7 @@ return { {Text = "@Hedreon", Desc = "Open Source Contributor"}; {Text = "@Mars7383", Desc = "Open Source Contributor"}; {Text = "@PurpleCreativity",Desc = "Open Source Contributor"}; - {Text = "@ScriptedConnor", Desc = "Open Source Contributor"}; + {Text = "@convxors", Desc = "Open Source Contributor"}; {Text = "@omwot", Desc = "Open Source Contributor"}; }; From 250d0a3dfc0dc883d2ae4c8a372560ec427f4a58 Mon Sep 17 00:00:00 2001 From: bt <49007543+btt-t@users.noreply.github.com> Date: Sun, 12 Jan 2025 21:57:58 +1100 Subject: [PATCH 37/60] GitHub Username Changed (#1826) * Update Changelog.luau * Update Credits.luau --- MainModule/Server/Shared/Changelog.luau | 10 +++++----- MainModule/Server/Shared/Credits.luau | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 14dfc25792..3d0523a491 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -1252,7 +1252,7 @@ return { "*Dex updated and moved to its own module; Also added server-side action support"; "*Fixed :countdown"; "*Fixed :slowmode"; - "(Git/happyman090) Fix for sp00ky and k1tty on MeshPart head places"; + "(Git/btt-t) Fix for sp00ky and k1tty on MeshPart head places"; "(Git/Expertcoderz) Mistake fixing + Aero theme"; "(Git/Expertcoderz) Add :transparency command"; "(Git/Expertcoderz) Command-related additions #379"; @@ -1315,7 +1315,7 @@ return { "(Git/ccuser44) Made print and warn work properly. Also fixed some indentation."; "(Git/ccuser44) Removed unnecessary references to filtering enabled."; "(Git/ccuser44) Fixed incorrect string literals"; - "(Git/happyman090) Refresh command update"; + "(Git/btt-t) Refresh command update"; ""; "[v217 5.9.2021 19:15 EST]"; "* Random bug fixes & changes"; @@ -1327,8 +1327,8 @@ return { "(Git/imskyyc) Updated TrelloAPI"; "(Git/ccuser44) Added unprotected metatable detection with tamper protection"; "(Git/LolloDev5123) :admins now correctly shows \"Head Admin\" instead of \"Supervisor\""; - "(Git/happyman090) Character animations for clones"; - "(Git/happyman090) Modified behaviour of kill command"; + "(Git/btt-t) Character animations for clones"; + "(Git/btt-t) Modified behaviour of kill command"; "(Git/p3tray & pbstFusion) Added :pban and :unpban as aliases for :gameban and :ungameban"; "(Git/p3tray) Added _G.Adonis.RunCommandAsNonAdmin(command, playerToRunCommandAs)"; "(Git/Expertcoderz) Revamped server details UI"; @@ -1351,7 +1351,7 @@ return { "*Removed some debug prints and debug/old code"; "*Fixed some typos"; "*Minor bug/security changes"; - "(Git/happyman090) Fixed donor neon command"; + "(Git/btt-t) Fixed donor neon command"; "(Git/Expertcoderz) Removed 'besties' from !usage"; "(Git/fxeP1) Updated ServerInfo command, HTTP.CheckHttp, and RunCommandAsPlayer"; "(Git/Expercoderz) Added :promptpremiumpurchase "; diff --git a/MainModule/Server/Shared/Credits.luau b/MainModule/Server/Shared/Credits.luau index 413a1bc2f1..2fe59fe052 100644 --- a/MainModule/Server/Shared/Credits.luau +++ b/MainModule/Server/Shared/Credits.luau @@ -39,7 +39,7 @@ return { {Text = "@NeoInversion", Desc = "Open Source Contributor"}; {Text = "@imskyyc", Desc = "Open Source Contributor"}; {Text = "@LolloDev5123", Desc = "Open Source Contributor"}; - {Text = "@happyman090", Desc = "Open Source Contributor"}; + {Text = "@btt-t", Desc = "Open Source Contributor"}; {Text = "@GalacticInspired",Desc = "Open Source Contributor"}; {Text = "@flgx16", Desc = "Open Source Contributor"}; {Text = "@DrewBokman", Desc = "Open Source Contributor"}; From 0f20c275122fdf016ddb3198268dd0368f282538 Mon Sep 17 00:00:00 2001 From: Project_HSI <57279339+ProjectHSI@users.noreply.github.com> Date: Sun, 12 Jan 2025 21:12:26 +1000 Subject: [PATCH 38/60] Update SECURITY.md to match CoasterTeam's message (#1810) --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index c51c053726..a4ebe97558 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,7 +11,7 @@ Only the *live* (release) version of Adonis is officially supported and given se ## Reporting a Vulnerability in Adonis -👉 **If the vulnerability is *severe* or highly damaging**, join the [Epix Incorporated Discord server](https://discord.gg/H5RvTP3) and DM an *Adonis Maintainer*. +👉 **If the vulnerability is *severe* or highly damaging**, join the [Epix Incorporated Discord server](https://discord.gg/H5RvTP3) and DM an *Moderator*, *Developer, or *Maintainer*. 👉 **If the vulnerability is relatively minor and can be safely discussed in public**, create a bug report [on GitHub](https://github.com/Epix-Incorporated/Adonis/issues/new/choose) or in our Discord server. From 1d89bf41f83b185856b3b4de16367810f6281c16 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:16:23 +0000 Subject: [PATCH 39/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 3d0523a491..2db3d51843 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -3,7 +3,7 @@ return { "*Drag edges to expand*"; "*Report bugs/issues on our GitHub repository*"; ""; - "[v262 2025-01-03 12:35 UTC] @Dimenpsyonal"; + "[v262 2025-01-12 11:16 UTC] @Dimenpsyonal"; "*First update of 2025 (!!!)"; "Set argument range limits on :lowres"; "(Git/fxeP1) Attempt to fix unbanning on changed player names (#1819)"; From 303fec808f56ec6838683f9f935c82d0d15900e0 Mon Sep 17 00:00:00 2001 From: Expertcoderz Date: Mon, 13 Jan 2025 03:06:12 +0000 Subject: [PATCH 40/60] Clamp #num selector to max players Prevents crashes e.g. due to `!inspect #999999999`. --- MainModule/Server/Core/Functions.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Core/Functions.luau b/MainModule/Server/Core/Functions.luau index 5f3b0d3d8f..e81407b0e3 100644 --- a/MainModule/Server/Core/Functions.luau +++ b/MainModule/Server/Core/Functions.luau @@ -355,7 +355,7 @@ return function(Vargs, GetEnv) return; end - for i = 1,num do + for i = 1, math.min(num, #service.Players:GetPlayers()) do Functions.PlayerFinders.random.Function(msg, plr, ...) end end From fda83d8fe32312857cd3a0c15c78a3254d247ba2 Mon Sep 17 00:00:00 2001 From: Expertcoderz Date: Mon, 13 Jan 2025 03:08:58 +0000 Subject: [PATCH 41/60] Load plugins asynchronously (#1822) --- MainModule/Client/Client.luau | 8 +++++--- MainModule/Server/Server.luau | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/MainModule/Client/Client.luau b/MainModule/Client/Client.luau index 4d6133487c..9b59dfc27a 100644 --- a/MainModule/Client/Client.luau +++ b/MainModule/Client/Client.luau @@ -218,7 +218,7 @@ do task.wait(1) service.Player:Kick(info) end) - + if not isStudio then spawn(pcall, function() task.wait(5) @@ -575,7 +575,7 @@ return service.NewProxy({ for i, line in ipairs(client.Changelog) do client.FormattedChangelog[i] = applyColour(line) end - + --// Setup MatIcons do local MaterialIcons = oldReq(service_UnWrap(client.Shared.MatIcons)) @@ -752,7 +752,9 @@ return service.NewProxy({ continue end - LoadModule(module, false, { script = module, cPcall = client.cPcall }) --noenv + task.defer(LoadModule, module, false, { --noenv + script = module, cPcall = client.cPcall + }) end --// We need to do some stuff *after* plugins are loaded (in case we need to be able to account for stuff they may have changed before doing something, such as determining the max length of remote commands) diff --git a/MainModule/Server/Server.luau b/MainModule/Server/Server.luau index 75245fb231..486f3ca2ae 100644 --- a/MainModule/Server/Server.luau +++ b/MainModule/Server/Server.luau @@ -632,7 +632,7 @@ return service.NewProxy({ server.FormattedChangelog[i] = applyColour(line) end - --// Setup MaterialIcons + --// Setup MaterialIcons do local MaterialIcons = require(server.Shared.MatIcons) server.MatIcons = setmetatable({}, { @@ -712,7 +712,7 @@ return service.NewProxy({ end for _, module in ipairs(data.ServerPlugins or {}) do - xpcall(LoadModule, function(reason) + task.defer(xpcall, LoadModule, function(reason) warn(`The plugin {type(module) == "string" and string.sub(module, 1, 15) or module} failed to load! Reason: {reason}`) logError(`The plugin {type(module) == "string" and string.sub(module, 1, 15) or module} failed to load! Reason: {reason}`) table.insert(server.messages, { From f4176fac76ea1775002a6afecc154fd100b63476 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:18:29 +0000 Subject: [PATCH 42/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 2db3d51843..fba90c3184 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -1,8 +1,12 @@ return { - "Version: 262"; + "Version: 263"; "*Drag edges to expand*"; "*Report bugs/issues on our GitHub repository*"; ""; + "[v263 2025-01-13 16:17 UTC] @Dimenpsyonal"; + "Load plugins asynchronously"; + "Clamp #num selector to max players"; + ""; "[v262 2025-01-12 11:16 UTC] @Dimenpsyonal"; "*First update of 2025 (!!!)"; "Set argument range limits on :lowres"; From 3c13b22754972f285fbb66ab65b0248a1cc16ce4 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:18:51 +0000 Subject: [PATCH 43/60] Update Version.model to 263 --- Loader/Version.model.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loader/Version.model.json b/Loader/Version.model.json index 50b0f991a1..6cde8b08e1 100644 --- a/Loader/Version.model.json +++ b/Loader/Version.model.json @@ -1,6 +1,6 @@ { "ClassName": "NumberValue", "Properties": { - "Value": 261 + "Value": 263 } } From f65cdf2d8a838cf3f218b3b108ed774141341de0 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:25:04 +0000 Subject: [PATCH 44/60] Change default prefix --- Loader/Config/Settings.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index 88b54846dd..44ba1efae3 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -238,7 +238,7 @@ settings.SaveAdmins = true -- If true anyone you :admin or :headadmin in-game settings.LoadAdminsFromDS = true -- If false, any admins saved in your DataStores will not load settings.WhitelistEnabled = false -- If true enables the whitelist/server lock; Only lets admins & whitelisted users join -settings.Prefix = ":" -- The : in :kill me +settings.Prefix = ";" -- The ; in ;kill me settings.PlayerPrefix = "!" -- The ! in !donate; Mainly used for commands that any player can run; Do not make it the same as settings.Prefix settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do :kill !me) settings.SplitKey = " " -- The space in :kill me (eg if you change it to / :kill me would be :kill/me) From 675e0232cb473a372760cfbc9ae5bcde4ff7cd88 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:34:56 +0000 Subject: [PATCH 45/60] Change prefix --- .../Server/Dependencies/DefaultSettings.luau | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/MainModule/Server/Dependencies/DefaultSettings.luau b/MainModule/Server/Dependencies/DefaultSettings.luau index 8bde88b275..c9a2e27bc7 100644 --- a/MainModule/Server/Dependencies/DefaultSettings.luau +++ b/MainModule/Server/Dependencies/DefaultSettings.luau @@ -75,7 +75,7 @@ local descs = {}; --// Contains settings descriptions settings.HeadAdmins = {"Group:181:121"} See? Not so hard is it? - If I wanted to add group 181 and all ranks in it to the :slock whitelist I would do; + If I wanted to add group 181 and all ranks in it to the ;slock whitelist I would do; settings.Whitelist = {"Group:181";} I can do the above if I wanted to give everyone in a group admin for any of the other admin tables @@ -85,11 +85,11 @@ local descs = {}; --// Contains settings descriptions --// Command Permissions You can set the permission level for specific commands using setting.Permissions - If I wanted to make it so only HeadAdmins+ can use :ff player then I would do: + If I wanted to make it so only HeadAdmins+ can use ;ff player then I would do: settings.Permissions = {"ff:HeadAdmins"} - ff is the Command ":ff scel" and HeadAdmins is the NewLevel + ff is the Command ";ff scel" and HeadAdmins is the NewLevel Built-In Permissions Levels: Players - 0 @@ -99,7 +99,7 @@ local descs = {}; --// Contains settings descriptions Creators - 900 Note that when changing command permissions you MUST include the prefix; - So if you change the prefix to $ you would need to do $ff instead of :ff + So if you change the prefix to $ you would need to do $ff instead of ;ff --// Trello @@ -115,12 +115,12 @@ local descs = {}; --// Contains settings descriptions 6. Congrats! The board is ready to be used; 7. Create a list and add cards to it; - - You can view lists in-game using :viewlist ListNameHere + - You can view lists in-game using ;viewlist ListNameHere Lists: Moderators - Card Format: Same as settings.Moderators Admins - Card Format: Same as settings.Admins - HeadAdmins - Card Format: Same as settings.HeadAdmins + HeadAdmins - Card Format: Same as settings.HeadAdmins Creators - Card Format: Same as settings.Creators Banlist - Card Format: Same as settings.Banned Mutelist - Card Format: Same as settings.Muted @@ -128,7 +128,7 @@ local descs = {}; --// Contains settings descriptions Whitelist - Card Format: Same as settings.Whitelist Permissions - Card Format: Same as settings.Permissions Music - Card Format: SongName:AudioID - Commands - Card Format: Command (eg. :ff bob) + Commands - Card Format: Command (eg. ;ff bob) Card format refers to how card names should look @@ -143,7 +143,7 @@ settings.DataStoreEnabled = true -- Disable if you don't want to load settin settings.LocalDatastore = false -- If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers settings.Storage = game:GetService("ServerStorage") -- Where things like tools are stored -settings.RecursiveTools = false -- Whether tools that are included in sub-containers within settings.Storage will be available via the :give command (useful if your tools are organized into multiple folders) +settings.RecursiveTools = false -- Whether tools that are included in sub-containers within settings.Storage will be available via the ;give command (useful if your tools are organized into multiple folders) settings.Theme = "Default" -- UI theme; settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI elements are disabled @@ -200,15 +200,15 @@ settings.Ranks = { --// Use the below table to set command permissions; Commented commands are included for example purposes settings.Permissions = { - -- "ff:HeadAdmins"; --// Changes :ff to HeadAdmins and higher (HeadAdmins = Level 300 by default) - -- "kill:300"; --// Changes :kill to level 300 and higher (Level 300 = HeadAdmins by default) - -- "ban:200,300" --// Makes it so :ban is only usable by levels 200 and 300 specifically (nothing higher or lower or in between) + -- "ff:HeadAdmins"; --// Changes ;ff to HeadAdmins and higher (HeadAdmins = Level 300 by default) + -- "kill:300"; --// Changes ;kill to level 300 and higher (Level 300 = HeadAdmins by default) + -- "ban:200,300" --// Makes it so ;ban is only usable by levels 200 and 300 specifically (nothing higher or lower or in between) }; -- Format: {"Command:NewLevel"; "Command:Customrank1,Customrank2,Customrank3";} --// Use the below table to define "pre-set" command aliases ---// Command aliases; Format: {[":alias ..."] = ":command ..."} +--// Command aliases; Format: {[";alias ..."] = ";command ..."} settings.Aliases = { - [":examplealias "] = ":ff | :fling | :fire " --// Order arguments appear in alias string determines their required order in the command message when ran later + [";examplealias "] = ";ff | ;fling | ;fire " --// Order arguments appear in alias string determines their required order in the command message when ran later }; --// Use the below table to define pre-set cameras @@ -227,33 +227,33 @@ settings.Muted = {} -- List of people muted (cannot send chat messages) settings.Blacklist = {} -- List of people banned from running commands Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} settings.Whitelist = {} -- People who can join if whitelist enabled Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} -settings.MusicList = {} -- List of songs to appear in the :musiclist Format: {{Name = "somesong", ID = 1234567}, {Name = "anotherone", ID = 1243562}} +settings.MusicList = {} -- List of songs to appear in the ;musiclist Format: {{Name = "somesong", ID = 1234567}, {Name = "anotherone", ID = 1243562}} settings.CapeList = {} -- List of capes Format: {{Name = "somecape", Material = "Fabric", Color = "Bright yellow", ID = 12345567, Reflectance = 1}; {etc more stuff here}} -settings.InsertList = {} -- List of models to appear in the :insertlist and can be inserted using ':insert ' Format: {{Name = "somemodel", ID = 1234567}; {Name = "anotherone", ID = 1243562}} -settings.Waypoints = {} -- List of waypoints you can teleport via ':to wp-WAYPOINTNAME' or ':teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} +settings.InsertList = {} -- List of models to appear in the ;insertlist and can be inserted using ';insert ' Format: {{Name = "somemodel", ID = 1234567}; {Name = "anotherone", ID = 1243562}} +settings.Waypoints = {} -- List of waypoints you can teleport via ';to wp-WAYPOINTNAME' or ';teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} -settings.OnStartup = {} -- List of commands ran at server start Format: {":notif TestNotif"} -settings.OnJoin = {} -- List of commands ran as player on join (ignores adminlevel) Format: {":cmds"} -settings.OnSpawn = {} -- List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",":ff me"} +settings.OnStartup = {} -- List of commands ran at server start Format: {";notif TestNotif"} +settings.OnJoin = {} -- List of commands ran as player on join (ignores adminlevel) Format: {";cmds"} +settings.OnSpawn = {} -- List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",";ff me"} -settings.SaveAdmins = true -- If true anyone you :admin or :headadmin in-game will save +settings.SaveAdmins = true -- If true anyone you ;admin or ;headadmin in-game will save settings.LoadAdminsFromDS = true -- If false, any admins saved in your DataStores will not load settings.WhitelistEnabled = false -- If true enables the whitelist/server lock; Only lets admins & whitelisted users join -settings.Prefix = ":" -- The : in :kill me +settings.Prefix = ";" -- The ; in ;kill me settings.PlayerPrefix = "!" -- The ! in !donate; Mainly used for commands that any player can run; Do not make it the same as settings.Prefix -settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do :kill !me) -settings.SplitKey = " " -- The space in :kill me (eg if you change it to / :kill me would be :kill/me) -settings.BatchKey = "|" -- :kill me | :ff bob | :explode scel +settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do ;kill !me) +settings.SplitKey = " " -- The space in ;kill me (eg if you change it to / ;kill me would be ;kill/me) +settings.BatchKey = "|" -- ;kill me | ;ff bob | ;explode scel settings.ConsoleKeyCode = "Quote" -- Keybind to open the console; Rebindable per player in userpanel; KeyCodes: https://developer.roblox.com/en-us/api-reference/enum/KeyCode --// Easily add new custom commands below (without needing to create a plugin module) --// You can also use this to overwrite existing commands if you know the command's index (found in the command's respective module within the Adonis MainModule) settings.Commands = { ExampleCommand1 = { --// The index & table of the command - Prefix = Settings.Prefix; --// The prefix the command will use, this is the ':' in ':ff me' - Commands = {"examplecommand1", "examplealias1", "examplealias2"}; --// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ':ff me') - Args = {"arg1", "arg2", "etc"}; --// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ':ff me' + Prefix = Settings.Prefix; --// The prefix the command will use, this is the ';' in ';ff me' + Commands = {"examplecommand1", "examplealias1", "examplealias2"}; --// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ';ff me') + Args = {"arg1", "arg2", "etc"}; --// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ';ff me' Description = "Example command";--// The description of the command AdminLevel = 100; -- Moderators --// The commands minimum admin level; This can also be a table containing specific levels rather than a minimum level: {124, 152, "HeadAdmins", etc}; -- Alternative option: AdminLevel = "Moderators" @@ -275,7 +275,7 @@ settings.Commands = { settings.CommandCooldowns = { --[[ REFERENCE: - command_full_name: The name of a command (e.g. :cmds) + command_full_name: The name of a command (e.g. ;cmds) [command_full_name] = { Player = 0; @@ -293,24 +293,24 @@ settings.CommandFeedback = false -- Should players be notified when commands wi settings.CrossServerCommands = true -- Are commands which affect more than one server enabled? settings.ChatCommands = true -- If false you will not be able to run commands via the chat; Instead, you MUST use the console or you will be unable to run commands settings.CreatorPowers = true -- Gives me creator-level admin; This is strictly used for debugging; I can't debug without full access to the script -settings.CodeExecution = true -- Enables the use of code execution in Adonis; Scripting related (such as :s) and a few other commands require this +settings.CodeExecution = true -- Enables the use of code execution in Adonis; Scripting related (such as ;s) and a few other commands require this settings.SilentCommandDenials = false -- If true, there will be no differences between the error messages shown when a user enters an invalid command and when they have insufficient permissions for the command settings.OverrideChatCallbacks = true -- If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for slowmode. Mutes use a CanSend method to mute when this is set to false. settings.BanMessage = "Banned" -- Message shown to banned users upon kick -settings.LockMessage = "Not Whitelisted" -- Message shown to people when they are kicked while the game is :slocked -settings.SystemTitle = "System Message" -- Title to display in :sm and :bc +settings.LockMessage = "Not Whitelisted" -- Message shown to people when they are kicked while the game is ;slocked +settings.SystemTitle = "System Message" -- Title to display in ;sm and ;bc settings.MaxLogs = 5000 -- Maximum logs to save before deleting the oldest settings.SaveCommandLogs = true -- If command logs are saved to the datastores settings.Notification = true -- Whether or not to show the "You're an admin" and "Updated" notifications -settings.SongHint = true -- Display a hint with the current song name and ID when a song is played via :music +settings.SongHint = true -- Display a hint with the current song name and ID when a song is played via ;music settings.TopBarShift = false -- By default hints and notifications will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. settings.HiddenThemes = {} -- Hide themes from the theme selector tab inside the userpanel. Each theme name must be the specific name such as "Mobilius" settings.Messages = {} -- A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level settings.AutoClean = false -- Will auto clean workspace of things like hats and tools settings.AutoCleanDelay = 60 -- Time between auto cleans -settings.AutoBackup = false -- Run :backupmap automatically when the server starts. To restore the map, run :restoremap +settings.AutoBackup = false -- Run ;backupmap automatically when the server starts. To restore the map, run ;restoremap settings.ReJail = false -- If true then when a player rejoins they'll go back into jail. Or if the moderator leaves everybody gets unjailed settings.Console = true -- Whether the command console is enabled @@ -340,7 +340,7 @@ settings.Trello_Primary = "" -- Primary Trello board settings.Trello_Secondary = {} -- Secondary Trello boards (read-only) Format: {"BoardID";"BoardID2","etc"} settings.Trello_AppKey = "" -- Your Trello AppKey settings.Trello_Token = "" -- Trello token (DON'T SHARE WITH ANYONE!) Get API key: /1/connect?name=Trello_API_Module&response_type=token&expires=never&scope=read,write&key=YOUR_APP_KEY_HERE -settings.Trello_HideRanks = false -- If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via :admins) +settings.Trello_HideRanks = false -- If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via ;admins) --------------------- @@ -404,7 +404,7 @@ descs.DataStoreEnabled = [[ Disable if you don't want settings and admins to be descs.LocalDatastore = [[ If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers ]] descs.Storage = [[ Where things like tools are stored ]] -descs.RecursiveTools = [[ Whether tools that are included in sub-containers within settings.Storage will be available via the :give command (useful if your tools are organized into multiple folders) ]] +descs.RecursiveTools = [[ Whether tools that are included in sub-containers within settings.Storage will be available via the ;give command (useful if your tools are organized into multiple folders) ]] descs.Theme = [[ UI theme; ]] descs.MobileTheme = [[ Theme to use on mobile devices; Mobile themes are optimized for smaller screens; Some GUIs are disabled ]] @@ -417,7 +417,7 @@ descs.HeadAdmins = [[ Head Admins; Format: {"Username"; "Username:UserId"; UserI descs.Creators = [[ Anyone to be identified as a place owner; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] descs.Permissions = [[ Command permissions; Format: {"Command:NewLevel";} ]] -descs.Aliases = [[ Command aliases; Format: {[":alias ..."] = ":command ..."} ]] +descs.Aliases = [[ Command aliases; Format: {[";alias ..."] = ";command ..."} ]] descs.Cameras = [[ Cameras; Format: {Name = "CamName", Position = Vector3.new(X, Y, Z)} ]] descs.Commands = [[ Custom commands ]] @@ -428,22 +428,22 @@ descs.Whitelist = [[ People who can join if whitelist enabled; Format: {"Usernam descs.MusicList = [[ List of songs to appear in the script; Format: {{Name = "somesong",ID = 1234567},{Name = "anotherone",ID = 1243562}} ]] descs.CapeList = [[ List of capes; Format: {{Name = "somecape",Material = "Fabric",Color = "Bright yellow",ID = 12345567,Reflectance = 1},{etc more stuff here}} ]] descs.InsertList = [[ List of models to appear in the script; Format: {{Name = "somemodel",ID = 1234567},{Name = "anotherone",ID = 1243562}} ]] -descs.Waypoints = [[ List of waypoints you can teleport via ':to wp-WAYPOINTNAME' or ':teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} ]] +descs.Waypoints = [[ List of waypoints you can teleport via ';to wp-WAYPOINTNAME' or ';teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} ]] descs.CustomRanks = [[ List of custom AdminLevel ranks Format: {RankName = {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";};} ]] -descs.OnStartup = [[ List of commands ran at server start Format: {":notif TestNotif"} ]] -descs.OnJoin = [[ List of commands ran as player on join (ignores adminlevel) Format: {":cmds"} ]] -descs.OnSpawn = [[ List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",":ff me"} ]] +descs.OnStartup = [[ List of commands ran at server start Format: {";notif TestNotif"} ]] +descs.OnJoin = [[ List of commands ran as player on join (ignores adminlevel) Format: {";cmds"} ]] +descs.OnSpawn = [[ List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",";ff me"} ]] -descs.SaveAdmins = [[ If true anyone you :mod, :admin, or :headadmin in-game will save]] +descs.SaveAdmins = [[ If true anyone you ;mod, ;admin, or ;headadmin in-game will save]] descs.LoadAdminsFromDS = [[ If false, any admins saved in your DataStores will not load ]] descs.WhitelistEnabled = [[ If true enables the whitelist/server lock; Only lets admins & whitelisted users join ]] -descs.Prefix = [[ The : in :kill me ]] +descs.Prefix = [[ The ; in ;kill me ]] descs.PlayerPrefix = [[ The ! in !donate; Mainly used for commands that any player can run ]] -descs.SpecialPrefix = [[ Used for things like "all", "me" and "others" (If changed to ! you would do :kill !me) ]] -descs.SplitKey = [[ The space in :kill me (eg if you change it to / :kill me would be :kill/me) ]] -descs.BatchKey = [[ :kill me | :ff bob | :explode scel ]] +descs.SpecialPrefix = [[ Used for things like "all", "me" and "others" (If changed to ! you would do ;kill !me) ]] +descs.SplitKey = [[ The space in ;kill me (eg if you change it to / ;kill me would be ;kill/me) ]] +descs.BatchKey = [[ ;kill me | ;ff bob | ;explode scel ]] descs.ConsoleKeyCode = [[ Keybind to open the console ]] descs.HttpWait = [[ How long things that use the HttpService will wait before updating again ]] @@ -452,7 +452,7 @@ descs.Trello_Primary = [[ Primary Trello board ]] descs.Trello_Secondary = [[ Secondary Trello boards; Format: {"BoardID";"BoardID2","etc"} ]] descs.Trello_AppKey = [[ Your Trello AppKey; ]] descs.Trello_Token = [[ Trello token (DON'T SHARE WITH ANYONE!) ]] -descs.Trello_HideRanks = [[ If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via :admins) ]] +descs.Trello_HideRanks = [[ If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via ;admins) ]] descs.G_API = [[ If true, allows other server scripts to access certain functions described in the API module through _G.Adonis ]] descs.G_Access = [[ If enabled, allows other scripts to access Adonis using _G.Adonis.Access; Scripts will still be able to do things like _G.Adonis.CheckAdmin(player) ]] @@ -471,22 +471,22 @@ descs.SilentCommandDenials = [[ If true, there will be no differences between th descs.OverrideChatCallbacks = [[ If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for muting ]] descs.BanMessage = [[ Message shown to banned users ]] -descs.LockMessage = [[ Message shown to people when they are kicked while the game is :slocked ]] -descs.SystemTitle = [[ Title to display in :sm ]] +descs.LockMessage = [[ Message shown to people when they are kicked while the game is ;slocked ]] +descs.SystemTitle = [[ Title to display in ;sm ]] descs.CreatorPowers = [[ Gives me creator-level admin; This is strictly used for debugging; I can't debug without access to the script and specific owner commands ]] descs.MaxLogs = [[ Maximum logs to save before deleting the oldest; Too high can lag the game ]] descs.SaveCommandLogs = [[ If command logs are saved to the datastores ]] descs.Notification = [[ Whether or not to show the "You're an admin" and "Updated" notifications ]] descs.CodeExecution = [[ Enables the use of code execution in Adonis; Scripting related and a few other commands require this ]] -descs.SongHint = [[ Display a hint with the current song name and ID when a song is played via :music ]] +descs.SongHint = [[ Display a hint with the current song name and ID when a song is played via ;music ]] descs.TopBarShift = [[ By default hints and notifs will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. ]] descs.ReJail = [[ If true then when a player rejoins they'll go back into jail. Or if the moderator leaves everybody gets unjailed ]] descs.Messages = [[ A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level ]] descs.AutoClean = [[ Will auto clean workspace of things like hats and tools ]] -descs.AutoBackup = [[ (not recommended) Run a map backup command when the server starts, this is mostly useless as clients cannot modify the server. To restore the map run :restoremap ]] +descs.AutoBackup = [[ (not recommended) Run a map backup command when the server starts, this is mostly useless as clients cannot modify the server. To restore the map run ;restoremap ]] descs.AutoCleanDelay = [[ Time between auto cleans ]] descs.PlayerList = [[ Custom playerlist ]] From 61615344a296283e9fd054e0fb59cbd21be5eefe Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Mon, 13 Jan 2025 21:35:33 +0000 Subject: [PATCH 46/60] Change prefix --- Loader/Config/Settings.luau | 114 ++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index 44ba1efae3..c9a2e27bc7 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -75,7 +75,7 @@ local descs = {}; --// Contains settings descriptions settings.HeadAdmins = {"Group:181:121"} See? Not so hard is it? - If I wanted to add group 181 and all ranks in it to the :slock whitelist I would do; + If I wanted to add group 181 and all ranks in it to the ;slock whitelist I would do; settings.Whitelist = {"Group:181";} I can do the above if I wanted to give everyone in a group admin for any of the other admin tables @@ -85,11 +85,11 @@ local descs = {}; --// Contains settings descriptions --// Command Permissions You can set the permission level for specific commands using setting.Permissions - If I wanted to make it so only HeadAdmins+ can use :ff player then I would do: + If I wanted to make it so only HeadAdmins+ can use ;ff player then I would do: settings.Permissions = {"ff:HeadAdmins"} - ff is the Command ":ff scel" and HeadAdmins is the NewLevel + ff is the Command ";ff scel" and HeadAdmins is the NewLevel Built-In Permissions Levels: Players - 0 @@ -99,7 +99,7 @@ local descs = {}; --// Contains settings descriptions Creators - 900 Note that when changing command permissions you MUST include the prefix; - So if you change the prefix to $ you would need to do $ff instead of :ff + So if you change the prefix to $ you would need to do $ff instead of ;ff --// Trello @@ -115,12 +115,12 @@ local descs = {}; --// Contains settings descriptions 6. Congrats! The board is ready to be used; 7. Create a list and add cards to it; - - You can view lists in-game using :viewlist ListNameHere + - You can view lists in-game using ;viewlist ListNameHere Lists: Moderators - Card Format: Same as settings.Moderators Admins - Card Format: Same as settings.Admins - HeadAdmins - Card Format: Same as settings.HeadAdmins + HeadAdmins - Card Format: Same as settings.HeadAdmins Creators - Card Format: Same as settings.Creators Banlist - Card Format: Same as settings.Banned Mutelist - Card Format: Same as settings.Muted @@ -128,7 +128,7 @@ local descs = {}; --// Contains settings descriptions Whitelist - Card Format: Same as settings.Whitelist Permissions - Card Format: Same as settings.Permissions Music - Card Format: SongName:AudioID - Commands - Card Format: Command (eg. :ff bob) + Commands - Card Format: Command (eg. ;ff bob) Card format refers to how card names should look @@ -140,13 +140,14 @@ settings.HideScript = true -- When the game starts the Adonis_Loader model settings.DataStore = "Adonis_1" -- DataStore the script will use for saving data; Changing this will lose any saved data settings.DataStoreKey = "CHANGE_THIS" -- CHANGE THIS TO ANYTHING RANDOM! Key used to encrypt all datastore entries; Changing this will lose any saved data settings.DataStoreEnabled = true -- Disable if you don't want to load settings and admins from the datastore; PlayerData will still save -settings.LocalDatastore = false -- If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers +settings.LocalDatastore = false -- If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers -settings.Storage = game:GetService("ServerStorage") -- Where things like tools are stored -settings.RecursiveTools = false -- Whether tools that are included in sub-containers within settings.Storage will be available via the :give command (useful if your tools are organized into multiple folders) +settings.Storage = game:GetService("ServerStorage") -- Where things like tools are stored +settings.RecursiveTools = false -- Whether tools that are included in sub-containers within settings.Storage will be available via the ;give command (useful if your tools are organized into multiple folders) settings.Theme = "Default" -- UI theme; settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI elements are disabled +settings.DefaultTheme = "Default" -- Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. --[[ **HOW TO ADD ADMINISTRATORS:** @@ -157,7 +158,7 @@ settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI el settings.Ranks = { ["Moderators"] = { Level = 100; - Users = {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID"; "Subscription:SubscriptionId";} + Users = {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} } } @@ -199,17 +200,18 @@ settings.Ranks = { --// Use the below table to set command permissions; Commented commands are included for example purposes settings.Permissions = { - -- "ff:HeadAdmins"; --// Changes :ff to HeadAdmins and higher (HeadAdmins = Level 300 by default) - -- "kill:300"; --// Changes :kill to level 300 and higher (Level 300 = HeadAdmins by default) - -- "ban:200,300" --// Makes it so :ban is only usable by levels 200 and 300 specifically (nothing higher or lower or in between) + -- "ff:HeadAdmins"; --// Changes ;ff to HeadAdmins and higher (HeadAdmins = Level 300 by default) + -- "kill:300"; --// Changes ;kill to level 300 and higher (Level 300 = HeadAdmins by default) + -- "ban:200,300" --// Makes it so ;ban is only usable by levels 200 and 300 specifically (nothing higher or lower or in between) }; -- Format: {"Command:NewLevel"; "Command:Customrank1,Customrank2,Customrank3";} --// Use the below table to define "pre-set" command aliases ---// Command aliases; Format: {[":alias ..."] = ":command ..."} +--// Command aliases; Format: {[";alias ..."] = ";command ..."} settings.Aliases = { - [":examplealias "] = ":ff | :fling | :fire " --// Order arguments appear in alias string determines their required order in the command message when ran later + [";examplealias "] = ";ff | ;fling | ;fire " --// Order arguments appear in alias string determines their required order in the command message when ran later }; +--// Use the below table to define pre-set cameras settings.Cameras = { --[[ "Camera Name" would be the name of your camera @@ -225,33 +227,33 @@ settings.Muted = {} -- List of people muted (cannot send chat messages) settings.Blacklist = {} -- List of people banned from running commands Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} settings.Whitelist = {} -- People who can join if whitelist enabled Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} -settings.MusicList = {} -- List of songs to appear in the :musiclist Format: {{Name = "somesong", ID = 1234567}, {Name = "anotherone", ID = 1243562}} +settings.MusicList = {} -- List of songs to appear in the ;musiclist Format: {{Name = "somesong", ID = 1234567}, {Name = "anotherone", ID = 1243562}} settings.CapeList = {} -- List of capes Format: {{Name = "somecape", Material = "Fabric", Color = "Bright yellow", ID = 12345567, Reflectance = 1}; {etc more stuff here}} -settings.InsertList = {} -- List of models to appear in the :insertlist and can be inserted using ':insert ' Format: {{Name = "somemodel", ID = 1234567}; {Name = "anotherone", ID = 1243562}} -settings.Waypoints = {} -- List of waypoints you can teleport via ':to wp-WAYPOINTNAME' or ':teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} +settings.InsertList = {} -- List of models to appear in the ;insertlist and can be inserted using ';insert ' Format: {{Name = "somemodel", ID = 1234567}; {Name = "anotherone", ID = 1243562}} +settings.Waypoints = {} -- List of waypoints you can teleport via ';to wp-WAYPOINTNAME' or ';teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} -settings.OnStartup = {} -- List of commands ran at server start Format: {":notif TestNotif"} -settings.OnJoin = {} -- List of commands ran as player on join (ignores adminlevel) Format: {":cmds"} -settings.OnSpawn = {} -- List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",":ff me"} +settings.OnStartup = {} -- List of commands ran at server start Format: {";notif TestNotif"} +settings.OnJoin = {} -- List of commands ran as player on join (ignores adminlevel) Format: {";cmds"} +settings.OnSpawn = {} -- List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",";ff me"} -settings.SaveAdmins = true -- If true anyone you :admin or :headadmin in-game will save +settings.SaveAdmins = true -- If true anyone you ;admin or ;headadmin in-game will save settings.LoadAdminsFromDS = true -- If false, any admins saved in your DataStores will not load settings.WhitelistEnabled = false -- If true enables the whitelist/server lock; Only lets admins & whitelisted users join settings.Prefix = ";" -- The ; in ;kill me settings.PlayerPrefix = "!" -- The ! in !donate; Mainly used for commands that any player can run; Do not make it the same as settings.Prefix -settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do :kill !me) -settings.SplitKey = " " -- The space in :kill me (eg if you change it to / :kill me would be :kill/me) -settings.BatchKey = "|" -- :kill me | :ff bob | :explode scel +settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do ;kill !me) +settings.SplitKey = " " -- The space in ;kill me (eg if you change it to / ;kill me would be ;kill/me) +settings.BatchKey = "|" -- ;kill me | ;ff bob | ;explode scel settings.ConsoleKeyCode = "Quote" -- Keybind to open the console; Rebindable per player in userpanel; KeyCodes: https://developer.roblox.com/en-us/api-reference/enum/KeyCode --// Easily add new custom commands below (without needing to create a plugin module) --// You can also use this to overwrite existing commands if you know the command's index (found in the command's respective module within the Adonis MainModule) settings.Commands = { ExampleCommand1 = { --// The index & table of the command - Prefix = Settings.Prefix; --// The prefix the command will use, this is the ':' in ':ff me' - Commands = {"examplecommand1", "examplealias1", "examplealias2"}; --// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ':ff me') - Args = {"arg1", "arg2", "etc"}; --// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ':ff me' + Prefix = Settings.Prefix; --// The prefix the command will use, this is the ';' in ';ff me' + Commands = {"examplecommand1", "examplealias1", "examplealias2"}; --// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ';ff me') + Args = {"arg1", "arg2", "etc"}; --// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ';ff me' Description = "Example command";--// The description of the command AdminLevel = 100; -- Moderators --// The commands minimum admin level; This can also be a table containing specific levels rather than a minimum level: {124, 152, "HeadAdmins", etc}; -- Alternative option: AdminLevel = "Moderators" @@ -273,7 +275,7 @@ settings.Commands = { settings.CommandCooldowns = { --[[ REFERENCE: - command_full_name: The name of a command (e.g. :cmds) + command_full_name: The name of a command (e.g. ;cmds) [command_full_name] = { Player = 0; @@ -291,25 +293,24 @@ settings.CommandFeedback = false -- Should players be notified when commands wi settings.CrossServerCommands = true -- Are commands which affect more than one server enabled? settings.ChatCommands = true -- If false you will not be able to run commands via the chat; Instead, you MUST use the console or you will be unable to run commands settings.CreatorPowers = true -- Gives me creator-level admin; This is strictly used for debugging; I can't debug without full access to the script -settings.CodeExecution = true -- Enables the use of code execution in Adonis; Scripting related (such as :s) and a few other commands require this +settings.CodeExecution = true -- Enables the use of code execution in Adonis; Scripting related (such as ;s) and a few other commands require this settings.SilentCommandDenials = false -- If true, there will be no differences between the error messages shown when a user enters an invalid command and when they have insufficient permissions for the command -settings.OverrideChatCallbacks = true -- If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for slowmode. Mutes use a CanSend method to mute when this is set to false. +settings.OverrideChatCallbacks = true -- If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for slowmode. Mutes use a CanSend method to mute when this is set to false. settings.BanMessage = "Banned" -- Message shown to banned users upon kick -settings.LockMessage = "Not Whitelisted" -- Message shown to people when they are kicked while the game is :slocked -settings.SystemTitle = "System Message" -- Title to display in :sm and :bc +settings.LockMessage = "Not Whitelisted" -- Message shown to people when they are kicked while the game is ;slocked +settings.SystemTitle = "System Message" -- Title to display in ;sm and ;bc settings.MaxLogs = 5000 -- Maximum logs to save before deleting the oldest settings.SaveCommandLogs = true -- If command logs are saved to the datastores settings.Notification = true -- Whether or not to show the "You're an admin" and "Updated" notifications -settings.SongHint = true -- Display a hint with the current song name and ID when a song is played via :music +settings.SongHint = true -- Display a hint with the current song name and ID when a song is played via ;music settings.TopBarShift = false -- By default hints and notifications will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. -settings.DefaultTheme = "Default" -- Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. settings.HiddenThemes = {} -- Hide themes from the theme selector tab inside the userpanel. Each theme name must be the specific name such as "Mobilius" settings.Messages = {} -- A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level settings.AutoClean = false -- Will auto clean workspace of things like hats and tools settings.AutoCleanDelay = 60 -- Time between auto cleans -settings.AutoBackup = false -- Run :backupmap automatically when the server starts. To restore the map, run :restoremap +settings.AutoBackup = false -- Run ;backupmap automatically when the server starts. To restore the map, run ;restoremap settings.ReJail = false -- If true then when a player rejoins they'll go back into jail. Or if the moderator leaves everybody gets unjailed settings.Console = true -- Whether the command console is enabled @@ -339,7 +340,7 @@ settings.Trello_Primary = "" -- Primary Trello board settings.Trello_Secondary = {} -- Secondary Trello boards (read-only) Format: {"BoardID";"BoardID2","etc"} settings.Trello_AppKey = "" -- Your Trello AppKey settings.Trello_Token = "" -- Trello token (DON'T SHARE WITH ANYONE!) Get API key: /1/connect?name=Trello_API_Module&response_type=token&expires=never&scope=read,write&key=YOUR_APP_KEY_HERE -settings.Trello_HideRanks = false -- If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via :admins) +settings.Trello_HideRanks = false -- If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via ;admins) --------------------- @@ -403,10 +404,11 @@ descs.DataStoreEnabled = [[ Disable if you don't want settings and admins to be descs.LocalDatastore = [[ If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers ]] descs.Storage = [[ Where things like tools are stored ]] -descs.RecursiveTools = [[ Whether tools that are included in sub-containers within settings.Storage will be available via the :give command (useful if your tools are organized into multiple folders) ]] +descs.RecursiveTools = [[ Whether tools that are included in sub-containers within settings.Storage will be available via the ;give command (useful if your tools are organized into multiple folders) ]] descs.Theme = [[ UI theme; ]] descs.MobileTheme = [[ Theme to use on mobile devices; Mobile themes are optimized for smaller screens; Some GUIs are disabled ]] +descs.DefaultTheme = [[ Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. ]] descs.Ranks = [[ All admin permission level ranks; ]]; descs.Moderators = [[ Mods; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] @@ -415,7 +417,7 @@ descs.HeadAdmins = [[ Head Admins; Format: {"Username"; "Username:UserId"; UserI descs.Creators = [[ Anyone to be identified as a place owner; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] descs.Permissions = [[ Command permissions; Format: {"Command:NewLevel";} ]] -descs.Aliases = [[ Command aliases; Format: {[":alias ..."] = ":command ..."} ]] +descs.Aliases = [[ Command aliases; Format: {[";alias ..."] = ";command ..."} ]] descs.Cameras = [[ Cameras; Format: {Name = "CamName", Position = Vector3.new(X, Y, Z)} ]] descs.Commands = [[ Custom commands ]] @@ -426,22 +428,22 @@ descs.Whitelist = [[ People who can join if whitelist enabled; Format: {"Usernam descs.MusicList = [[ List of songs to appear in the script; Format: {{Name = "somesong",ID = 1234567},{Name = "anotherone",ID = 1243562}} ]] descs.CapeList = [[ List of capes; Format: {{Name = "somecape",Material = "Fabric",Color = "Bright yellow",ID = 12345567,Reflectance = 1},{etc more stuff here}} ]] descs.InsertList = [[ List of models to appear in the script; Format: {{Name = "somemodel",ID = 1234567},{Name = "anotherone",ID = 1243562}} ]] -descs.Waypoints = [[ List of waypoints you can teleport via ':to wp-WAYPOINTNAME' or ':teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} ]] +descs.Waypoints = [[ List of waypoints you can teleport via ';to wp-WAYPOINTNAME' or ';teleport PLAYER tp.WAYPOINTNAME' Format {YOURNAME1 = Vector3.new(1,2,3), YOURNAME2 = Vector(231,666,999)} ]] descs.CustomRanks = [[ List of custom AdminLevel ranks Format: {RankName = {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";};} ]] -descs.OnStartup = [[ List of commands ran at server start Format: {":notif TestNotif"} ]] -descs.OnJoin = [[ List of commands ran as player on join (ignores adminlevel) Format: {":cmds"} ]] -descs.OnSpawn = [[ List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",":ff me"} ]] +descs.OnStartup = [[ List of commands ran at server start Format: {";notif TestNotif"} ]] +descs.OnJoin = [[ List of commands ran as player on join (ignores adminlevel) Format: {";cmds"} ]] +descs.OnSpawn = [[ List off commands ran as player on spawn (ignores adminlevel) Format: {"!fire Really red",";ff me"} ]] -descs.SaveAdmins = [[ If true anyone you :mod, :admin, or :headadmin in-game will save]] +descs.SaveAdmins = [[ If true anyone you ;mod, ;admin, or ;headadmin in-game will save]] descs.LoadAdminsFromDS = [[ If false, any admins saved in your DataStores will not load ]] descs.WhitelistEnabled = [[ If true enables the whitelist/server lock; Only lets admins & whitelisted users join ]] -descs.Prefix = [[ The : in :kill me ]] +descs.Prefix = [[ The ; in ;kill me ]] descs.PlayerPrefix = [[ The ! in !donate; Mainly used for commands that any player can run ]] -descs.SpecialPrefix = [[ Used for things like "all", "me" and "others" (If changed to ! you would do :kill !me) ]] -descs.SplitKey = [[ The space in :kill me (eg if you change it to / :kill me would be :kill/me) ]] -descs.BatchKey = [[ :kill me | :ff bob | :explode scel ]] +descs.SpecialPrefix = [[ Used for things like "all", "me" and "others" (If changed to ! you would do ;kill !me) ]] +descs.SplitKey = [[ The space in ;kill me (eg if you change it to / ;kill me would be ;kill/me) ]] +descs.BatchKey = [[ ;kill me | ;ff bob | ;explode scel ]] descs.ConsoleKeyCode = [[ Keybind to open the console ]] descs.HttpWait = [[ How long things that use the HttpService will wait before updating again ]] @@ -450,7 +452,7 @@ descs.Trello_Primary = [[ Primary Trello board ]] descs.Trello_Secondary = [[ Secondary Trello boards; Format: {"BoardID";"BoardID2","etc"} ]] descs.Trello_AppKey = [[ Your Trello AppKey; ]] descs.Trello_Token = [[ Trello token (DON'T SHARE WITH ANYONE!) ]] -descs.Trello_HideRanks = [[ If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via :admins) ]] +descs.Trello_HideRanks = [[ If true, Trello-assigned ranks won't be shown in the admins list UI (accessed via ;admins) ]] descs.G_API = [[ If true, allows other server scripts to access certain functions described in the API module through _G.Adonis ]] descs.G_Access = [[ If enabled, allows other scripts to access Adonis using _G.Adonis.Access; Scripts will still be able to do things like _G.Adonis.CheckAdmin(player) ]] @@ -469,23 +471,22 @@ descs.SilentCommandDenials = [[ If true, there will be no differences between th descs.OverrideChatCallbacks = [[ If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for muting ]] descs.BanMessage = [[ Message shown to banned users ]] -descs.LockMessage = [[ Message shown to people when they are kicked while the game is :slocked ]] -descs.SystemTitle = [[ Title to display in :sm ]] +descs.LockMessage = [[ Message shown to people when they are kicked while the game is ;slocked ]] +descs.SystemTitle = [[ Title to display in ;sm ]] descs.CreatorPowers = [[ Gives me creator-level admin; This is strictly used for debugging; I can't debug without access to the script and specific owner commands ]] descs.MaxLogs = [[ Maximum logs to save before deleting the oldest; Too high can lag the game ]] descs.SaveCommandLogs = [[ If command logs are saved to the datastores ]] descs.Notification = [[ Whether or not to show the "You're an admin" and "Updated" notifications ]] descs.CodeExecution = [[ Enables the use of code execution in Adonis; Scripting related and a few other commands require this ]] -descs.SongHint = [[ Display a hint with the current song name and ID when a song is played via :music ]] +descs.SongHint = [[ Display a hint with the current song name and ID when a song is played via ;music ]] descs.TopBarShift = [[ By default hints and notifs will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. ]] -descs.DefaultTheme = [[ Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. ]] descs.ReJail = [[ If true then when a player rejoins they'll go back into jail. Or if the moderator leaves everybody gets unjailed ]] descs.Messages = [[ A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level ]] descs.AutoClean = [[ Will auto clean workspace of things like hats and tools ]] -descs.AutoBackup = [[ (not recommended) Run a map backup command when the server starts, this is mostly useless as clients cannot modify the server. To restore the map run :restoremap ]] +descs.AutoBackup = [[ (not recommended) Run a map backup command when the server starts, this is mostly useless as clients cannot modify the server. To restore the map run ;restoremap ]] descs.AutoCleanDelay = [[ Time between auto cleans ]] descs.PlayerList = [[ Custom playerlist ]] @@ -529,6 +530,7 @@ order = { " "; "Theme"; "MobileTheme"; + "DefaultTheme"; " "; "Ranks"; " "; @@ -596,7 +598,6 @@ order = { "Notification"; "SongHint"; "TopBarShift"; - "DefaultTheme"; "ReJail"; ""; "AutoClean"; @@ -604,7 +605,6 @@ order = { "AutoBackup"; " "; "PlayerList"; - " "; "Console"; "Console_AdminsOnly"; " "; From b95a500360689a80266ffa2c158053a7b14d9b69 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:14:04 +0000 Subject: [PATCH 47/60] Remove default theme --- Loader/Config/Settings.luau | 2 -- 1 file changed, 2 deletions(-) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index c9a2e27bc7..c00d191527 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -147,8 +147,6 @@ settings.RecursiveTools = false -- Whether tools that are included in sub-c settings.Theme = "Default" -- UI theme; settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI elements are disabled -settings.DefaultTheme = "Default" -- Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. - --[[ **HOW TO ADD ADMINISTRATORS:** Below are the administrator permission levels/ranks (Mods, Admins, HeadAdmins, Creators, StuffYouAdd, etc) From 79fdfc7c64c962566576e09742b42728edd865c4 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:15:12 +0000 Subject: [PATCH 48/60] Readd Default theme --- Loader/Config/Settings.luau | 1 + 1 file changed, 1 insertion(+) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index c00d191527..d93f007a70 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -304,6 +304,7 @@ settings.SaveCommandLogs = true -- If command logs are saved to the d settings.Notification = true -- Whether or not to show the "You're an admin" and "Updated" notifications settings.SongHint = true -- Display a hint with the current song name and ID when a song is played via ;music settings.TopBarShift = false -- By default hints and notifications will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. +settings.DefaultTheme = "Default" -- Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. settings.HiddenThemes = {} -- Hide themes from the theme selector tab inside the userpanel. Each theme name must be the specific name such as "Mobilius" settings.Messages = {} -- A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level settings.AutoClean = false -- Will auto clean workspace of things like hats and tools From f72db1972aba82068ff73e22dd5a86793c2fead5 Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:17:36 +0000 Subject: [PATCH 49/60] Move DefaultTheme down --- MainModule/Server/Dependencies/DefaultSettings.luau | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MainModule/Server/Dependencies/DefaultSettings.luau b/MainModule/Server/Dependencies/DefaultSettings.luau index c9a2e27bc7..a29f9e46f2 100644 --- a/MainModule/Server/Dependencies/DefaultSettings.luau +++ b/MainModule/Server/Dependencies/DefaultSettings.luau @@ -147,7 +147,6 @@ settings.RecursiveTools = false -- Whether tools that are included in sub-c settings.Theme = "Default" -- UI theme; settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI elements are disabled -settings.DefaultTheme = "Default" -- Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. --[[ **HOW TO ADD ADMINISTRATORS:** @@ -306,6 +305,7 @@ settings.SaveCommandLogs = true -- If command logs are saved to the d settings.Notification = true -- Whether or not to show the "You're an admin" and "Updated" notifications settings.SongHint = true -- Display a hint with the current song name and ID when a song is played via ;music settings.TopBarShift = false -- By default hints and notifications will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. +settings.DefaultTheme = "Default" -- Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. settings.HiddenThemes = {} -- Hide themes from the theme selector tab inside the userpanel. Each theme name must be the specific name such as "Mobilius" settings.Messages = {} -- A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level settings.AutoClean = false -- Will auto clean workspace of things like hats and tools @@ -408,7 +408,6 @@ descs.RecursiveTools = [[ Whether tools that are included in sub-containers with descs.Theme = [[ UI theme; ]] descs.MobileTheme = [[ Theme to use on mobile devices; Mobile themes are optimized for smaller screens; Some GUIs are disabled ]] -descs.DefaultTheme = [[ Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. ]] descs.Ranks = [[ All admin permission level ranks; ]]; descs.Moderators = [[ Mods; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] @@ -481,6 +480,7 @@ descs.Notification = [[ Whether or not to show the "You're an admin" and "Update descs.CodeExecution = [[ Enables the use of code execution in Adonis; Scripting related and a few other commands require this ]] descs.SongHint = [[ Display a hint with the current song name and ID when a song is played via ;music ]] descs.TopBarShift = [[ By default hints and notifs will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. ]] +descs.DefaultTheme = [[ Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. ]] descs.ReJail = [[ If true then when a player rejoins they'll go back into jail. Or if the moderator leaves everybody gets unjailed ]] descs.Messages = [[ A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level ]] @@ -530,7 +530,6 @@ order = { " "; "Theme"; "MobileTheme"; - "DefaultTheme"; " "; "Ranks"; " "; @@ -598,6 +597,7 @@ order = { "Notification"; "SongHint"; "TopBarShift"; + "DefaultTheme"; "ReJail"; ""; "AutoClean"; From 05029261ecaeb0029a823b689384ea7c40b7b39e Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:18:47 +0000 Subject: [PATCH 50/60] Move defaulttheme down --- Loader/Config/Settings.luau | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index d93f007a70..7a4a25ebc8 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -407,7 +407,6 @@ descs.RecursiveTools = [[ Whether tools that are included in sub-containers with descs.Theme = [[ UI theme; ]] descs.MobileTheme = [[ Theme to use on mobile devices; Mobile themes are optimized for smaller screens; Some GUIs are disabled ]] -descs.DefaultTheme = [[ Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. ]] descs.Ranks = [[ All admin permission level ranks; ]]; descs.Moderators = [[ Mods; Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID";} ]] @@ -480,6 +479,7 @@ descs.Notification = [[ Whether or not to show the "You're an admin" and "Update descs.CodeExecution = [[ Enables the use of code execution in Adonis; Scripting related and a few other commands require this ]] descs.SongHint = [[ Display a hint with the current song name and ID when a song is played via ;music ]] descs.TopBarShift = [[ By default hints and notifs will appear from the top edge of the window. Set this to true if you don't want hints/notifications to appear in that region. ]] +descs.DefaultTheme = [[ Theme to be used as a replacement for "Default". The new replacement theme can still use "Default" as its Base_Theme however any other theme that references "Default" as its redirects to this theme. ]] descs.ReJail = [[ If true then when a player rejoins they'll go back into jail. Or if the moderator leaves everybody gets unjailed ]] descs.Messages = [[ A list of notifications shown on join. Messages can either be strings or tables. Messages are shown to HeadAdmins+ by default but tables can define a different minimum level via .Level ]] @@ -529,7 +529,6 @@ order = { " "; "Theme"; "MobileTheme"; - "DefaultTheme"; " "; "Ranks"; " "; @@ -597,6 +596,7 @@ order = { "Notification"; "SongHint"; "TopBarShift"; + "DefaultTheme"; "ReJail"; ""; "AutoClean"; From 34d67746a624b3f465cacaf84c4531382b189fd0 Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:37:11 +0200 Subject: [PATCH 51/60] Convert more models out of XML (#1831) * Delete MainModule/Server/Dependencies/RebootHandler.rbxmx * Create init.server.lua * Create init.meta.json * Create Mode.model.json * Create Model.model.json * Create mParent.model.json * Create Runner.model.json * Create init.server.lua * Create init.meta.json * Create Event.model.json * Delete MainModule/Server/Dependencies/Assets/BotBrain.rbxmx * Create init.client.lua * Create init.meta.json * Create Mode.model.json * Create Target.model.json * Delete MainModule/Server/Dependencies/Assets/ClickTeleport.rbxmx * Create init.client.lua * Create init.meta.json * Create Num.model.json * Create Type.model.json * Update Num.model.json * Delete MainModule/Server/Dependencies/Assets/Glitcher.rbxmx * Create init.client.lua * Create init.meta.json * Create Strength.model.json * Delete MainModule/Server/Dependencies/Assets/Sfling.rbxmx * Fix lint * Fix lint --- .../Assets/BotBrain/Event.model.json | 3 + .../Assets/BotBrain/init.meta.json | 5 + .../init.server.lua} | 43 ++----- .../Assets/ClickTeleport/Mode.model.json | 6 + .../Assets/ClickTeleport/Target.model.json | 6 + .../init.client.lua} | 38 +----- .../Assets/ClickTeleport/init.meta.json | 5 + .../Server/Dependencies/Assets/Glitcher.rbxmx | 60 ---------- .../Assets/Glitcher/Num.model.json | 6 + .../Assets/Glitcher/Type.model.json | 6 + .../Assets/Glitcher/init.client.lua | 26 ++++ .../Assets/Glitcher/init.meta.json | 5 + .../Server/Dependencies/Assets/Sfling.rbxmx | 44 ------- .../Assets/Sfling/Strength.model.json | 6 + .../Assets/Sfling/init.client.lua | 19 +++ .../Dependencies/Assets/Sfling/init.meta.json | 5 + .../Server/Dependencies/RebootHandler.rbxmx | 113 ------------------ .../RebootHandler/Mode.model.json | 6 + .../RebootHandler/Model.model.json | 3 + .../RebootHandler/Runner.model.json | 3 + .../Dependencies/RebootHandler/init.meta.json | 5 + .../RebootHandler/init.server.lua | 62 ++++++++++ .../RebootHandler/mParent.model.json | 3 + 23 files changed, 190 insertions(+), 288 deletions(-) create mode 100644 MainModule/Server/Dependencies/Assets/BotBrain/Event.model.json create mode 100644 MainModule/Server/Dependencies/Assets/BotBrain/init.meta.json rename MainModule/Server/Dependencies/Assets/{BotBrain.rbxmx => BotBrain/init.server.lua} (80%) create mode 100644 MainModule/Server/Dependencies/Assets/ClickTeleport/Mode.model.json create mode 100644 MainModule/Server/Dependencies/Assets/ClickTeleport/Target.model.json rename MainModule/Server/Dependencies/Assets/{ClickTeleport.rbxmx => ClickTeleport/init.client.lua} (60%) create mode 100644 MainModule/Server/Dependencies/Assets/ClickTeleport/init.meta.json delete mode 100644 MainModule/Server/Dependencies/Assets/Glitcher.rbxmx create mode 100644 MainModule/Server/Dependencies/Assets/Glitcher/Num.model.json create mode 100644 MainModule/Server/Dependencies/Assets/Glitcher/Type.model.json create mode 100644 MainModule/Server/Dependencies/Assets/Glitcher/init.client.lua create mode 100644 MainModule/Server/Dependencies/Assets/Glitcher/init.meta.json delete mode 100644 MainModule/Server/Dependencies/Assets/Sfling.rbxmx create mode 100644 MainModule/Server/Dependencies/Assets/Sfling/Strength.model.json create mode 100644 MainModule/Server/Dependencies/Assets/Sfling/init.client.lua create mode 100644 MainModule/Server/Dependencies/Assets/Sfling/init.meta.json delete mode 100644 MainModule/Server/Dependencies/RebootHandler.rbxmx create mode 100644 MainModule/Server/Dependencies/RebootHandler/Mode.model.json create mode 100644 MainModule/Server/Dependencies/RebootHandler/Model.model.json create mode 100644 MainModule/Server/Dependencies/RebootHandler/Runner.model.json create mode 100644 MainModule/Server/Dependencies/RebootHandler/init.meta.json create mode 100644 MainModule/Server/Dependencies/RebootHandler/init.server.lua create mode 100644 MainModule/Server/Dependencies/RebootHandler/mParent.model.json diff --git a/MainModule/Server/Dependencies/Assets/BotBrain/Event.model.json b/MainModule/Server/Dependencies/Assets/BotBrain/Event.model.json new file mode 100644 index 0000000000..4c86de4ed5 --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/BotBrain/Event.model.json @@ -0,0 +1,3 @@ +{ + "ClassName": "BindableEvent" +} diff --git a/MainModule/Server/Dependencies/Assets/BotBrain/init.meta.json b/MainModule/Server/Dependencies/Assets/BotBrain/init.meta.json new file mode 100644 index 0000000000..5077db135e --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/BotBrain/init.meta.json @@ -0,0 +1,5 @@ +{ + "properties": { + "Disabled": true + } +} diff --git a/MainModule/Server/Dependencies/Assets/BotBrain.rbxmx b/MainModule/Server/Dependencies/Assets/BotBrain/init.server.lua similarity index 80% rename from MainModule/Server/Dependencies/Assets/BotBrain.rbxmx rename to MainModule/Server/Dependencies/Assets/BotBrain/init.server.lua index 0db12f9a55..ad580461d6 100644 --- a/MainModule/Server/Dependencies/Assets/BotBrain.rbxmx +++ b/MainModule/Server/Dependencies/Assets/BotBrain/init.server.lua @@ -1,18 +1,4 @@ - - true - null - nil - - - - 0 - false - true - - BotBrain - 1 - {57C75EF3-A7BD-4721-AC2E-EF182347E0A6} - - -1 - - - - - - 0 - false - Event - -1 - - - - - \ No newline at end of file +end) diff --git a/MainModule/Server/Dependencies/Assets/ClickTeleport/Mode.model.json b/MainModule/Server/Dependencies/Assets/ClickTeleport/Mode.model.json new file mode 100644 index 0000000000..35572a4e92 --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/ClickTeleport/Mode.model.json @@ -0,0 +1,6 @@ +{ + "ClassName": "StringValue", + "Properties": { + "Value": "" + } +} diff --git a/MainModule/Server/Dependencies/Assets/ClickTeleport/Target.model.json b/MainModule/Server/Dependencies/Assets/ClickTeleport/Target.model.json new file mode 100644 index 0000000000..35572a4e92 --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/ClickTeleport/Target.model.json @@ -0,0 +1,6 @@ +{ + "ClassName": "StringValue", + "Properties": { + "Value": "" + } +} diff --git a/MainModule/Server/Dependencies/Assets/ClickTeleport.rbxmx b/MainModule/Server/Dependencies/Assets/ClickTeleport/init.client.lua similarity index 60% rename from MainModule/Server/Dependencies/Assets/ClickTeleport.rbxmx rename to MainModule/Server/Dependencies/Assets/ClickTeleport/init.client.lua index a1602fc675..6c2fb848b4 100644 --- a/MainModule/Server/Dependencies/Assets/ClickTeleport.rbxmx +++ b/MainModule/Server/Dependencies/Assets/ClickTeleport/init.client.lua @@ -1,15 +1,4 @@ - - true - null - nil - - - - true - - ClickTeleport - {BDAA343E-7C81-459C-A2DB-06B5F4C8C90A} - - -1 - - - - - - Mode - -1 - - - - - - - - Target - -1 - - - - - - +humanoid.Died:Connect(function() tool:Destroy() end) diff --git a/MainModule/Server/Dependencies/Assets/ClickTeleport/init.meta.json b/MainModule/Server/Dependencies/Assets/ClickTeleport/init.meta.json new file mode 100644 index 0000000000..5077db135e --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/ClickTeleport/init.meta.json @@ -0,0 +1,5 @@ +{ + "properties": { + "Disabled": true + } +} diff --git a/MainModule/Server/Dependencies/Assets/Glitcher.rbxmx b/MainModule/Server/Dependencies/Assets/Glitcher.rbxmx deleted file mode 100644 index af0d4db9a1..0000000000 --- a/MainModule/Server/Dependencies/Assets/Glitcher.rbxmx +++ /dev/null @@ -1,60 +0,0 @@ - - true - null - nil - - - - true - - Glitcher - {53875408-B9EB-48D7-AF56-6C82B2C7F77E} - - -1 - - - - - - Num - -1 - - 3214.431999999999789 - - - - - - Type - -1 - - - - - - diff --git a/MainModule/Server/Dependencies/Assets/Glitcher/Num.model.json b/MainModule/Server/Dependencies/Assets/Glitcher/Num.model.json new file mode 100644 index 0000000000..9381de9457 --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Glitcher/Num.model.json @@ -0,0 +1,6 @@ +{ + "ClassName": "NumberValue", + "Properties": { + "Value": 3214.431999999999789 + } +} diff --git a/MainModule/Server/Dependencies/Assets/Glitcher/Type.model.json b/MainModule/Server/Dependencies/Assets/Glitcher/Type.model.json new file mode 100644 index 0000000000..35572a4e92 --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Glitcher/Type.model.json @@ -0,0 +1,6 @@ +{ + "ClassName": "StringValue", + "Properties": { + "Value": "" + } +} diff --git a/MainModule/Server/Dependencies/Assets/Glitcher/init.client.lua b/MainModule/Server/Dependencies/Assets/Glitcher/init.client.lua new file mode 100644 index 0000000000..58f18b99b9 --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Glitcher/init.client.lua @@ -0,0 +1,26 @@ +task.wait() +local torso = script.Parent +local posed = false +local type = script:WaitForChild("Type").Value +local int = tonumber(script:WaitForChild("Num").Value) or 50 + +game:GetService("RunService").RenderStepped:Connect(function() + if type == "ghost" then + torso.CFrame += Vector3.new(tonumber(int) * (posed and 4 or -2), 0, 0) + elseif type == "trippy" then + torso.CFrame *= CFrame.new(tonumber(int) * (posed and 4 or -2), 0, 0) + elseif type == "vibrate" then + local num = math.random(1,4) + + if num == 1 then + torso.CFrame *= CFrame.new(tonumber(int) * 2, 0, 0) + elseif num == 2 then + torso.CFrame *= CFrame.new(-tonumber(int) * 2, 0, 0) + elseif num == 3 then + torso.CFrame *= CFrame.new(0, 0, -tonumber(int) * 2) + elseif num == 4 then + torso.CFrame *= CFrame.new(0 ,0, tonumber(int) * 2) + end + end + posed = not posed +end) diff --git a/MainModule/Server/Dependencies/Assets/Glitcher/init.meta.json b/MainModule/Server/Dependencies/Assets/Glitcher/init.meta.json new file mode 100644 index 0000000000..5077db135e --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Glitcher/init.meta.json @@ -0,0 +1,5 @@ +{ + "properties": { + "Disabled": true + } +} diff --git a/MainModule/Server/Dependencies/Assets/Sfling.rbxmx b/MainModule/Server/Dependencies/Assets/Sfling.rbxmx deleted file mode 100644 index c37215ed6a..0000000000 --- a/MainModule/Server/Dependencies/Assets/Sfling.rbxmx +++ /dev/null @@ -1,44 +0,0 @@ - - true - null - nil - - - - true - - Sfling - {61F447BE-6192-4214-8938-59EF4489FA89} - - -1 - - - - - - Strength - -1 - - 0 - - - - diff --git a/MainModule/Server/Dependencies/Assets/Sfling/Strength.model.json b/MainModule/Server/Dependencies/Assets/Sfling/Strength.model.json new file mode 100644 index 0000000000..e21ad5d0af --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Sfling/Strength.model.json @@ -0,0 +1,6 @@ +{ + "ClassName": "NumberValue", + "Properties": { + "Value": 0 + } +} diff --git a/MainModule/Server/Dependencies/Assets/Sfling/init.client.lua b/MainModule/Server/Dependencies/Assets/Sfling/init.client.lua new file mode 100644 index 0000000000..49ed248e3b --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Sfling/init.client.lua @@ -0,0 +1,19 @@ +task.wait() +local cam = workspace.CurrentCamera +local torso = script.Parent +local humanoid = torso.Parent:FindFirstChildOfClass("Humanoid") +local strength = script:WaitForChild("Strength").Value + +for i = 1, 100 do + task.wait(0.1) + humanoid.Sit = true + local ex = Instance.new("Explosion") + ex.Position = torso.Position + Vector3.new(math.random(-5, 5), -10, math.random(-5, 5)) + ex.BlastRadius = 35 + ex.BlastPressure = strength + ex.ExplosionType = Enum.ExplosionType.NoCraters--Enum.ExplosionType.Craters + ex.DestroyJointRadiusPercent = 0 + ex.Archivable = false + ex.Parent = cam +end +script:Destroy() diff --git a/MainModule/Server/Dependencies/Assets/Sfling/init.meta.json b/MainModule/Server/Dependencies/Assets/Sfling/init.meta.json new file mode 100644 index 0000000000..5077db135e --- /dev/null +++ b/MainModule/Server/Dependencies/Assets/Sfling/init.meta.json @@ -0,0 +1,5 @@ +{ + "properties": { + "Disabled": true + } +} diff --git a/MainModule/Server/Dependencies/RebootHandler.rbxmx b/MainModule/Server/Dependencies/RebootHandler.rbxmx deleted file mode 100644 index 02ee5ff485..0000000000 --- a/MainModule/Server/Dependencies/RebootHandler.rbxmx +++ /dev/null @@ -1,113 +0,0 @@ - - true - null - nil - - - - true - - RebootHandler - {62D59941-4C6D-45EB-9E45-D4A6587DB801} - - -1 - - - - - - Mode - -1 - - - - - - - - Model - -1 - - null - - - - - - mParent - -1 - - null - - - - - - Runner - -1 - - null - - - - diff --git a/MainModule/Server/Dependencies/RebootHandler/Mode.model.json b/MainModule/Server/Dependencies/RebootHandler/Mode.model.json new file mode 100644 index 0000000000..35572a4e92 --- /dev/null +++ b/MainModule/Server/Dependencies/RebootHandler/Mode.model.json @@ -0,0 +1,6 @@ +{ + "ClassName": "StringValue", + "Properties": { + "Value": "" + } +} diff --git a/MainModule/Server/Dependencies/RebootHandler/Model.model.json b/MainModule/Server/Dependencies/RebootHandler/Model.model.json new file mode 100644 index 0000000000..186993e282 --- /dev/null +++ b/MainModule/Server/Dependencies/RebootHandler/Model.model.json @@ -0,0 +1,3 @@ +{ + "ClassName": "ObjectValue" +} diff --git a/MainModule/Server/Dependencies/RebootHandler/Runner.model.json b/MainModule/Server/Dependencies/RebootHandler/Runner.model.json new file mode 100644 index 0000000000..186993e282 --- /dev/null +++ b/MainModule/Server/Dependencies/RebootHandler/Runner.model.json @@ -0,0 +1,3 @@ +{ + "ClassName": "ObjectValue" +} diff --git a/MainModule/Server/Dependencies/RebootHandler/init.meta.json b/MainModule/Server/Dependencies/RebootHandler/init.meta.json new file mode 100644 index 0000000000..5077db135e --- /dev/null +++ b/MainModule/Server/Dependencies/RebootHandler/init.meta.json @@ -0,0 +1,5 @@ +{ + "properties": { + "Disabled": true + } +} diff --git a/MainModule/Server/Dependencies/RebootHandler/init.server.lua b/MainModule/Server/Dependencies/RebootHandler/init.server.lua new file mode 100644 index 0000000000..fa02ab72a8 --- /dev/null +++ b/MainModule/Server/Dependencies/RebootHandler/init.server.lua @@ -0,0 +1,62 @@ +--# selene: allow(incorrect_standard_library_use) +if script.Parent then + local dTargetVal = script:WaitForChild("Runner") + local parentVal = script:WaitForChild("mParent") + local modelVal = script:WaitForChild("Model") + local modeVal = script:WaitForChild("Mode") + + warn("Reloading in 5 seconds...") + task.wait(5) + script.Parent = nil + + local dTarget = dTargetVal.Value + local tParent = parentVal.Value + local model = modelVal.Value + local mode = modeVal.Value + + local function CleanUp() + warn("TARGET DISABLED") + dTarget.Disabled = true + pcall(function() dTarget.Parent = game:GetService("ServerScriptService") end) + task.wait() + pcall(function() dTarget:Destroy() end) + + warn("TARGET DESTROYED") + task.wait() + + warn("CLEANING") + + if not table.isfrozen(_G) then + rawset(_G, "Adonis", nil) + rawset(_G, "__Adonis_MODULE_MUTEX", nil) + rawset(_G, "__Adonis_MUTEX", nil) + end + + warn("_G VARIABLES CLEARED") + + warn("MOVING MODEL") + model.Parent = tParent + end + + if mode == "REBOOT" then + warn("ATTEMPTING TO RELOAD ADONIS") + CleanUp() + task.wait() + + warn("MOVING") + model.Parent = tParent + + task.wait() + + dTarget.Disabled = false + warn("RUNNING") + elseif mode == "STOP" then + warn("ATTEMPTING TO STOP ADONIS") + CleanUp() + end + + warn("COMPLETE") + + warn("Destroying reboot handler...") + script:Destroy() +end diff --git a/MainModule/Server/Dependencies/RebootHandler/mParent.model.json b/MainModule/Server/Dependencies/RebootHandler/mParent.model.json new file mode 100644 index 0000000000..186993e282 --- /dev/null +++ b/MainModule/Server/Dependencies/RebootHandler/mParent.model.json @@ -0,0 +1,3 @@ +{ + "ClassName": "ObjectValue" +} From 6a735fc1d29351fb6edcb13383b6da7fa9eb368b Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Wed, 22 Jan 2025 04:54:37 -0500 Subject: [PATCH 52/60] Prevent creating a team with the same name (#1836) --- MainModule/Server/Commands/Admins.luau | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MainModule/Server/Commands/Admins.luau b/MainModule/Server/Commands/Admins.luau index fae7da28af..f3312c057b 100644 --- a/MainModule/Server/Commands/Admins.luau +++ b/MainModule/Server/Commands/Admins.luau @@ -679,6 +679,12 @@ return function(Vargs, env) Function = function(plr: Player, args: {string}) local teamName = assert(args[1], "Missing team name (argument #1)") local teamColor = Functions.ParseBrickColor(args[2]) + + if service.Teams:FindFirstChild(teamName) then + Functions.Hint(string.format("Team '%s' already exists!", teamName), {plr}) + return; + end + service.New("Team", { Parent = service.Teams; Name = teamName; From 85d985bf447eb14298195101b373d3b3ca50424d Mon Sep 17 00:00:00 2001 From: Alex Yerkes Date: Wed, 22 Jan 2025 17:57:26 +0800 Subject: [PATCH 53/60] Update :watchcam description (#1835) --- MainModule/Server/Commands/Moderators.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Moderators.luau b/MainModule/Server/Commands/Moderators.luau index af76d904f4..95b0420985 100644 --- a/MainModule/Server/Commands/Moderators.luau +++ b/MainModule/Server/Commands/Moderators.luau @@ -1445,7 +1445,7 @@ return function(Vargs, env) Prefix = Settings.Prefix; Commands = {"viewcam", "viewc", "camview", "watchcam", "cam"}; Args = {"camera"}; - Description = "Makes you view the target player"; + Description = "Makes you view the target camera"; AdminLevel = "Moderators"; Function = function(plr: Player, args: {string}) for i, v in Variables.Cameras do From acbff4a1d3868ad44631c5f3cb788293656af5e9 Mon Sep 17 00:00:00 2001 From: WalkerOfBacon <50679909+WalkerOfBacon@users.noreply.github.com> Date: Wed, 22 Jan 2025 04:59:41 -0500 Subject: [PATCH 54/60] Show command aliases in :commands (#1833) * Show command aliases in :commands * oops forgot this * Remove prefix showing up * Actually made it accurate --- MainModule/Server/Commands/Players.luau | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/MainModule/Server/Commands/Players.luau b/MainModule/Server/Commands/Players.luau index 33b54e3335..233703bd1b 100644 --- a/MainModule/Server/Commands/Players.luau +++ b/MainModule/Server/Commands/Players.luau @@ -23,14 +23,25 @@ return function(Vargs, env) local cmdCount = 0 for _, cmd in Admin.SearchCommands(plr, "all") do + local cmdAliases = table.create(#cmd.Commands) + if cmd.Hidden or cmd.Disabled then continue end + for _,alias in cmd.Commands do + if #cmdAliases >= 4 and (#cmd.Commands - #cmdAliases) ~= 0 then + table.insert(cmdAliases, `and {#cmd.Commands - #cmdAliases} more...`) + break + end + end + + table.remove(cmdAliases, 1) + local permissionDesc = Admin.FormatCommandAdminLevel(cmd) table.insert(tab, { Text = Admin.FormatCommand(cmd), - Desc = `[{permissionDesc}] {cmd.Description or "(No description provided)"}`, + Desc = `[{permissionDesc}] {if #cmdAliases >= 1 then `\nAliases: {table.concat(cmdAliases, ", ")}` else ""} \n\n{cmd.Description or "(No description provided)"}`, Filter = permissionDesc }) cmdCount += 1 From ee457e824d00e72019e803d89ce991456f5f9cda Mon Sep 17 00:00:00 2001 From: ccuser44 <68124053+ccuser44@users.noreply.github.com> Date: Wed, 22 Jan 2025 12:01:50 +0200 Subject: [PATCH 55/60] Disable visualizer when window is minimized (#1832) --- MainModule/Client/UI/Default/Music/init.luau | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MainModule/Client/UI/Default/Music/init.luau b/MainModule/Client/UI/Default/Music/init.luau index 3725aba090..5bbd19740a 100644 --- a/MainModule/Client/UI/Default/Music/init.luau +++ b/MainModule/Client/UI/Default/Music/init.luau @@ -205,7 +205,14 @@ return function(data, env) Position = UDim2.new(0, 10, 1, -410); OnClose = function() doOnClose() - end + end, + OnMinimized = function(opened) + if opened and not visualiser.Sound then + visualiser:LinkToSound(audioLib:GetSound()) + elseif not opened and visualiser.Sound then + visualiser:UnlinkFromSound() + end + end, }) -- The controls frame at the bottom of the window From 0435a942db21f7358b678cde3fb4bcccc87c30fc Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Wed, 22 Jan 2025 11:12:19 +0000 Subject: [PATCH 56/60] Update Changelog.luau --- MainModule/Server/Shared/Changelog.luau | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index fba90c3184..0a197a31a1 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -6,6 +6,10 @@ return { "[v263 2025-01-13 16:17 UTC] @Dimenpsyonal"; "Load plugins asynchronously"; "Clamp #num selector to max players"; + "(Git/ccuser44) Disable visualiser when window is minimised (#1832)"; + "(Git/WalkerOfBacon) Show command aliases in :commands (#1833)"; + "(Git/Z3phrz) Update :watchcam description (#1835)"; + "(Git/WalkerOfBacon) Prevent creating a team with the same name (#1836)"; ""; "[v262 2025-01-12 11:16 UTC] @Dimenpsyonal"; "*First update of 2025 (!!!)"; From ba62ee2d2f03ef40e4ae0f72d595238fd09a15df Mon Sep 17 00:00:00 2001 From: nichole <64012878+Dimenpsyonal@users.noreply.github.com> Date: Wed, 22 Jan 2025 11:28:38 +0000 Subject: [PATCH 57/60] Update time --- MainModule/Server/Shared/Changelog.luau | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainModule/Server/Shared/Changelog.luau b/MainModule/Server/Shared/Changelog.luau index 0a197a31a1..ad2f09c540 100644 --- a/MainModule/Server/Shared/Changelog.luau +++ b/MainModule/Server/Shared/Changelog.luau @@ -3,7 +3,7 @@ return { "*Drag edges to expand*"; "*Report bugs/issues on our GitHub repository*"; ""; - "[v263 2025-01-13 16:17 UTC] @Dimenpsyonal"; + "[v263 2025-01-22 11:29 UTC] @Dimenpsyonal"; "Load plugins asynchronously"; "Clamp #num selector to max players"; "(Git/ccuser44) Disable visualiser when window is minimised (#1832)"; From e57a9625ae1a5b8152b4cb021e2b0106884f75eb Mon Sep 17 00:00:00 2001 From: hallowxd Date: Thu, 23 Jan 2025 09:28:35 -0600 Subject: [PATCH 58/60] fix spelling errors/etc. in comments (#1730) * fix spelling errors/etc. in comments * apply changes to DefaultSettings.luau --- CONTRIBUTING.md | 2 +- Loader/Config/API.luau | 2 +- Loader/Config/Settings.luau | 2 +- MainModule/Server/Dependencies/DefaultSettings.luau | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 47fcb6e03c..7ecfb7e259 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ There is a very clear/obvious difference between unavoidably complex code and in ## Q: Is there a style guide for writing code? -**A:** Not really, but we would normally try to follow the format of the other existing code in the module we are editing, as well as the [Roblox Lua Style Guide](https://roblox.github.io/lua-style-guide/) where applicable. Also, be sure to use US English spellings for both code variable names and user-facing text. +**A:** Not really, but we would normally try to follow the format of the other existing code in the module we are editing, as well as the [Roblox Luau Style Guide](https://roblox.github.io/lua-style-guide/) where applicable. Also, be sure to use US English spellings for both code variable names and user-facing text. ## Q: What are some things I should watch out for when submitting my changes? diff --git a/Loader/Config/API.luau b/Loader/Config/API.luau index a7e9137eaf..bf01639289 100644 --- a/Loader/Config/API.luau +++ b/Loader/Config/API.luau @@ -1,6 +1,6 @@ --[[ If you're learning how to create in Adonis, the wiki may be of help. - The wiki contains informationa about the Adonis API and how to use it; + The wiki contains information about the Adonis API and how to use it; as well as information about settings and how to use Adonis. It can be viewed here: diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index 88b54846dd..51cc435e0f 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -36,7 +36,7 @@ local descs = {}; --// Contains settings descriptions Numbers do not use quotes. setting = 56 - This green block of text you are reading is called a comment. It's like a message + This block of text you are reading is called a comment. It's like a message from the programmer to anyone who reads their stuff. Anything in a comment will not be seen by Luau when the script is run. diff --git a/MainModule/Server/Dependencies/DefaultSettings.luau b/MainModule/Server/Dependencies/DefaultSettings.luau index 8bde88b275..cfc7bb1e61 100644 --- a/MainModule/Server/Dependencies/DefaultSettings.luau +++ b/MainModule/Server/Dependencies/DefaultSettings.luau @@ -36,7 +36,7 @@ local descs = {}; --// Contains settings descriptions Numbers do not use quotes. setting = 56 - This green block of text you are reading is called a comment. It's like a message + This block of text you are reading is called a comment. It's like a message from the programmer to anyone who reads their stuff. Anything in a comment will not be seen by Luau when the script is run. From 4225863e202f8a6c9422da91879f0aaf49002a80 Mon Sep 17 00:00:00 2001 From: Cater <84566931+SuperCater@users.noreply.github.com> Date: Mon, 27 Jan 2025 08:55:51 -0500 Subject: [PATCH 59/60] Add multiple prefix support and adds ; as a prefix. (#1841) * add multiple prefix support * fox ;cmdinfo * Fix player command reference * fix all players command + new func * hacky metatable patch * metatables more like magictables * oops * fix some moderator commands * fix all moderator commands * fix all commands * fix admin core * fixed __concat * fix userpanel --------- Co-authored-by: nichole <64012878+Dimenpsyonal@users.noreply.github.com> --- Loader/Config/Settings.luau | 2 +- MainModule/Client/UI/Default/UserPanel.luau | 3 +- MainModule/Server/Commands/Admins.luau | 2939 +++++++++-------- MainModule/Server/Commands/Moderators.luau | 20 +- MainModule/Server/Commands/Players.luau | 49 +- MainModule/Server/Core/Admin.luau | 39 +- MainModule/Server/Core/Commands.luau | 10 +- MainModule/Server/Core/Functions.luau | 8 +- .../Server/Dependencies/DefaultSettings.luau | 14 +- MainModule/Server/Server.luau | 17 + 10 files changed, 1637 insertions(+), 1464 deletions(-) diff --git a/Loader/Config/Settings.luau b/Loader/Config/Settings.luau index 9f14428beb..cda345f7e6 100644 --- a/Loader/Config/Settings.luau +++ b/Loader/Config/Settings.luau @@ -238,7 +238,7 @@ settings.SaveAdmins = true -- If true anyone you ;admin or ;headadmin in-game settings.LoadAdminsFromDS = true -- If false, any admins saved in your DataStores will not load settings.WhitelistEnabled = false -- If true enables the whitelist/server lock; Only lets admins & whitelisted users join -settings.Prefix = ";" -- The ; in ;kill me +settings.Prefix = {";", ":"} -- A list of prefixes for commands, the ; in ;kill me settings.PlayerPrefix = "!" -- The ! in !donate; Mainly used for commands that any player can run; Do not make it the same as settings.Prefix settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do ;kill !me) settings.SplitKey = " " -- The space in ;kill me (eg if you change it to / ;kill me would be ;kill/me) diff --git a/MainModule/Client/UI/Default/UserPanel.luau b/MainModule/Client/UI/Default/UserPanel.luau index 7d50c7f385..363fcfbdd8 100644 --- a/MainModule/Client/UI/Default/UserPanel.luau +++ b/MainModule/Client/UI/Default/UserPanel.luau @@ -497,7 +497,8 @@ return function(data, env) chatMod = Remote.Get("Setting",{"Prefix","SpecialPrefix","BatchKey","AnyPrefix","DonorCommands","DonorCapes"}) settingsData = Remote.Get("AllSettings") Variables.Aliases = playerData.Aliases or {} - commandPrefix = chatMod.Prefix + commandPrefix = if type(chatMod.Prefix) == "table" then chatMod.Prefix[1] else chatMod.Prefix + for _, v in loadingIcons do v:Destroy() diff --git a/MainModule/Server/Commands/Admins.luau b/MainModule/Server/Commands/Admins.luau index f3312c057b..c38d42b7ed 100644 --- a/MainModule/Server/Commands/Admins.luau +++ b/MainModule/Server/Commands/Admins.luau @@ -1,1598 +1,1719 @@ ---!nocheck -return function(Vargs, env) +server = nil +service = nil +Routine = nil +GetEnv = nil +origEnv = nil +logError = nil + +--// Admin +return function(Vargs, GetEnv) + local env = GetEnv(nil, {script = script}) + setfenv(1, env) + local server = Vargs.Server; local service = Vargs.Service; - local Settings = server.Settings - local Functions, Commands, Admin, Anti, Core, HTTP, Logs, Remote, Process, Variables, Deps = - server.Functions, server.Commands, server.Admin, server.Anti, server.Core, server.HTTP, server.Logs, server.Remote, server.Process, server.Variables, server.Deps - - if env then setfenv(1, env) end - - local Routine = env.Routine - - return { - SetRank = { - Prefix = Settings.Prefix; - Commands = {"setrank", "permrank", "permsetrank"}; - Args = {"player/user", "rank"}; - Description = "Sets the admin rank of the target user(s); THIS SAVES!"; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - assert(args[1], "Missing target user (argument #1)") - local rankName = assert(args[2], "Missing rank name (argument #2)") - - local newRank = Settings.Ranks[rankName] - if not newRank then - for thisRankName, thisRank in Settings.Ranks do - if thisRankName:lower() == rankName:lower() then - rankName = thisRankName - newRank = thisRank - break + local Functions, Admin, Anti, Core, HTTP, Logs, Remote, Process, Variables, Settings, Commands + local AddLog, TrackTask, Defaults + local CreatorId = game.CreatorType == Enum.CreatorType.User and game.CreatorId or service.GetGroupCreatorId(game.CreatorId) + local function Init() + Functions = server.Functions; + Admin = server.Admin; + Anti = server.Anti; + Core = server.Core; + HTTP = server.HTTP; + Logs = server.Logs; + Remote = server.Remote; + Process = server.Process; + Variables = server.Variables; + Settings = server.Settings; + Commands = server.Commands; + Defaults = server.Defaults + + TrackTask = service.TrackTask + AddLog = Logs.AddLog; + + TrackTask("Thread: ChatServiceHandler", function() + + --// Support for modern TextChatService + if service.TextChatService and service.TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then + local function onNewTextchannel(textchannel: TextChannel) + AddLog("Script", `Connected to TextChannel: {textchannel.Name}`) + + if Settings.OverrideChatCallbacks ~= false then --// Default to "on" this for all games + AddLog("Script", "Overriding ShouldDeliverCallback for " .. textchannel.Name) + textchannel.ShouldDeliverCallback = function(chatMessage, textSource) + if + chatMessage.Status == Enum.TextChatMessageStatus.Success + or chatMessage.Status == Enum.TextChatMessageStatus.Sending + then + local SenderId = chatMessage.TextSource.UserId + local SenderPlayer = service.Players:GetPlayerByUserId(SenderId) + local Receiver = service.Players:GetPlayerByUserId(textSource.UserId) + local slowCache = Admin.SlowCache + + local IsOriginalSender = SenderPlayer == Receiver + + if not SenderPlayer then + return true + elseif Admin.DoHideChatCmd(SenderPlayer, chatMessage.Text) then -- // Hide chat commands? + return false + elseif Admin.IsMuted(SenderPlayer) then -- // Mute handler + if IsOriginalSender then + server.Remote.Send(SenderPlayer, "Function", "DisplaySystemMessageInTextChat", nil, `[Adonis Chat]: You are muted! Other players cannot see your messages.`) + end + + return false + elseif Admin.SlowMode and not Admin.CheckAdmin(SenderPlayer) and slowCache[SenderPlayer] and os.time() - slowCache[SenderPlayer] < Admin.SlowMode then + if IsOriginalSender then --// Only show this for the person sending! Hide for others, however + --Functions.Notification("You are chatting too fast!", string.format("[Adonis] :: Slow mode enabled! (%g second(s) remaining)", Admin.SlowMode - (os.time() - slowCache[SenderPlayer])), {SenderPlayer}, 10) + + server.Remote.Send(SenderPlayer, "Function", "DisplaySystemMessageInTextChat", nil, `[Adonis Chat]: You are sending messages too fast! {string.format("(%g second(s) remaining)", Admin.SlowMode - (os.time() - slowCache[SenderPlayer]))}`) + end + + return false + end + + if Variables.DisguiseBindings[SenderId] then -- // Disguise command handler + chatMessage.PrefixText = Variables.DisguiseBindings[SenderId].TargetUsername..":" + end + + if Admin.SlowMode and IsOriginalSender then + slowCache[SenderPlayer] = os.time() + end + end + + return true end - end - end - assert(newRank, `No rank named '{rankName}' exists`) - - local newLevel = newRank.Level - local senderLevel = data.PlayerData.Level - - assert(newLevel < senderLevel, string.format("Rank level (%s) cannot be equal to or above your own level (%s)", newLevel, senderLevel)) - local v = Functions.GetPlayers(plr, args[1], {NoFakePlayer = false}) - for _, p in v do - if senderLevel > Admin.GetLevel(p) then - Admin.AddAdmin(p, rankName) - Functions.LogAdminAction(plr, "Set Rank", p.Name, `New rank: {rankName}, New level: {newLevel}`) - Functions.Notification( - "Notification", - `You are {if string.lower(string.sub(rankName, 1, 3)) == "the" then "" elseif string.match(rankName, "^[AEIOUaeiou]") and string.lower(string.sub(rankName, 1, 3)) ~= "uni" then "an " else "a "}{rankName}. Click to view commands.`, - {p}, 10, "MatIcon://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}cmds')`) - ) - Functions.Hint(`{service.FormatPlayer(p, true)} is now rank {rankName} (Permission Level: {newLevel})`, {plr}) else - Functions.Hint(`You do not have permission to set the rank of {service.FormatPlayer(p, true)}`, {plr}) + AddLog("Script", `Using the 'CanSend' method of handling chat connectivity in channel {textchannel.Name}`) + server.Variables.TextChatSpeakers = {} + local function AddUserToTextChatSpeakers(player: Player, speaker: TextSource) + if not server.Variables.TextChatSpeakers[player] then + server.Variables.TextChatSpeakers[player] = {} + end + table.insert(server.Variables.TextChatSpeakers[player], speaker) + --// Check if the player is muted or not + speaker:SetAttribute("OriginalCanSend", speaker.CanSend) + if server.Admin.IsMuted(player) then + speaker.CanSend = false + end + end + local function SpeakerAdded(speaker: TextSource) + if speaker.UserId and speaker.UserId > 0 then + local Player = service.Players:GetPlayerByUserId(speaker.UserId) + if Player then + AddUserToTextChatSpeakers(Player, speaker) + end + end + end + local function SpeakerRemoved(speaker: TextSource) + if speaker.UserId and speaker.UserId > 0 then + local Player = service.Players:GetPlayerByUserId(speaker.UserId) + local Tab = server.Variables.TextChatSpeakers[Player] + if Tab then + local index = table.find(Tab, speaker) + while index do + table.remove(Tab, index) + index = table.find(Tab, speaker) + end + task.defer(function() + if #Tab == 0 then + server.Variables.TextChatSpeakers[Player] = nil + end + end) + end + end + end + + textchannel.ChildAdded:Connect(function(textSource) + if textSource:IsA("TextSource") then + SpeakerAdded(textSource) + end + end) + + textchannel.ChildRemoved:Connect(function(textSource) + if textSource:IsA("TextSource") then + SpeakerRemoved(textSource) + end + end) + + for _,inst in textchannel:GetChildren() do + if inst:IsA("TextSource") then + SpeakerAdded(inst) + end + end + end end - end; - }; - - SetTempRank = { - Prefix = Settings.Prefix; - Commands = {"settemprank", "temprank", "tempsetrank"}; - Args = {"player", "rank"}; - Description = `Identical to {Settings.Prefix}setrank, but doesn't save`; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - assert(args[1], "Missing target player (argument #1)") - local rankName = assert(args[2], "Missing rank name (argument #2)") - - local newRank = Settings.Ranks[rankName] - if not newRank then - for thisRankName, thisRank in Settings.Ranks do - if thisRankName:lower() == rankName:lower() then - rankName = thisRankName - newRank = thisRank - break + + --// Only set this up once + --// This is for commands to tell us when a player should be muted + if not Settings.OverrideChatCallbacks then + service.Events.PlayerMuted:Connect(function(data) + local PlayerId = data.Target; + local ModId = data.Moderator; + + local Player = service.Players:GetPlayerByUserId(PlayerId) + --// Loop through CanSend of a speaker + for _,speakers : TextSource in if Player then server.Variables.TextChatSpeakers[Player] or {} else {} do + speakers.CanSend = false end - end + if Player then + AddLog("Script", `Muted player {Player.Name}:{Player.UserId} using CanSend method`) + end + end) + service.Events.PlayerUnMuted:Connect(function(data) + local PlayerId = data.Target; + local ModId = data.Moderator; + + local Player = service.Players:GetPlayerByUserId(PlayerId) + --// Loop through CanSend of a speaker + for _,speakers : TextSource in if Player then server.Variables.TextChatSpeakers[Player] or {} else {} do + local original = speakers:GetAttribute("OriginalCanSend") + speakers.CanSend = if original ~= nil then original else true + end + if Player then + AddLog("Script", `UnMuted player {Player.Name}:{Player.UserId} via CanSend method`) + end + end) + service.Events.MutedPlayerChat_UnFiltered:Connect(function(p, ...) + server.Remote.Send(p, "Function", "DisplaySystemMessageInTextChat", nil, `[Adonis Chat]: You are muted! Other players cannot see your messages.`) + end) end - assert(newRank, `No rank named '{rankName}' exists`) - local newLevel = newRank.Level - local senderLevel = data.PlayerData.Level - assert(newLevel < senderLevel, string.format("Rank level (%s) cannot be equal to or above your own level (%s)", newLevel, senderLevel)) + local function onTextChannelsAdded(textChannels) + textChannels.ChildAdded:Connect(function(child) + if child:IsA("TextChannel") then + task.spawn(onNewTextchannel, child) + end + end) - for _, v in service.GetPlayers(plr, args[1]) do - if senderLevel > Admin.GetLevel(v) then - Admin.AddAdmin(v, rankName, true) - Functions.LogAdminAction(plr, "Set Temporary Rank", v.Name, `Temporary rank set to: {rankName}`) - Functions.Notification("Notification", `You are a temp {rankName}. Click to view commands.`, {v}, 10, "MatIcon://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}cmds')`)) - Functions.Hint(`{service.FormatPlayer(v, true)} is now rank {rankName} (Permission Level: {newLevel})`, {plr}) - else - Functions.Hint(`You do not have permission to set the rank of {service.FormatPlayer(v, true)}`, {plr}) + for _, v in textChannels:GetChildren() do + if v:IsA("TextChannel") then + task.spawn(onNewTextchannel, v) + end end end - end; - }; - - SetLevel = { - Prefix = Settings.Prefix; - Commands = {"setlevel", "setadminlevel"}; - Args = {"player", "level"}; - Description = "Sets the target player(s) permission level for the current server; does not save"; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - local senderLevel = data.PlayerData.Level - local newLevel = assert(tonumber(args[2]), "Level must be a number") - - assert(newLevel < senderLevel, `Level cannot be equal to or above your own permission level ({senderLevel})`); - - for _, v in service.GetPlayers(plr, args[1])do - if senderLevel > Admin.GetLevel(v) then - Admin.SetLevel(v, newLevel, args[3] == "true") - Functions.LogAdminAction(plr, "Set Level", v.Name, `New level: {newLevel}`) - Functions.Notification("Notification", `Your admin permission level was set to {newLevel} for this server only. Click to view commands.`, {v}, 10, "MatIcon://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}cmds')`)) - Functions.Hint(`{service.FormatPlayer(v, true)} is now permission level {newLevel}`, {plr}) - else - Functions.Hint(`You do not have permission to set the permission level of {service.FormatPlayer(v, true)}`, {plr}) + + service.TextChatService.ChildAdded:Connect(function(child) + if child.Name == "TextChannels" then + task.spawn(onTextChannelsAdded, child) end + end) + + if service.TextChatService:FindFirstChild("TextChannels") then + task.spawn(pcall, onTextChannelsAdded, service.TextChatService:FindFirstChild("TextChannels")) end - end; - }; - - UnAdmin = { - Prefix = Settings.Prefix; - Commands = {"unadmin", "unmod", "unowner", "unpadmin", "unheadadmin", "unrank"}; - Args = {"player/user / list entry", "temp? (true/false) (default: false)"}; - Description = "Removes admin/moderator ranks from the target player(s); saves unless is 'true'"; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - local target = assert(args[1], "Missing target user (argument #1)") - local temp = args[2] and args[2]:lower() == "true" - local senderLevel = data.PlayerData.Level - local userFound = false - - if not string.find(target, ":") then - for _, v in service.GetPlayers(plr, target, { - UseFakePlayer = true; - DontError = true; - }) - do - userFound = true - local targLevel, targRank = Admin.GetLevel(v) - if targLevel > 0 then - if senderLevel > targLevel then - Admin.RemoveAdmin(v, temp) - Functions.LogAdminAction(plr, "Remove Admin", v.Name, `Temporary: {temp}`) - Functions.Hint(string.format("Removed %s from rank %s", service.FormatPlayer(v, true), targRank or "[unknown rank]"), {plr}) - Functions.Notification("Notification", `You are no longer a(n) {targRank or "admin"}`, {v}, 10, "MatIcon://Shield") - else - Functions.Hint(`You do not have permission to remove {service.FormatPlayer(v, true)}'s rank`, {plr}) - end - else - Functions.Hint(`{service.FormatPlayer(v, true)} does not already have any rank to remove`, {plr}) - end + + AddLog("Script", "TextChatService Handler Loaded") + end + + --// Support for legacy Lua chat system + --// ChatService mute handler (credit to Coasterteam) + AddLog("Script", "Starting loading of legacy chatservice handler") + local chatService = Functions.GetChatService(300) + if chatService then + chatService:RegisterProcessCommandsFunction("ADONIS_CMD", function(speakerName, message) + local speaker = chatService:GetSpeaker(speakerName) + local speakerPlayer = speaker and speaker:GetPlayer() + + if not speakerPlayer then + return false end - if userFound then - return - else - Functions.Hint("User not found in server; searching datastore", {plr}) + if Admin.DoHideChatCmd(speakerPlayer, message) then + return true end - end - for rankName, rankData in Settings.Ranks do - if senderLevel <= rankData.Level then - continue + return false + end) + + chatService:RegisterProcessCommandsFunction("ADONIS_MUTE_SERVER", function(speakerName, _, channelName) + local slowCache = Admin.SlowCache + + local speaker = chatService:GetSpeaker(speakerName) + local speakerPlayer = speaker and speaker:GetPlayer() + + if not speakerPlayer then + return false end - for i, user in rankData.Users do - if not (user:lower() == target:lower() or user:lower():match(`^{target:lower()}:`) or Admin.DoCheck(target, user)) then - continue - end - if - Remote.GetGui(plr, "YesNoPrompt", { - Question = `Remove '{user}' from '{rankName}'?`; - }) == "Yes" - then - table.remove(rankData.Users, i) - if not temp and Settings.SaveAdmins then - service.TrackTask("Thread: RemoveAdmin", Core.DoSave, false, { - Type = "TableRemove"; - Table = {"Settings", "Ranks", rankName, "Users"}; - Value = user; - }); - Functions.Hint(`Removed entry '{user}' from {rankName}`, {plr}) - Logs:AddLog("Script", `{plr} removed {user} from {rankName}`) - end - end - userFound = true + + if speakerPlayer and Admin.IsMuted(speakerPlayer) then + speaker:SendSystemMessage("[Adonis] :: You are muted!", channelName) + return true + elseif speakerPlayer and Admin.SlowMode and not Admin.CheckAdmin(speakerPlayer) and slowCache[speakerPlayer] and os.time() - slowCache[speakerPlayer] < Admin.SlowMode then + speaker:SendSystemMessage(string.format("[Adonis] :: Slow mode enabled! (%g second(s) remaining)", Admin.SlowMode - (os.time() - slowCache[speakerPlayer])), channelName) + return true end - end - assert(userFound, `No table entries matching '{args[1]}' were found`) - end - }; - - TempUnAdmin = { - Prefix = Settings.Prefix; - Commands = {"tempunadmin", "untempadmin", "tunadmin", "untadmin"}; - Args = {"player"}; - Description = "Removes the target players' admin powers for this server; does not save"; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - local senderLevel = data.PlayerData.Level - - for _, v in service.GetPlayers(plr, assert(args[1], "Missing target player (argument #1)")) do - local targetLevel = Admin.GetLevel(v) - if targetLevel > 0 then - if senderLevel > targetLevel then - Admin.RemoveAdmin(v, true) - Functions.LogAdminAction(plr, "Temporary Unadmin", v.Name, "Admin powers temporarily removed") - Functions.Hint(`Removed {service.FormatPlayer(v)}'s admin powers`, {plr}) - Functions.Notification("Notification", "Your admin powers have been temporarily removed", {v}, 10, "MatIcons://Remove moderator") - else - Functions.Hint(`You do not have permission to remove {service.FormatPlayer(v, true)}'s admin powers`, {plr}) - end - else - Functions.Hint(`{service.FormatPlayer(v, true)} is not an admin`, {plr}) + + if Admin.SlowMode then + slowCache[speakerPlayer] = os.time() end - end + + return false + end) + + AddLog("Script", "ChatService Handler Loaded") + elseif chatService == false then + AddLog("Script", "Using TextChatService; Handler Loaded") + else + warn("Place is missing ChatService; Vanilla Roblox chat related features may not work") + AddLog("Script", "ChatService Handler Not Found") end - }; - - TempModerator = { - Prefix = Settings.Prefix; - Commands = {"tempmod", "tmod", "tempmoderator", "tmoderator"}; - Args = {"player"}; - Description = "Makes the target player(s) a temporary moderator; does not save"; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - local senderLevel = data.PlayerData.Level - - for _, v in service.GetPlayers(plr, assert(args[1], "Missing target player (argument #1)")) do - if senderLevel > Admin.GetLevel(v) then - Admin.AddAdmin(v, "Moderators", true) - Functions.LogAdminAction(plr, "Temporary Moderator", v.Name, "N/A") - Functions.Notification("Notification", "You are a temp moderator. Click to view commands.", {v}, 10, "MatIcons://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}cmds')`)) - Functions.Hint(`{service.FormatPlayer(v, true)} is now a temp moderator`, {plr}) - else - Functions.Hint(`{service.FormatPlayer(v, true)} is already the same admin level as you or higher`, {plr}) + end) + + --// Make sure the default ranks are always present for compatability with existing commands + local Ranks = Settings.Ranks + for rank, data in Defaults.Settings.Ranks do + if not Ranks[rank] then + for r, d in Ranks do + if d.Level == data.Level then + data.Hidden = true + break end end + Ranks[rank] = data end - }; + end - Moderator = { - Prefix = Settings.Prefix; - Commands = {"permmod", "pmod", "mod", "moderator", "pmoderator"}; - Args = {"player/user"}; - Description = "Makes the target player(s) a moderator; saves"; - AdminLevel = "Admins"; - Dangerous = true; - Function = function(plr: Player, args: {string}, data: {any}) - local senderLevel = data.PlayerData.Level + if Settings.CustomRanks then + local Ranks = Settings.Ranks + for name, users in Settings.CustomRanks do + if not Ranks[name] then + Ranks[name] = { + Level = 1; + Users = users; + }; + end + end + end - for _, v in service.GetPlayers(plr, assert(args[1], "Missing target player (argument #1)"), { - UseFakePlayer = true; - }) - do - if senderLevel > Admin.GetLevel(v) then - Admin.AddAdmin(v, "Moderators") - Functions.LogAdminAction(plr, "Promoted to Moderator", v.Name, "N/A") - Functions.Notification("Notification", "You are a moderator. Click to view commands.", {v}, 10, "MatIcons://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}cmds')`)) - Functions.Hint(`{service.FormatPlayer(v, true)} is now a moderator`, {plr}) - else - Functions.Hint(`{service.FormatPlayer(v, true)} is already the same admin level as you or higher`, {plr}) + if Settings.CommandCooldowns then + for cmdName, cooldownData in Settings.CommandCooldowns do + local realCmd = Admin.GetCommand(cmdName) + + if realCmd then + if cooldownData.Player then + realCmd.PlayerCooldown = cooldownData.Player + end + + if cooldownData.Server then + realCmd.ServerCooldown = cooldownData.Server + end + + if cooldownData.Cross then + realCmd.CrossCooldown = cooldownData.Cross end end end - }; - - Broadcast = { - Prefix = Settings.Prefix; - Commands = {"broadcast", "bc"}; - Args = {"Message"}; - Filter = true; - Description = "Makes a message in the chat window"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - for _, v in service.GetPlayers() do - if service.TextChatService and service.TextChatService.ChatVersion == Enum.ChatVersion.TextChatService then - local TextToUse = args[1] - if data.Options.Chat ~= true then - TextToUse = service.SanitizeXML(args[1] or "Hello world!") - end - Remote.Send( - v, "Function", "DisplaySystemMessageInTextChat", nil, `{ - string.format(`[%s] %s`, Settings.SystemTitle, service.Filter(TextToUse), plr, v) - }`) - else - Remote.Send(v, "Function", "ChatMessage", string.format("[%s] %s", Settings.SystemTitle, service.Filter(args[1], plr, v)), Color3.fromRGB(255,64,77)) + end + + Admin.Init = nil; + AddLog("Script", "Admin Module Initialized") + end; + + local function RunAfterPlugins(data) + --// Backup Map + if Settings.AutoBackup then + TrackTask("Thread: Initial Map Backup", Admin.RunCommand, false, `{Settings.Prefix}backupmap`) + end + + --// Run OnStartup Commands + for i,v in Settings.OnStartup do + print(`Running startup command {v}`) + TrackTask(`Thread: Startup_Cmd: {v}`, Admin.RunCommand, false, v) + AddLog("Script", { + Text = `Startup: Executed {v}`; + Desc = `Executed startup command; {v}`; + }) + end + + --// Check if Shutdownlogs is set and if not then set it + if Core.DataStore and not Core.GetData("ShutdownLogs") then + Core.SetData("ShutdownLogs", {}) + end + + Admin.RunAfterPlugins = nil; + AddLog("Script", "Admin Module RunAfterPlugins Finished") + end + + service.MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player, id, purchased) + if Variables and player.Parent and table.find(Variables.DonorPass, id) and purchased then + Variables.CachedDonors[tostring(player.UserId)] = os.time() + end + end) + + local function stripArgPlaceholders(alias) + return service.Trim(string.gsub(alias, "<%S+>", "")) + end + + local function FormatAliasArgs(alias, aliasCmd, msg) + local uniqueArgs = {} + local argTab = {} + local numArgs = 0 + + --// First try to extract args info from the alias + for arg in string.gmatch(alias, "<(%S+)>") do + if arg ~= "" and arg ~= " " then + local arg = `<{arg}>` + if not uniqueArgs[arg] then + numArgs += 1 + uniqueArgs[arg] = true + table.insert(argTab, arg) + end + end + end + + --// If no args in alias string, check the command string instead and try to guess args based on order of appearance + if numArgs == 0 then + for arg in string.gmatch(aliasCmd, "<(%S+)>") do + if arg ~= "" and arg ~= " " then + local arg = `<{arg}>` + if not uniqueArgs[arg] then --// Get only unique placeholder args, repeats will be matched to the same arg pos + numArgs += 1 + uniqueArgs[arg] = true --// :cmd + table.insert(argTab, arg) end end end - }; + end - ShutdownLogs = { - Prefix = Settings.Prefix; - Commands = {"shutdownlogs", "shutdownlog", "slogs", "shutdowns"}; - Args = {}; - Description = "Shows who shutdown or restarted a server and when"; - AdminLevel = "Admins"; - ListUpdater = function(plr: Player) - local logs = Core.GetData("ShutdownLogs") or {} - local tab = {} - for i, v in logs do - if v.Restart then v.Time ..= " [RESTART]" end - tab[i] = { - Text = `{v.Time}: {v.User}`; - Desc = `Reason: {v.Reason}`; - } - end - return tab - end; - Function = function(plr: Player, args: {string}) - Remote.MakeGui(plr, "List", { - Title = "Shutdown Logs"; - Table = Logs.ListUpdaters.ShutdownLogs(plr); - Update = "ShutdownLogs"; - }) + local suppliedArgs = Admin.GetArgs(msg, numArgs) -- User supplied args (when running :alias arg) + local out = aliasCmd + + local SanitizePattern = service.SanitizePattern + for i,argType in argTab do + local replaceWith = suppliedArgs[i] + if replaceWith then + out = string.gsub(out, SanitizePattern(argType), replaceWith) end - }; - - ServerLock = { - Prefix = Settings.Prefix; - Commands = {"slock", "serverlock", "lockserver"}; - Args = {"on/off"}; - Description = "Enables/disables server lock"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local arg = args[1] and string.lower(args[1]) - Functions.LogAdminAction(plr, "Server Lock", "Server is now " .. (if (arg == "on" or arg == "true") then "locked" else "unlocked"), "") - if (not arg and Variables.ServerLock ~= true) or arg == "on" or arg == "true" then - Variables.ServerLock = true - Functions.Hint("Server Locked", service.Players:GetPlayers()) - elseif Variables.ServerLock == true or arg == "off" or arg == "false" then - Variables.ServerLock = false - Functions.Hint("Server Unlocked", service.Players:GetPlayers()) - end - end - }; - - Whitelist = { - Prefix = Settings.Prefix; - Commands = {"wl", "enablewhitelist", "whitelist"}; - Args = {"on/off/add/remove/list/clear", "optional player"}; - Description = "Enables/disables the server whitelist; :wl username to add them to the whitelist"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local sub = string.lower(args[1]) - - if sub == "on" or sub == "enable" then - Variables.Whitelist.Enabled = true - Functions.Hint("Enabled server whitelist", service.Players:GetPlayers()) - elseif sub == "off" or sub == "disable" then - Variables.Whitelist.Enabled = false - Functions.Hint("Disabled server whitelist", service.Players:GetPlayers()) - elseif sub == "add" then - if args[2] then - local plrs = service.GetPlayers(plr, args[2], { - DontError = true; - IsServer = false; - IsKicking = false; - NoFakePlayer = false; - }) - if #plrs>0 then - for _, v in plrs do - table.insert(Variables.Whitelist.Lists.Settings, `{v.Name}:{v.UserId}`) - Functions.Hint(`Added {service.FormatPlayer(v)} to the whitelist`, {plr}) - end - else - table.insert(Variables.Whitelist.Lists.Settings, args[2]) - end + end + + return out + end + + server.Admin = { + Init = Init; + RunAfterPlugins = RunAfterPlugins; + + SpecialLevels = {}; + TempAdmins = {}; + + PrefixCache = {}; + CommandCache = {}; + SlowCache = {}; + UserIdCache = {}; + UsernameCache = {}; + GroupsCache = {}; + + BlankPrefix = false; + + --// How long admin levels will be cached (unless forcibly updated via something like :admin user) + AdminLevelCacheTimeout = 30; + + CheckSlowMode = function(p: Player) + if Admin.SlowMode and Admin.SlowCache[p] and os.time() - Admin.SlowCache[p] < Admin.SlowMode then + return true + else + return false + end + end, + + DoHideChatCmd = function(p: Player, message: string, data: {[string]: any}?) + local pData = data or Core.GetPlayer(p) + if pData.Client.HideChatCommands then + if Admin.BlankPrefix and + + (string.sub(message,1,1) ~= Settings.Prefix or string.sub(message,1,1) ~= Settings.PlayerPrefix or (type(Settings.Prefix) == "table" and not table.find(Settings.Prefix, string.sub(message,1,1)))) then + local isCMD = Admin.GetCommand(message) + if isCMD then + return true else - error("Missing user argument") + return false end - elseif sub == "remove" then - if args[2] then - for i, v in Variables.Whitelist.Lists.Settings do - if string.sub(string.lower(v), 1,#args[2]) == string.lower(args[2])then - table.remove(Variables.Whitelist.Lists.Settings,i) - Functions.Hint(`Removed {v} from the whitelist`, {plr}) - end - end - else - error("Missing user argument") + elseif (string.sub(message,1,1) == Settings.Prefix or string.sub(message,1,1) == Settings.PlayerPrefix or (type(Settings.Prefix) == "table" and table.find(Settings.Prefix, string.sub(message,1,1)))) + and string.sub(message,2,2) ~= string.sub(message,1,1) then + return true; + end + end + end; + + GetPlayerGroups = function(p: Player) + if not p or p.Parent ~= service.Players then + return {} + end + return Admin.GetGroups(p.UserId) + end; + + GetPlayerGroup = function(p, group) + local groups = Admin.GetPlayerGroups(p) + local isId = type(group) == "number" + if groups and #groups > 0 then + for _, g in groups do + if (isId and g.Id == group) or (not isId and g.Name == group) then + return g end - elseif sub == "list" then - local Tab = {} - for Key, List in Variables.Whitelist.Lists do - local Prefix = Key == "Settings" and "" or `[{Key}] ` - for _, User in List do - table.insert(Tab, {Text = Prefix .. User, Desc = User}) - end + end + end + end; + + GetGroups = function(uid, updateCache) + uid = tonumber(uid) + + if type(uid) == "number" then + local existCache = Admin.GroupsCache[uid] + local canUpdate = false + + if not updateCache then + --> Feel free to adjust the time to update over or less than 300 seconds (5 minutes). + --> 300 seconds is recommended in the event of unexpected server breakdowns with Roblox and faster performance. + if (existCache and (os.time()-existCache.LastUpdated > 300)) or not existCache then + canUpdate = true end - Remote.MakeGui(plr, "List", {Title = "Whitelist List"; Tab = Tab;}) - elseif sub == "clear" then - Variables.Whitelist.Lists.Settings = {} - Functions.Hint("Cleared server whitelist", service.Players:GetPlayers()) else - error("Invalid subcommand (on/off/add/remove/list/clear)") - end - end - }; - - SystemNotify = { - Prefix = Settings.Prefix; - Commands = {"sn", "systemnotify", "sysnotif", "sysnotify", "systemsmallmessage", "snmessage", "snmsg", "ssmsg", "ssmessage"}; - Args = {"message"}; - Filter = true; - Description = "Makes a system small message"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[1], "Missing message") - for _, v in service.GetPlayers() do - Remote.RemoveGui(v, "Notify") - Functions.Notify(Settings.SystemTitle, service.Filter(args[1], plr, v), {v}) - end - end - }; - - Notif = { - Prefix = Settings.Prefix; - Commands = {"setmessage", "notif", "setmsg", "permhint"}; - Args = {"message OR off"}; - Filter = true; - Description = "Sets a small hint message at the top of the screen"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[1], "Missing message (or enter 'off' to disable)") - - if args[1] == "off" or args[1] == "false" then - Variables.NotifMessage = nil - for _, v in service.GetPlayers() do - Remote.RemoveGui(v, "Notif") + canUpdate = true + end + + if canUpdate then + local cacheTab = { + Groups = (existCache and existCache.Groups) or {}; + LastUpdated = os.time(); + } + Admin.GroupsCache[uid] = cacheTab + + local suc,groups = pcall(function() + return service.GroupService:GetGroupsAsync(uid) or {} + end) + + if suc and type(groups) == "table" then + cacheTab.Groups = groups + return cacheTab.Groups end + + Admin.GroupsCache[uid] = cacheTab + return table.clone(cacheTab.Groups) else - Variables.NotifMessage = args[1] - for _, v in service.GetPlayers() do - Remote.MakeGui(v, "Notif", { - Message = Variables.NotifMessage; - }) - end + return table.clone((existCache and existCache.Groups) or {}) end end - }; - - SetBanMessage = { - Prefix = Settings.Prefix; - Commands = {"setbanmessage", "setbmsg"}; - Args = {"message"}; - Filter = true; - Description = "Sets the ban message banned players see"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - Variables.BanMessage = assert(args[1], "Missing message (argument #1)") - end - }; - - SetLockMessage = { - Prefix = Settings.Prefix; - Commands = {"setlockmessage", "slockmsg", "setlmsg"}; - Args = {"message"}; - Filter = true; - Description = "Sets the lock message unwhitelisted players see if :whitelist or :slock is on"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - Variables.LockMessage = assert(args[1], "Missing message (argument #1)") - end - }; - - SystemMessage = { - Prefix = Settings.Prefix; - Commands = {"sm", "systemmessage", "sysmsg"}; - Args = {"message"}; - Filter = true; - Description = "Same as message but says SYSTEM MESSAGE instead of your name, or whatever system message title is server to..."; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - Functions.Message(Settings.SystemTitle, service.BroadcastFilter(assert(args[1], "Missing message (argument #1)"), plr), service.GetPlayers(), true) - end - }; - - SetCoreGuiEnabled = { - Prefix = Settings.Prefix; - Commands = {"setcoreguienabled", "setcoreenabled", "showcoregui", "setcoregui", "setcgui", "setcore", "setcge"}; - Args = {"player", "All/Backpack/Chat/EmotesMenu/Health/PlayerList", "true/false"}; - Description = "Enables or disables CoreGui elements for the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[3], "Missing state (argument #3)") - local enable = if args[3]:lower() == "on" or args[3]:lower() == "true" then true elseif args[3]:lower() == "off" or args[3]:lower() == "false" then false else nil - assert(enable ~= nil, `Invalid state '{args[3]}'; please supply 'true' or 'false' (argument #3)`) - for _,v in service.GetPlayers(plr, args[1]) do - if string.lower(args[3]) == "on" or string.lower(args[3]) == "true" then - Remote.Send(v, "Function", "SetCoreGuiEnabled", args[2], true) - elseif string.lower(args[3]) == 'off' or string.lower(args[3]) == "false" then - Remote.Send(v, "Function", "SetCoreGuiEnabled", args[2], false) + end; + + GetGroupLevel = function(uid, groupId) + groupId = tonumber(groupId) + + if groupId then + local groups = Admin.GetGroups(uid) or {} + + for _, group in groups do + if group.Id == groupId then + return group.Rank end end end - }; - - Alert = { - Prefix = Settings.Prefix; - Commands = {"alert", "alarm", "annoy"}; - Args = {"player", "message"}; - Filter = true; - Description = "Get someone's attention"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr,string.lower(args[1]))do - Remote.MakeGui(v, "Alert", {Message = args[2] and service.Filter(args[2],plr, v) or "Wake up; Your attention is required"}) - end - end - }; - - LockMap = { - Prefix = Settings.Prefix; - Commands = {"lockmap"}; - Args = {}; - Description = "Locks the map"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, obj in workspace:GetDescendants()do - if obj:IsA("BasePart")then - obj.Locked = true + + return 0 + end; + + CheckInGroup = function(uid, groupId) + local groups = Admin.GetGroups(uid) or {} + groupId = tonumber(groupId) + + if groupId then + for i,group in groups do + if group.Id == groupId then + return true end end end - }; - UnlockMap = { - Prefix = Settings.Prefix; - Commands = {"unlockmap"}; - Args = {}; - Description = "Unlocks the map"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, obj in workspace:GetDescendants()do - if obj:IsA("BasePart")then - obj.Locked = false - end + return false + end, + + IsLax = function(str) + for _, v in {"plr", "user", "player", "brickcolor"} do + if string.match(string.lower(str), v) then + return true end end - }; - - BuildingTools = { - Prefix = Settings.Prefix; - Commands = {"btools", "f3x", "buildtools", "buildingtools", "buildertools"}; - Args = {"player"}; - Description = "Gives the target player(s) F3X building tools."; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local F3X = Deps.Assets:FindFirstChild("F3X Deps") and (function(deps) - local F3X = service.New("Tool", { - GripPos = Vector3.new(0, 0, 0.4), - CanBeDropped = false, - ManualActivationOnly = false, - ToolTip = "Building Tools by F3X", - Name = "Building Tools" - }, true) - local clonedDeps = deps:Clone() - - for _, obj in clonedDeps:GetDescendants() do - if obj:IsA("BaseScript") then - obj.Disabled = false - end - end - for _, obj in clonedDeps:GetChildren() do - obj.Parent = F3X - end - clonedDeps:Destroy() - return F3X - end)(Deps.Assets:FindFirstChild("F3X Deps")) or Variables.F3XCached and Variables.F3XCached:Clone() or require(580330877)() - Variables.F3XCached = Variables.F3XCached or F3X:Clone() - service.New("StringValue", { - Name = `__ADONIS_VARIABLES_{Variables.CodeName}`, - Parent = F3X - }) + return false + end, - for _, v in service.GetPlayers(plr, args[1]) do - local Backpack = v:FindFirstChildOfClass("Backpack") + IsMuted = function(player) + local DoCheck = Admin.DoCheck + for _, v in Settings.Muted do + if DoCheck(player, v) then + return true + end + end - if Backpack then - F3X:Clone().Parent = Backpack - end + for _, v in HTTP.Trello.Mutes do + if DoCheck(player, v) then + return true end + end - F3X:Destroy() + if HTTP.WebPanel.Mutes then + for _, v in HTTP.WebPanel.Mutes do + if DoCheck(player, v) then + return true + end + end + end + end; + + DoCheck = function(pObj, check, banCheck) + local pType = typeof(pObj) + local cType = typeof(check) + + local pUnWrapped = service.UnWrap(pObj) + + local plr: Player = if pType == "userdata" and pObj:IsA("Player") then pObj + elseif pType == "number" then service.Players:GetPlayerByUserId(pObj) + elseif pType == "string" then service.Players:FindFirstChild(pObj) + elseif typeof(pUnWrapped) == "Instance" and pUnWrapped:IsA("Player") then pUnWrapped + elseif pType == "userdata" then service.Players:GetPlayerByUserId(pObj.UserId) + else nil + if not plr then + return false end - }; - Insert = { - Prefix = Settings.Prefix; - Commands = {"insert", "ins"}; - Args = {"id"}; - Description = "Inserts whatever object belongs to the ID you supply, the object must be in the place owner's or Roblox's inventory"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local id = string.lower(args[1]) + if cType == "number" then + return plr.UserId == check + elseif cType == "string" then + if plr.Name == check then + return true + end - for i, v in Variables.InsertList do - if id == string.lower(v.Name)then - id = v.ID - break + local filterName, filterData = string.match(check, "^(.-):(.+)$") + if filterName then + filterName = string.lower(filterName) + else + return false + end + if filterName == "group" then + local groupId = tonumber((string.match(filterData, "^%d+"))) + if groupId then + local plrRank = Admin.GetGroupLevel(plr.UserId, groupId) + local requiredRank,noRank = tonumber((string.match(filterData, "^%d+:(.+)$"))), string.match(filterData,"^%d+$") + if requiredRank then + if requiredRank < 0 then + return plrRank >= math.abs(requiredRank) + else + return plrRank == requiredRank + end + elseif noRank then + return plrRank > 0 + end + end + return false + elseif filterName == "item" then + local itemId = tonumber((string.match(filterData, "^%d+"))) + return itemId and service.CheckAssetOwnership(plr, itemId) + elseif filterName == "gamepass" then + local gamepassId = tonumber((string.match(filterData, "^%d+"))) + return gamepassId and service.CheckPassOwnership(plr, gamepassId) + elseif filterName == "subscription" then + local subscriptionId = string.match(filterData, "^EXP%-%d+$") + return subscriptionId and service.CheckSubscriptionStatus(plr, subscriptionId) + else + local username, userId = string.match(check, "^(.*):(.*)") + if username and userId and (plr.UserId == tonumber(userId) or string.lower(plr.Name) == string.lower(username)) then + return true end - end - for i, v in HTTP.Trello.InsertList do - if id == string.lower(v.Name) then - id = v.ID - break + if not banCheck and type(check) == "string" and not string.find(check, ":") then + local cache = Functions.GetUserIdFromNameAsync(check) + if cache and plr.UserId == cache then + return true + end end end - - local obj = service.Insert(tonumber(id), true) - if obj and plr.Character then - table.insert(Variables.InsertedObjects, obj) - obj.Parent = workspace - pcall(obj.MakeJoints, obj) - obj:PivotTo(plr.Character:GetPivot()) - end - end - }; - - SaveTool = { - Prefix = Settings.Prefix; - Commands = {"addtool", "savetool", "maketool"}; - Args = {"optional player", "optional new tool name"}; - Description = `Saves the equipped tool to the storage so that it can be inserted using {Settings.Prefix}give`; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - local tool = v.Character and v.Character:FindFirstChildWhichIsA("BackpackItem") - if tool then - tool = tool:Clone() - if args[2] then tool.Name = args[2] end - tool.Parent = service.UnWrap(Settings.Storage) - Variables.SavedTools[tool] = service.FormatPlayer(plr) - Functions.Hint(`Added tool: {tool.Name}`, {plr}) - elseif not args[1] then - error("You must have an equipped tool to add to the storage.") + elseif cType == "table" then + local groupId, rank = check.Group, check.Rank + if groupId and rank then + local plrGroupInfo = Admin.GetPlayerGroup(plr, groupId) + if plrGroupInfo then + local plrRank = plrGroupInfo.Rank + return plrRank == rank or (rank < 0 and plrRank >= math.abs(rank)) end end end - }; - - ClearSavedTools = { - Prefix = Settings.Prefix; - Commands = {"clraddedtools", "clearaddedtools", "clearsavedtools", "clrsavedtools"}; - Args = {}; - Description = `Removes any tools in the storage added using {Settings.Prefix}savetool`; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local count = 0 - for tool in Variables.SavedTools do - count += 1 - tool:Destroy() - end - table.clear(Variables.SavedTools) - Functions.Hint(string.format("Cleared %d saved tool%s.", count, count == 1 and "" or "s"), {plr}) - end - }; - - NewTeam = { - Prefix = Settings.Prefix; - Commands = {"newteam", "createteam", "maketeam"}; - Args = {"name", "BrickColor"}; - Filter = true; - Description = "Make a new team with the specified name and color"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local teamName = assert(args[1], "Missing team name (argument #1)") - local teamColor = Functions.ParseBrickColor(args[2]) - - if service.Teams:FindFirstChild(teamName) then - Functions.Hint(string.format("Team '%s' already exists!", teamName), {plr}) - return; - end - - service.New("Team", { - Parent = service.Teams; - Name = teamName; - TeamColor = teamColor; - AutoAssignable = false; - }) - if Settings.CommandFeedback then - Functions.Hint(string.format("Created new team '%s' (%s)", teamName, teamColor.Name), {plr}) - end - end - }; - - RemoveTeam = { - Prefix = Settings.Prefix; - Commands = {"removeteam", "deleteteam"}; - Args = {"name"}; - Description = "Remove the specified team"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.Teams:GetTeams() do - if string.sub(string.lower(v.Name), 1, #args[1]) == string.lower(args[1]) then - local ans = Remote.GetGui(plr, "YesNoPrompt", { Question = `Remove team: '{v.Name}'?` }) - - if ans == "Yes" then - v:Destroy() - return Functions.Hint(`Removed team {v.Name}`, {plr}) - else - return Functions.Hint("Cancelled team removal operation", {plr}) - end - end + + return check == plr + end; + + LevelToList = function(lvl) + local lvl = tonumber(lvl) + if not lvl then return nil end + local listName = Admin.LevelToListName(lvl) + if listName then + local list = Settings.Ranks[listName]; + if list then + return list.Users, listName, list; end end - }; + end; - RestoreMap = { - Prefix = Settings.Prefix; - Commands = {"restoremap", "maprestore", "rmap"}; - Args = {}; - Description = "Restore the map to the the way it was the last time it was backed up"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local plrName = plr and service.FormatPlayer(plr) or "" + LevelToListName = function(lvl) + if lvl > 999 then + return "Place Owner" + elseif lvl == 0 then + return "Players" + end - if not Variables.MapBackup then - error("Cannot restore when there are no backup maps!", 0) - return + --// Check if this is a default rank and if the level matches the default (so stuff like [Trello] Admins doesn't appear in the command list) + for i,v in server.Defaults.Settings.Ranks do + local tRank = Settings.Ranks[i]; + if tRank and tRank.Level == v.Level and v.Level == lvl then + return i end - if Variables.RestoringMap then - error("Map has not been backed up",0) - return + end + + for i,v in Settings.Ranks do + if v.Level == lvl then + return i end - if Variables.BackingupMap then - error("Cannot restore map while backing up map is in process!", 0) - return + end + end; + + UpdateCachedLevel = function(p, data) + local data = data or Core.GetPlayer(p) + local oLevel, oRank = data.AdminLevel, data.AdminRank + local level, rank = Admin.GetUpdatedLevel(p, data) + + data.AdminLevel = level + data.AdminRank = rank + data.LastLevelUpdate = os.time() + + AddLog("Script", { + Text = `Updating cached level for {p.Name}`; + Desc = `Updating the cached admin level for {p.Name}`; + Player = p; + }) + + if Settings.Console and (oLevel ~= level or oRank ~= rank) then + if not Settings.Console_AdminsOnly or (Settings.Console_AdminsOnly and level > 0) then + task.defer(Remote.RefreshGui, p, "Console") + else + task.defer(Remote.RemoveGui, p, "Console") end + end + + return level, rank + end; + + GetLevel = function(p) + local data = Core.GetPlayer(p) + local level = data.AdminLevel + local rank = data.AdminRank + local lastUpdate = data.LastLevelUpdate or 0 + local clients = Remote.Clients + local key = tostring(p.UserId) - Variables.RestoringMap = true - Functions.Hint("Restoring Map...", service.Players:GetPlayers()) - workspace.Gravity = Variables.OriginalGravity + local currentTime = os.time() - for _, obj in workspace:GetChildren() do - if obj.ClassName ~= "Terrain" and not service.Players:GetPlayerFromCharacter(obj) then - obj:Destroy() - service.RunService.Stepped:Wait() + if (not level or not lastUpdate or currentTime - lastUpdate > Admin.AdminLevelCacheTimeout) or lastUpdate > currentTime then + local newLevel, newRank = Admin.UpdateCachedLevel(p, data) + + if clients[key] and level and newLevel and type(p) == "userdata" and p:IsA("Player") then + if newLevel < level then + Functions.Hint(`Your admin level has been reduced to {newLevel} [{newRank or "Unknown"}]`, {p}) + elseif newLevel > level then + Functions.Hint(`Your admin level has been increased to {newLevel} [{newRank or "Unknown"}]`, {p}) end end - local new = Variables.MapBackup:Clone() - for _, obj in new:GetChildren() do - obj.Parent = workspace - if obj:IsA("Model") then - obj:MakeJoints() - end + return newLevel, newRank + end + + return level or 0, rank; + end; + + GetUpdatedLevel = function(p, data) + local checkTable = Admin.CheckTable + local doCheck = Admin.DoCheck + + for _, admin in Admin.SpecialLevels do + if doCheck(p, admin.Player) then + return admin.Level, admin.Rank end - new:Destroy() + end - local Terrain = workspace.Terrain or workspace:FindFirstChildOfClass("Terrain") - if Terrain and Variables.TerrainMapBackup then - Terrain:Clear() - Terrain:PasteRegion(Variables.TerrainMapBackup, Terrain.MaxExtents.Min, true) + local sortedRanks = {} + for rank, data in Settings.Ranks do + table.insert(sortedRanks, { + Rank = rank; + Users = data.Users; + Level = data.Level; + }); + end + + table.sort(sortedRanks, function(t1, t2) + return t1.Level > t2.Level + end) + + local highestLevel = 0 + local highestRank = nil + + for _, data in sortedRanks do + local level = data.Level + if level > highestLevel then + for _, v in data.Users do + if doCheck(p, v) then + highestLevel, highestRank = level, data.Rank + break + end + end end + end - task.wait() + if Admin.IsPlaceOwner(p) and highestLevel < 1000 then + return 1000, "Place Owner" + end - Admin.RunCommand(`{Settings.Prefix}fixlighting`) - Admin.RunCommand(`{Settings.Prefix}respawn`, "all") - Variables.RestoringMap = false - Functions.Hint('Map Restore Complete.',service.Players:GetPlayers()) + return highestLevel, highestRank + end; - Logs:AddLog("Script", { - Text = "Map Restoration Complete", - Desc = `{plrName} has restored the map.`, - }) + IsPlaceOwner = function(p) + if type(p) == "userdata" and p:IsA("Player") then + --// These are my accounts; Lately I've been using my game dev account(698712377) more so I'm adding it so I can debug without having to sign out and back in (it's really a pain) + --// Disable CreatorPowers in settings if you don't trust me. It's not like I lose or gain anything either way. Just re-enable it BEFORE telling me there's an issue with the script so I can go to your place and test it. + if Settings.CreatorPowers and table.find(Variables.DeveloperWhitelist, p.UserId) then + return true + end + + if tonumber(CreatorId) and p.UserId == CreatorId then + return true + end + + if p.UserId == -1 and Variables.IsStudio then --// To account for player emulators in multi-client Studio tests + return true + end end - }; - - ScriptBuilder = { - Prefix = Settings.Prefix; - Commands = {"scriptbuilder", "scriptb", "sb"}; - Args = {"create/remove/edit/close/clear/append/run/stop/list", "localscript/script", "scriptName", "data"}; - Description = "[Deprecated] Script Builder; make a script, then edit it and chat it's code or use :sb append "; - AdminLevel = "Admins"; - Hidden = true; - NoFilter = true; - CrossServerDenied = true; - Function = function(plr: Player, args: {string}) - assert(Settings.CodeExecution, "CodeExecution must be enabled for this command to work") - local sb = Variables.ScriptBuilder[tostring(plr.UserId)] - if not sb then - sb = { - Script = {}; - LocalScript = {}; - Events = {}; + end; + + CheckAdmin = function(p) + return Admin.GetLevel(p) > 0 + end; + + SetLevel = function(p, level, doSave, rankName) + local current, rank = Admin.GetLevel(p) + + if tonumber(level) then + if current >= 1000 then + return false + else + Admin.SpecialLevels[tostring(p.UserId)] = { + Player = p.UserId, + Level = level, + Rank = rankName } - Variables.ScriptBuilder[tostring(plr.UserId)] = sb end + elseif level == "Reset" then + Admin.SpecialLevels[tostring(p.UserId)] = nil + end - local action = string.lower(args[1]) - local class = args[2] or "LocalScript" - local name = args[3] + Admin.UpdateCachedLevel(p) + end; - if string.lower(class) == "script" or string.lower(class) == "s" then - class = "Script" - elseif string.lower(class) == "clientscript" or string.lower(class) == "cs" then - class = "ClientScript" - --elseif string.lower(class) == "localscript" or string.lower(class) == "ls" then - -- class = "LocalScript" - else - class = "LocalScript" + IsTempAdmin = function(p) + local DoCheck = Admin.DoCheck + for i,v in Admin.TempAdmins do + if DoCheck(p,v) then + return true, i end + end + end; - if action == "create" then - assert(args[1] and args[2] and args[3], "Missing arguments") - local code = args[4] or " " + RemoveAdmin = function(p, temp, override) + local current, rank = Admin.GetLevel(p) + local listData = rank and Settings.Ranks[rank] + local listName = listData and rank + local list = listData and listData.Users - if sb[class][name] then - pcall(function() - sb[class][name].Script.Disabled = true - sb[class][name].Script:Destroy() - end) - if sb.ChatEvent then - sb.ChatEvent:Disconnect() - end - end + local isTemp,tempInd = Admin.IsTempAdmin(p) - local wrapped,scr = Core.NewScript(class,code,false,true) + if isTemp then + temp = true + table.remove(Admin.TempAdmins, tempInd) + end - sb[class][name] = { - Wrapped = wrapped; - Script = scr; - } + if override then + temp = false + end - if args[4] then - Functions.Hint(`Created {class} {name} and appended text`, {plr}) - else - Functions.Hint(`Created {class} {name}`, {plr}) - end - elseif action == "edit" then - assert(args[1] and args[2] and args[3], "Missing arguments") - if sb[class][name] then - local scr = sb[class][name].Script - local tab = Core.GetScript(scr) - if scr and tab then - sb[class][name].Event = plr.Chatted:Connect(function(msg) - if string.sub(msg, 1,#(`{Settings.Prefix}sb`)) ~= `{Settings.Prefix}sb` then - tab.Source ..= `\n{msg}` - Functions.Hint(`Appended message to {class} {name}`, {plr}) - end - end) - Functions.Hint(`Now editing {class} {name}; Chats will be appended`, {plr}) - end - else - error(`{class} {name} not found!`) - end - elseif action == "close" then - assert(args[1] and args[2] and args[3], "Missing arguments") - local scr = sb[class][name].Script - local tab = Core.GetScript(scr) - if sb[class][name] then - if sb[class][name].Event then - sb[class][name].Event:Disconnect() - sb[class][name].Event = nil - Functions.Hint(`No longer editing {class} {name}`, {plr}) + if type(p) == "userdata" then + Admin.SetLevel(p, 0) + end + + if list then + local DoCheck = Admin.DoCheck + for ind,check in list do + if DoCheck(p, check) and not (type(check) == "string" and (string.match(check,"^Group:") or string.match(check,"^Item:"))) then + table.remove(list, ind) + + if not temp and Settings.SaveAdmins then + TrackTask("Thread: RemoveAdmin", Core.DoSave, false, { + Type = "TableRemove"; + Table = {"Settings", "Ranks", listName, "Users"}; + Value = check; + }) end - else - error(`{class} {name} not found!`) end - elseif action == "clear" then - assert(args[1] and args[2] and args[3], "Missing arguments") - local scr = sb[class][name].Script - local tab = Core.GetScript(scr) - if scr and tab then - tab.Source = " " - Functions.Hint(`Cleared {class} {name}`, {plr}) - else - error(`{class} {name} not found!`) + end + end + + Admin.UpdateCachedLevel(p) + end; + + AddAdmin = function(p, level, temp) + local current, rank = Admin.GetLevel(p) + local list = rank and Settings.Ranks[rank] + local levelName, newRank, newList + + if type(level) == "string" then + local newRank = Settings.Ranks[level] + levelName = newRank and level + newList = newRank and newRank.Users + level = (newRank and newRank.Level) or Admin.StringToComLevel(levelName) or level + else + local nL, nLN = Admin.LevelToList(level) + levelName = nLN + newRank = nLN + newList = nL + end + + Admin.RemoveAdmin(p, temp) + Admin.SetLevel(p, level, nil, levelName) + + if temp then + table.insert(Admin.TempAdmins, p) + end + + if list and type(list) == "table" then + local index,value + + for ind,ent in list do + if (type(ent)=="number" or type(ent)=="string") and (ent==p.UserId or string.lower(ent)==string.lower(p.Name) or string.lower(ent)==string.lower(`{p.Name}:{p.UserId}`)) then + index = ind + value = ent end - elseif action == "remove" then - assert(args[1] and args[2] and args[3], "Missing arguments") - if sb[class][name] then - pcall(function() - sb[class][name].Script.Disabled = true - sb[class][name].Script:Destroy() - end) - if sb.ChatEvent then - sb.ChatEvent:Disconnect() - sb.ChatEvent = nil - end - sb[class][name] = nil - else - error(`{class} {name} not found!`) + end + + if index and value then + table.remove(list, index) + end + end + + local value = `{p.Name}:{p.UserId}` + + if newList then + table.insert(newList, value) + + if Settings.SaveAdmins and levelName and not temp then + TrackTask("Thread: SaveAdmin", Core.DoSave, false, { + Type = "TableAdd"; + Table = {"Settings", "Ranks", levelName, "Users"}; + Value = value + }) + end + end + + Admin.UpdateCachedLevel(p) + end; + + CheckDonor = function(p) + local key = tostring(p.UserId) + if Variables.CachedDonors[key] then + return true + else + local pGroup = Admin.GetPlayerGroup(p, 886423) + for _, pass in Variables.DonorPass do + if p.Parent ~= service.Players then + return false end - elseif action == "append" then - assert(args[1] and args[2] and args[3] and args[4], "Missing arguments") - if sb[class][name] then - local scr = sb[class][name].Script - local tab = Core.GetScript(scr) - if scr and tab then - tab.Source ..= `\n{args[4]}` - Functions.Hint(`Appended message to {class} {name}`, {plr}) - end - else - error(`{class} {name} not found!`) + + local ran, ret + if type(pass) == "number" then + ran, ret = pcall(service.MarketPlace.UserOwnsGamePassAsync, service.MarketPlace, p.UserId, pass) + elseif type(pass) == "string" and tonumber(pass) then + ran, ret = pcall(service.MarketPlace.PlayerOwnsAsset, service.MarketPlace, p, tonumber(pass)) end - elseif action == "run" then - assert(args[1] and args[2] and args[3], "Missing arguments") - if sb[class][name] then - if class == "LocalScript" then - sb[class][name].Script.Parent = plr:FindFirstChildOfClass("Backpack") - else - sb[class][name].Script.Parent = service.ServerScriptService - end - sb[class][name].Script.Disabled = true - task.wait(0.03) - sb[class][name].Script.Disabled = false - Functions.Hint(`Running {class} {name}`, {plr}) - else - error(`{class} {name} not found!`) + + if (ran and ret) or (pGroup and pGroup.Rank >= 10) then --// Complimentary donor access is given to Adonis contributors & developers. + Variables.CachedDonors[key] = os.time() + return true end - elseif action == "stop" then - assert(args[1] and args[2] and args[3], "Missing arguments") - if sb[class][name] then - sb[class][name].Script.Disabled = true - Functions.Hint(`Stopped {class} {name}`, {plr}) + end + end + end; + + CheckBan = function(p) + local doCheck = Admin.DoCheck + local banCheck = Admin.DoBanCheck + + for ind, admin in Settings.Banned do + if (type(admin) == "table" and ((admin.UserId and doCheck(p, admin.UserId, true)) or (admin.Name and not admin.UserId and doCheck(p, admin.Name, true)))) or doCheck(p, admin, true) then + return true, (type(admin) == "table" and admin.Reason) + end + end + + for ind, ban in Core.Variables.TimeBans do + if p.UserId == ban.UserId then + if ban.EndTime-os.time() <= 0 then + table.remove(Core.Variables.TimeBans, ind) else - error(`{class} {name} not found!`) - end - elseif action == "list" then - local tab = {} - for i, v in sb.Script do - table.insert(tab, {Text = `Script: {i}`, Desc = `Running: {v.Script.Disabled}`}) + return true, `\n {ban.Reason or "(No reason provided.)"}\n | Banned until {service.FormatTime(ban.EndTime, {WithWrittenDate = true})}` end + end + end - for i, v in sb.LocalScript do - table.insert(tab, {Text = `LocalScript: {i}`, Desc = `Running: {v.Script.Disabled}`}) - end + for ind, admin in HTTP.Trello.Bans do + local name = type(admin) == "table" and admin.Name or admin + if doCheck(p, name) or banCheck(p, name) then + return true, (type(admin) == "table" and admin.Reason and service.Filter(admin.Reason, p, p)) + end + end - Remote.MakeGui(plr, "List", {Title = "SB Scripts", Table = tab}) - end - end - }; - - MakeScript = { - Prefix = Settings.Prefix; - Commands = {"s", "ss", "serverscript", "sscript", "script", "makescript"}; - Args = {"code"}; - Description = "Executes the given Lua code on the server"; - AdminLevel = "Admins"; - NoFilter = true; - CrossServerDenied = true; - Function = function(plr: Player, args: {string}) - assert(Settings.CodeExecution, "CodeExecution config must be enabled for this command to work") - local bytecode = Core.Bytecode(assert(args[1], "Missing Script code (argument #2)")) - assert(string.find(bytecode, "\27Lua"), `Script unable to be created: {string.gsub(bytecode, "Loadstring%.LuaX:%d+:", "")}`) - - local cl = Core.NewScript("Script", args[1], true) - cl.Name = "[Adonis] Script" - cl.Parent = service.ServerScriptService - task.wait() - cl.Disabled = false - Functions.Hint("Ran Script", {plr}) - end - }; - - MakeLocalScript = { - Prefix = Settings.Prefix; - Commands = {"ls", "localscript", "lscript"}; - Args = {"code"}; - Description = "Executes the given code on your client"; - AdminLevel = "Admins"; - NoFilter = true; - Function = function(plr: Player, args: {string}) - Commands.LoadLocalScript.Function(plr, {`@{plr.Name}`, args[1]}) - end - }; - - LoadLocalScript = { - Prefix = Settings.Prefix; - Commands = {"cs", "cscript", "clientscript"}; - Args = {"player", "code"}; - Description = "Executes the given code on the client of the target player(s)"; - AdminLevel = "Admins"; - NoFilter = true; - Function = function(plr: Player, args: {string}) - assert(args[2], "Missing LocalScript code (argument #2)") - - local bytecode = Core.Bytecode(args[2]) - assert(string.find(bytecode, "\27Lua"), `LocalScript unable to be created: {string.gsub(bytecode, "Loadstring%.LuaX:%d+:", "")}`) - - local new = Core.NewScript("LocalScript", `script.Parent = game:GetService('Players').LocalPlayer.PlayerScripts; {args[2]}`, true) - local function cloneScript(targetPlayer) - local playerName = if targetPlayer == plr then "your client" else service.FormatPlayer(targetPlayer) - - local backpack = targetPlayer:FindFirstChildOfClass("Backpack") - if not backpack then - Functions.Hint(`Couldn't run LocalScript on {playerName} (Backpack missing?)`, {plr}) - return + if HTTP.WebPanel.Bans then + for ind, admin in HTTP.WebPanel.Bans do + if doCheck(p, admin) or banCheck(p, admin) then + return true, (type(admin) == "table" and admin.Reason) end + end + end + end; + + AddBan = function(p, reason, doSave, moderator, banType) + local value = { + Name = p.Name; + UserId = p.UserId; + Reason = reason; + Moderator = if moderator then service.FormatPlayer(moderator) else "%SYSTEM%"; + BanType = banType + } + + table.insert(Settings.Banned, value) + + if doSave then + Core.DoSave({ + Type = "TableAdd"; + Table = "Banned"; + Value = value; + }) - local cl = new:Clone() - cl.Name = "[Adonis] LocalScript" - cl.Disabled = true - cl.Parent = targetPlayer:FindFirstChildOfClass("Backpack") - task.wait(.1) - cl.Disabled = false - Functions.Hint(`Ran LocalScript on {playerName}`, {plr}) - end - - for i, v in service.GetPlayers(plr, args[1]) do - task.spawn(cloneScript, v) - end - end - }; - - CreateStarterScript = { - Prefix = Settings.Prefix; - Commands = {"starterscript", "clientstarterscript", "starterclientscript", "createstarterscript"}; - Args = {"name", "code"}; - Description = "Executes the given code on everyone's client upon respawn"; - AdminLevel = "Admins"; - NoFilter = true; - Function = function(plr: Player, args: {string}) - assert(args[1], "Missing starter script name (argument #1)") - assert(args[2], "Missing LocalScript code (argument #2)") - - local bytecode = Core.Bytecode(args[2]) - assert(string.find(bytecode, "\27Lua"), `LocalScript unable to be created: {string.gsub(bytecode, "Loadstring%.LuaX:%d+:", "")}`) - - local new = Core.NewScript("LocalScript", args[2], true) - new.Name = `[Adonis] {args[1]}` - new.Parent = service.StarterGui - new.Disabled = false - Functions.Hint("Created starter script", {plr}) - end - }; - - - StarterScripts = { - Prefix = Settings.Prefix; - Commands = {"starterscripts", "clientstarterscripts", "starterclientscripts"}; - Args = {}; - Description = "Show existing starterscripts"; - AdminLevel = "Admins"; - NoFilter = true; - Function = function(plr: Player, args: {string}) - local result = {} - - for _,v : Instance in service.StarterGui:GetChildren() do - if v:IsA("LocalScript") and v.Name:find("[Adonis]") then - table.insert(result, (v.Name:gsub("%[Adonis%] ", ""))) - end + Core.CrossServer("RemovePlayer", p.Name, Variables.BanMessage, value.Reason or "No reason provided") + end + + if type(p) ~= "table" then + if not service.Players:FindFirstChild(p.Name) then + Remote.Send(p,'Function','KillClient') + else + if p then pcall(function() p:Kick(`{Variables.BanMessage} | Reason: {value.Reason or "No reason provided"}`) end) end end + end + service.Events.PlayerBanned:Fire(p, reason, doSave, moderator) + end; - Remote.MakeGui(plr,"List",{ - Title = "Starter Scripts"; - Tab = result; - }) + AddTimeBan = function(p : Player | {[string]: any}, duration: number, reason: string, moderator: Player?) + local value = { + Name = p.Name; + UserId = p.UserId; + EndTime = os.time() + tonumber(duration); + Reason = reason; + Moderator = if moderator then service.FormatPlayer(moderator) else "%SYSTEM%"; + } + + table.insert(Core.Variables.TimeBans, value) + + Core.DoSave({ + Type = "TableAdd"; + Table = {"Core", "Variables", "TimeBans"}; + Value = value; + }) + + Core.CrossServer("RemovePlayer", p.Name, Variables.BanMessage, value.Reason or "No reason provided") + + if type(p) ~= "table" then + if not service.Players:FindFirstChild(p.Name) then + Remote.Send(p, "Function", "KillClient") + else + if p then pcall(function() p:Kick(`{Variables.BanMessage} | Reason: {value.Reason or "No reason provided"}`) end) end + end end - }; + service.Events.PlayerBanned:Fire(p, reason, true, moderator) + end, - RemoveStarterScript = { - Prefix = Settings.Prefix; - Commands = {"removestarterscript", "removeclientstarterscripts", "removestarterclientscripts", "unstarterscript"}; - Args = {"name"}; - Description = "Remove a starterscript"; - AdminLevel = "Admins"; - NoFilter = true; - Function = function(plr: Player, args: {string}) - assert(args[1], "No starterscript name provided!") + DoBanCheck = function(name: string | number | Instance, check: string | {[string]: any}) + local id = type(name) == "number" and name - for _,v : Instance in service.StarterGui:GetChildren() do - if v:IsA("LocalScript") and v.Name:find("[Adonis]") then - if v.Name:gsub("%[Adonis%] ", ""):lower() == args[1]:lower() or args[1]:lower() == "all" then - service.Delete(v) - Functions.Hint("Removed starter script "..v.Name, {plr}) - end + if type(name) == "userdata" and name:IsA("Player") then + id = name.UserId + name = name.Name + end + + if type(check) == "table" then + if type(name) == "string" and check.Name and string.lower(check.Name) == string.lower(name) then + return true + elseif id and check.UserId and check.UserId == id then + return true + end + elseif type(check) == "string" then + local cName, cId = string.match(check, "(.*):(.*)") + if not cName and cId then cName = check end + + if cName then + if string.lower(cName) == string.lower(name) then + return true + elseif id and cId and id == tonumber(cId) then + return true end + else + return string.lower(tostring(check)) == string.lower(tostring(name)) end end - }; - - Note = { - Prefix = Settings.Prefix; - Commands = {"note", "writenote", "makenote"}; - Args = {"player", "note"}; - Filter = true; - Description = "Makes a note on the target player(s) that says "; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[2], "Missing note (argument #2)") - for _, v in service.GetPlayers(plr, args[1]) do - local PlayerData = Core.GetPlayer(v) - if not PlayerData.AdminNotes then PlayerData.AdminNotes = {} end - table.insert(PlayerData.AdminNotes, args[2]) - Functions.Hint(`Added {service.FormatPlayer(v)} Note {args[2]}`, {plr}) - Core.SavePlayer(v, PlayerData) - end - end - }; - - DeleteNote = { - Prefix = Settings.Prefix; - Commands = {"removenote", "remnote", "deletenote", "clearnote"}; - Args = {"player", "note (specify 'all' to delete all notes)"}; - Description = "Removes a note on the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[2], "Missing note (argument #2)") - for _, v in service.GetPlayers(plr, args[1]) do - local PlayerData = Core.GetPlayer(v) - if PlayerData.AdminNotes then - if string.lower(args[2]) == "all" then - PlayerData.AdminNotes = {} - else - for k, m in PlayerData.AdminNotes do - if string.sub(string.lower(m), 1, #args[2]) == string.lower(args[2]) then - Functions.Hint(`Removed {service.FormatPlayer(v)} Note {m}`, {plr}) - table.remove(PlayerData.AdminNotes, k) - end + + return false + end; + + RemoveBan = function(name, doSave) + local ret + for i,v in Settings.Banned do + if Admin.DoBanCheck(name, v) then + ret = table.remove(Settings.Banned, i) + if doSave then + Core.DoSave({ + Type = "TableRemove"; + Table = "Banned"; + Value = ret; + LaxCheck = true; + }) + end + end + end + return ret + end; + + RemoveTimeBan = function(name : string | number | Instance) + local ret + for i,v in Core.Variables.TimeBans do + if Admin.DoBanCheck(name, v) then + table.remove(Core.Variables.TimeBans, i) + ret = v + Core.DoSave({ + Type = "TableRemove"; + Table = {"Core", "Variables", "TimeBans"}; + Value = v; + LaxCheck = true; + }) + end + end + return ret + end, + + RunCommand = function(coma: string, ...) + local _, com = Admin.GetCommand(coma) + if com then + local cmdArgs = com.Args or com.Arguments + local args = Admin.GetArgs(coma, #cmdArgs, ...) + + TrackTask(`Command: {coma}`, com.Function, function(err) + warn(`Encountered an error while running a command: {coma}\n{err}\n{debug.traceback()}`) + end, false, args) + end + end; + + RunCommandAsPlayer = function(coma, plr, ...) + local ind, com = Admin.GetCommand(coma) + if com then + local adminLvl = Admin.GetLevel(plr) + + local cmdArgs = com.Args or com.Arguments + local args = Admin.GetArgs(coma, #cmdArgs, ...) + local ran, error = TrackTask( + `{plr.Name}: {coma}`, + com.Function, + function(err) + err = string.match(err, ":(.+)$") or "Unknown error" + Remote.MakeGui(plr, "Output", { + Title = "Error", + Message = error, + Color = Color3.new(1, 0, 0), + }) + warn(`Encountered an error while running a command: {coma}\n{err}\n{debug.traceback()}`) + end, + plr, + args, + { + PlayerData = { + Player = plr, + Level = adminLvl, + isDonor = ((Settings.DonorCommands or com.AllowDonors) and Admin.CheckDonor(plr)) or false, + }, + } + ) + end + end; + + RunCommandAsNonAdmin = function(coma, plr, ...) + local ind, com = Admin.GetCommand(coma) + if com and com.AdminLevel == 0 then + local cmdArgs = com.Args or com.Arguments + local args = Admin.GetArgs(coma, #cmdArgs, ...) + local _, error = TrackTask( + `{plr.Name}: {coma}`, + com.Function, + function(err) + err = string.match(err, ":(.+)$") or "Unknown error" + Remote.MakeGui(plr, "Output", { + Title = "", + Message = error, + Color = Color3.new(1, 0, 0), + }) + warn(`Encountered an error while running a command: {coma}\n{err}\n{debug.traceback()}`) + end, + plr, + args, + { PlayerData = { + Player = plr, + Level = 0, + isDonor = false, + } } + ) + end + end; + + CacheCommands = function() + local tempTable = {} + local tempPrefix = {} + for ind, data in Commands do + if type(data) == "table" then + for i,cmd in data.Commands do + if type(data.Prefix) ~= "table" and data.Prefix == "" then Admin.BlankPrefix = true end + if type(data.Prefix) == "table" then + for _,p in data.Prefix do + tempPrefix[p] = true + tempTable[string.lower(p..cmd)] = ind end + else + tempPrefix[data.Prefix] = true + tempTable[string.lower(data.Prefix..cmd)] = ind end - Core.SavePlayer(v, PlayerData) end end end - }; - - ShowNotes = { - Prefix = Settings.Prefix; - Commands = {"notes", "viewnotes"}; - Args = {"player"}; - Description = "Views notes on the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - local PlayerData = Core.GetPlayer(v) - local notes = PlayerData.AdminNotes - if not notes then - Functions.Hint(`No notes found on {service.FormatPlayer(v)}`, {plr}) - continue + + Admin.PrefixCache = tempPrefix + Admin.CommandCache = tempTable + + if Variables.ChatCreateRobloxCommands then + -- // Support for commands to be ran via TextChat + task.spawn(function() + local container = service.TextChatService.ChatVersion == Enum.ChatVersion.TextChatService and service.TextChatService:WaitForChild("TextChatCommands", 9e9) + + if container then + for _, v in container:GetChildren() do + if string.sub(v.Name, 1, 7) == "Adonis_" then + v:Destroy() + end + end + + local blacklistedCommands = {} + + for _, v in container:GetDescendants() do + if v:IsA("TextChatCommand") then + blacklistedCommands[v.PrimaryAlias] = true + blacklistedCommands[v.SecondaryAlias] = true + end + end + + for name, data in Commands do + local command1, command2 = nil, nil + + if type(data) ~= "table" or data.Hidden then + continue + end + + for _, v in data.Commands do + if type(data.Prefix) == "table" then + for _, p in data.Prefix do + if not blacklistedCommands["/"..p..v] then + if not command1 then + command1 = "/"..p..v + else + command2 = "/"..p..v + end + end + end + else + if not blacklistedCommands["/"..data.Prefix..v] then + if not command1 then + command1 = "/"..data.Prefix..v + else + command2 = "/"..data.Prefix..v + end + end + + end + + end + + if command1 then + local command = service.New("TextChatCommand") + + command.Name = "Adonis_"..name + command.PrimaryAlias = command1 + command.SecondaryAlias = command2 or "" + command.Archivable = false + command:SetAttribute("AdminLevel", tonumber(data.AdminLevel) or data.AdminLevel or nil) + command.Parent = container + command.Triggered:Connect(function(textSource, text) + local player = service.Players:GetPlayerByUserId(textSource.UserId) + + if player then + Process.Command(player, string.sub(text, 2)) + end + end) + end + end end - Remote.MakeGui(plr, "List", {Title = service.FormatPlayer(v), Table = notes}) - end - end - }; - - LoopKill = { - Prefix = Settings.Prefix; - Commands = {"loopkill"}; - Args = {"player", "num (optional)"}; - Description = "Repeatedly kills the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local num = tonumber(args[2]) or 9999 - - for _, v in service.GetPlayers(plr, args[1]) do - service.StopLoop(`{v.UserId}LOOPKILL`) - local count = 0 - Routine(service.StartLoop, `{v.UserId}LOOPKILL`, 3, function() - local hum = v.Character and v.Character:FindFirstChildOfClass("Humanoid") - if hum and hum.Health > 0 then - hum.Health = 0 - count += 1 + end) + end + end; + + GetCommand = function(Command) + if Admin.PrefixCache[string.sub(Command, 1, 1)] or Admin.BlankPrefix then + local matched + matched = if string.find(Command, Settings.SplitKey) then + string.match(Command, `^(%S+){Settings.SplitKey}`) + else string.match(Command, "^(%S+)") + + if matched then + local found = Admin.CommandCache[string.lower(matched)] + if found then + local real = Commands[found] + if real then + return found,real,matched end - if count == num then - service.StopLoop(`{v.UserId}LOOPKILL`) + end + end + end + end; + + FindCommands = function(Command) + local prefixChar = string.sub(Command, 1, 1) + local checkPrefix = Admin.PrefixCache[prefixChar] and prefixChar + local matched + + if checkPrefix then + Command = string.sub(Command, 2) + end + + if string.find(Command, Settings.SplitKey) then + matched = string.match(Command, `^(%S+){Settings.SplitKey}`) + else + matched = string.match(Command, "^(%S+)") + end + + if matched then + local foundCmds = {} + matched = string.lower(matched) + + for ind,cmd in Commands do + if type(cmd) == "table" and ((checkPrefix and prefixChar == cmd.Prefix) or not checkPrefix) then + for _, alias in cmd.Commands do + if string.lower(alias) == matched then + foundCmds[ind] = cmd + break + end end - end) + end end + + return foundCmds end - }; + end; - UnLoopKill = { - Prefix = Settings.Prefix; - Commands = {"unloopkill"}; - Args = {"player"}; - Description = "Un-Loop Kill"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - service.StopLoop(`{v.UserId}LOOPKILL`) + SetPermission = function(comString, newLevel) + local cmds = Admin.FindCommands(comString) + if cmds then + for ind, cmd in cmds do + cmd.AdminLevel = newLevel end end - }; + end; - Lag = { - Prefix = Settings.Prefix; - Commands = {"lag", "fpslag"}; - Args = {"player"}; - Description = "Makes the target player(s)'s FPS drop"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - for _, v in service.GetPlayers(plr, args[1]) do - if Admin.CheckAuthority(plr, v, "lag") then - Remote.Send(v, "Function", "SetFPS", 5.6) - end + FormatCommandArguments = function(command) + local text = table.create(#command.Args) + for i, arg in command.Args do + text[i] = `<{arg}>` + end + return table.concat(text, Settings.SplitKey) + end; + + FormatCommand = function(command, cmdn) + return table.concat({ + (if type(command.Prefix) == "table" then command.Prefix[1] else command.Prefix or ""), + tostring(command.Commands[cmdn or 1]), + #command.Args > 0 and Settings.SplitKey or "", + #command.Args > 0 and Admin.FormatCommandArguments(command) or "" + }) + end; + + FormatCommandAdminLevel = function(command) + local levels = if type(command.AdminLevel) == "table" + then table.clone(command.AdminLevel) + else {command.AdminLevel} + local permissionDesc = table.create(#levels) + + for i, lvl in levels do + if type(lvl) == "number" then + local list, name, data = Admin.LevelToList(lvl) + permissionDesc[i] = `{name or "No Rank"}; Level {lvl}` + elseif type(lvl) == "string" then + local numLvl = Admin.StringToComLevel(lvl) + permissionDesc[i] = `{lvl}; Level {numLvl or "Unknown"}` + else + permissionDesc[i] = "N/A" end end - }; - UnLag = { - Prefix = Settings.Prefix; - Commands = {"unlag", "unfpslag"}; - Args = {"player"}; - Description = "Un-Lag"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - Remote.Send(v, "Function", "RestoreFPS") + return table.concat(permissionDesc, ", ") + end; + + CheckTable = function(p, tab) + local doCheck = Admin.DoCheck + for i,v in tab do + if doCheck(p, v) then + return true end end - }; + end; + + --// Make it so you can't accidentally overwrite certain existing commands... resulting in being unable to add/edit/remove aliases (and other stuff) + CheckAliasBlacklist = function(alias) + local playerPrefix = Settings.PlayerPrefix; + local prefix = Settings.Prefix + local blacklist = { + [`{playerPrefix}alias`] = true; + [`{playerPrefix}newalias`] = true; + [`{playerPrefix}removealias`] = true; + [`{playerPrefix}client`] = true; + [`{playerPrefix}userpanel`] = true; + [":adonissettings"] = true; + } + --return Admin.CommandCache[alias:lower()] --// Alternatively, we could make it so you can't overwrite ANY existing commands... + return blacklist[alias]; + end; + + GetArgs = function(msg, num, ...) + local newArgs = table.pack(...) + local args = Functions.Split(string.match(msg, `^.-{Settings.SplitKey}(.+)`) or "", Settings.SplitKey, num) or table.create(newArgs.n) + for i = 1, newArgs.n do + table.insert(args, newArgs[i]) + end + return args + end; - Crash = { - Prefix = Settings.Prefix; - Commands = {"crash"}; - Args = {"player"}; - Description = "Crashes the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - for _, v in service.GetPlayers(plr, args[1], { - IsKicking = true; - NoFakePlayer = false; - }) - do - if Admin.CheckAuthority(plr, v, "crash") then - Remote.Send(v, "Function", "Crash") + AliasFormat = function(aliases, msg) + local foundPlayerAlias = false --// Check if there's a player-defined alias first then otherwise check settings aliases + + local CheckAliasBlacklist, SanitizePattern = Admin.CheckAliasBlacklist, service.SanitizePattern + + if aliases then + for alias, cmd in aliases do + local tAlias = stripArgPlaceholders(alias) + if not Admin.CheckAliasBlacklist(tAlias) then + local escAlias = SanitizePattern(tAlias) + --// Ignore any "empty" aliases, aka aliases that would basically match any command + if string.len(Functions.Trim(escAlias)) == 0 then + continue + end + local trimmedMsg = Functions.Trim(msg) + --// Use Adonis split to better support various characters that string.split can't handle properly + local aliasCharacters = Functions.Split(trimmedMsg, Settings.SplitKey) + --// Matching an alias can result in an infinite loop like running !fire with the alias !f, it will infinitely run the !f alias + --// If you have an alias !f + if escAlias == aliasCharacters[1] or string.match(trimmedMsg, `%s{escAlias}`) then + msg = FormatAliasArgs(alias, cmd, msg) + end end end end - }; - HardCrash = { - Prefix = Settings.Prefix; - Commands = {"hardcrash"}; - Args = {"player"}; - Description = "Hard-crashes the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - for _, v in service.GetPlayers(plr, args[1], { - IsKicking = true; - NoFakePlayer = false; - }) - do - if Admin.CheckAuthority(plr, v, "hard-crash") then - Remote.Send(v, "Function", "HardCrash") + for alias, cmd in Variables.Aliases do + local tAlias = stripArgPlaceholders(alias) + if not CheckAliasBlacklist(tAlias) then + local escAlias = SanitizePattern(tAlias) + if string.match(msg, `^{escAlias}`) or string.match(msg, `%s{escAlias}`) then + msg = FormatAliasArgs(alias, cmd, msg) end end end - }; - RAMCrash = { - Prefix = Settings.Prefix; - Commands = {"ramcrash", "memcrash"}; - Args = {"player"}; - Description = "RAM-crashes the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - for _, v in service.GetPlayers(plr, args[1], { - IsKicking = true; - NoFakePlayer = false; - }) - do - if Admin.CheckAuthority(plr, v, "RAM-crash") then - Remote.Send(v, "Function", "RAMCrash") + return msg + end; + + StringToComLevel = function(str) + local strType = type(str) + if strType == "string" and string.lower(str) == "players" then + return 0 + end + if strType == "number" then + return str + end + + local lvl = Settings.Ranks[str] + return (lvl and lvl.Level) or tonumber(str) + end; + + CheckComLevel = function(plrAdminLevel, comLevel) + if type(comLevel) == "string" then + comLevel = Admin.StringToComLevel(comLevel) + elseif type(comLevel) == "table" then + for _, level in comLevel do + if Admin.CheckComLevel(plrAdminLevel, level) then + return true end end + return false end - }; - GPUCrash = { - Prefix = Settings.Prefix; - Commands = {"gpucrash"}; - Args = {"player"}; - Description = "GPU crashes the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - for _, v in service.GetPlayers(plr, args[1], { - IsKicking = true; - NoFakePlayer = false; - }) - do - if Admin.CheckAuthority(plr, v, "GPU-crash") then - Remote.Send(v, "Function", "GPUCrash") - end + return type(comLevel) == "number" and plrAdminLevel >= comLevel + end; + + IsBlacklisted = function(p) + local CheckTable = Admin.CheckTable + for _, list in Variables.Blacklist.Lists do + if CheckTable(p, list) then + return true end end - }; + end; - CustomKick = { - Prefix = Settings.Prefix; - Commands = {"ckick", "customkick", "customcrash"}; - Args = {"player", "title", "message"}; - Description = "Disconnects (crashes) the target player with a custom Roblox dialog"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[3], "Argument(s) missing or nil") + CheckPermission = function(pDat, cmd, ignoreCooldown, opts) + opts = opts or {} - local title = service.BroadcastFilter(args[2], plr) - assert(title == args[2], "Title was filtered: "..title) + local adminLevel = pDat.Level + local comLevel = cmd.AdminLevel - local msg = service.BroadcastFilter(args[3], plr) - assert(msg == args[3], "Message was filtered: "..msg) + if cmd.Disabled then + return false, "This command has been disabled." + end - for _, v in service.GetPlayers(plr, args[1], { - IsKicking = true; - NoFakePlayer = false; - }) - do - if not Admin.CheckAuthority(plr, v, "custom-kick") then - continue - end + if Variables.IsStudio and cmd.NoStudio then + return false, "This command cannot be used in Roblox Studio." + end - local plrgui = v:FindFirstChildOfClass("PlayerGui") - if not plrgui then - Remote.MakeGui(plr, "Output", { - Message = `Failed to custom-kick {service.FormatPlayer(v)} (PlayerGui not found)`; - }) - continue - end + if opts.CrossServer and cmd.CrossServerDenied then -- Ignore when disabled then + return false, "This command may not be run across servers (cross-server-blacklisted)." + end - local promptGui = Deps.Assets.RobloxPromptGui:Clone() - promptGui.promptOverlay.ErrorPrompt.TitleFrame.ErrorTitle.Text = title - promptGui.promptOverlay.ErrorPrompt.MessageArea.ErrorFrame.ErrorMessage.Text = msg - promptGui.Parent = plrgui + if cmd.CrossServer and not Settings.CrossServerCommands then + return false, "This command has been disabled due to CrossServerCommands being disabled" + end - Remote.Send(v, "Function", "CustomKick") - task.delay(5, function() - if v.Parent == service.Players then - -- make sure they're really kicked - v:Kick("Unexpected Error") - end - end) - Functions.Hint(`Custom-kicking {service.FormatPlayer(v)}`, {plr}) - end - end - }; - - Shutdown = { - Prefix = Settings.Prefix; - Commands = {"shutdown"}; - Args = {"reason"}; - Description = "Shuts the server down"; - Filter = true; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - if Core.DataStore then - Core.UpdateData("ShutdownLogs", function(logs) - table.insert(logs, 1, { - User = plr and plr.Name or "[Server]", - Time = os.time(), - Reason = args[1] or "N/A" - }) + if Admin.IsPlaceOwner(pDat.Player) or adminLevel >= Settings.Ranks.Creators.Level then + return true, nil + end - local nlogs = #logs - if nlogs > Logs.OldCommandLogsLimit then - table.remove(logs, nlogs) - end + if Admin.IsBlacklisted(pDat.Player) then + return false, "You are blacklisted from running commands." + end - return logs - end) - end + if (comLevel == 0 or comLevel == "Players") and adminLevel <= 0 and not Settings.PlayerCommands then + return false, "Player commands are disabled in this game." + end - Functions.Shutdown(args[1]) + if cmd.Fun and not Settings.FunCommands then + return false, "Fun commands are disabled in this game." end - }; - ServerBan = { - Prefix = Settings.Prefix; - Commands = {"serverban", "ban"}; - Args = {"player/user", "reason"}; - Description = "Bans the target player(s) from the server"; - AdminLevel = "Admins"; - Filter = true; - Function = function(plr: Player, args: {string}, data: {any}) - local reason = args[2] or "No reason provided" - for _, v in service.GetPlayers(plr, args[1], { - IsKicking = true; - NoFakePlayer = false; - }) - do - if Admin.CheckAuthority(plr, v, "server-ban", false) then - Admin.AddBan(v, reason, false, plr, "Server") - Functions.LogAdminAction(plr, "Server Ban", v.Name, `Reason: {reason}`) - Functions.Hint(`Server-banned {service.FormatPlayer(v, true)}`, {plr}) + if opts.Chat and cmd.Chattable == false then + return false, "This command is not permitted as chat message (non-chattable command)." + end + + local permAllowed = (cmd.Donors and (pDat.isDonor and (Settings.DonorCommands or cmd.AllowDonors))) or (cmd.Agent and HTTP.Trello.CheckAgent) and HTTP.Trello.CheckAgent(pDat.Player) + or Admin.CheckComLevel(adminLevel, comLevel) + + if permAllowed and not ignoreCooldown and type(pDat.Player) == "userdata" then + local playerCooldown = tonumber(cmd.PlayerCooldown) + local serverCooldown = tonumber(cmd.ServerCooldown) + local crossCooldown = tonumber(cmd.CrossCooldown) + + local cmdFullName = cmd._fullName or (function() + local aliases = cmd.Aliases or cmd.Commands or {} + cmd._fullName = `{cmd.Prefix}{aliases[1] or `{service.HttpService:GenerateGUID(false)}-RANDOM_COMMAND`}` + return cmd._fullName + end)() + + local pCooldown_Cache = cmd._playerCooldownCache or (function() + local tab = {} + cmd._playerCooldownCache = tab + return tab + end)() + + local sCooldown_Cache = cmd._serverCooldownCache or (function() + local tab = {} + cmd._serverCooldownCache = tab + return tab + end)() + + local crossCooldown_Cache = cmd._crossCooldownCache or (function() + local tab = {} + cmd._crossCooldownCache = tab + return tab + end)() + + local cooldownIndex = tostring(pDat.Player.UserId) + local pCooldown_playerCache = pCooldown_Cache[cooldownIndex] + local sCooldown_playerCache = sCooldown_Cache[cooldownIndex] + + if playerCooldown and pCooldown_playerCache then + local secsTillPass = os.clock() - pCooldown_playerCache + if secsTillPass < playerCooldown then + return false, string.format("[PlayerCooldown] You must wait %.0f seconds to run the command.", playerCooldown - secsTillPass) end end - end - }; - UnBan = { - Prefix = Settings.Prefix; - Commands = {"unserverban", "unban"}; - Args = {"user"}; - Description = "Unbans the target user(s) from the server"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, assert(args[1], "Missing user (argument #1)"), { - UseFakePlayer = true; - }) - do - if Admin.RemoveBan(v) then - Functions.LogAdminAction(plr, "Unban", v.Name, "User has been unbanned.") - Functions.Hint(`{service.FormatPlayer(v, true)} has been unbanned`, {plr}) - else - Functions.Hint(`{service.FormatPlayer(v, true)} is not currently banned`, {plr}) + if serverCooldown and sCooldown_playerCache then + local secsTillPass = os.clock() - sCooldown_playerCache + if secsTillPass < serverCooldown then + return false, string.format("[ServerCooldown] You must wait %.0f seconds to run the command.", serverCooldown - secsTillPass) end end - end - }; - - BanMenu = { - Prefix = Settings.Prefix; - Commands = {"banmenu"}; - Args = {}; - Description = "Opens the ban menu"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}, data: {any}) - Remote.MakeGui(plr,"BanMenu",{ - AdminLevel = Admin.GetLevel(plr); - CanBan = Admin.CheckComLevel(Admin.GetLevel(plr),Commands.ServerBan.AdminLevel); - CanTimeBan = Admin.CheckComLevel(Admin.GetLevel(plr),Commands.TimeBan.AdminLevel); - CanPermBan = Admin.CheckComLevel(Admin.GetLevel(plr),Commands.PermanentBan.AdminLevel); - Prefix = Settings.Prefix; - }) - end, - }; - - CustomMessage = { - Prefix = Settings.Prefix; - Commands = {"cm", "custommessage"}; - Args = {"Upper message", "message"}; - Filter = true; - Description = "Same as message but says whatever you want upper message to be instead of your name."; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[1], "Missing message title (argument #1)") - assert(args[2], "Missing message (argument #2)") - for _, v in service.Players:GetPlayers() do - Remote.RemoveGui(v, "Message") - Remote.MakeGui(v, "Message", { - Title = args[1]; - Message = args[2]; - Time = (#tostring(args[1]) / 19) + 2.5; - --service.Filter(args[1],plr, v); - }) + + if crossCooldown then + local playerData = Core.GetPlayer(pDat.Player) or {} + local crossCooldown_Cache = playerData._crossCooldownCache or (function() + local tab = {} + playerData._crossCooldownCache = tab + return tab + end)() + local crossCooldown_playerCache = crossCooldown_Cache[cmdFullName] + + if crossCooldown_playerCache then + local secsTillPass = os.clock() - crossCooldown_playerCache + if secsTillPass < crossCooldown then + return false, string.format("[CrossServerCooldown] You must wait %.0f seconds to run the command.", crossCooldown - secsTillPass) + end + end end end - }; - - Nil = { - Prefix = Settings.Prefix; - Commands = {"nil"}; - Args = {"player"}; - Hidden = true; - Description = `Deletes the player forcefully, causing them to be kicked for "Player has been removed from the DataModel"`; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - v.Character = nil - v.Parent = nil - Functions.Hint(`Sent {service.FormatPlayer(v)} to nil`, {plr}) - end - end - }; - - PromptPremiumPurchase = { - Prefix = Settings.Prefix; - Commands = {"promptpremiumpurchase", "premiumpurchaseprompt"}; - Args = {"player"}; - Description = "Opens the Roblox Premium purchase prompt for the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - service.MarketplaceService:PromptPremiumPurchase(v) - end - end - }; - - RobloxNotify = { - Prefix = Settings.Prefix; - Commands = {"rbxnotify", "robloxnotify", "robloxnotif", "rblxnotify", "rnotif", "rn"}; - Args = {"player", "duration (seconds)", "text"}; - Filter = true; - Description = "Sends a Roblox-styled notification for the target player(s)"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - for _, v in service.GetPlayers(plr, args[1]) do - Remote.Send(v, "Function", "SetCore", "SendNotification", { - Title = "Notification"; - Text = args[3] or "Hello, from Adonis!"; - Duration = tonumber(args[2]) or 5; - }) - end + + return permAllowed, nil + end; + + UpdateCooldown = function(pDat, cmd) + if pDat.Player == "SYSTEM" then return end + local playerCooldown = tonumber(cmd.PlayerCooldown) + local serverCooldown = tonumber(cmd.ServerCooldown) + local crossCooldown = tonumber(cmd.CrossCooldown) + + local cmdFullName = cmd._fullName or (function() + local aliases = cmd.Aliases or cmd.Commands or {} + cmd._fullName = `{cmd.Prefix}{aliases[1] or `{service.HttpService:GenerateGUID(false)}-RANDOM_COMMAND`}` + return cmd._fullName + end)() + + local pCooldown_Cache = cmd._playerCooldownCache or (function() + local tab = {} + cmd._playerCooldownCache = tab + return tab + end)() + + local sCooldown_Cache = cmd._serverCooldownCache or (function() + local tab = {} + cmd._serverCooldownCache = tab + return tab + end)() + + local crossCooldown_Cache = cmd._crossCooldownCache or (function() + local tab = {} + cmd._crossCooldownCache = tab + return tab + end)() + + local cooldownIndex = tostring(pDat.Player.UserId) + local pCooldown_playerCache = pCooldown_Cache[cooldownIndex] + local sCooldown_playerCache = sCooldown_Cache[cooldownIndex] + local lastUsed = os.clock() + + if playerCooldown then + pCooldown_Cache[cooldownIndex] = lastUsed end - }; - Disguise = { - Prefix = Settings.Prefix; - Commands = {"disguise", "masquerade"}; - Args = {"player", "username"}; - Description = "Names the player, chars the player, and modifies the player's chat tag"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - assert(args[2], "Argument missing or nil") - local userId = Functions.GetUserIdFromNameAsync(args[2]) - assert(userId, "Invalid username supplied/user not found") + if serverCooldown then + sCooldown_Cache[cooldownIndex] = lastUsed + end - local username = select(2, xpcall(function() - return service.Players:GetNameFromUserIdAsync(userId) - end, function() return args[2] end)) + --// Cross cooldown + do + local playerData = Core.GetPlayer(pDat.Player) + local crossCooldown_Cache = playerData._crossCooldownCache or {} + local crossCooldown_playerCache = crossCooldown_Cache[cmdFullName] - if service.Players:GetPlayerByUserId(userId) then - error("You cannot disguise as this player (currently in server)") + if not crossCooldown and crossCooldown_playerCache then + crossCooldown_playerCache[cmdFullName] = nil + elseif crossCooldown then + crossCooldown_Cache[cmdFullName] = lastUsed end + end + end; - Commands.Char.Function(plr, args) - Commands.DisplayName.Function(plr, {args[1], username}) - - local ChatService = Functions.GetChatService() + SearchCommands = function(p, search) + local checkPerm = Admin.CheckPermission + local tab = {} + local pDat = { + Player = p; + Level = Admin.GetLevel(p); + isDonor = Admin.CheckDonor(p); + } - for _, v in service.GetPlayers(plr, args[1]) do - if Variables.DisguiseBindings[v.UserId] then - Variables.DisguiseBindings[v.UserId].Rename:Disconnect() - Variables.DisguiseBindings[v.UserId].Rename = nil - if ChatService then - ChatService:RemoveSpeaker(Variables.DisguiseBindings[v.UserId].TargetUsername) - ChatService:UnregisterProcessCommandsFunction(`Disguise_{v.Name}`) - end - end + for ind, cmd in Commands do + if checkPerm(pDat, cmd, true) then + tab[ind] = cmd + end + end - Variables.DisguiseBindings[v.UserId] = { - TargetUsername = username; - Rename = v.CharacterAppearanceLoaded:Connect(function(char) - Commands.DisplayName.Function(v, {v.Name, username}) - end); - } + return tab + end; - if ChatService then - local disguiseSpeaker = ChatService:AddSpeaker(username) - disguiseSpeaker:JoinChannel("All") - ChatService:RegisterProcessCommandsFunction(`Disguise_{v.Name}`, function(speaker, message, channelName) - if speaker == v.Name then - local filteredMessage = select(2, xpcall(function() - return service.TextService:FilterStringAsync(message, v.UserId, Enum.TextFilterContext.PrivateChat):GetChatForUserAsync(v.UserId) - end, function() - Remote.Send(v, "Function", "ChatMessage", "A message filtering error occurred.", Color3.new(1, 64/255, 77/255)) - return - end)) - if filteredMessage and not server.Admin.DoHideChatCmd(v, message) then - disguiseSpeaker:SayMessage(filteredMessage, channelName) - if v.Character then - service.Chat:Chat(v.Character, filteredMessage, Enum.ChatColor.White) - end - end - return true - end - return false - end) - end + CheckAuthority = function(p, target, actionName, allowSelf) + if p == target then + if allowSelf == false then + Functions.Hint(`You cannot {actionName} yourself`, {p}) + return false end + + return allowSelf or Remote.GetGui(p, "YesNoPrompt", { + Question = `Are you sure you want to {actionName} yourself?`; + }) == "Yes" + + elseif Admin.GetLevel(p) > Admin.GetLevel(target) then + return true end - }; - - UnDisguise = { - Prefix = Settings.Prefix; - Commands = {"undisguise", "removedisguise", "cleardisguise", "nodisguise"}; - Args = {"player"}; - Description = "Removes the player's disguise"; - AdminLevel = "Admins"; - Function = function(plr: Player, args: {string}) - local ChatService = Functions.GetChatService() - for _, v in service.GetPlayers(plr, args[1]) do - if Variables.DisguiseBindings[v.UserId] then - Variables.DisguiseBindings[v.UserId].Rename:Disconnect() - Variables.DisguiseBindings[v.UserId].Rename = nil - pcall(function() - ChatService:RemoveSpeaker(Variables.DisguiseBindings[v.UserId].TargetUsername) - ChatService:UnregisterProcessCommandsFunction(`Disguise_{v.Name}`) - end) - end - Variables.DisguiseBindings[v.UserId] = nil + + Functions.Hint(`You don't have permission to {actionName} {service.FormatPlayer(target)}`, {p}) + return false + end; + + GetAliases = function(player) + local aliases = table.clone(Variables.Aliases) + local pData = player and Core.GetPlayer(player) + + if pData and pData.Aliases then + for alias, command in pData.Aliases do + aliases[alias] = command end - Commands.UnChar.Function(plr, args) - Commands.UnDisplayName.Function(plr, args) end - }; + + return aliases + end; } end diff --git a/MainModule/Server/Commands/Moderators.luau b/MainModule/Server/Commands/Moderators.luau index 95b0420985..1dff5e8411 100644 --- a/MainModule/Server/Commands/Moderators.luau +++ b/MainModule/Server/Commands/Moderators.luau @@ -292,7 +292,7 @@ return function(Vargs, env) Commands = {"cn", "customsmallmessage", "cnmessage"}; Args = {"title", "message"}; Filter = true; - Description = `Same as {Settings.Prefix}n but says whatever you want the title to be instead of your name.`; + Description = `Same as {Functions.GetMainPrefix()}n but says whatever you want the title to be instead of your name.`; AdminLevel = "Moderators"; Function = function(plr: Player, args: {string}) Functions.Notify(service.BroadcastFilter(assert(args[1], "Missing title"), plr), service.BroadcastFilter(assert(args[2], "Missing message") , plr), service.GetPlayers()) @@ -377,7 +377,7 @@ return function(Vargs, env) Remote.RemoveGui(v, "Notify") Functions.Notify(`Warning from {service.FormatPlayer(plr)}`, reason, {v}) - Functions.Notification("Notification", `Warned {service.FormatPlayer(v)}`, {plr}, 5, "MatIcons://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}warnings {v.Name}')`)) + Functions.Notification("Notification", `Warned {service.FormatPlayer(v)}`, {plr}, 5, "MatIcons://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Functions.GetMainPrefix()}warnings {v.Name}')`)) end end end @@ -416,7 +416,7 @@ return function(Vargs, env) Core.CrossServer("RemovePlayer", v.Name, `Warning from {service.FormatPlayer(plr)}`, reason) end - Functions.Notification("Notification", `Kick-warned {service.FormatPlayer(v)}`, {plr}, 5, "MatIcons://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}warnings {v.Name}')`)) + Functions.Notification("Notification", `Kick-warned {service.FormatPlayer(v)}`, {plr}, 5, "MatIcons://Shield", Core.Bytecode(`client.Remote.Send('ProcessCommand','{Functions.GetMainPrefix()}warnings {v.Name}')`)) end end end @@ -725,7 +725,7 @@ return function(Vargs, env) for k, t in v.Backpack:GetChildren() do t.Parent = tools end - Admin.RunCommand(`{Settings.Prefix}name`, v.Name, `-AFK-_{service.FormatPlayer(v)}_-AFK-`) + Admin.RunCommand(`{Functions.GetMainPrefix()}name`, v.Name, `-AFK-_{service.FormatPlayer(v)}_-AFK-`) local torso = v.Character.HumanoidRootPart local pos = torso.CFrame local running=true @@ -738,7 +738,7 @@ return function(Vargs, env) for k, t in tools:GetChildren() do t.Parent = v.Backpack end - Admin.RunCommand(`{Settings.Prefix}unname`, v.Name) + Admin.RunCommand(`{Functions.GetMainPrefix()}unname`, v.Name) event:Disconnect() end) repeat torso.CFrame = pos wait() until not v or not v.Character or not torso or not running or not torso.Parent @@ -811,7 +811,7 @@ return function(Vargs, env) Prefix = Settings.Prefix; Commands = {"fullgod", "totalgod"}; Args = {"player"}; - Description = `Same as {server.Settings.Prefix}god, but also provides blast protection`; + Description = `Same as {Functions.GetMainPrefix()}god, but also provides blast protection`; AdminLevel = "Moderators"; Function = function(plr: Player, args: {string}) for _, v in service.GetPlayers(plr, args[1]) do @@ -1243,7 +1243,7 @@ return function(Vargs, env) TitleButtons = { { Text = ""; - OnClick = Core.Bytecode(`client.Remote.Send('ProcessCommand','{Settings.Prefix}tools')`); + OnClick = Core.Bytecode(`client.Remote.Send('ProcessCommand','{Functions.GetMainPrefix()}tools')`); Children = { { Class = "ImageLabel"; @@ -1594,7 +1594,7 @@ return function(Vargs, env) local command = args[3] local name = string.lower(plr.Name) assert(command, "Missing command name to repeat") - if string.lower(string.sub(command, 1, #Settings.Prefix+string.len("repeat"))) == string.lower(`{Settings.Prefix}repeat`) or string.sub(command, 1, #Settings.Prefix+string.len("loop")) == string.lower(`{Settings.Prefix}loop`) or string.find(command, `^{Settings.Prefix}loop`) or string.find(command, `^{Settings.Prefix}repeat`) then + if string.lower(string.sub(command, 1, #Functions.GetMainPrefix()+string.len("repeat"))) == string.lower(`{Settings.Prefix}repeat`) or string.sub(command, 1, #Functions.GetMainPrefix()+string.len("loop")) == string.lower(`{Settings.Prefix}loop`) or string.find(command, `^{Settings.Prefix}loop`) or string.find(command, `^{Settings.Prefix}repeat`) then error("Cannot repeat the loop command in a loop command") return end @@ -2116,7 +2116,7 @@ return function(Vargs, env) local data = { Tools = {}; SavedTools = {}; - Prefix = Settings.Prefix; + Prefix = Functions.GetMainPrefix(); SplitKey = Settings.SplitKey; SpecialPrefix = Settings.SpecialPrefix; } @@ -4468,7 +4468,7 @@ return function(Vargs, env) AdminLevel = "Moderators"; Function = function(plr: Player, args: {[number]:string}) Remote.MakeGui(plr, "Teams", { - CmdPrefix = Settings.Prefix; CmdPlayerPrefix = Settings.PlayerPrefix; CmdSpecialPrefix = Settings.SpecialPrefix; CmdSplitKey = Settings.SplitKey; + CmdPrefix = Functions.GetMainPrefix(); CmdPlayerPrefix = Settings.PlayerPrefix; CmdSpecialPrefix = Settings.SpecialPrefix; CmdSplitKey = Settings.SplitKey; }) end }; diff --git a/MainModule/Server/Commands/Players.luau b/MainModule/Server/Commands/Players.luau index 233703bd1b..ee7ac02dbd 100644 --- a/MainModule/Server/Commands/Players.luau +++ b/MainModule/Server/Commands/Players.luau @@ -31,11 +31,11 @@ return function(Vargs, env) for _,alias in cmd.Commands do if #cmdAliases >= 4 and (#cmd.Commands - #cmdAliases) ~= 0 then - table.insert(cmdAliases, `and {#cmd.Commands - #cmdAliases} more...`) + table.insert(cmdAliases, `and {#cmd.Commands - #cmdAliases} more...`) break end end - + table.remove(cmdAliases, 1) local permissionDesc = Admin.FormatCommandAdminLevel(cmd) @@ -83,7 +83,7 @@ return function(Vargs, env) local cmd, ind for i, v in Admin.SearchCommands(plr, "all") do for _, p in v.Commands do - if (v.Prefix or "")..string.lower(p) == string.lower(args[1]) then + if (if type(v.Prefix) == "table" then v.Prefix[1] else v.Prefix or "")..string.lower(p) == string.lower(args[1]) then cmd, ind = v, i break end @@ -107,7 +107,7 @@ return function(Vargs, env) Title = "Command Info"; Icon = server.MatIcons.Info; Table = { - {Text = `Prefix: {cmd.Prefix}`, Desc = "Prefix used to run the command"}, + {Text = `Prefix: {if type(cmd.Prefix) =="table" then table.concat(cmd.Prefix, ", ") else cmd.Prefix}`, Desc = "Prefix used to run the command"}, {Text = `Commands: {SanitizeXML(table.concat(cmd.Commands, ", "))}`, Desc = "Valid default aliases for the command"}, {Text = `Arguments: {if cmdArgs == "" then "-" else SanitizeXML(cmdArgs)}`, Desc = "Parameters taken by the command"}, {Text = `Admin Level: {Admin.FormatCommandAdminLevel(cmd)}`, Desc = "Rank required to run the command"}, @@ -150,7 +150,7 @@ return function(Vargs, env) Description = "Shows you the command prefix using the :cmds command"; AdminLevel = "Players"; Function = function(plr: Player, args: {string}) - Functions.Hint(`{Settings.Prefix}cmds`, {plr}) + Functions.Hint(`{if type(Settings.Prefix) == "table" then Settings.Prefix[1] else Settings.Prefix}cmds`, {plr}) end }; @@ -567,46 +567,47 @@ return function(Vargs, env) Description = "Shows you how to use some syntax related things"; AdminLevel = "Players"; Function = function(plr: Player, args: {string}) + local Prefix = if type(Settings.Prefix) == "table" then Settings.Prefix[1] else Settings.Prefix local usage = { ""; "Mouse over things in lists to expand them"; "You can also resize windows by dragging the edges"; ""; - `Put /e in front to silence commands in chat (/e {Settings.Prefix}kill scel) or enable chat command hiding in client settings`; + `Put /e in front to silence commands in chat (/e {Prefix}kill scel) or enable chat command hiding in client settings`; `Player commands can be used by anyone, these commands have {Settings.PlayerPrefix} infront, such as {Settings.PlayerPrefix}info and {Settings.PlayerPrefix}rejoin`; ""; `――――― Player Selectors ―――――`; - `Usage example: {Settings.Prefix}kill {Settings.SpecialPrefix}all (where {Settings.SpecialPrefix}all is the selector)`; + `Usage example: {Prefix}kill {Settings.SpecialPrefix}all (where {Settings.SpecialPrefix}all is the selector)`; `{Settings.SpecialPrefix}me - Yourself`; `{Settings.SpecialPrefix}all - Everyone in the server`; `{Settings.SpecialPrefix}admins - All admins in the server`; `{Settings.SpecialPrefix}nonadmins - Non-admins (normal players) in the server`; `{Settings.SpecialPrefix}others - Everyone except yourself`; `{Settings.SpecialPrefix}random - A random person in the server excluding those removed with -SELECTION`; - `@USERNAME - Targets a specific player with that exact username Ex: {Settings.Prefix}god @Sceleratis would give a player with the username 'Sceleratis' god powers`; - `#NUM - NUM random players in the server {Settings.Prefix}ff #5 will ff 5 random players excluding those removed with -SELECTION.`; + `@USERNAME - Targets a specific player with that exact username Ex: {Prefix}god @Sceleratis would give a player with the username 'Sceleratis' god powers`; + `#NUM - NUM random players in the server {Prefix}ff #5 will ff 5 random players excluding those removed with -SELECTION.`; `{Settings.SpecialPrefix}friends - Your friends who are in the server`; - `%TEAMNAME - Members of the team TEAMNAME Ex: {Settings.Prefix}kill %raiders`; + `%TEAMNAME - Members of the team TEAMNAME Ex: {Prefix}kill %raiders`; `$GROUPID - Members of the group with ID GROUPID (number in the Roblox group webpage URL)`; - `-SELECTION - Inverts the selection, ie. will remove SELECTION from list of players to run command on. {Settings.Prefix}kill all,-%TEAM will kill everyone except players on TEAM`; - `+SELECTION - Readds the selection, ie. will readd SELECTION from list of players to run command on. {Settings.Prefix}kill all,-%TEAM,+Lethalitics will kill everyone except players on TEAM but also Lethalitics`; - `radius-NUM -- Anyone within a NUM-stud radius of you. {Settings.Prefix}ff radius-5 will ff anyone within a 5-stud radius of you.`; + `-SELECTION - Inverts the selection, ie. will remove SELECTION from list of players to run command on. {Prefix}kill all,-%TEAM will kill everyone except players on TEAM`; + `+SELECTION - Readds the selection, ie. will readd SELECTION from list of players to run command on. {Prefix}kill all,-%TEAM,+Lethalitics will kill everyone except players on TEAM but also Lethalitics`; + `radius-NUM -- Anyone within a NUM-stud radius of you. {Prefix}ff radius-5 will ff anyone within a 5-stud radius of you.`; ""; `――――― Repetition ―――――`; - `Multiple player selections - {Settings.Prefix}kill me,noob1,noob2,{Settings.SpecialPrefix}random,%raiders,$123456,{Settings.SpecialPrefix}nonadmins,-scel`; - `Multiple Commands at a time - {Settings.Prefix}ff me {Settings.BatchKey} {Settings.Prefix}sparkles me {Settings.BatchKey} {Settings.Prefix}rocket jim`; - `You can add a delay if you want; {Settings.Prefix}ff me {Settings.BatchKey} !wait 10 {Settings.BatchKey} {Settings.Prefix}m hi we waited 10 seconds`; - `{Settings.Prefix}repeat 10(how many times to run the cmd) 1(how long in between runs) {Settings.Prefix}respawn jim`; + `Multiple player selections - {Prefix}kill me,noob1,noob2,{Settings.SpecialPrefix}random,%raiders,$123456,{Settings.SpecialPrefix}nonadmins,-scel`; + `Multiple Commands at a time - {Prefix}ff me {Settings.BatchKey} {Prefix}sparkles me {Settings.BatchKey} {Prefix}rocket jim`; + `You can add a delay if you want; {Prefix}ff me {Settings.BatchKey} !wait 10 {Settings.BatchKey} {Prefix}m hi we waited 10 seconds`; + `{Prefix}repeat 10(how many times to run the cmd) 1(how long in between runs) {Prefix}respawn jim`; ""; `――――― Reference Info ―――――`; - `{Settings.Prefix}cmds for a list of available commands`; - `{Settings.Prefix}cmdinfo <command> for detailed info about a specific command`; + `{Prefix}cmds for a list of available commands`; + `{Prefix}cmdinfo <command> for detailed info about a specific command`; `{Settings.PlayerPrefix}brickcolors for a list of BrickColors`; `{Settings.PlayerPrefix}materials for a list of materials`; ""; - `{Settings.Prefix}capes for a list of preset admin capes`; - `{Settings.Prefix}musiclist for a list of preset audios`; - `{Settings.Prefix}insertlist for a list of insertable assets using {Settings.Prefix}insert`; + `{Prefix}capes for a list of preset admin capes`; + `{Prefix}musiclist for a list of preset audios`; + `{Prefix}insertlist for a list of insertable assets using {Prefix}insert`; } Remote.MakeGui(plr, "List", { Title = "Usage"; @@ -937,7 +938,7 @@ return function(Vargs, env) IsDonor = Admin.CheckDonor(v); GameData = gameData; IsServerOwner = v.UserId == game.PrivateServerOwnerId; - CmdPrefix = Settings.Prefix; + CmdPrefix = Functions.GetMainPrefix(); CmdSplitKey = Settings.SplitKey; OnlineFriends = Remote.Get(v, "Function", "GetFriendsOnline"); }) @@ -1018,7 +1019,7 @@ return function(Vargs, env) ServerAge = service.FormatTime(os.time() - server.ServerStartTime); ServerInternetInfo = serverInfo; Refreshables = Logs.ListUpdaters.ServerDetails(plr); - CmdPrefix = Settings.Prefix; + CmdPrefix = if type(Settings.Prefix) == "table" then Settings.Prefix[1] else Settings.Prefix, CmdPlayerPrefix = Settings.PlayerPrefix; SplitKey = Settings.SplitKey; }) diff --git a/MainModule/Server/Core/Admin.luau b/MainModule/Server/Core/Admin.luau index 0ad9ff97ae..551cdbaf8f 100644 --- a/MainModule/Server/Core/Admin.luau +++ b/MainModule/Server/Core/Admin.luau @@ -1193,9 +1193,16 @@ return function(Vargs, GetEnv) for ind, data in Commands do if type(data) == "table" then for i,cmd in data.Commands do - if data.Prefix == "" then Admin.BlankPrefix = true end - tempPrefix[data.Prefix] = true - tempTable[string.lower(data.Prefix..cmd)] = ind + if type(data.Prefix) ~= "table" and data.Prefix == "" then Admin.BlankPrefix = true end + if type(data.Prefix) == "table" then + for _,p in data.Prefix do + tempPrefix[p] = true + tempTable[string.lower(p..cmd)] = ind + end + else + tempPrefix[data.Prefix] = true + tempTable[string.lower(data.Prefix..cmd)] = ind + end end end end @@ -1232,13 +1239,27 @@ return function(Vargs, GetEnv) end for _, v in data.Commands do - if not blacklistedCommands["/"..data.Prefix..v] then - if not command1 then - command1 = "/"..data.Prefix..v - else - command2 = "/"..data.Prefix..v + if type(data.Prefix) == "table" then + for _, p in data.Prefix do + if not blacklistedCommands["/"..p..v] then + if not command1 then + command1 = "/"..p..v + else + command2 = "/"..p..v + end + end end + else + if not blacklistedCommands["/"..data.Prefix..v] then + if not command1 then + command1 = "/"..data.Prefix..v + else + command2 = "/"..data.Prefix..v + end + end + end + end if command1 then @@ -1336,7 +1357,7 @@ return function(Vargs, GetEnv) FormatCommand = function(command, cmdn) return table.concat({ - (command.Prefix or ""), + (if type(command.Prefix) == "table" then command.Prefix[1] else command.Prefix or ""), tostring(command.Commands[cmdn or 1]), #command.Args > 0 and Settings.SplitKey or "", #command.Args > 0 and Admin.FormatCommandArguments(command) or "" diff --git a/MainModule/Server/Core/Commands.luau b/MainModule/Server/Core/Commands.luau index c8edb07110..e9b9ad82b8 100644 --- a/MainModule/Server/Core/Commands.luau +++ b/MainModule/Server/Core/Commands.luau @@ -34,7 +34,7 @@ return function(Vargs, GetEnv) t = server.Typechecker; local ValidateCommandDefinition = t.interface({ - Prefix = t.string, + Prefix = t.union(t.string, t.array(t.string)), Commands = t.array(t.string), Description = t.string, AdminLevel = t.union(t.string, t.number, t.nan, t.array(t.union(t.string, t.number, t.nan))), @@ -99,7 +99,13 @@ return function(Vargs, GetEnv) Admin.PrefixCache[cmd.Prefix] = true for _, v in cmd.Commands do - Admin.CommandCache[string.lower(cmd.Prefix..v)] = ind + if type(cmd.Prefix) == "table" then + for _,p in cmd.Prefix do + Admin.CommandCache[string.lower(p..v)] = ind + end + else + Admin.CommandCache[string.lower(cmd.Prefix..v)] = ind + end end cmd.Args = cmd.Args or cmd.Arguments or {} diff --git a/MainModule/Server/Core/Functions.luau b/MainModule/Server/Core/Functions.luau index e81407b0e3..f137444a85 100644 --- a/MainModule/Server/Core/Functions.luau +++ b/MainModule/Server/Core/Functions.luau @@ -1664,5 +1664,11 @@ return function(Vargs, GetEnv) end return if allowNil then nil else BrickColor.random() end; - }; + + GetMainPrefix = function() + if type(Settings.Prefix) == "table" then return Settings.Prefix[1] else return Settings.Prefix end + end; + } + + end diff --git a/MainModule/Server/Dependencies/DefaultSettings.luau b/MainModule/Server/Dependencies/DefaultSettings.luau index 4f1b082dd2..d3eceb87d0 100644 --- a/MainModule/Server/Dependencies/DefaultSettings.luau +++ b/MainModule/Server/Dependencies/DefaultSettings.luau @@ -140,10 +140,10 @@ settings.HideScript = true -- When the game starts the Adonis_Loader model settings.DataStore = "Adonis_1" -- DataStore the script will use for saving data; Changing this will lose any saved data settings.DataStoreKey = "CHANGE_THIS" -- CHANGE THIS TO ANYTHING RANDOM! Key used to encrypt all datastore entries; Changing this will lose any saved data settings.DataStoreEnabled = true -- Disable if you don't want to load settings and admins from the datastore; PlayerData will still save -settings.LocalDatastore = false -- If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers +settings.LocalDatastore = false -- If this is turned on, a mock DataStore will forcibly be used instead and shall never save across servers -settings.Storage = game:GetService("ServerStorage") -- Where things like tools are stored -settings.RecursiveTools = false -- Whether tools that are included in sub-containers within settings.Storage will be available via the ;give command (useful if your tools are organized into multiple folders) +settings.Storage = game:GetService("ServerStorage") -- Where things like tools are stored +settings.RecursiveTools = false -- Whether tools that are included in sub-containers within settings.Storage will be available via the ;give command (useful if your tools are organized into multiple folders) settings.Theme = "Default" -- UI theme; settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI elements are disabled @@ -157,7 +157,7 @@ settings.MobileTheme = "Mobilius" -- Theme to use on mobile devices; Some UI el settings.Ranks = { ["Moderators"] = { Level = 100; - Users = {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";} + Users = {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID"; "Subscription:SubscriptionId";} } } @@ -210,7 +210,6 @@ settings.Aliases = { [";examplealias "] = ";ff | ;fling | ;fire " --// Order arguments appear in alias string determines their required order in the command message when ran later }; ---// Use the below table to define pre-set cameras settings.Cameras = { --[[ "Camera Name" would be the name of your camera @@ -239,7 +238,7 @@ settings.SaveAdmins = true -- If true anyone you ;admin or ;headadmin in-game settings.LoadAdminsFromDS = true -- If false, any admins saved in your DataStores will not load settings.WhitelistEnabled = false -- If true enables the whitelist/server lock; Only lets admins & whitelisted users join -settings.Prefix = ";" -- The ; in ;kill me +settings.Prefix = {";", ":"} -- A list of prefixes for commands, the ; in ;kill me settings.PlayerPrefix = "!" -- The ! in !donate; Mainly used for commands that any player can run; Do not make it the same as settings.Prefix settings.SpecialPrefix = "" -- Used for things like "all", "me" and "others" (If changed to ! you would do ;kill !me) settings.SplitKey = " " -- The space in ;kill me (eg if you change it to / ;kill me would be ;kill/me) @@ -294,7 +293,7 @@ settings.ChatCommands = true -- If false you will not be able to run commands settings.CreatorPowers = true -- Gives me creator-level admin; This is strictly used for debugging; I can't debug without full access to the script settings.CodeExecution = true -- Enables the use of code execution in Adonis; Scripting related (such as ;s) and a few other commands require this settings.SilentCommandDenials = false -- If true, there will be no differences between the error messages shown when a user enters an invalid command and when they have insufficient permissions for the command -settings.OverrideChatCallbacks = true -- If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for slowmode. Mutes use a CanSend method to mute when this is set to false. +settings.OverrideChatCallbacks = true -- If the TextChatService ShouldDeliverCallbacks of all channels are overridden by Adonis on load. Required for slowmode. Mutes use a CanSend method to mute when this is set to false. settings.BanMessage = "Banned" -- Message shown to banned users upon kick settings.LockMessage = "Not Whitelisted" -- Message shown to people when they are kicked while the game is ;slocked @@ -605,6 +604,7 @@ order = { "AutoBackup"; " "; "PlayerList"; + " "; "Console"; "Console_AdminsOnly"; " "; diff --git a/MainModule/Server/Server.luau b/MainModule/Server/Server.luau index 486f3ca2ae..3294a0e6e6 100644 --- a/MainModule/Server/Server.luau +++ b/MainModule/Server/Server.luau @@ -597,6 +597,23 @@ return service.NewProxy({ end end + --// Attempts to patch Settings.Prefix to fix issues + if type(server.Settings.Prefix) == "table" then + setmetatable(server.Settings.Prefix, { + __concat = function(self, value) + return `{self[1]}{value}` + end, + __tostring = function(self) + return self[1] + end, + + }) + end + + + + + --// Bind cleanup service.DataModel:BindToClose(function(...) server.CleanUp(...) From 6d1c95971b14a4dcd17e395b0d8d24ded37cefdc Mon Sep 17 00:00:00 2001 From: GalacticInspired <73362346+GalacticInspired@users.noreply.github.com> Date: Tue, 28 Jan 2025 01:22:21 +0100 Subject: [PATCH 60/60] rtezrhfgshfsd hfhfsdgh --- MainModule/Client/UI/BasicAdmin/Message.rbxmx | 2 +- MainModule/Server/Commands/Moderators.luau | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MainModule/Client/UI/BasicAdmin/Message.rbxmx b/MainModule/Client/UI/BasicAdmin/Message.rbxmx index 3b9996452a..bd3c02a3d3 100644 --- a/MainModule/Client/UI/BasicAdmin/Message.rbxmx +++ b/MainModule/Client/UI/BasicAdmin/Message.rbxmx @@ -6,7 +6,7 @@ false - 0 + 0dgxzhjgfhjfhgjhdjgfzjdhg true false 0 diff --git a/MainModule/Server/Commands/Moderators.luau b/MainModule/Server/Commands/Moderators.luau index 1dff5e8411..6e5391f464 100644 --- a/MainModule/Server/Commands/Moderators.luau +++ b/MainModule/Server/Commands/Moderators.luau @@ -1891,7 +1891,7 @@ return function(Vargs, env) local reason = "No reason provided" local moderator = "%UNKNOWN%" - local banType = if typeof(v) == 'table' and v.BanType == "Server" then + local banType = if typeof(v) == 'table' and v. == "Server" then "SERVER" else "GLOBAL";