--Implementation of a command.
--!strict

local CLOSE_THRESHOLD = 0.1
local CHARACTER_HISTORY_MAX_ENTRIES = 1000
local TYPE_TO_COLOR = {
    Movement = Color3.fromRGB(0, 170, 255),
    NewCharacter = Color3.fromRGB(0, 255, 0),
    ServerTeleport = Color3.fromRGB(0, 0, 255),
    ClientTeleport = Color3.fromRGB(255, 0, 0),
}

local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

local Logs = require(script.Parent.Parent.Parent:WaitForChild("Common"):WaitForChild("Logs")) :: Types.Logs

return {
    Keyword = "characterhistory",
    Category = "Administrative",
    Description = "Displays the recent history of a player's location and some properties.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Player",
            Description = "Player to view the snapshot of. Multiple players is not supported.",
        },
    },
    ClientLoad = function(Api: Types.NexusAdminApi)
        --Store the history of the local player.
        local CharacterLogs = Logs.new(CHARACTER_HISTORY_MAX_ENTRIES)
        task.spawn(function()
            --[[
            Adds a log entry.
            --]]
            local function AddLog(Type: string, Position: Vector3, Humanoid: Humanoid): ()
                --Return if the log is a duplicate.
                local CurrentLogs = CharacterLogs:GetLogs()
                local LastLog = CurrentLogs[1]
                local PreviousIsClose = LastLog and (LastLog.Position - Position).Magnitude < CLOSE_THRESHOLD
                if PreviousIsClose and Type == "Movement" then
                    return
                end

                --Add the entry.
                local Entry = {
                    Time = Workspace:GetServerTimeNow(),
                    Type = Type,
                    Position = Position,
                    Humanoid = {
                        WalkSpeed = Humanoid.WalkSpeed,
                        Health = Humanoid.Health,
                        MaxHealth = Humanoid.MaxHealth,
                    },
                }
                if Humanoid.UseJumpPower then
                    Entry.Humanoid.JumpPower = Humanoid.JumpPower
                else
                    Entry.Humanoid.JumpHeight = Humanoid.JumpHeight
                end
                CharacterLogs:Add(Entry)
            end

            --Start the loop.
            local LastCharacter: Model? = nil
            while true do
                task.wait(0.5)

                --Ignore if the character does not exist.
                local Character = Players.LocalPlayer.Character :: Model
                if not Character then continue end
                local Humanoid = Character:FindFirstChildOfClass("Humanoid") :: Humanoid
                local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart") :: BasePart
                if not Humanoid or not HumanoidRootPart then continue end

                if LastCharacter ~= Character then
                    --Connect the new character.
                    HumanoidRootPart:GetPropertyChangedSignal("CFrame"):Connect(function()
                        AddLog("ClientTeleport", HumanoidRootPart.Position, Humanoid)
                    end)
                    AddLog("NewCharacter", HumanoidRootPart.Position, Humanoid)
                    LastCharacter = Character
                else
                    --Add the movement entry.
                    AddLog("Movement", HumanoidRootPart.Position, Humanoid)
                end
            end
        end);

        --Connect fetching the logs.
        (Api.EventContainer:WaitForChild("GetCharacterHistory") :: RemoteFunction).OnClientInvoke = function()
            local Entries = {}
            local CurrentEntries = CharacterLogs:GetLogs()
            for i = #CurrentEntries, 1, -1 do
                table.insert(Entries, CurrentEntries[i])
            end
            return Entries
        end
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        local TeleportLogs = {} :: {[Player]: Types.Logs}
        Api.CommandData.TeleportLogs = TeleportLogs
        local CharacterEvents, PlayerEvents = {}, {}

        --[[
        Connects a character.
        --]]
        local function ConnectCharacter(Player: Player, Character: Model): ()
            if CharacterEvents[Player] then
                CharacterEvents[Player]:Disconnect()
            end
            if not Character then return end
            local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart", 60) :: BasePart
            if not HumanoidRootPart then return end
            CharacterEvents[Player] = HumanoidRootPart:GetPropertyChangedSignal("CFrame"):Connect(function()
                if not TeleportLogs[Player] then return end
                TeleportLogs[Player]:Add(HumanoidRootPart.Position)
            end)
        end

        --[[
        Connects a player.
        --]]
        local function ConnectPlayer(Player: Player): ()
            TeleportLogs[Player] = Logs.new(CHARACTER_HISTORY_MAX_ENTRIES)
            PlayerEvents[Player] = Player.CharacterAppearanceLoaded:Connect(function(Character)
                ConnectCharacter(Player, Character)
            end)
            ConnectCharacter(Player, Player.Character :: Model)
        end

        --Connect players joining.
        Players.PlayerAdded:Connect(ConnectPlayer)
        for _, Player in Players:GetPlayers() do
            task.spawn(function()
                ConnectPlayer(Player)
            end)
        end

        --Connect players leaving.
        Players.PlayerRemoving:Connect(function(Player)
            if CharacterEvents[Player] then
                CharacterEvents[Player]:Disconnect()
                CharacterEvents[Player] = nil
            end
            if PlayerEvents[Player] then
                PlayerEvents[Player]:Disconnect()
                PlayerEvents[Player] = nil
            end
            TeleportLogs[Player] = nil
        end)

        --Create the remote function.
        local GetCharacterHistoryRemoteFunction = Instance.new("RemoteFunction")
        GetCharacterHistoryRemoteFunction.Name = "GetCharacterHistory"
        GetCharacterHistoryRemoteFunction.Parent = Api.EventContainer

        function GetCharacterHistoryRemoteFunction.OnServerInvoke(Player, TargetPlayer)
            if not TargetPlayer or not TargetPlayer.Parent then
                return nil
            elseif Api.Authorization:IsPlayerAuthorized(Player, Api.Configuration:GetCommandAdminLevel("Administrative", "characterhistory")) then
                local History = GetCharacterHistoryRemoteFunction:InvokeClient(TargetPlayer) :: {any}
                local TeleportLocations = TeleportLogs[TargetPlayer]:GetLogs()
                for _, Entry in History do
                    if Entry.Type ~= "ClientTeleport" then continue end
                    local IsClose = false
                    for _, Position in TeleportLocations do
                        if (Position - Entry.Position).Magnitude > CLOSE_THRESHOLD then continue end
                        IsClose = true
                        break
                    end
                    if not IsClose then continue end
                    Entry.Type = "ServerTeleport"
                end
                return History
            else
                return "Unauthorized"
            end
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext, PlayersList: {Player})
        local Player = PlayersList[1]
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Create the window.
        local CharacterHistoryScreenGui = Instance.new("ScreenGui")
        CharacterHistoryScreenGui.Name = "CharacterHistoryView"
        CharacterHistoryScreenGui.ResetOnSpawn = false
        CharacterHistoryScreenGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")

        local CurrentDisplayCenter: BasePart? = nil
        local CurrentInfoCenter: BasePart? = nil
        local GetClientViewRemoteFunction = Api.EventContainer:WaitForChild("GetCharacterHistory") :: RemoteFunction
        local Window = Api.Window:CreateWindow(`History - {Player.DisplayName} ({Player.Name})`)
        Window:EnableResizing()

        local ScreenSizeText = Instance.new("TextLabel")
        ScreenSizeText.BackgroundTransparency = 1
        ScreenSizeText.Size = UDim2.new(0.95, 0, 1, -10)
        ScreenSizeText.Position = UDim2.new(0.025, 0, 0, 5)
        ScreenSizeText.Font = Enum.Font.SourceSans
        ScreenSizeText.TextColor3 = Color3.fromRGB(255, 255, 255)
        ScreenSizeText.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
        ScreenSizeText.TextStrokeTransparency = 0
        ScreenSizeText.TextSize = Window.TextHeight
        ScreenSizeText.TextXAlignment = Enum.TextXAlignment.Left
        ScreenSizeText.TextYAlignment = Enum.TextYAlignment.Top
        ScreenSizeText.Text = "Loading..."
        ScreenSizeText.Parent = Window.ContentsAdorn

        local function Refresh()
            --Get the screen data.
            ScreenSizeText.Text = "Loading..."
            if CurrentDisplayCenter then
                CurrentDisplayCenter:Destroy()
                CurrentDisplayCenter = nil
            end
            local CharacterHistory = GetClientViewRemoteFunction:InvokeServer(Player) :: {any}
            if not CharacterHistory then
                return
            end

            --Replace the display.
            local NewDisplayCenter = Instance.new("Part")
            NewDisplayCenter.Transparency = 1
            NewDisplayCenter.Anchored = true
            NewDisplayCenter.CanCollide = false
            NewDisplayCenter.Size = Vector3.zero
            NewDisplayCenter.CFrame = CFrame.identity
            NewDisplayCenter.Parent = CharacterHistoryScreenGui
            CurrentDisplayCenter = NewDisplayCenter

            local TypeCounts = {} :: {[string]: number}
            for i, Entry in CharacterHistory do
                --Create the pointer for the position.
                local Pointer = Instance.new("SphereHandleAdornment")
                Pointer.Color3 = TYPE_TO_COLOR[Entry.Type]
                Pointer.Transparency = 0.25
                Pointer.Radius = (Entry.Type == "Movement" and 0.5 or 1)
                Pointer.ZIndex = 0
                Pointer.AlwaysOnTop = true
                Pointer.Name = tostring(i)
                Pointer.CFrame = CFrame.new(Entry.Position)
                Pointer.Adornee = NewDisplayCenter
                Pointer.Parent = NewDisplayCenter
                if not TypeCounts[Entry.Type] then
                    TypeCounts[Entry.Type] = 0
                end
                TypeCounts[Entry.Type] += 1

                --Connect showing the details.
                Pointer.MouseEnter:Connect(function()
                    --Clear the existing details.
                    if CurrentInfoCenter then
                        CurrentInfoCenter:Destroy()
                        CurrentInfoCenter = nil
                    end

                    --Show the details.
                    local InfoCenter = Instance.new("Part")
                    InfoCenter.Transparency = 1
                    InfoCenter.Anchored = true
                    InfoCenter.CanCollide = false
                    InfoCenter.CanQuery = false
                    InfoCenter.CFrame = CFrame.new(Entry.Position)
                    InfoCenter.Size = Vector3.zero
                    InfoCenter.Parent = CharacterHistoryScreenGui
                    CurrentInfoCenter = InfoCenter

                    local Messsage = `{Entry.Type}\n{string.format("%.3f, %.3f, %.3f", Entry.Position.X, Entry.Position.Y, Entry.Position.Z)}`
                    local HumanoidEntries = 0
                    for Property, Value in Entry.Humanoid do
                        Messsage ..= `\n{Property}: {Value}`
                        HumanoidEntries += 1
                    end

                    local BillboardGui = Instance.new("BillboardGui")
                    BillboardGui.AlwaysOnTop = true
                    BillboardGui.Size = UDim2.new(0, 300, 0, 24 * (2 + HumanoidEntries))
                    BillboardGui.Adornee = InfoCenter
                    BillboardGui.Parent = InfoCenter

                    local Background = Instance.new("Frame")
                    Background.BackgroundTransparency = 0.5 * GuiService.PreferredTransparency
                    Background.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
                    Background.BorderSizePixel = 0
                    Background.Size = UDim2.new(1, 0, 1, 0)
                    Background.Parent = BillboardGui

                    local BackgroundCorner = Instance.new("UICorner")
                    BackgroundCorner.CornerRadius = UDim.new(0, 8)
                    BackgroundCorner.Parent = Background

                    local TextLabel = Instance.new("TextLabel")
                    TextLabel.BackgroundTransparency = 1
                    TextLabel.Size = UDim2.new(1, -6, 1, -6)
                    TextLabel.Position = UDim2.new(0, 3, 0, 3)
                    TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                    TextLabel.Text = Messsage
                    TextLabel.Font = Enum.Font.SourceSans
                    TextLabel.TextScaled = true
                    TextLabel.TextWrapped = true
                    TextLabel.Parent = Background
                end)
                Pointer.MouseLeave:Connect(function()
                    --Clear the details.
                    if CurrentInfoCenter then
                        CurrentInfoCenter:Destroy()
                        CurrentInfoCenter = nil
                    end
                end)

                --Create the line to the previous section.
                if i == 1 or Entry.Type == "NewCharacter" then continue end
                local LastEntry = CharacterHistory[i - 1]
                local Length = (LastEntry.Position - Entry.Position).Magnitude
                local Line = Instance.new("CylinderHandleAdornment")
                Line.Transparency = 0.25
                Line.Name = `{i - 1}-{i}`
                Line.ZIndex = 0
                Line.AlwaysOnTop = true
                Line.Color3 = TYPE_TO_COLOR[Entry.Type]
                Line.Radius = 0.2
                Line.CFrame = CFrame.new(LastEntry.Position, Entry.Position) * CFrame.new(0, 0, -Length / 2)
                Line.Height = Length
                Line.Adornee = NewDisplayCenter
                Line.Parent = NewDisplayCenter
            end

            --Update the screen text.
            local Text =  "Total entries: "..tostring(#CharacterHistory)
            for Type, Value in TypeCounts do
                Text ..= `\n{Type}: {Value}`
            end
            ScreenSizeText.Text = Text
        end

        Window:EnableRefreshing(Refresh)
        task.spawn(Refresh)

        Window:EnableClosing(function()
            if CurrentDisplayCenter then
                CurrentDisplayCenter:Destroy()
                CurrentDisplayCenter = nil
            end
            if CurrentInfoCenter then
                CurrentInfoCenter:Destroy()
                CurrentInfoCenter = nil
            end
        end)

        --Show the window.
        Window:SetRelativeSize(0.3, 0.175)
        Window:Show(UDim2.new(0.5, 0, 0.8, 0), Vector2.new(0.5, 1), Enum.NormalId.Bottom)
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "cmdbar",
    Category = "Administrative",
    Description = "Brings up the command line. Alternative to pressing F2.",
    Prefix = "!",
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        (IncludedCommandUtil.ForContext(CommandContext):GetApi().Cmdr :: any):SetEnabled(true)
    end,
}


