diff options
Diffstat (limited to 'MCServer/Plugins')
-rw-r--r-- | MCServer/Plugins/.gitignore | 2 | ||||
-rw-r--r-- | MCServer/Plugins/APIDump/APIDesc.lua | 3 | ||||
-rw-r--r-- | MCServer/Plugins/InfoDump.lua | 233 |
3 files changed, 232 insertions, 6 deletions
diff --git a/MCServer/Plugins/.gitignore b/MCServer/Plugins/.gitignore new file mode 100644 index 000000000..89eab800a --- /dev/null +++ b/MCServer/Plugins/.gitignore @@ -0,0 +1,2 @@ +*.txt +*.md diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 61de0c1a6..c0056ac4a 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1748,10 +1748,11 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); GetCommandPermission = { Params = "Command", Return = "Permission", Notes = "Returns the permission needed for executing the specified command" }, GetCurrentPlugin = { Params = "", Return = "{{cPlugin}}", Notes = "Returns the {{cPlugin}} object for the calling plugin. This is the same object that the Initialize function receives as the argument." }, GetNumPlugins = { Params = "", Return = "number", Notes = "Returns the number of plugins, including the disabled ones" }, - GetPlugin = { Params = "PluginName", Return = "{{cPlugin}}", Notes = "Returns a plugin handle of the specified plugin" }, + GetPlugin = { Params = "PluginName", Return = "{{cPlugin}}", Notes = "(<b>DEPRECATED, UNSAFE</b>) Returns a plugin handle of the specified plugin, or nil if such plugin is not loaded. Note thatdue to multithreading the handle is not guaranteed to be safe for use when stored - a single-plugin reload may have been triggered in the mean time for the requested plugin." }, IsCommandBound = { Params = "Command", Return = "bool", Notes = "Returns true if in-game Command is already bound (by any plugin)" }, IsConsoleCommandBound = { Params = "Command", Return = "bool", Notes = "Returns true if console Command is already bound (by any plugin)" }, LoadPlugin = { Params = "PluginFolder", Return = "", Notes = "(<b>DEPRECATED</b>) Loads a plugin from the specified folder. NOTE: Loading plugins may be an unsafe operation and may result in a deadlock or a crash. This API is deprecated and might be removed." }, + LogStackTrace = { Params = "", Return = "", Notes = "(STATIC) Logs a current stack trace of the Lua engine to the server console log. Same format as is used when the plugin fails." }, ReloadPlugins = { Params = "", Return = "", Notes = "Reloads all active plugins" }, }, Constants = diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index 28a17c214..8fac09d60 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -69,6 +69,47 @@ end +--- Replaces generic formatting with forum-specific formatting +-- Also removes the single line-ends +local function GithubizeString(a_Str) + assert(type(a_Str) == "string"); + + -- Remove the indentation, unless in the code tag: + -- Only one code or /code tag per line is supported! + local IsInCode = false; + local function RemoveIndentIfNotInCode(s) + if (IsInCode) then + -- we're in code section, check if this line terminates it + IsInCode = (s:find("{%%/code}") ~= nil); + return s .. "\n"; + else + -- we're not in code section, check if this line starts it + IsInCode = (s:find("{%%code}") ~= nil); + return s:gsub("^%s*", "") .. "\n"; + end + end + a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode); + + -- Replace multiple line ends with {%p} and single line ends with a space, + -- so that manual word-wrap in the Info.lua file doesn't wrap in the forum. + a_Str = a_Str:gsub("\n\n", "{%%p}"); + a_Str = a_Str:gsub("\n", " "); + + -- Replace the generic formatting: + a_Str = a_Str:gsub("{%%p}", "\n\n"); + a_Str = a_Str:gsub("{%%b}", "**"):gsub("{%%/b}", "**"); + a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*"); + a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/list}", ""); + a_Str = a_Str:gsub("{%%li}", " - "):gsub("{%%/li}", ""); + -- TODO: Other formatting + + return a_Str; +end + + + + + --- Builds an array of categories, each containing all the commands belonging to the category, -- and the category description, if available. -- Returns the array table, each item has the following format: @@ -156,6 +197,28 @@ end +--- Returns a string specifying the command. +-- If a_CommandParams is nil, returns a_CommandName apostrophed +-- If a_CommandParams is a string, apostrophes a_CommandName with a_CommandParams +local function GetCommandRefGithub(a_CommandName, a_CommandParams) + assert(type(a_CommandName) == "string"); + if (a_CommandParams == nil) then + return "`" .. a_CommandName .. "`"; + end + + assert(type(a_CommandParams) == "table"); + if ((a_CommandParams.Params == nil) or (a_CommandParams.Params == "")) then + return "`" .. a_CommandName .. "`"; + end + + assert(type(a_CommandParams.Params) == "string"); + return "`" .. a_CommandName .. " " .. a_CommandParams.Params .. "`"; +end + + + + + --- Writes the specified command detailed help array to the output file, in the forum dump format local function WriteCommandParameterCombinationsForum(a_CmdString, a_ParameterCombinations, f) assert(type(a_CmdString) == "string"); @@ -184,6 +247,34 @@ end +--- Writes the specified command detailed help array to the output file, in the forum dump format +local function WriteCommandParameterCombinationsGithub(a_CmdString, a_ParameterCombinations, f) + assert(type(a_CmdString) == "string"); + assert(type(a_ParameterCombinations) == "table"); + assert(f ~= nil); + + if (#a_ParameterCombinations == 0) then + -- No explicit parameter combinations to write + return; + end + + f:write("The following parameter combinations are recognized:\n\n"); + for idx, combination in ipairs(a_ParameterCombinations) do + f:write(GetCommandRefGithub(a_CmdString, combination)); + if (combination.Help ~= nil) then + f:write(" - ", GithubizeString(combination.Help)); + end + if (combination.Permission ~= nil) then + f:write(" (Requires permission '**", combination.Permission, "**')"); + end + f:write("\n"); + end +end + + + + + --- Writes all commands in the specified category to the output file, in the forum dump format local function WriteCommandsCategoryForum(a_Category, f) -- Write category name: @@ -206,7 +297,7 @@ local function WriteCommandsCategoryForum(a_Category, f) f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n"); end if (cmd.Info.DetailedDescription ~= nil) then - f:write(cmd.Info.DetailedDescription); + f:write(ForumizeString(cmd.Info.DetailedDescription)); end if (cmd.Info.ParameterCombinations ~= nil) then WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f); @@ -219,6 +310,41 @@ end +--- Writes all commands in the specified category to the output file, in the Github dump format +local function WriteCommandsCategoryGithub(a_Category, f) + -- Write category name: + local CategoryName = a_Category.Name; + if (CategoryName == "") then + CategoryName = "General"; + end + f:write("\n## ", GithubizeString(a_Category.DisplayName or CategoryName), "\n"); + + -- Write description: + if (a_Category.Description ~= "") then + f:write(GithubizeString(a_Category.Description), "\n"); + end + + -- Write commands: + f:write("\n"); + for idx2, cmd in ipairs(a_Category.Commands) do + f:write("\n### ", cmd.CommandString, "\n", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n\n"); + if (cmd.Info.Permission ~= nil) then + f:write("Permission required: **", cmd.Info.Permission, "**\n\n"); + end + if (cmd.Info.DetailedDescription ~= nil) then + f:write(GithubizeString(cmd.Info.DetailedDescription)); + end + if (cmd.Info.ParameterCombinations ~= nil) then + WriteCommandParameterCombinationsGithub(cmd.CommandString, cmd.Info.ParameterCombinations, f); + end + end + f:write("\n\n") +end + + + + + local function DumpCommandsForum(a_PluginInfo, f) -- Copy all Categories from a dictionary into an array: local Categories = BuildCategories(a_PluginInfo); @@ -246,9 +372,36 @@ end +local function DumpCommandsGithub(a_PluginInfo, f) + -- Copy all Categories from a dictionary into an array: + local Categories = BuildCategories(a_PluginInfo); + + -- Sort the categories by name: + table.sort(Categories, + function(cat1, cat2) + return (string.lower(cat1.Name) < string.lower(cat2.Name)); + end + ); + + if (#Categories == 0) then + return; + end + + f:write("\n# Commands\n"); + + -- Dump per-category commands: + for idx, cat in ipairs(Categories) do + WriteCommandsCategoryGithub(cat, f); + end +end + + + + + local function DumpAdditionalInfoForum(a_PluginInfo, f) local AInfo = a_PluginInfo.AdditionalInfo; - if ((AInfo == nil) or (type(AInfo) ~= "table")) then + if (type(AInfo) ~= "table") then -- There is no AdditionalInfo in a_PluginInfo return; end @@ -265,6 +418,25 @@ end +local function DumpAdditionalInfoGithub(a_PluginInfo, f) + local AInfo = a_PluginInfo.AdditionalInfo; + if (type(AInfo) ~= "table") then + -- There is no AdditionalInfo in a_PluginInfo + return; + end + + for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do + if ((info.Title ~= nil) and (info.Contents ~= nil)) then + f:write("\n# ", GithubizeString(info.Title), "\n"); + f:write(GithubizeString(info.Contents), "\n"); + end + end +end + + + + + --- Collects all permissions mentioned in the info, returns them as a sorted array -- Each array item is {Name = "PermissionName", Info = { PermissionInfo }} local function BuildPermissions(a_PluginInfo) @@ -333,7 +505,7 @@ local function DumpPermissionsForum(a_PluginInfo, f) f:write("\n[size=X-Large]Permissions[/size]\n[list]\n"); for idx, perm in ipairs(Permissions) do f:write(" - [color=red]", perm.Name, "[/color] - "); - f:write(perm.Info.Description or ""); + f:write(ForumizeString(perm.Info.Description or "")); local CommandsAffected = perm.Info.CommandsAffected or {}; if (#CommandsAffected > 0) then f:write("\n[list] Commands affected:\n- "); @@ -356,6 +528,43 @@ end +local function DumpPermissionsGithub(a_PluginInfo, f) + -- Get the processed sorted array of permissions: + local Permissions = BuildPermissions(a_PluginInfo); + if ((Permissions == nil) or (#Permissions <= 0)) then + return; + end + + -- Dump the permissions: + f:write("\n# Permissions\n"); + for idx, perm in ipairs(Permissions) do + f:write("### ", perm.Name, "\n"); + f:write(GithubizeString(perm.Info.Description or "")); + local CommandsAffected = perm.Info.CommandsAffected or {}; + if (#CommandsAffected > 0) then + f:write("\n\nCommands affected:\n - "); + local Affects = {}; + for idx2, cmd in ipairs(CommandsAffected) do + if (type(cmd) == "string") then + table.insert(Affects, GetCommandRefGithub(cmd)); + else + table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd)); + end + end + f:write(table.concat(Affects, "\n - ")); + f:write("\n"); + end + if (perm.Info.RecommendedGroups ~= nil) then + f:write("\n\nRecommended groups: ", perm.Info.RecommendedGroups, "\n"); + end + f:write("\n"); + end +end + + + + + local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo) -- Open the output file: local f, msg = io.open(a_PluginInfo.Name .. "_forum.txt", "w"); @@ -377,8 +586,21 @@ end -local function DumpPluginInfoGitHub() - -- TODO +local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo) + -- Open the output file: + local f, msg = io.open(a_PluginInfo.Name .. ".md", "w"); -- TODO: Save to a_PluginFolder .. "/Readme.md" instead + if (f == nil) then + print("\tCannot dump github info for plugin " .. a_PluginFolder .. ": " .. msg); + return; + end + + -- Write the description: + f:write(GithubizeString(a_PluginInfo.Description), "\n"); + DumpAdditionalInfoGithub(a_PluginInfo, f); + DumpCommandsGithub(a_PluginInfo, f); + DumpPermissionsGithub(a_PluginInfo, f); + + f:close(); end @@ -418,6 +640,7 @@ local function ProcessPluginFolder(a_FolderName) return; end DumpPluginInfoForum(a_FolderName, PluginInfo); + DumpPluginInfoGithub(a_FolderName, PluginInfo); end |