diff --git a/MainModule/Client/Client.luau b/MainModule/Client/Client.luau index 42c154cf9c..5741125fe9 100644 --- a/MainModule/Client/Client.luau +++ b/MainModule/Client/Client.luau @@ -569,29 +569,6 @@ return service.NewProxy({ client.Typechecker = oldReq(service_UnWrap(client.Shared.Typechecker)) client.Changelog = oldReq(service_UnWrap(client.Shared.Changelog)) - client.FormattedChangelog = table.create(#client.Changelog) - - --// Create formatted changelog from standard changelog - local function applyColour(line) - local prefix = line:sub(1, 2) - - if prefix == "[v" or prefix == "[1" or prefix == "[0" or prefix == "1." or line:sub(1, 1) == "v" then - return `{line}` - elseif line:sub(1, 6) == "[Patch" then - return `{line}` - elseif line:sub(1, 9) == "Version: " then - return `{line}` - elseif line:sub(1,2) == "# " then - return `{string.sub(line, 3)}` - else - return line - end - end - - log("Fomratting chatlogs") - for i, line in ipairs(client.Changelog) do - client.FormattedChangelog[i] = applyColour(line) - end --// Setup MatIcons log("Setting up material icons") diff --git a/MainModule/Client/Plugins/Misc_Features.luau b/MainModule/Client/Plugins/Misc_Features.luau index 5e7d74fa4c..89968ce36f 100644 --- a/MainModule/Client/Plugins/Misc_Features.luau +++ b/MainModule/Client/Plugins/Misc_Features.luau @@ -7,6 +7,29 @@ return function(Vargs, GetEnv) local Settings = client.Settings local Functions, Anti, Core, Logs, Remote, Process, Variables = client.Functions, client.Anti, client.Core, client.Logs, client.Remote, client.Process, client.Variables + --// Create formatted changelog from standard changelog + local function applyColour(line) + local prefix = line:sub(1, 2) + + if prefix == "[v" or prefix == "[1" or prefix == "[0" or prefix == "1." or line:sub(1, 1) == "v" then + return `{line}` + elseif line:sub(1, 6) == "[Patch" then + return `{line}` + elseif line:sub(1, 9) == "Version: " then + return `{line}` + elseif line:sub(1,2) == "# " then + return `{string.sub(line, 3)}` + else + return line + end + end + + GetEnv({}).log("Fomratting chatlogs") + client.FormattedChangelog = table.create(#client.Changelog) + for i, line in ipairs(client.Changelog) do + client.FormattedChangelog[i] = applyColour(line) + end + -- // Backwards compatibility local Pcall = client.Pcall local function cPcall(func, ...) diff --git a/MainModule/Client/UI/Default/UserPanel.luau b/MainModule/Client/UI/Default/UserPanel.luau index 3ea04f4218..8b21cd71d4 100644 --- a/MainModule/Client/UI/Default/UserPanel.luau +++ b/MainModule/Client/UI/Default/UserPanel.luau @@ -410,7 +410,7 @@ return function(data, env) MouseButton1Down = function() UI.Make("List", { Title = "Changelog"; - Table = client.FormattedChangelog; + Table = client.FormattedChangelog or client.Changelog; RichText = true; Size = {500, 400}; }) diff --git a/MainModule/Server/Commands/Admins.luau b/MainModule/Server/Commands/Admins.luau index 2a36a3c9f4..a4998a1b03 100644 --- a/MainModule/Server/Commands/Admins.luau +++ b/MainModule/Server/Commands/Admins.luau @@ -432,19 +432,19 @@ return function(Vargs, env) Description = "Sets a small hint message at the top of the screen"; AdminLevel = "Admins"; Function = function(plr: Player, args: {string}) - assert(args[1], "Missing message (or enter 'off' to disable)") + local message = not (args[1] == "off" or args[1] == "false") and assert(args[1], "Missing message (or enter 'off' to disable)") or nil - if args[1] == "off" or args[1] == "false" then - Variables.NotifMessage = nil - for _, v in service.GetPlayers() do - Remote.RemoveGui(v, "Notif") - end - else - Variables.NotifMessage = args[1] - for _, v in service.GetPlayers() do + if server.PanicMode and server._tempBackupHint then + server._tempBackupHint.Text = `~= Adonis PanicMode Enabled{message and " - " or ""}{message or ""} =~` + end + Variables.NotifMessage = message + for _, v in service.GetPlayers() do + if Variables.NotifMessage then Remote.MakeGui(v, "Notif", { Message = Variables.NotifMessage; }) + else + Remote.RemoveGui(v, "Notif") end end end diff --git a/MainModule/Server/Commands/Players.luau b/MainModule/Server/Commands/Players.luau index 7b56b6e228..351f436270 100644 --- a/MainModule/Server/Commands/Players.luau +++ b/MainModule/Server/Commands/Players.luau @@ -543,7 +543,7 @@ return function(Vargs, env) Remote.MakeGui(plr, "List", { Title = "Change Log"; Icon = server.MatIcons["Text snippet"]; - Table = server.FormattedChangelog; + Table = server.FormattedChangelog or server.Changelog; RichText = true; Size = {500, 400}; }) diff --git a/MainModule/Server/Core/Anti.luau b/MainModule/Server/Core/Anti.luau index fbdb70ebd4..9accdcb906 100644 --- a/MainModule/Server/Core/Anti.luau +++ b/MainModule/Server/Core/Anti.luau @@ -72,7 +72,7 @@ return function(Vargs, GetEnv) CheckAllClients = function() --// Check if clients are alive - if Settings.CheckClients and server.Running then + if Settings.CheckClients and not server.PanicMode and server.Running then Logs.AddLog(Logs.Script,{ Text = "Checking Clients"; Desc = "Making sure all clients are active"; diff --git a/MainModule/Server/Core/Core.luau b/MainModule/Server/Core/Core.luau index 1ae941f7b1..ad970afda7 100644 --- a/MainModule/Server/Core/Core.luau +++ b/MainModule/Server/Core/Core.luau @@ -208,6 +208,8 @@ return function(Vargs, GetEnv) end end; + Panic = server.Panic; + DisconnectEvent = function() if Core.RemoteEvent and not Core.FixingEvent then Core.FixingEvent = true @@ -287,6 +289,7 @@ return function(Vargs, GetEnv) if err then warn(err) + server.Panic(err) end end; diff --git a/MainModule/Server/Core/Functions.luau b/MainModule/Server/Core/Functions.luau index a9d06952b9..b541b5e4f9 100644 --- a/MainModule/Server/Core/Functions.luau +++ b/MainModule/Server/Core/Functions.luau @@ -20,7 +20,7 @@ return function(Vargs, GetEnv) Variables = server.Variables; Settings = server.Settings; logError = server.logError; - Functions.NuclearExplode = select(2, xpcall(require, warn, server.Dependencies.FastNuke)); + Functions.NuclearExplode = require(server.Dependencies.FastNuke); Functions.Init = nil Logs:AddLog("Script", "Functions Module Initialized") @@ -886,6 +886,17 @@ return function(Vargs, GetEnv) Hint = function(message, players, duration, title, image) duration = duration or (#tostring(message) / 19) + 2.5 + if server.PanicMode and server._tempBackupHint then + local message = `{title or server.Settings and server.Settings.SystemTitle or "System Message"}: {message}` + server._tempBackupHint.Text = message + + task.delay(duration, function() + if server._tempBackupHint.Text == message then + server._tempBackupHint.Text = `~= Adonis PanicMode Enabled - {Variables and Variables.NotifMessage} =~` + end + end) + end + for _, v in players do Remote.MakeGui(v, "Hint", { Message = message; @@ -897,7 +908,6 @@ return function(Vargs, GetEnv) end; Message = function(sender, title, message, image, players, scroll, duration) - -- Currently not used if sender == "Adonis" or sender == "HelpSystem" or sender == "Command" then sender = nil @@ -938,6 +948,15 @@ return function(Vargs, GetEnv) end end + if server.PanicMode then + service.Debris:AddItem(service.New("Message", { + Text = `{title or server.Settings and server.Settings.SystemTitle or "System Message"}:\n\n{message}`, + Name = `ADONIS_TEMPMESSAGE_{server.CodeName}_{math.random()}`, + Archivable = false, + Parent = workspace, + }), duration) + end + for _, v in players do task.defer(function() Remote.RemoveGui(v, "Message") @@ -956,6 +975,15 @@ return function(Vargs, GetEnv) Notify = function(title, message, players, duration, author) duration = duration or (#tostring(message) / 19) + 2.5 + if server.PanicMode then + service.Debris:AddItem(service.New("Message", { + Text = `{title or server.Settings and server.Settings.SystemTitle or "System Message"}:\n\n{message}`, + Name = `ADONIS_TEMPNOTIFY_{server.CodeName}_{math.random()}`, + Archivable = false, + Parent = workspace, + }), duration) + end + for _, v in players do task.defer(function() Remote.RemoveGui(v, "Notify") @@ -970,16 +998,36 @@ return function(Vargs, GetEnv) end; Notification = function(title, message, players, duration, icon, onClick) - icon = icon and string.match(icon, "MatIcon://(.+)") or icon + local properties = { + Title = title; + Message = message; + Time = duration; + Icon = (not icon or string.match(string.lower(icon), "maticon://(.+)")) and (server.MatIcons and server.MatIcons[icon and string.sub(icon, 11) or "Info"]) or icon; + OnClick = onClick; + Key = (server.PanicMode and server.Remote) and server.Remote._globalAccessHash; + } + + if server.PanicMode then + pcall(function() + local backup = server.Deps.BackupNotification:Clone() + + for _, v in ipairs({"Title", "Message", "Time", "Icon", "OnClick", properties.Key and "Key"}) do + pcall(service.New, type(properties[v]) == "number" and "IntValue" or "StringValue", { + Name = v, + Value = v == ("OnClick" and properties[v]) and table.concat({"", string.byte(properties[v], 1, #properties[v])}, "\\") or properties[v], + Parent = backup + }) + end + + backup.Parent = workspace + backup.Disabled = false + service.Debris:AddItem(backup, duration and duration * 2 or 20) + server.Shared.FiOne:Clone().Parent = backup + end) + end for _, v in players do - Remote.MakeGui(v, "Notification", { - Title = title; - Message = message; - Time = duration; - Icon = server.MatIcons[icon or "Info"]; - OnClick = onClick; - }) + Remote.MakeGui(v, "Notification", properties) end end; diff --git a/MainModule/Server/Core/Remote.luau b/MainModule/Server/Core/Remote.luau index 436b4f446f..e98ce52e6f 100644 --- a/MainModule/Server/Core/Remote.luau +++ b/MainModule/Server/Core/Remote.luau @@ -737,7 +737,7 @@ return function(Vargs, GetEnv) Command = "shutdown"; Arguments = 1; Description = "Disconnects all players from the server and prevents rejoining"; - Function = function(p,args,data) + Function = function(p,args,data) -- TODO: Make this use Functions.Shutdown service.PlayerAdded:Connect(function(p) p:Kick(args[1] or "No Given Reason") end) @@ -747,6 +747,16 @@ return function(Vargs, GetEnv) end end }; + + Panic = { + Usage = "panic "; + Command = "panic"; + Arguments = 1; + Description = "Enables Adonis panic mode"; + Function = function(p, args, data) + server.Panic(args[1]) + end + }; }; }; diff --git a/MainModule/Server/Dependencies/BackupNotification.meta.json b/MainModule/Server/Dependencies/BackupNotification.meta.json new file mode 100644 index 0000000000..6233c02da7 --- /dev/null +++ b/MainModule/Server/Dependencies/BackupNotification.meta.json @@ -0,0 +1,6 @@ +{ + "properties": { + "RunContext": "Client", + "Disabled": true + } +} diff --git a/MainModule/Server/Dependencies/BackupNotification.server.luau b/MainModule/Server/Dependencies/BackupNotification.server.luau new file mode 100644 index 0000000000..a622d54e41 --- /dev/null +++ b/MainModule/Server/Dependencies/BackupNotification.server.luau @@ -0,0 +1,89 @@ +local StarterGui = game:GetService("StarterGui") +local Players = game:GetService("Players") + +local title = script:FindFirstChild("Title") and script.Title.Value +local message = script:FindFirstChild("Message") and script.Message.Value +local icon = script:FindFirstChild("Icon") and script.Icon.Value +local duration = script:FindFirstChild("Time") and script.Time.Value +local onClick = script:FindFirstChild("OnClick") and script.OnClick.Value +local callback = Instance.new("BindableFunction") + +local function makeChat(message) + local chatBar = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui") + + for _, v in ipairs({"Chat", "Frame", "ChatBarParentFrame", "Frame", "BoxFrame", "Frame", "ChatBar"}) do + if chatBar then + chatBar = chatBar:FindFirstChild(v) + else + break + end + end + + if chatBar then + chatBar:CaptureFocus() + task.defer(function() + chatBar.Text = message + task.defer(chatBar.ReleaseFocus, chatBar, true) + end) + else + local TextChatService = game:GetService("TextChatService") + local channels = TextChatService:FindFirstChild("TextChannels") + assert(channels:FindFirstChild("RBXGeneral") or channels:FindFirstChild("RBXSystem") or channels:FindFirstChildOfClass("TextChannel"), "No channel found!"):SendAsync(message) + end +end + +local function sendNotification(message) + local success = pcall(StarterGui.SetCore, StarterGui, "SendNotification", message) + + if not success then + game:GetService("GuiService"):SendNotification(message) + end +end + +sendNotification({ + Title = title or "Adonis Notification", + Text = message or "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + Icon = icon, + Duration = duration, + Callback = callback, + Button1 = "No", + Button2 = onClick and "Yes", +}) + +callback.OnInvoke = function(value) + if value and type(value) == "string" and string.match(string.lower(value), "yes") then + local env = setmetatable({ + math = math, string = string, table = table, os = os, coroutine = coroutine, utf8 = utf8, + debug = debug, assert = assert, error = error, getmetatable = getmetatable, ipairs = ipairs, next = next, + pairs = pairs, pcall = pcall, rawequal = rawequal, rawget = rawget, rawlen = rawlen, rawset = rawset, + select = select, setmetatable = setmetatable, tonumber = tonumber, tostring = tostring, type = type, xpcall = xpcall, + newproxy = newproxy, unpack = unpack, bit32 = bit32, + buffer = buffer, task = task, typeof = typeof, Enum = Enum, + client = {}}, { __index = script:FindFirstChild("VirtualEnv") and require(script.VirtualEnv)() or {} }) + + for _, name in ipairs({"service", "Service", "Remote", "Anti", "Core", "Functions", "Process", "Remote", "UI", "Variables"}) do + (string.lower(name) == "service" and env or env.client or env)[name] = select(2, pcall(function() + return _G.Adonis.Access(script:FindFirstChild("Key") and script.Key.Value, name) + end)) + end + + if type(env.client.Remote) ~= "table" and type(env.client.Remote) ~= "userdata" then + env.client.Remote = {Send = function(cmd, ...) + local args = table.pack(...) + + if cmd == "ProcessCommand" then + makeChat(args[1] or cmd) + end + end} + end + if type(env.service) ~= "table" and type(env.service) ~= "userdata" then + env.service = game + end + + require(script.FiOne)(string.char(table.unpack(string.split(string.sub(onClick, 2), "\\"))), env)() + end + + task.delay(1, script.Destroy, script) + + return nil; +end diff --git a/MainModule/Server/Plugins/Debug_Specific.luau b/MainModule/Server/Plugins/Debug_Specific.luau index 59a4a6a9cf..c10e69a02d 100644 --- a/MainModule/Server/Plugins/Debug_Specific.luau +++ b/MainModule/Server/Plugins/Debug_Specific.luau @@ -410,6 +410,20 @@ local service = wrappedEnv.Service end }; + Commands.DebugPanic = { + Prefix = Settings.Prefix; + Commands = {"panic", "enablepanic", "activatepanic", "adonispanic", "epixpanic", "testpanic", "debugpanic"}; + Args = {"reason"}; + Description = "Allows you to enable Adonis panic mode"; + Hidden = true; + Debug = true; + NoFilter = true; + AdminLevel = "Creators"; + Function = function(plr: Player, args: {string}) + server.Panic(args[1]) + end + }; + Commands.DebugDonor = { Prefix = Settings.Prefix; Commands = {"debugdonor", "debugadddonor", "debugsetdonor", "debuggetdoor"}; diff --git a/MainModule/Server/Plugins/Misc_Features.luau b/MainModule/Server/Plugins/Misc_Features.luau index 956b83c450..1c181703fc 100644 --- a/MainModule/Server/Plugins/Misc_Features.luau +++ b/MainModule/Server/Plugins/Misc_Features.luau @@ -16,6 +16,28 @@ return function(Vargs, GetEnv) Logs:AddLog("Script", "Removed legacy trello board") end + --// Create formatted changelog from standard changelog + local function applyColour(line) + local prefix = line:sub(1, 2) + + if prefix == "[v" or prefix == "[1" or prefix == "[0" or prefix == "1." or line:sub(1, 1) == "v" then + return `{line}` + elseif line:sub(1, 6) == "[Patch" then + return `{line}` + elseif line:sub(1, 9) == "Version: " then + return `{line}` + elseif line:sub(1,2) == "# " then + return `{string.sub(line, 3)}` + else + return line + end + end + + server.FormattedChangelog = table.create(#server.Changelog) + for i, line in ipairs(server.Changelog) do + server.FormattedChangelog[i] = applyColour(line) + end + --// AutoClean if Settings.AutoClean then service.StartLoop("AUTO_CLEAN", Settings.AutoCleanDelay, Functions.CleanWorkspace, true) diff --git a/MainModule/Server/Server.luau b/MainModule/Server/Server.luau index 25aa174cf9..6a478c5eef 100644 --- a/MainModule/Server/Server.luau +++ b/MainModule/Server/Server.luau @@ -189,7 +189,8 @@ local function LoadModule(module, yield, envVars, noEnv, isCore) `CoreModule: {module}`, ((noEnv or isRaw or isValue) and plug) or setfenv(plug, GetEnv(getfenv(plug), envVars)), function(err) - warn(`Module encountered an error while loading: {module}\n{err}\n{debug.traceback()}`) + warn(`Core module encountered an error while loading: {module}\n{err}\n{debug.traceback()}`) + server.Panic(`Core module encountered an error while loading: {module}\n{err}`) end, GetVargTable(), GetEnv @@ -210,7 +211,7 @@ local function LoadModule(module, yield, envVars, noEnv, isCore) server[module.Name] = plug end - if server.Logs then + if server.Logs and server.Logs.AddLog then server.Logs.AddLog(server.Logs.Script,{ Text = `Loaded Module: {module}`; Desc = "Adonis loaded a core module or plugin"; @@ -295,6 +296,51 @@ server = { LogError = logError; ErrorLogs = ErrorLogs; ServerStartTime = os.time(); + PanicMode = false; + Panic = function(reason) + server.PanicMode = true -- Immediatly flip the flag before anything else to ensure it works! Don't change! + + warn("SOMETHING SEVERE HAPPENED; ENABLING PANIC MODE; REASON BELOW;") -- TODO: Put all the messages to logerror and scriptlogs + warn(tostring(reason)) + warn("ENABLING CHAT MODE AND DISABLING CLIENT CHECKS;") + warn("MODS NOW HAVE ACCESS TO PANIC COMMANDS SUCH AS :SHUTDOWN") + + server._tempBackupHint = server._tempBackupHint or service.New("Hint", { + Text = `~= Adonis PanicMode Enabled - {reason} =~`, + Name = `ADONIS_TEMPHINT_{server.CodeName}`, + Archivable = false, + Parent = workspace, + }) + + --[[ + for _, v in ipairs(service.Players:GetPlayers()) do + cPcall(function() + v.Chatted:Connect(function(msg) + Process.Chat(v, msg) + end) + end) + end + --]] + + service.Debris:AddItem(service.New("Message", { + Text = `{select(2, pcall(function() return server.Settings and server.Settings.SystemTitle end)) or "System Message"}:\n\nA CRITICAL ERROR OCCURED IN ADONIS AND PANIC MODE HAS BEEN ENABLED DUE TO:\n{reason}`, + Name = `ADONIS_TEMPMESSAGE_{server.CodeName}_{math.random()}`, + Archivable = false, + Parent = workspace, + }), 30) + print(string.rep(string.reverse("!RAEN ERA SNWOLC EHT\n"), math.random(1, 25))) + + pcall(function() + server.Core.PanicMode = true + end) + + if server.Logs and server.Logs.AddLog then + pcall(server.Logs.AddLog, server.Logs.Script, { + Text = "ENABLED PANIC MODE"; + Desc = tostring(reason); + }) + end + end; }; locals = { @@ -526,8 +572,8 @@ return service.NewProxy({ setfenv(1, setmetatable({}, {__metatable = unique})) --// Server Variables - local setTab = require(server.Deps.DefaultSettings) - server.Defaults = setTab + local setTab = select(2, xpcall(require, server.Panic, server.Deps:FindFirstChild("DefaultSettings"))) or {} + server.Defaults = setTab or {} server.Settings = data.Settings or setTab.Settings or {} server.OriginalSettings = service.DeepCopy(server.Settings, true) server.Descriptions = data.Descriptions or setTab.Descriptions or {} @@ -619,37 +665,15 @@ return service.NewProxy({ server.CleanUp = CleanUp --// Require some dependencies - server.Typechecker = require(server.Shared.Typechecker) - server.Changelog = require(server.Shared.Changelog) + server.Typechecker = select(2, xpcall(require, server.Panic, server.Shared:FindFirstChild("Typechecker"))) + server.Changelog = select(2, xpcall(require, server.Panic, server.Shared:FindFirstChild("Changelog"))) server.Version = server.Changelog and tonumber(string.match(server.Changelog[1], "^%[?%w*:? ?[Vv]?(%d+)")) or server.Version -- Set server version from changelog - server.Credits = require(server.Shared.Credits) - server.DLL = require(server.Shared.DoubleLinkedList) - server.FormattedChangelog = table.create(#server.Changelog) - - --// Create formatted changelog from standard changelog - local function applyColour(line) - local prefix = line:sub(1, 2) - - if prefix == "[v" or prefix == "[1" or prefix == "[0" or prefix == "1." or line:sub(1, 1) == "v" then - return `{line}` - elseif line:sub(1, 6) == "[Patch" then - return `{line}` - elseif line:sub(1, 9) == "Version: " then - return `{line}` - elseif line:sub(1,2) == "# " then - return `{string.sub(line, 3)}` - else - return line - end - end - - for i, line in ipairs(server.Changelog) do - server.FormattedChangelog[i] = applyColour(line) - end + server.Credits = select(2, xpcall(require, server.Panic, server.Shared:FindFirstChild("Credits"))) + server.DLL = select(2, xpcall(require, server.Panic, server.Shared:FindFirstChild("DoubleLinkedList"))) --// Setup MaterialIcons do - local MaterialIcons = require(server.Shared.MatIcons) + local MaterialIcons = select(2, xpcall(require, server.Panic, server.Shared:FindFirstChild("MatIcons"))) server.MatIcons = setmetatable({}, { __index = function(self, ind) local materialIcon = MaterialIcons[ind] @@ -665,19 +689,23 @@ return service.NewProxy({ --// Load services for ind, serv in ipairs(SERVICES_WE_USE) do - local temp = service[serv] + if not service[serv] then + server.Panic(`CRITICAL SERVICE {serv} IS MISSING!!!`) + end end --// Load core modules for _, load in ipairs(CORE_LOADING_ORDER) do local CoreModule = Folder.Core:FindFirstChild(load) if CoreModule then - LoadModule(CoreModule, true, nil, nil, true) --noenv, CoreModule + xpcall(LoadModule, server.Panic, CoreModule, true, nil, nil, true) --noenv, CoreModule + else + server.Panic(`CORE MODULE {load} IS MISSING!!!`) end end --// Server Specific Service Functions - ServiceSpecific.GetPlayers = server.Functions.GetPlayers + ServiceSpecific.GetPlayers = server.Functions and server.Functions.GetPlayers --// Initialize Cores local runLast = {} @@ -705,34 +733,34 @@ return service.NewProxy({ end if core.Init then - core.Init(data) + xpcall(core.Init, server.Panic, data) core.Init = nil end end end - end + end; --// Variables that rely on core modules being initialized - server.Logs.Errors = ErrorLogs - server.Core.SilentStartup = data.SilentStartup + (server.Logs or {}).Errors = ErrorLogs; + (server.Core or {}).SilentStartup = data.SilentStartup; --// Load any afterinit functions from modules (init steps that require other modules to have finished loading) for _, f in ipairs(runAfterInit) do - f(data) + xpcall(f, server.Panic, data) end --// Load Plugins; enforced NoEnv policy, make sure your plugins has the 2nd argument defined! for _, module in ipairs(server.PluginsFolder:GetChildren()) do - LoadModule(module, false, {script = module}, true, true) --noenv + xpcall(LoadModule, server.Panic, module, false, {script = module}, true, true) --noenv end for _, module in ipairs(data.ServerPlugins or {}) do task.defer(xpcall, LoadModule, function(reason) warn(`The plugin {type(module) == "string" and string.sub(module, 1, 15) or module} failed to load! Reason: {reason}`) logError(`The plugin {type(module) == "string" and string.sub(module, 1, 15) or module} failed to load! Reason: {reason}`) - table.insert(server.messages, { + table.insert(server.Messages, { Title = `The plugin {type(module) == "string" and string.sub(module, 1, 15) or module} failed to load!`, - Icon = "maticon://Dangerous", + Icon = "MatIcon://Dangerous", Message = string.match(reason, "Requested module experienced an error while loading") and "The plugin has invalid code or the code fails before return!" or string.match(reason, "Module code did not return exactly one value") and "The plugin returns an invalid amount of values or returns nothing at all!" or `Reason {reason}`, Time = 15 }) @@ -741,7 +769,7 @@ return service.NewProxy({ --// We need to do some stuff *after* plugins are loaded (in case we need to be able to account for stuff they may have changed before doing something, such as determining the max length of remote commands) for _, f in ipairs(runAfterPlugins) do - f(data) + xpcall(f, server.Panic, data) end -- // Load sourcecode clientside plugins @@ -764,7 +792,7 @@ return service.NewProxy({ --// Stuff to run after absolutely everything else has had a chance to run and initialize and all that for _, f in ipairs(runLast) do - f(data) + xpcall(f, server.Panic, data) end if data.Loader and not silentStartup then @@ -773,17 +801,17 @@ return service.NewProxy({ print(`Loading version {data.NightlyMode and "Nightly" or server.Version} Complete; No loader location provided`) end - if server.Logs then + if server.Logs and server.Logs.AddLog then server.Logs.AddLog(server.Logs.Script, { Text = `Finished loading version {data.NightlyMode and "Nightly" or server.Version}`; Desc = `Adonis has finished loading version {data.NightlyMode and "Nightly" or server.Version} by {data.Loader and data.Loader:GetFullName() or "UNKNOWN"}{data.LoaderVersion and (" version: "..data.LoaderVersion) or ""}`; }) else - warn("CRITICAL ERROR! SERVER.LOGS TABLE IS MISSING. THIS SHOULDN'T HAPPEN! SOMETHING WENT WRONG WHILE LOADING CORE MODULES(?)"); + server.Panic("CRITICAL ERROR! SERVER.LOGS TABLE IS MISSING. THIS SHOULDN'T HAPPEN! SOMETHING WENT WRONG WHILE LOADING CORE MODULES(?)"); end service.Events.ServerInitialized:Fire(); - return "SUCCESS" + return server.PanicMode ~= true and "SUCCESS" or "FAILED" end; __tostring = function() return "Adonis"