--Implementation of a command.
--!strict

local MESSAGE_TYPE_TO_COLOR = {
    [Enum.MessageType.MessageError] = Color3.fromRGB(255, 0, 0),
    [Enum.MessageType.MessageInfo] = Color3.fromRGB(102, 127, 255),
    [Enum.MessageType.MessageWarning] = Color3.fromRGB(255, 153, 102),
}

local LogService = game:GetService("LogService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "debug",
    Category = "Administrative",
    Description = "Displays the output of the server.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the logs.
        local ServerOutputLogs = Api.Logs.new()
        Api.LogsRegistry:RegisterLogs("ServerOutput", ServerOutputLogs, Api.Configuration:GetCommandAdminLevel("Administrative", "debug"))

        --Listen for new output messages.
        LogService.MessageOut:Connect(function(Message, MessageType)
            ServerOutputLogs:Add({
                Font = Enum.Font.Code,
                Text = Message,
                TextColor3 = MESSAGE_TYPE_TO_COLOR[MessageType],
            })
        end)

        --Add the existing output.
        for _, Line in LogService:GetLogHistory() do
            ServerOutputLogs:Add({
                Font = Enum.Font.Code,
                Text = Line.message,
                TextColor3 = MESSAGE_TYPE_TO_COLOR[Line.messageType],
            })
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Command: string)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Server Output")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()
        TextList:DisplayLogs(Api.LogsRegistry:GetLogs("ServerOutput"), "OldestFirst")
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "featureflaglogs",
    Category = "Administrative",
    Description = "Opens up a window logs of feature flag changes.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        local NexusDataStore = require(ReplicatedStorage:WaitForChild("NexusAdminClient"):WaitForChild("Packages"):WaitForChild("NexusDataStore")) :: any
        xpcall(function()
            Api.CommandData.FeatureFlagLogsDataStore = NexusDataStore:GetDataStore("NexusAdmin_Persistence", "FeatureFlagLogs")
        end, function(ErrorMessage)
            warn(`Failed to get feature flag logs because {ErrorMessage}`)
        end)

        local GetFeatureFlagLogsFunction = Instance.new("RemoteFunction")
        GetFeatureFlagLogsFunction.Name = "GetFeatureFlagLogs"
        GetFeatureFlagLogsFunction.Parent = Api.EventContainer

        function GetFeatureFlagLogsFunction.OnServerInvoke(Player): {string}
            if Api.Authorization:IsPlayerAuthorized(Player, Api.Configuration:GetCommandAdminLevel("Administrative", "featureflaglogs")) then
                if Api.CommandData.FeatureFlagLogsDataStore then
                    local LogEntries = Api.CommandData.FeatureFlagLogsDataStore:Get("FeatureFlagChangesLog") or {}
                    local Logs = {}
                    for i = #LogEntries, 1, -1 do
                        local Log = LogEntries[i]
                        table.insert(Logs, `{Api.Time:GetDateTimeString(Log.Time)}: {Log.UserName} changed {Log.Name} from {Log.PreviousValue} to {Log.NewValue}`)
                    end
                    return Logs
                else
                    return {"Logs failed to load."}
                end
            else
                return {"Unauthorized"}
            end
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Feature Flag Logs")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()

        local function UpdateText()
            TextList:SetLines({"Loading..."})
            TextList:SetLines((Api.EventContainer:WaitForChild("GetFeatureFlagLogs") :: RemoteFunction):InvokeServer())
        end

        task.spawn(UpdateText)
        Window:EnableRefreshing(UpdateText)
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "featureflags",
    Category = "Administrative",
    Description = "Opens up a window containing the feature flags and their current value.",
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Feature Flags")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()

        local function UpdateText()
            local FeatureFlags = {}
            for _, FeatureFlagName in Api.FeatureFlags:GetAllFeatureFlags() do
                table.insert(FeatureFlags, `{FeatureFlagName} - {Api.FeatureFlags:GetFeatureFlag(FeatureFlagName)}`)
            end
            table.sort(FeatureFlags)
            TextList:SetLines(FeatureFlags)
        end

        task.spawn(UpdateText)
        Window:EnableRefreshing(UpdateText)
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "keybinds",
    Category = "Administrative",
    Description = "Displays the current keybinds.",
    Prefix = "!",
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Keybinds")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()

        local function UpdateText()
            local Keybinds = {}
            for Key, Commands in Api.CommandData.Keybinds do
                for _, Command in Commands do
                    table.insert(Keybinds, `{(Key :: Enum.KeyCode).Name}: {Command}`)
                end
            end
            TextList:SetLines(Keybinds)
        end

        task.spawn(UpdateText)
        Window:EnableRefreshing(UpdateText)
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local LogService = game:GetService("LogService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "localdebug",
    Category = "Administrative",
    Description = "Displays the output of a client.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to get the local logs of.",
        },
    },
    ClientLoad = function(Api: Types.NexusAdminApi)
        --Connect the remote function.
        (Api.EventContainer:WaitForChild("GetClientOutput") :: RemoteFunction).OnClientInvoke = function()
            local Output = {}
            for _,Line in LogService:GetLogHistory() do
                local LineData = {
                    Font = Enum.Font.Code,
                    Text = Line.message,
                }
                table.insert(Output,LineData)

                if Line.messageType == Enum.MessageType.MessageError then
                    LineData.TextColor3 = Color3.fromRGB(255, 0, 0)
                elseif Line.messageType == Enum.MessageType.MessageInfo then
                    LineData.TextColor3 = Color3.fromRGB(102, 127, 255)
                elseif Line.messageType == Enum.MessageType.MessageWarning then
                    LineData.TextColor3 = Color3.fromRGB(255, 153, 102)
                end
            end

            return Output
        end
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the remote function.
        local GetClientOutputRemoteFunction = Instance.new("RemoteFunction")
        GetClientOutputRemoteFunction.Name = "GetClientOutput"
        GetClientOutputRemoteFunction.Parent = Api.EventContainer

        function GetClientOutputRemoteFunction.OnServerInvoke(Player, TargetPlayer)
            if not TargetPlayer or not TargetPlayer.Parent then
                return {"Disconnected"}
            elseif Api.Authorization:IsPlayerAuthorized(Player, Api.Configuration:GetCommandAdminLevel("Administrative", "localdebug")) then
                return GetClientOutputRemoteFunction:InvokeClient(TargetPlayer)
            else
                return {"Unauthorized"}
            end
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the windows.
        for _, Player in Players do
            local Window = Api.Window:CreateWindow(`Client Output - {Player.DisplayName} ({Player.Name})`)
            local TextList = Window:AddTextList()
            TextList:EnableSearching()

            local function UpdateText()
                TextList:SetLines({"Loading..."})
                TextList:SetLines((Api.EventContainer:WaitForChild("GetClientOutput") :: RemoteFunction):InvokeServer(Player))
            end

            task.spawn(UpdateText)
            Window:EnableRefreshing(UpdateText)
            Window:EnableClosing()
            Window:EnableResizing()
            Window:Show()
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "logs",
    Category = "Administrative",
    Description = "Opens up a window containing the logs of the commands used.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        Api.LogsRegistry:RegisterLogs("MainLogs", Api.Logs, Api.Configuration:GetCommandAdminLevel("Administrative", "logs"))
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Logs")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()
        TextList:DisplayLogs(Api.LogsRegistry:GetLogs("MainLogs"), "NewestFirst")
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))
local Serialization = nil
if RunService:IsClient() then
    Serialization = require(script.Parent.Parent:WaitForChild("Resources"):WaitForChild("Serialization")) :: any
