import { OnStart, Service } from "@flamework/core"; import { Cmdr } from "@rbxts/cmdr"; import Log from "@rbxts/log"; import { Players, RunService } from "@rbxts/services"; import { Trove } from "@rbxts/trove"; import { isCmdrAllowed } from "server/config/cmdr-permissions"; import { CMDR_ACCESS_ATTRIBUTE } from "shared/cmdr"; @Service() export class CmdrService implements OnStart { private readonly trove = new Trove(); public onStart(): void { // Register authorization before exposing the built-in commands. Cmdr.Registry.RegisterHook("BeforeRun", (context) => { if (!this.canUseConsole(context.Executor)) { return "You do not have permission to run this command."; } }); Cmdr.Registry.RegisterDefaultCommands((command) => command.Name !== "announce"); Cmdr.Registry.RegisterCommandsIn(script.Parent!.Parent!.WaitForChild("commands")); this.trove.connect(Players.PlayerAdded, (player) => { this.updateAccess(player); }); for (const player of Players.GetPlayers()) { this.updateAccess(player); } game.BindToClose(() => this.trove.destroy()); Log.Info("Cmdr ready with {CommandCount} commands", Cmdr.Registry.GetCommands().size()); } private canUseConsole(player: Player): boolean { return isCmdrAllowed( player.UserId, RunService.IsStudio(), game.CreatorType === Enum.CreatorType.User ? game.CreatorId : undefined, ); } private updateAccess(player: Player): void { player.SetAttribute(CMDR_ACCESS_ATTRIBUTE, this.canUseConsole(player)); } }