### Example command definition with all options Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Commands Complete example of a command definition for server.Commands. It includes the prefix, command strings, arguments, description, admin level, filter, hidden flag, and the function that runs when the command is executed. After adding commands, call Admin.CacheCommands() to make them usable. ```Lua server.Commands.SomeNewCommand = { --// The index & table of the command Prefix = Settings.Prefix; --// The prefix the command will use, this is the ':' in ':ff me' Commands = {"examplecommand"}; --// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ':ff me') Args = {"arg1", "arg2", "etc"}; --// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ':ff me' Description = "Example command";--// The description of the command AdminLevel = 100; -- Moderators --// The commands minimum admin level; This can also be a table containing specific levels rather than a minimum level: {124, 152, "HeadAdmins", etc}; -- Alternative option: AdminLevel = "Moderators" Filter = true; --// Should user supplied text passed to this command be filtered automatically? Use this if you plan to display a user-defined message to other players Hidden = true; --// Should this command be hidden from the command list? Function = function(plr, args, data) --// The command's function; This is the actual code of the command which runs when you run the command --// "plr" is the player running the command --// "args" is a table containing command arguments supplied by the user --// "data" is a table containing information related to the command and the player running it, such as data.PlayerData.Level (the player's admin level) print("This is 'arg1': ".. tostring(args[1])); print("This is 'arg2': ".. tostring(args[2])); print("This is 'etc'(arg 3): ".. tostring(args[3])); end }; ``` -------------------------------- ### ChatLogs List Updater Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Logs Example list updater for ChatLogs that returns the Chats log table. ```Lua ListUpdaters = { ChatLogs = function() return Logs.Chats end; } ``` -------------------------------- ### Add a new command with a server plugin (Lua) Source: https://github.com/epix-incorporated/adonis/wiki/Plugins-&-Modules Creates a new command 'ExampleCommand1' with aliases, arguments, and various settings. The command is added to server.Commands and can be run with ':examplecommand1' (assuming prefix ':'). The command function prints the first three arguments and then throws an error. ```Lua return function(Vargs) local server = Vargs.Server local service = Vargs.Service --// Add a new command to the Commands table at index "ExampleCommand1" server.Commands.ExampleCommand1 = { --// The index & table of the command Prefix = server.Settings.Prefix; --// The prefix the command will use, this is the ':' in ':ff me' Commands = {"examplecommand1", "examplealias1", "examplealias2"}; --// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ':ff me') Args = {"arg1", "arg2", "etc"}; --// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ':ff me' Description = "Example command"; --// The description of the command AdminLevel = 100; -- Moderators --// The command's minimum admin level; This can also be a table containing specific levels rather than a minimum level: {124, 152, "HeadAdmins", etc}; --// Alternative option: AdminLevel = "Moderators"; Filter = true; --// Should user supplied text passed to this command be filtered automatically? Use this if you plan to display a user-defined message to other players Fun = false; --// Is this command considered as fun? Hidden = true; --// Should this command be hidden from the command list? Disabled = true; --// Should this command be unusable? NoStudio = false; --// Should this command be blocked from being executed in a Studio environment? NonChattable = false; --// Should this command be blocked from being executed via chat? CrossServerDenied = false; --// If true, this command will not be usable via :crossserver Function = function(plr: Player, args: {string}, data: {}) --// The command's function; This is the actual code of the command which runs when you run the command --// "plr" is the player running the command --// "args" is a table containing command arguments supplied by the user --// "data" is a table containing information related to the command and the player running it, such as data.PlayerData.Level (the player's admin level) print("This is 'arg1':", args[1]) print("This is 'arg2':", args[2]) print("This is 'etc'(arg 3):", args[3]) error("this is an example error :o !") end } end ``` -------------------------------- ### Add a new command to server.Commands Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Commands Shows the basic syntax for adding a new command to the server.Commands table. Assign a command data table to a new index (e.g., server.Commands.SomeNewCommand). ```Lua server.Commands.CommandIndexHere = CommandDataTableHere ``` -------------------------------- ### TrackTask with coroutine for existing players Source: https://github.com/epix-incorporated/adonis/wiki/The-"Service"-Metatable Use TrackTask to create a coroutine-based task for each existing player. The task name starts with "Thread:" so Adonis runs it as a coroutine; otherwise TrackTask would yield until completion. The player object is passed as an argument to the task function. ```Lua --// Add existing players in case some are already in the server for _, player in service.Players:GetPlayers() do service.TrackTask("Thread: LoadPlayer "..tostring(player.Name), server.Core.LoadExistingPlayer, player); end ``` -------------------------------- ### Server: Create and manage a PrivateChat session with Remote.NewSession Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Remote Creates a new session of type 'PrivateChat', connects to its SessionEvent to handle commands like SendMessage, LeaveSession, and EndSession. Adds users with a Messages table, sends a GUI to each user, and sends a test message after a 2-second wait. ```Lua local newSession = Remote.NewSession("PrivateChat"); local eventConnection = newSession.SessionEvent.Event:Connect(function(p, ...) local args = {...}; local cmd = args[1]; if cmd == "SendMessage" then if newSession.Users[p] then table.insert(newSession.Users[p].Messages, args[2]); end newSession.SendToUsers("PlayerSentMessage", p, args[2]); elseif cmd == "LeaveSession" then newSession.Users[p] = nil; newSession.SendToUsers("PlayerLeftSession", p); elseif cmd == "EndSession" and p == plr then newSession.End(); end end) for i,v in ipairs(service.GetPlayers(plr, args[1])) do newSession.AddUser(v, { Messages = {}; }); Remote.MakeGui(v, "PrivateChat", { Owner = plr; SessionKey = newSession.SessionKey; }) -- testing stuff below wait(2) newSession.SendToUsers("PlayerSentMessage", plr, "this is a test message"); end ``` -------------------------------- ### LogAdded event usage and LogTypes Source: https://github.com/epix-incorporated/adonis/wiki/The-"Service"-Metatable Shows how to use the LogAdded event with :Connect, :Wait, and :Fire. The event passes LogType, Log, and LogTable arguments. Also maps log table names to their LogType strings. ```Lua --// Connect to the LogAdded event service.Events.LogAdded:Connect(function(LogType, Log, LogTable) print("New " .. LogType .." log: ".. Log.Text .. " - " .. Log.Desc) end) --// Wait for a log to be added local LogType, Log, LogTable = service.Events.LogAdded:Wait() --// Fire the LogAdded event service.Events.LogAdded:Fire("Command", {Text = "Player1: :ff me", Desc = "Player1 ran a command"}, server.Logs.Commands) --// Also here's the list of potential LogTypes: --// Chats in the first entry of this table corresponds to server.Logs.Chats, it's log type is "Chat" local indToName = { Chats = "Chat"; Joins = "Join"; Script = "Script"; Replications = "Replication"; NetworkOwners = "NetworkOwner"; RemoteFires = "RemoteFire"; Commands = "Command"; Exploit = "Exploit"; Errors = "Error"; } ``` -------------------------------- ### Default PlayerFinders table for service.GetPlayers Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Functions Defines the default PlayerFinders table used by service.GetPlayers to match player search input. Each entry has a Match string, optional Prefix and Absolute flags, and a Function that inserts matching players into the players table and calls plus(). Includes finders for me, all, @everyone, others, random, admins, nonadmins, friends, @username, %team, and $group. ```Lua PlayerFinders = { ["me"] = { Match = "me"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) table.insert(players,plr) plus() end; }; ["all"] = { Match = "all"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) local everyone = true if isKicking then for i,v in next,parent:GetChildren() do local p = getplr(v) if p.Name:lower():sub(1,#msg)==msg:lower() then everyone = false table.insert(players,p) plus() end end end if everyone then for i,v in next,parent:GetChildren() do local p = getplr(v) if p then table.insert(players,p) plus() end end end end; }; ["@everyone"] = { Match = "@everyone"; Absolute = true; Function = function(...) return Functions.PlayerFinders.all.Function(...) end }; ["others"] = { Match = "others"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) for i,v in next,parent:GetChildren() do local p = getplr(v) if p ~= plr then table.insert(players,p) plus() end end end; }; ["random"] = { Match = "random"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) if #players>=#parent:GetChildren() then return end local rand = parent:GetChildren()[math.random(#parent:children())] local p = getplr(rand) for i,v in pairs(players) do if(v.Name == p.Name)then Functions.PlayerFinders.random.Function(msg, plr, parent, players, getplr, plus, isKicking) return; end end table.insert(players,p) plus(); end; }; ["admins"] = { Match = "admins"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) for i,v in next,parent:GetChildren() do local p = getplr(v) if Admin.CheckAdmin(p,false) then table.insert(players, p) plus() end end end; }; ["nonadmins"] = { Match = "nonadmins"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) for i,v in next,parent:GetChildren() do local p = getplr(v) if not Admin.CheckAdmin(p,false) then table.insert(players,p) plus() end end end; }; ["friends"] = { Match = "friends"; Prefix = true; Absolute = true; Function = function(msg, plr, parent, players, getplr, plus, isKicking) for i,v in next,parent:GetChildren() do local p = getplr(v) if p:IsFriendsWith(plr.userId) then table.insert(players,p) plus() end end end; }; ["@username"] = { Match = "@"; Function = function(msg, plr, parent, players, getplr, plus, isKicking) local matched = tonumber(msg:match("@(.*)")) local foundNum = 0 if matched then for i,v in next,parent:GetChildren() do local p = getplr(v) if p and p.Name == matched then table.insert(players,p) plus() foundNum = foundNum+1 end end end end; }; ["%team"] = { Match = "%"; Function = function(msg, plr, parent, players, getplr, plus, isKicking) local matched = msg:match("%%(.*)") if matched then for i,v in next,service.Teams:GetChildren() do if v.Name:lower():sub(1,#matched) == matched:lower() then for k,m in next,parent:GetChildren() do local p = getplr(m) if p.TeamColor == v.TeamColor then table.insert(players,p) plus() end end end end end end; }; ["$group"] = { Match = "$"; Function = function(msg, plr, parent, players, getplr, plus, isKicking) local matched = msg:match("%$(.*)") if matched and tonumber(matched) then for i,v in next,parent:children() do local p = getplr(v) if p:IsInGroup(tonumber(matched)) then table.insert(players,p) plus() end end end end; }; } ``` -------------------------------- ### Modify and remove commands with a server plugin (Lua) Source: https://github.com/epix-incorporated/adonis/wiki/Plugins-&-Modules Shows how to remove the ':ff' command by setting its entry to nil and how to override the ':kick' command to do nothing but print a message. The command index can be found in the Commands module or via ':cmdinfo ' in-game. ```Lua return function(Vargs) local server = Vargs.Server local service = Vargs.Service --// Remove ForceField from the Commands table server.Commands.ForceField = nil --// Change the Kick command to do nothing: server.Commands.Kick.Function = function(plr: Player, args: {string}) print(plr.Name .." tried to kick someone") end end ``` -------------------------------- ### Client: Listen for session events via service.Events.SessionData Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Remote Connects to the SessionData event to receive session messages. Checks if the session key matches, then handles the 'PlayerSentChat' command by printing the player name and message. ```Lua local sessionEvent = service.Events.SessionData:Connect(function(sessionKey, cmd, ...) local vargs = {...}; print("we got session thing!"); if SessionKey == sessionKey then print("SESSION KEY VALID") if cmd == "PlayerSentChat" then local p = vargs[1]; local message = vargs[2]; print("got chat: ".. p.Name, "Message: ".. message) end end end) ``` -------------------------------- ### Datastore-related variables Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Core Defines timing delays for datastore operations and salt values used for resetting specific datastore keys. ```Lua --// Datastore update/queue timers/delays DS_SetDataQueueDelay = 0.5; DS_UpdateQueueDelay = 1; DS_AllPlayerDataSaveInterval = 30; DS_AllPlayerDataSaveQueueDelay = 0.5; --// Used to change/"reset" specific datastore keys DS_RESET_SALTS = { SavedSettings = "32K5j4"; SavedTables = "32K5j4"; }; ``` -------------------------------- ### PlayerFinder: #number pattern (random selection) Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Functions Matches a number using the '#' prefix and selects that many random players. If the number is invalid, it shows an output message. ```lua ["#number"] = { Match = "#"; Function = function(msg, plr, ...) local matched = msg:match("%#(.*)") if matched and tonumber(matched) then local num = tonumber(matched) if not num then Remote.MakeGui(plr,'Output',{Title = 'Output'; Message = "Invalid number!"}) end for i = 1,num do Functions.PlayerFinders.random.Function(msg, plr, ...) end end end; }; ``` -------------------------------- ### PlayerFinder: team- pattern Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Functions Matches players by team name using the 'team-' prefix. It prints '1' to the console and checks each team's children for matching team color. ```lua ["team-"] = { Match = "team-"; Function = function(msg, plr, parent, players, getplr, plus, isKicking) print(1) local matched = msg:match("team%-(.*)") if matched then for i,v in next,service.Teams:GetChildren() do if v.Name:lower():sub(1,#matched) == matched:lower() then for k,m in next,parent:GetChildren() do local p = getplr(m) if p.TeamColor == v.TeamColor then table.insert(players, p) plus() end end end end end end; }; ``` -------------------------------- ### PlayerFinder: -name pattern (exclude by name) Source: https://github.com/epix-incorporated/adonis/wiki/Tables:-server.Functions Matches players to exclude by name using the '-' prefix. It removes matching players from the list and calls plus() for each removal. ```lua ["-name"] = { Match = "-"; Function = function(msg, plr, parent, players, getplr, plus, isKicking) local matched = msg:match("%-(.*)") if matched then local removes = service.GetPlayers(plr,matched,true) for i,v in next,players do for k,p in next,removes do if v.Name == p.Name then table.remove(players,i) plus() end end end end end; }; ```