end

return {
    Keyword = "snapshot",
    Category = "Administrative",
    Description = "Displays the current ScreenGuis of a player. CoreGuis are not shown due to security permissions.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Player",
            Description = "Player to view the snapshot of. Multiple players is not supported.",
        },
    },
    ClientLoad = function(Api: Types.NexusAdminApi)
        (Api.EventContainer:WaitForChild("GetClientViewRemoteFunction") :: RemoteFunction).OnClientInvoke = function()
            --Get the ScreenGuis.
            local PlayerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
            local SnapshotRootFolder = PlayerGui:FindFirstChild("NexusAdmin_Snapshots")
            local BaseScreenGuis = {}
            local ScreenGuis = {}
            for _, ScreenGui in PlayerGui:GetDescendants() do
                if ScreenGui:IsA("ScreenGui") and ScreenGui.Enabled and #ScreenGui:GetChildren() > 0 and (not SnapshotRootFolder or not ScreenGui:IsDescendantOf(SnapshotRootFolder)) then
                    table.insert(BaseScreenGuis, ScreenGui)
                end
            end
            for _, ScreenGui in BaseScreenGuis do
                local ContainedInScreenGui = false
                for _, OtherScreenGui in BaseScreenGuis do
                    if ScreenGui:IsDescendantOf(OtherScreenGui) then
                        ContainedInScreenGui = true
                        break
                    end
                end
                if not ContainedInScreenGui then
                    table.insert(ScreenGuis, ScreenGui)
                end
            end

            --Determine the screen resolution.
            local Resolution = Workspace.CurrentCamera.ViewportSize
            if #ScreenGuis > 0 then
                Resolution = ScreenGuis[1].AbsoluteSize
            end

            --Return the data.
            return {
                ScreenSizeX = Resolution.X,
                ScreenSizeY = Resolution.Y,
                ScreenGuis = Serialization:Serialize(ScreenGuis, function(Ins)
                    return Ins:IsA("GuiObject") and not Ins.Visible
                end),
            }
        end
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the remote function.
        local GetClientViewRemoteFunction = Instance.new("RemoteFunction")
        GetClientViewRemoteFunction.Name = "GetClientViewRemoteFunction"
        GetClientViewRemoteFunction.Parent = Api.EventContainer

        function GetClientViewRemoteFunction.OnServerInvoke(Player, TargetPlayer)
            if not TargetPlayer or not TargetPlayer.Parent then
                return nil
            elseif Api.Authorization:IsPlayerAuthorized(Player, Api.Configuration:GetCommandAdminLevel("Administrative", "snapshot")) then
                return GetClientViewRemoteFunction:InvokeClient(TargetPlayer)
            else
                return "Unauthorized"
            end
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext, PlayersList: {Player})
        local Player = PlayersList[1]
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Determine the offset.
        local PlayerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
        local Offset = 0
        for _, Folder in PlayerGui:GetChildren() do
            local SnapshotBackground = Folder:FindFirstChild("SnapshotBackground")
            if Folder:IsA("Folder") and SnapshotBackground then
                Offset = math.max(Offset, SnapshotBackground.DisplayOrder)
            end
        end
        Offset = Offset + 1000

        --Create the containers.
        local SnapshotRootFolder = PlayerGui:FindFirstChild("NexusAdmin_Snapshots")
        if not SnapshotRootFolder then
            SnapshotRootFolder = Instance.new("Folder")
            SnapshotRootFolder.Name = "NexusAdmin_Snapshots"
            SnapshotRootFolder.Parent = PlayerGui
        end

        local SnapshotFolder = Instance.new("Folder")
        SnapshotFolder.Name = `Snapshot_{Player}`
        SnapshotFolder.Parent = SnapshotRootFolder

        local SnapshotBackground = Instance.new("ScreenGui")
        SnapshotBackground.Name = "SnapshotBackground"
        SnapshotBackground.DisplayOrder = Offset
        SnapshotBackground.Parent = SnapshotFolder

        local SnapshotBackgroundFrame = Instance.new("Frame")
        SnapshotBackgroundFrame.BackgroundTransparency = 0.75
        SnapshotBackgroundFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
        SnapshotBackgroundFrame.BorderSizePixel = 0
        SnapshotBackgroundFrame.Size = UDim2.new(1, 0, 1, 0)
        SnapshotBackgroundFrame.Parent = SnapshotBackground

        local SnapshotScreenGuisFolder = Instance.new("Folder")
        SnapshotScreenGuisFolder.Name = "ScreenGuis"
        SnapshotScreenGuisFolder.Parent = SnapshotFolder

        --Create the window.
        local Camera = Workspace.Camera
        local CameraViewportSize = Camera.ViewportSize
        local GetClientViewRemoteFunction = Api.EventContainer:WaitForChild("GetClientViewRemoteFunction") :: RemoteFunction
        local Window = Api.Window:CreateWindow(`Snapshot - {Player.DisplayName} ({Player.Name})`)
        Window:EnableResizing()

        local ScreenSizeText = Instance.new("TextLabel")
        ScreenSizeText.BackgroundTransparency = 1
        ScreenSizeText.Size = UDim2.new(0.95, 0, 1, -10)
        ScreenSizeText.Position = UDim2.new(0.025, 0, 0, 5)
        ScreenSizeText.Font = Enum.Font.SourceSans
        ScreenSizeText.TextColor3 = Color3.fromRGB(255, 255, 255)
        ScreenSizeText.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
        ScreenSizeText.TextStrokeTransparency = 0
        ScreenSizeText.TextSize = CameraViewportSize.Y * 0.5 * 0.045
        ScreenSizeText.TextXAlignment = Enum.TextXAlignment.Left
        ScreenSizeText.TextYAlignment = Enum.TextYAlignment.Top
        ScreenSizeText.Text = "Loading..."
        ScreenSizeText.Parent = Window.ContentsAdorn

        local function Refresh()
            --Get the screen data.
            ScreenSizeText.Text = "Loading..."
            local ScreenData = GetClientViewRemoteFunction:InvokeServer(Player)
            if not ScreenData then
                return
            end

            --Update the screen text.
            ScreenSizeText.Text = `Screen size X: {ScreenData.ScreenSizeX}\nScreen size Y: {ScreenData.ScreenSizeY}`

            --Show the ScreenGuis.
            SnapshotScreenGuisFolder:ClearAllChildren()
            for _, ScreenGui in Serialization:Deserialize(ScreenData.ScreenGuis) do
                ScreenGui.Parent = SnapshotScreenGuisFolder
                ScreenGui.DisplayOrder += (1000 + 1)
            end
        end

        Window:EnableRefreshing(Refresh)
        task.spawn(Refresh)

        Window:EnableClosing(function()
            SnapshotBackground:Destroy()
            SnapshotScreenGuisFolder:Destroy()
        end)

        --Show the window.
        Window:SetDisplayOrder(Offset + 900)
        Window:SetRelativeSize(0.3, 0.125)
        Window:Show(UDim2.new(0.5, 0, 0.8, 0), Vector2.new(0.5, 1), Enum.NormalId.Bottom)
    end,
}


--Implementation of a command.
--!strict

local INDENT = "    "

local Workspace = game:GetService("Workspace")
local Localizationservice = game:GetService("LocalizationService")
local PolicyService = game:GetService("PolicyService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local VRServie = game:GetService("VRService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

--[[
Attempts to determine the client type.
--]]
local function GetAddressLength(): number
    local MemoryAddressLength = string.match(tostring({}), "x([%dabcdef]+)") :: string
    while true do
        local RemainingAddress = string.match(MemoryAddressLength, "^00000000([%dabcdef]+)")
        if not RemainingAddress then break end
        MemoryAddressLength = RemainingAddress :: string
    end
    return string.len(MemoryAddressLength) * 4
end

--[[
Tries to get a value as a string.
--]]
local function TryGet(Call: () -> (any)): string
    local Worked, Return = pcall(function()
        return tostring(Call())
    end)
    if Worked then
        return Return
    end
    return "Unknown"
end

--[[
Converts an enum to a string.
--]]
local function EnumToString(EnumItem: any): string
    return tostring(string.match(tostring(EnumItem), "[^%.]+%.[^%.]+%.(.+)"))
end

return {
    Keyword = "system",
    Category = "Administrative",
    Description = "Displays information about the system of a client.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to get the system information of.",
        },
    },
    ClientLoad = function(Api: Types.NexusAdminApi)
        --Connect the remote function.
        (Api.EventContainer:WaitForChild("GetSystemInformation") :: RemoteFunction).OnClientInvoke = function()
            local Output = {}

            --Add the initial client information.
            table.insert(Output, `Client version: {TryGet(Version)}`)
            table.insert(Output, `Client type: {TryGet(GetAddressLength)}-bit ({tostring({})})`)
            table.insert(Output, `Client uptime: {Workspace.DistributedGameTime} seconds`)
            table.insert(Output, "")

            --Add the localization information.
            table.insert(Output, "Localization:")
            table.insert(Output, `{INDENT}RobloxLocaleId: {TryGet(function() return Localizationservice.RobloxLocaleId end)}`)
            table.insert(Output, `{INDENT}SystemLocaleId: {TryGet(function() return Localizationservice.SystemLocaleId end)}`)
            table.insert(Output, "")

            --Add the input information.
            table.insert(Output, "Hardware:")
            for _, PropertyName in {"KeyboardEnabled", "MouseEnabled", "TouchEnabled", "GamepadEnabled", "VREnabled", "AccelerometerEnabled", "GyroscopeEnabled"} do
                table.insert(Output, `{INDENT}{PropertyName}: {TryGet(function() return UserInputService[PropertyName] end)}`)
                if PropertyName == "GamepadEnabled" then
                    for _, EnumItem in Enum.UserInputType:GetEnumItems() do
                        local EnumItemName = EnumToString(EnumItem)
                        if not string.find(EnumItemName, "Gamepad") then continue end
                        table.insert(Output, `{INDENT}{INDENT}{EnumItemName}: {TryGet(function() return UserInputService:GetGamepadConnected(EnumItem) end)}`)
                    end
                elseif PropertyName == "VREnabled" then
                    for _, EnumItem in Enum.UserCFrame:GetEnumItems() do
                        local EnumItemName = EnumToString(EnumItem)
                        table.insert(Output, `{INDENT}{INDENT}{EnumItemName}: {TryGet(function() return VRServie:GetUserCFrameEnabled(EnumItem) end)}`)
                    end
                end
            end
            table.insert(Output, "")

            --Add the runtime information.
            table.insert(Output, "Runtime:")
            for _, MethodName in {"IsClient", "IsServer", "IsStudio", "IsEdit", "IsRunMode"} do
                table.insert(Output, `{INDENT}{MethodName}: {TryGet(function() return RunService[MethodName](RunService) end)}`)
            end

            --Return the output.
            return Output
        end
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the remote function.
        local GetSystemInformationRemoteFunction = Instance.new("RemoteFunction")
        GetSystemInformationRemoteFunction.Name = "GetSystemInformation"
        GetSystemInformationRemoteFunction.Parent = Api.EventContainer

        function GetSystemInformationRemoteFunction.OnServerInvoke(Player, TargetPlayer: Player)
            if not TargetPlayer or not TargetPlayer.Parent then
                return {"Disconnected"}
            elseif Api.Authorization:IsPlayerAuthorized(Player, Api.Configuration:GetCommandAdminLevel("Administrative", "system")) then
                local Output = GetSystemInformationRemoteFunction:InvokeClient(TargetPlayer)
                xpcall(function()
                    local Policy = PolicyService:GetPolicyInfoForPlayerAsync(TargetPlayer)
                    table.insert(Output, "")
                    table.insert(Output, "Policy:")
                    for Key, Value in Policy do
                        if typeof(Value) == "table" then
                            table.insert(Output, `{INDENT}{Key}:`)
                            for SubKey, SubValue in Value do
                                table.insert(Output, `{INDENT}{INDENT}{SubKey}: {SubValue}`)
                            end
                        else
                            table.insert(Output, `{INDENT}{Key}: {Value}`)
                        end
                    end
                end, function(ErrorMessage: string)
                    warn(`Failed to fetch policy for {TargetPlayer.UserId} because {ErrorMessage}`)
                end)
                return Output
            else
                return {"Unauthorized"}
            end
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the windows.
        for _, Player in Players do
            local Window = Api.Window:CreateWindow(`System - {Player.DisplayName} ({Player.Name})`)
            local TextList = Window:AddTextList("TextLabel")
            TextList:EnableSearching()

            local function UpdateText()
                TextList:SetLines({"Loading..."})
                TextList:SetLines((Api.EventContainer:WaitForChild("GetSystemInformation") :: RemoteFunction):InvokeServer(Player))
            end

            task.spawn(UpdateText)
            Window:EnableRefreshing(UpdateText)
            Window:EnableClosing()
            Window:EnableResizing()
            Window:Show()
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "unban",
    Category = "Administrative",
    Description = "Unbans players.",
    Arguments = {
        {
            Type = "string",
            Name = "Players",
            Description = "Players to unban.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, PlayersString: string)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Get the user ids to remove.
        local UserIdsToRemove = {}
        for _, PlayerString in string.split(PlayersString, ",") do
            PlayerString = string.lower(PlayerString)
            if PlayerString == "all" or PlayerString == "other" or PlayerString == "*" then
                for UserId, _ in Api.CommandData.BannedUserIds do
                    table.insert(UserIdsToRemove, UserId)
                end
            else
                for UserId, Data in Api.CommandData.BannedUserIds do
                    if string.find(Data[2], PlayerString) then
                        table.insert(UserIdsToRemove, UserId)
                    else
                        Util:SendError(`"{PlayerString}" doesn't match a banned user.`)
                    end
                end
            end
        end

        --Unban the users.
        for _, UserId in UserIdsToRemove do
            Api.CommandData.BannedUserIds[UserId] = nil
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "unkeybind",
    Category = "Administrative",
    Description = "Unbinds the key from all commands.",
    Prefix = "!",
    Arguments = {
        {
            Type = "userInput",
            Name = "Key",
            Description = "Key to bind.",
        },
    },
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Key: Enum.KeyCode)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Unbind the key.
        if Api.CommandData.Keybinds[Key] then
            Api.CommandData.Keybinds[Key] = nil
            return "Key unbound."
        else
            return "Key was not bound."
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "age",
    Category = "BasicCommands",
    Description = "Displays the age of a set of players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to show the age of.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)

        --Show the ages.
        for _, Player in Players do
            Util:SendMessage(`{Player.DisplayName} ({Player.Name}, {Player.UserId}) has the age of {Player.AccountAge} days.`)
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))
local Sword = script.Parent.Parent:WaitForChild("Resources"):WaitForChild("Sword")

return {
    Keyword = "atksword",
    Category = "BasicCommands",
    Description = "Gives an anti-teamkill sword to the given players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to give swords.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Give the swords.
        for _, Player in Players do
            local Backpack = Player:FindFirstChild("Backpack")
            if Backpack then
                local NewSword = Sword:Clone()
                NewSword.CanBeDropped = Api.FeatureFlags:GetFeatureFlag("AllowDroppingSwords")
                NewSword:WaitForChild("Configurations"):WaitForChild("CanTeamkill").Value = false
                NewSword.Parent = Backpack
            end
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "change",
    Category = "BasicCommands",
    Description = "Changes the stat of a set of players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to reset the stats for.",
        },
        {
            Type = "strings",
            Name = "Stats",
            Description = "Stats to change.",
        },
        {
            Type = "string",
            Name = "Value",
            Description = "Value to change to.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player}, Stats: {string}, Value: string)
        local Util = IncludedCommandUtil.ForContext(CommandContext)

        --Reset the stats.
        for _, Player in Players do
            local leaderstats = Player:FindFirstChild("leaderstats")
            if leaderstats then
                for _, Stat in leaderstats:GetChildren() do
                    for _, StatName in Stats do
                        StatName = string.lower(StatName)
                        if string.sub(string.lower(Stat.Name), 1, string.len(StatName)) == StatName then
                            if type((Stat :: StringValue).Value) == "string" then
                                (Stat :: StringValue).Value = Value
                            elseif type((Stat :: NumberValue).Value) == "number" then
                                (Stat :: NumberValue).Value = tonumber(Value) or (Stat :: NumberValue).Value
                            else
                                Util:SendError("Unable to assign value to stat.")
                            end
                        end
                    end
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Players = game:GetService("Players")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "chatlogs",
    Category = "BasicCommands",
    Description = "Opens up a window containing the chat logs.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the logs.
        local ChatLogs = Api.Logs.new()
        Api.LogsRegistry:RegisterLogs("ChatLogs", ChatLogs, Api.Configuration:GetCommandAdminLevel("BasicCommands", "chatlogs"))
        local ChatEvents = {}

        --[[
        Connects the Chatted event for a player.
        --]]
        local function ConnectPlayerChatted(Player: Player)
            ChatEvents[Player] = Player.Chatted:Connect(function(Message: string)
                ChatLogs:Add(`{Player.Name} [{Api.Time:GetTimeString()}]: {Api.Filter:FilterString(Message, Player)}`)
            end)
        end

        --Connect the players.
        Players.PlayerRemoving:Connect(function(Player)
            if not ChatEvents[Player] then return end
            ChatEvents[Player]:Disconnect()
            ChatEvents[Player] = nil
        end)
        Players.PlayerAdded:Connect(ConnectPlayerChatted)
        for _, Player in Players:GetPlayers() do
            ConnectPlayerChatted(Player)
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Chat Logs")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()
        TextList:DisplayLogs(Api.LogsRegistry:GetLogs("ChatLogs"), "NewestFirst")
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local Workspace = game:GetService("Workspace")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "clean",
    Category = "BasicCommands",
    Description = "Clears items that admins have created.",
    ServerRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Clear the dropped tools.
        for _, Ins in Workspace:GetChildren() do
            if Ins:IsA("Tool") then
                Ins:Destroy()
            end
        end

        --Clear the admin items.
        Api.AdminItemContainer:ClearAllChildren()
    end,
}


--Implementation of a command.
--!strict

local HttpService = game:GetService("HttpService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "countdown",
    Category = "BasicCommands",
    Description = "Creates a countdown with the given seconds.",
    Arguments = {
        {
            Type = "integer",
            Name = "Time",
            Description = "Time to count down.",
        },
    },
    ClientLoad = function(Api: Types.NexusAdminApiClient)
        Api.CommandData.Countdowns = {}

        --[[
        Performs a countdown.
        --]]
        local function PerformCountdown(Duration: number)
            --Create the psuedo-object.
            local Countdown = {}
            Countdown.Active = true
            function Countdown:Start()
                for i = Duration, 1, -1 do
                    if not self.Active then return end
                    Api.Messages:DisplayHint(tostring(i), 1)
                    task.wait(1)
                end
            end
            function Countdown:Stop()
                self.Active = false
            end

            --Store the countdown and start it.
            table.insert(Api.CommandData.Countdowns, Countdown)
            Countdown:Start()
        end

        --Connect the remote event.
        (IncludedCommandUtil:GetRemote("StartCountdown") :: RemoteEvent).OnClientEvent:Connect(function(Duration)
            PerformCountdown(Duration)
        end)

        task.spawn(function()
            --Wait for the previous countdowns to load.
            local PreviousCountdownsValue = IncludedCommandUtil:GetRemote("PreviousCountdowns") :: StringValue
            while PreviousCountdownsValue.Value == "" do
                wait()
            end

            --Start the existing countdowns.
            for _, CountdownEnd in HttpService:JSONDecode(PreviousCountdownsValue.Value) do
                local RemainingTime = math.floor(CountdownEnd - os.time())
                if RemainingTime > 0 then
                    PerformCountdown(RemainingTime)
                end
            end
        end)
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        IncludedCommandUtil:CreateRemote("RemoteEvent", "StartCountdown")
        IncludedCommandUtil:CreateRemote("StringValue", "PreviousCountdowns", {Value = "[]"})
    end,
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Duration: number)
        local Util = IncludedCommandUtil.ForContext(CommandContext);

        --Send the countdown.
        (Util:GetRemote("StartCountdown") :: RemoteEvent):FireAllClients(Duration)

        --Store the countdown.
        local PreviousCountdownsValue = Util:GetRemote("PreviousCountdowns") :: StringValue
        local PreviousCountdowns = HttpService:JSONDecode(PreviousCountdownsValue.Value)
        table.insert(PreviousCountdowns, os.time() + Duration)
        PreviousCountdownsValue.Value = HttpService:JSONEncode(PreviousCountdowns)
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "crash",
    Category = "BasicCommands",
    Description = "Crashes a set of players. Admins can not be crashed.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to crash.",
        },
    },
    ClientLoad = function(Api: Types.NexusAdminApi)
        (IncludedCommandUtil:GetRemote("CrashPlayer") :: RemoteEvent).OnClientEvent:Connect(function()
            while true do
                string.rep("Crash",3e12)
            end
        end)
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        IncludedCommandUtil:CreateRemote("RemoteEvent", "CrashPlayer")
    end,
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Crash the players.
        local CrashPlayerEvent = Util:GetRemote("CrashPlayer") :: RemoteEvent
        for _, Player in Players do
            if Api.Authorization:GetAdminLevel(Player) >= 0 then
                Util:SendError("You can't crash admins.")
            else
                CrashPlayerEvent:FireClient(Player)
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Teams = game:GetService("Teams")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "createteam",
    Category = "BasicCommands",
    Description = "Creates teams of given colors and given name.",
    Arguments = {
        {
            Type = "brickColors",
            Name = "Colors",
            Description = "Colors to create.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Colors: {BrickColor})
        local Util = IncludedCommandUtil.ForContext(CommandContext)

        --Create the teams.
        for _, Color in Colors do
            --Get if the team exists.
            local ExistingTeam
            for _, Team in Teams:GetTeams() do
                if Team.TeamColor == Color then
                    ExistingTeam = Team
                end
            end

            --Create a team or display an error.
            if ExistingTeam then
                Util:SendError(`Team with color {Color} ({ExistingTeam.Name}) already exists.`)
            else
                local NewTeam = Instance.new("Team")
                NewTeam.TeamColor = Color
                NewTeam.AutoAssignable = false
                NewTeam.Name = `{Color} Team`
                NewTeam.Parent = Teams
            end
        end
    end,
}


--Implementation of a command.
--!strict

local InsertService = game:GetService("InsertService")

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "gear",
    Category = "BasicCommands",
    Description = "Gives gear items to the given players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to give the gear.",
        },
        {
            Type = "integers",
            Name = "Ids",
            Description = "Gear ids to insert.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player}, Ids: {number})
        --Get the tools.
        local Tools = {}
        for _, Id in Ids do
            local Model = InsertService:LoadAsset(Id)
            for _, Tool in Model:GetChildren() do
                if Tool:IsA("Tool") then
                    table.insert(Tools,Tool)
                end
            end
        end

        --Give the tools to the players.
        for _, Player in Players do
            local Backpack = Player:FindFirstChild("Backpack")
            if Backpack then
                for _, Tool in Tools do
                    Tool:Clone().Parent = Backpack
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))
local ToolListEnum = require(script.Parent.Parent:WaitForChild("Resources"):WaitForChild("ToolListEnum"))

return {
    Keyword = "give",
    Category = "BasicCommands",
    Description = "Gives a set of players tools matching the tool name(s) from Lighting, ReplicatedStorage, ServerStorage, or StarterPack.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to give tools.",
        },
        {
            Type = "nexusAdminTools",
            Name = "Tools",
            Description = "Tools to give.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player}, ToolNames: {string})
        --Give the tools.
        for _, Tool in ToolListEnum:GetTools(ToolNames) do
            for _, Player in Players do
                local Backpack = Player:FindFirstChild("Backpack")
                if Backpack then
                    Tool:Clone().Parent = Backpack
                end
            end
        end
    end
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = {"inventory", "viewinventory"},
    Category = "BasicCommands",
    Description = "Displays the inventory of the given players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to show the inventory of.",
        },
    },
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Inventories")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()

        local function UpdateText()
            --Get the inventories.
            local Inventories = {}
            for _,Player in Players do
                local Inventory = `{Player.Name}:`

                --Add the backpack tools.
                local Backpack = Player:FindFirstChildOfClass("Backpack")
                if Backpack then
                    for _, Tool in Backpack:GetChildren() do
                        if Tool:IsA("BackpackItem") then
                            Inventory = `{Inventory}\n    {Tool.Name}`
                        end
                    end
                end

                --Add the character tools.
                local Character = Player.Character
                if Character then
                    for _, Tool in Character:GetChildren() do
                        if Tool:IsA("BackpackItem") then
                            Inventory = `{Inventory}\n    {Tool.Name}`
                        end
                    end
                end

                --Add the line.
                table.insert(Inventories, Inventory)
            end

            --Sort the lines by name.
            table.sort(Inventories, function(a, b) return string.lower(a) < string.lower(b) end)
            TextList:SetLines(Inventories)
        end

        task.spawn(UpdateText)
        Window:EnableRefreshing(UpdateText)
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local Players = game:GetService("Players")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "joinlogs",
    Category = "BasicCommands",
    Description = "Opens up a window containing the logs of when players joined and left.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the logs.
        local JoinLogs = Api.Logs.new()
        Api.LogsRegistry:RegisterLogs("JoinLogs", JoinLogs, Api.Configuration:GetCommandAdminLevel("BasicCommands", "joinlogs"))

        --Connect the players.
        Players.PlayerAdded:Connect(function(Player)
            JoinLogs:Add(`[{Api.Time:GetTimeString()}]: {Player.DisplayName} ({Player.Name}, {Player.UserId}) joined.`)
        end)
        Players.PlayerRemoving:Connect(function(Player, ExitReason)
            JoinLogs:Add(`[{Api.Time:GetTimeString()}]: {Player.DisplayName} ({Player.Name}, {Player.UserId}) left ({ExitReason.Name}).`)
        end)
        for _, Player in Players:GetPlayers() do
            JoinLogs:Add(`[{Api.Time:GetTimeString()}]: {Player.DisplayName} ({Player.Name}, {Player.UserId}) was already in the server when Nexus Admin loaded.`)
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Join Logs")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()
        TextList:DisplayLogs(Api.LogsRegistry:GetLogs("JoinLogs"), "NewestFirst")
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local Players = game:GetService("Players")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "killlogs",
    Category = "BasicCommands",
    Description = "Opens up a window containing the logs of kills.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the logs.
        local KillLogs = Api.Logs.new()
        Api.LogsRegistry:RegisterLogs("KillLogs", KillLogs, Api.Configuration:GetCommandAdminLevel("BasicCommands", "killlogs"))
        local CharacterAddedEvents = {}
        local DiedEvents = {}

        --[[
        Connects the a character dieing.
        --]]
        local function CharacterAdded(Player: Player, Character: Model): ()
            --Disconnect the previous event.
            if DiedEvents[Player] then
                DiedEvents[Player]:Disconnect()
            end

            --Connect the humanoid death.
            local Humanoid = Character:WaitForChild("Humanoid") :: Humanoid
            local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") :: BasePart
            DiedEvents[Player] = Humanoid.Died:Connect(function()
                --Get the information.
                local CreatorTag = Humanoid:FindFirstChild("creator")
                local KillingPlayer = CreatorTag and (CreatorTag :: ObjectValue).Value :: Player
                local KillingCharacter = KillingPlayer and KillingPlayer.Character :: Model
                local KillingCharacterTool = KillingCharacter and KillingCharacter:FindFirstChildOfClass("Tool") :: Tool
                local KillingCharacterHumanoidRootPart = KillingCharacter and KillingCharacter:FindFirstChild("HumanoidRootPart") :: BasePart

                --Build and store the message.
                local Timestamp = `[{Api.Time:GetTimeString()}]: `
                local KilledPlayerName = `{Player.DisplayName} ({Player.Name})`
                if KillingPlayer then
                    local KillingPlayerName = `{KillingPlayer.DisplayName} ({KillingPlayer.Name})`
                    local Message = `{Timestamp}{KillingPlayerName} killed {KilledPlayerName} `
                    if KillingCharacterTool then
                        Message = `{Message}holding {KillingCharacterTool.Name} `
                    end
                    if KillingCharacterHumanoidRootPart then
                        Message = `{Message}({(KillingCharacterHumanoidRootPart.Position - HumanoidRootPart.Position).Magnitude} studs)`
                    end
                    KillLogs:Add(Message)
                else
                    KillLogs:Add(`{Timestamp}{KilledPlayerName} died.`)
                end
            end)
        end

        --[[
        Connects the characters being added for a player.
        --]]
        local function PlayerAdded(Player: Player): ()
            CharacterAddedEvents[Player] = Player.CharacterAdded:Connect(function(Character)
                CharacterAdded(Player, Character)
            end)
            if Player.Character then
                CharacterAdded(Player, Player.Character)
            end
        end

        --Connect the players.
        Players.PlayerRemoving:Connect(function(Player)
            if CharacterAddedEvents[Player] then
                CharacterAddedEvents[Player]:Disconnect()
                CharacterAddedEvents[Player] = nil
            end
            if DiedEvents[Player] then
                DiedEvents[Player]:Disconnect()
                DiedEvents[Player] = nil
            end
        end)
        Players.PlayerAdded:Connect(PlayerAdded)
        for _,Player in Players:GetPlayers() do
            task.spawn(function()
                PlayerAdded(Player)
            end)
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Kill Logs")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()
        TextList:DisplayLogs(Api.LogsRegistry:GetLogs("KillLogs"), "NewestFirst")
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local TextChatService = game:GetService("TextChatService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "mute",
    Category = "BasicCommands",
    Description = "Mutes a set of players. Admins can not be muted.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to mute.",
        },
    },
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Create the event.
        Api.CommandData.MutedPlayers = {}

        --Handle muted players joining.
        task.spawn(function()
            local TextChannels = TextChatService:WaitForChild("TextChannels", 10 ^ 99)
            local GeneralChat = TextChannels:WaitForChild("RBXGeneral")
            GeneralChat.ChildAdded:Connect(function(TextSource)
                if not TextSource:IsA("TextSource") then return end
                if not Api.CommandData.MutedPlayers[TextSource.UserId] then return end
                TextSource.CanSend = false
            end)
        end)
    end,
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Mute the players.
        local TextChannels = TextChatService:FindFirstChild("TextChannels")
        local GeneralChat = TextChannels and TextChannels:FindFirstChild("RBXGeneral")
        for _, Player in Players do
            if Api.Authorization:GetAdminLevel(Player) >= 0 then
                Util:SendError("You can't mute admins.")
            else
                Api.CommandData.MutedPlayers[Player.UserId] = true
                local PlayerSource = GeneralChat and GeneralChat:FindFirstChild(Player.Name) :: TextSource
                if PlayerSource then
                    PlayerSource.CanSend = false
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "punish",
    Category = "BasicCommands",
    Description = "Punishes a set of players by removing their character.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to punish.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        for _,Player in Players do
            local Character = Player.Character
            if Character then
                Character:Destroy()
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "removeteam",
    Category = "BasicCommands",
    Description = "Removes selected teams.",
    Arguments = {
        {
            Type = "teams",
            Name = "Teams",
            Description = "Teams to remove.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Teams: {Team})
        for _,Team in Teams do
            Team:Destroy()
        end
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "removetools",
    Category = "BasicCommands",
    Description = "Removes all tools from the players given.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to remove tools from.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        for _, Player in Players do
            --Unequip the character.
            if Player.Character then
                local Humanoid = Player.Character:FindFirstChildOfClass("Humanoid")
                if Humanoid then
                    Humanoid:UnequipTools()
                end
            end

            --Clear the backback.
            local Backpack = Player:FindFirstChild("Backpack")
            if Backpack then
                for _, Tool in Backpack:GetChildren() do
                    if Tool:IsA("BackpackItem") then
                        Tool:Destroy()
                    end
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "resetstats",
    Category = "BasicCommands",
    Description = "Resets all number leaderstats of a player.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to reset the stats for.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        for _, Player in Players do
            local leaderstats = Player:FindFirstChild("leaderstats")
            if leaderstats then
                for _,Stat in leaderstats:GetChildren() do
                    if Stat:IsA("ValueBase") and type((Stat :: NumberValue).Value) == "number" then
                        (Stat :: NumberValue).Value = 0
                    end
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Players = game:GetService("Players")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "shutdown",
    Category = "BasicCommands",
    Description = "Shuts down the server.",
    ServerRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetServerApi()

        --Display the server is shutting down.
        for _,Player in Players:GetPlayers() do
            Api.Messages:DisplayMessage(Player, "Nexus Admin", "Server is shutting down.")
        end
        task.wait(1)

        --Kick the players.
        for _,Player in Players:GetPlayers() do
            Player:Kick("Server has shut down.")
        end
        Players.PlayerAdded:Connect(function(Player)
            Player:Kick("Server has shut down.")
        end)
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "sortteams",
    Category = "BasicCommands",
    Description = "Splits the given players into teams with some randomness.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to sort.",
        },
        {
            Type = "teams",
            Name = "Teams",
            Description = "Teams to sort to.",
        },
    },
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        --Set the default sort method.
        --No sorting is done by default, but some services use custom initial sorting.
        if not Api.CommandData.SortTeamsSortMethod then
            Api.CommandData.SortTeamsSortMethod = function(Players)
                return Players
            end
        end
    end,
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player}, Teams: {Team})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Sort the players.
        if Api.CommandData.SortTeamsSortMethod then
            Players = Api.CommandData.SortTeamsSortMethod(Players)
        end

        --Assign the players to teams.
        --Players are sorted and then randomized in groupings by team.
        for i = 1, math.ceil(#Players / #Teams) do
            --Determine the team indexes and randomize them.
            local TeamIndexes = {}
            for j = 1, #Teams do
                table.insert(TeamIndexes, j)
            end
            for j = 1, #TeamIndexes - 1 do
                local RandomIndex = math.random(j, #TeamIndexes)
                TeamIndexes[j], TeamIndexes[RandomIndex] = TeamIndexes[RandomIndex], TeamIndexes[j]
            end

            --Assign the players.
            for j, TeamIndex in TeamIndexes do
                local PlayerIndex = j + ((i - 1) * #TeamIndexes)
                local Player = Players[PlayerIndex]
                if Player then
                    Player.Neutral = false
                    Players[PlayerIndex].TeamColor = Teams[TeamIndex].TeamColor
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))
local ToolListEnum = require(script.Parent.Parent:WaitForChild("Resources"):WaitForChild("ToolListEnum"))

return {
    Keyword = "startergive",
    Category = "BasicCommands",
    Description = "Gives a set of players tools matching the tool name(s) from Lighting, ReplicatedStorage, ServerStorage, or StarterPack and makes it so they spawn with them.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to give tools.",
        },
        {
            Type = "nexusAdminTools",
            Name = "Tools",
            Description = "Tools to give.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player}, ToolNames: {string})
        for _, Tool in ToolListEnum:GetTools(ToolNames) do
            for _, Player in Players do
                local Backpack = Player:FindFirstChild("Backpack")
                local StarterGear = Player:FindFirstChild("StarterGear")
                if Backpack then
                    Tool:Clone().Parent = Backpack
                end
                if StarterGear then
                    Tool:Clone().Parent = StarterGear
                end
            end
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "stopcountdown",
    Category = "BasicCommands",
    Description = "Stops the current countdowns.",
    ClientLoad = function(Api: Types.NexusAdminApi)
        (IncludedCommandUtil:GetRemote("StopCountdown") :: RemoteEvent).OnClientEvent:Connect(function()
            --Stop and clear the countdowns.
            for _, Countdown in Api.CommandData.Countdowns do
                Countdown:Stop()
            end
            Api.CommandData.Countdowns = {}
        end)
    end,
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        IncludedCommandUtil:CreateRemote("RemoteEvent", "StopCountdown")
    end,
    ServerRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext);

        --Send the countdown stop.
        (Util:GetRemote("StopCountdown") :: RemoteEvent):FireAllClients();

        --Clear the countdown values.
        (Util:GetRemote("PreviousCountdowns") :: StringValue).Value = "[]"
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "stoploops",
    Category = "BasicCommands",
    Description = "Stops all active loop commands.",
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Times: number, Delay: number, Command: string)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Stop and unregister the loops.
        for _, Loop in Api.CommandData.Loops do
            Loop:Stop()
        end
        Api.CommandData.Loops = {}
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))
local Sword = script.Parent.Parent:WaitForChild("Resources"):WaitForChild("Sword")

return {
    Keyword = "sword",
    Category = "BasicCommands",
    Description = "Gives a sword to the given players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to give swords.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Give the swords.
        for _, Player in Players do
            local Backpack = Player:FindFirstChild("Backpack")
            if Backpack then
                local NewSword = Sword:Clone()
                NewSword.CanBeDropped = Api.FeatureFlags:GetFeatureFlag("AllowDroppingSwords")
                NewSword.Parent = Backpack
            end
        end
    end,
}


--Implementation of a command.
--!strict

local TOOL_CONTAINERS = {
    game:GetService("Lighting"),
    game:GetService("ReplicatedStorage"),
    game:GetService("ServerStorage"),
    game:GetService("StarterPack"),
}

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "tools",
    Category = "BasicCommands",
    Description = "Opens up a window containing the list of tools usable by :give.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        local ToolListEnum = require(script.Parent.Parent:WaitForChild("Resources"):WaitForChild("ToolListEnum"));
        (ToolListEnum :: any):SetUp(Api.Registry)

        --Create the remote function.
        local GetToolsInContainers = IncludedCommandUtil:CreateRemote("RemoteFunction", "GetToolsInContainers") :: RemoteFunction
        function GetToolsInContainers.OnServerInvoke(Player)
            if Api.Authorization:IsPlayerAuthorized(Player, Api.Configuration:GetCommandAdminLevel("BasicCommands", "tools")) then
                --Get the tools for each container.
                local ToolsByContainer = {}
                for _, Container in TOOL_CONTAINERS do
                    ToolsByContainer[Container] = {}
                end
                for _, Tool in ToolListEnum:GetTools({"all"}) do
                    for _, Container in TOOL_CONTAINERS do
                        if not Tool:IsDescendantOf(Container) then continue end
                        table.insert(ToolsByContainer[Container], Tool.Name)
                        break
                    end
                end

                --Create the list.
                local ToolsList = {} :: {string | {[string]: any}}
                for _, Container in TOOL_CONTAINERS do
                    table.insert(ToolsList, {Text=Container.Name, Font = Enum.Font.SourceSansBold})
                    local ToolsInContainer = ToolsByContainer[Container]
                    table.sort(ToolsInContainer, function(a, b) return string.lower(a) < string.lower(b) end)
                    if #ToolsInContainer ~= 0 then
                        for _,Tool in ToolsInContainer do
                            table.insert(ToolsList, Tool)
                        end
                    else
                        table.insert(ToolsList, {Text="(None)", Font = Enum.Font.SourceSans})
                    end
                    table.insert(ToolsList, "")
                end

                --Return the list.
                table.remove(ToolsList,#ToolsList)
                return ToolsList
            else
                return {"Unauthorized"}
            end
        end
    end,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetClientApi()

        --Show the window.
        local Window = Api.Window:CreateWindow("Tools")
        local TextList = Window:AddTextList()
        TextList:EnableSearching()

        local function UpdateText()
            TextList:SetLines({"Loading..."})
            TextList:SetLines((Api.EventContainer:WaitForChild("GetToolsInContainers") :: RemoteFunction):InvokeServer())
        end

        task.spawn(UpdateText)
        Window:EnableRefreshing(UpdateText)
        Window:EnableClosing()
        Window:EnableResizing()
        Window:Show()
    end,
}


--Implementation of a command.
--!strict

local TextChatService = game:GetService("TextChatService")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "unmute",
    Category = "BasicCommands",
    Description = "Unmutes a set of players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to unmute.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Mute the players.
        local TextChannels = TextChatService:FindFirstChild("TextChannels")
        local GeneralChat = TextChannels and TextChannels:FindFirstChild("RBXGeneral")
        for _, Player in Players do
            if Api.CommandData.MutedPlayers then
                Api.CommandData.MutedPlayers[Player.UserId] = nil
            end
            local PlayerSource = GeneralChat and GeneralChat:FindFirstChild(Player.Name) :: TextSource
            if PlayerSource then
                PlayerSource.CanSend = true
            end
        end
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "untrack",
    Category = "BasicCommands",
    Description = "Untracks a set of players.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to untrack.",
        },
    },
    ClientRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Destroy the trackers.
        for _, Player in Players do
            if Api.CommandData.PlayerTrackers[Player] then
                Api.CommandData.PlayerTrackers[Player]:Destroy()
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "ambient",
    Category = "BuildUtility",
    Description = "Sets the ambient.",
    Arguments = {
        {
            Type = "color3",
            Name = "Ambient",
            Description = "Ambient to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Ambient: Color3)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.Ambient then
            Api.CommandData.LightingProperties.Ambient = Lighting.Ambient
        end
        Lighting.Ambient = Ambient
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "brightness",
    Category = "BuildUtility",
    Description = "Sets the brightness.",
    Arguments = {
        {
            Type = "number",
            Name = "Brightness",
            Description = "Brightness to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Brightness: number)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.Brightness then
            Api.CommandData.LightingProperties.Brightness = Lighting.Brightness
        end
        Lighting.Brightness = Brightness
    end,
}


--Implementation of a command.
--!strict

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "btools",
    Category = "BuildUtility",
    Description = "Gives the given players a set of the HopperBin tools.",
    Arguments = {
        {
            Type = "nexusAdminPlayers",
            Name = "Players",
            Description = "Players to give build tools.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, Players: {Player})
        --Give the build tools.
        for _, Player in Players do
            local Backpack = Player:FindFirstChild("Backpack")
            if Backpack then
                local GrabHopperBin = Instance.new("HopperBin")
                GrabHopperBin.Name = "Grab"
                GrabHopperBin.BinType = Enum.BinType.Grab
                GrabHopperBin.Parent = Backpack

                local CloneHopperBin = Instance.new("HopperBin")
                CloneHopperBin.Name = "Clone"
                CloneHopperBin.BinType = Enum.BinType.Clone
                CloneHopperBin.Parent = Backpack

                local HammerHopperBin = Instance.new("HopperBin")
                HammerHopperBin.Name = "Hammer"
                HammerHopperBin.BinType = Enum.BinType.Hammer
                HammerHopperBin.Parent = Backpack
            end
        end
    end,
}


--Implementation of a command.
--!strict

local Workspace = game:GetService("Workspace")

local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "clearterrain",
    Category = "BuildUtility",
    Description = "Clears the terrain.",
    ServerRun = function(CommandContext: Types.CmdrCommandContext)
        Workspace.Terrain:Clear()
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "fixlighting",
    Category = "BuildUtility",
    Description = "Reverts the lighting changed by the admin.",
    ServerLoad = function(Api: Types.NexusAdminApiServer)
        Api.CommandData.LightingProperties = {}
    end,
    ServerRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        --Revert the settings.
        for Key,Value in Api.CommandData.LightingProperties do
            Lighting[Key] = Value
        end
        Api.CommandData.LightingProperties = {}
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "fogcolor",
    Category = "BuildUtility",
    Description = "Sets the fog color.",
    Arguments = {
        {
            Type = "color3",
            Name = "FogColor",
            Description = "Fog color to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, FogColor: Color3)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.FogColor then
            Api.CommandData.LightingProperties.FogColor = Lighting.FogColor
        end
        Lighting.FogColor = FogColor
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "fogend",
    Category = "BuildUtility",
    Description = "Sets the fog end.",
    Arguments = {
        {
            Type = "number",
            Name = "FogEnd",
            Description = "Fog start to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, FogEnd: number)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.FogEnd then
            Api.CommandData.LightingProperties.FogEnd = Lighting.FogEnd
        end
        Lighting.FogEnd = FogEnd
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "fogstart",
    Category = "BuildUtility",
    Description = "Sets the fog start.",
    Arguments = {
        {
            Type = "number",
            Name = "FogStart",
            Description = "Fog start to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, FogStart: number)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.FogStart then
            Api.CommandData.LightingProperties.FogStart = Lighting.FogStart
        end
        Lighting.FogStart = FogStart
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "outdoorambient",
    Category = "BuildUtility",
    Description = "Sets the outdoor ambient.",
    Arguments = {
        {
            Type = "color3",
            Name = "OutdoorAmbient",
            Description = "OutdoorAmbient to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, OutdoorAmbient: Color3)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.OutdoorAmbient then
            Api.CommandData.LightingProperties.OutdoorAmbient = Lighting.OutdoorAmbient
        end
        Lighting.OutdoorAmbient = OutdoorAmbient
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "shadows",
    Category = "BuildUtility",
    Description = "Toggles the shadows",
    ServerRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.GlobalShadows then
            Api.CommandData.LightingProperties.GlobalShadows = Lighting.GlobalShadows
        end
        Lighting.GlobalShadows = not Lighting.GlobalShadows
    end,
}


--Implementation of a command.
--!strict

local Lighting = game:GetService("Lighting")

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "time",
    Category = "BuildUtility",
    Description = "Sets the time of day.",
    Arguments = {
        {
            Type = "number",
            Name = "Time",
            Description = "Time of day to set.",
        },
    },
    ServerRun = function(CommandContext: Types.CmdrCommandContext, ClockTime: number)
        local Util = IncludedCommandUtil.ForContext(CommandContext)
        local Api = Util:GetApi()

        if Api.CommandData.LightingProperties and not Api.CommandData.LightingProperties.ClockTime then
            Api.CommandData.LightingProperties.ClockTime = Lighting.ClockTime
        end
        Lighting.ClockTime = ClockTime
    end,
}


--Implementation of a command.
--!strict

local IncludedCommandUtil = require(script.Parent.Parent:WaitForChild("IncludedCommandUtil"))
local Types = require(script.Parent.Parent.Parent:WaitForChild("Types"))

return {
    Keyword = "exit",
    Category = "DefaultUtil",
    Description = "Closes the command line. (Added by Nexus Admin.)",
    AllowAllUsers = true,
    ClientRun = function(CommandContext: Types.CmdrCommandContext)
        local Util = IncludedCommandUtil.ForContext(CommandContext)

        --Return if it wasn't executed from the command line.
        if Util:ExecutedFromChat() or Util:ExecutedFromGuiConsole() or Util:ExecutedFromKeybind() then
            return "This command is only intended to be run from the Cmdr command line."
        end

        --Toggle the window.
        (IncludedCommandUtil.ForContext(CommandContext):GetApi().Cmdr :: any):Toggle()
        return ""
    end,
}