diff options
Diffstat (limited to 'MCServer/Plugins')
-rw-r--r-- | MCServer/Plugins/APIDump/APIDesc.lua | 16 | ||||
-rw-r--r-- | MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua | 5 | ||||
-rw-r--r-- | MCServer/Plugins/APIDump/InfoFile.html | 246 | ||||
-rw-r--r-- | MCServer/Plugins/ChunkWorx/chunkworx_web.lua | 2 | ||||
-rw-r--r-- | MCServer/Plugins/Debuggers/Debuggers.lua | 14 | ||||
-rw-r--r-- | MCServer/Plugins/Handy/handy_functions.lua | 4 |
6 files changed, 278 insertions, 9 deletions
diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1423d64bc..19ca971e2 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -114,6 +114,7 @@ g_APIDesc = GetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified absolute coords" }, GetBlockType = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified absolute coords" }, GetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified absolute coords" }, + GetCoordRange = {Params = "", Return = "MaxX, MaxY, MaxZ", Notes = "Returns the maximum relative coords in all 3 axes. See also GetSize()." }, GetDataTypes = { Params = "", Return = "number", Notes = "Returns the mask of datatypes that the object is currently holding" }, GetOrigin = { Params = "", Return = "OriginX, OriginY, OriginZ", Notes = "Returns the origin coords of where the area was read from." }, GetOriginX = { Params = "", Return = "number", Notes = "Returns the origin x-coord" }, @@ -124,7 +125,7 @@ g_APIDesc = GetRelBlockSkyLight = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified relative coords" }, GetRelBlockType = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified relative coords" }, GetRelBlockTypeMeta = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified relative coords" }, - GetSize = { Params = "", Return = "SizeX, SizeY, SizeZ", Notes = "Returns the size of the area in all 3 axes." }, + GetSize = { Params = "", Return = "SizeX, SizeY, SizeZ", Notes = "Returns the size of the area in all 3 axes. See also GetCoordRange()." }, GetSizeX = { Params = "", Return = "number", Notes = "Returns the size of the held data in the x-axis" }, GetSizeY = { Params = "", Return = "number", Notes = "Returns the size of the held data in the y-axis" }, GetSizeZ = { Params = "", Return = "number", Notes = "Returns the size of the held data in the z-axis" }, @@ -1969,7 +1970,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." }, BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." }, CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil." }, - FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for the given player." }, + FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for all players with names partially (or fully) matching the name string provided." }, ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|cPlayer}})</pre>" }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cWorld|cWorld}})</pre>" }, GetCraftingRecipes = { Params = "", Return = "{{cCraftingRecipe|cCraftingRecipe}}", Notes = "Returns the CraftingRecipes object" }, @@ -2294,10 +2295,14 @@ end IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the current gamemode is gmCreative." }, IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the current gamemode is gmSurvival." }, IsPVPEnabled = { Params = "", Return = "bool", Notes = "Returns whether PVP is enabled in the world settings." }, - IsWeatherRain = { Params = "", Return = "bool", Notes = "Returns true if the current weather is rain." }, - IsWeatherStorm = { Params = "", Return = "bool", Notes = "Returns true if the current weather is a storm." }, + IsWeatherRain = { Params = "", Return = "bool", Notes = "Returns true if the current world is raining." }, + IsWeatherRainAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location is raining (takes into account biomes)." }, + IsWeatherStorm = { Params = "", Return = "bool", Notes = "Returns true if the current world is stormy." }, + IsWeatherStormAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location is stormy (takes into account biomes)." }, IsWeatherSunny = { Params = "", Return = "bool", Notes = "Returns true if the current weather is sunny." }, - IsWeatherWet = { Params = "", Return = "bool", Notes = "Returns true if the current weather has any precipitation (rain or storm)." }, + IsWeatherSunnyAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the current weather is sunny at the specified location (takes into account biomes)." }, + IsWeatherWet = { Params = "", Return = "bool", Notes = "Returns true if the current world has any precipitation (rain or storm)." }, + IsWeatherWetAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location has any precipitation (rain or storm) (takes into account biomes)." }, QueueBlockForTick = { Params = "BlockX, BlockY, BlockZ, TicksToWait", Return = "", Notes = "Queues the specified block to be ticked after the specified number of gameticks." }, QueueSaveAllChunks = { Params = "", Return = "", Notes = "Queues all chunks to be saved in the world storage thread" }, QueueSetBlock = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta, TickDelay", Return = "", Notes = "Queues the block to be set to the specified blocktype and meta after the specified amount of game ticks. Uses SetBlock() for the actual setting, so simulators are woken up and block entities are handled correctly." }, @@ -2929,6 +2934,7 @@ end { -- No sorting is provided for these, they will be output in the same order as defined here { FileName = "Writing-a-MCServer-plugin.html", Title = "Writing a MCServer plugin" }, + { FileName = "InfoFile.html", Title = "Using the Info.lua file" }, { FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" }, { FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" }, { FileName = "UsingChunkStays.html", Title = "Using ChunkStays" }, diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua index 1588d420c..72cf85821 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua @@ -10,6 +10,11 @@ return Params = { { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + { Name = "BlockX", Type = "number", Notes = "The X-coord where the projectile hit." }, + { Name = "BlockY", Type = "number", Notes = "The Y-coord where the projectile hit." }, + { Name = "BlockZ", Type = "number", Notes = "The Z-coord where the projectile hit." }, + { Name = "BlockFace", Type = "number", Notes = "The side of the block where the projectile hit." }, + { Name = "BlockHitPos", Type = "Vector3d", Notes = "The exact position where the projectile hit." }, }, Returns = [[ If the function returns false or no value, the next plugin's callback is called. If the function diff --git a/MCServer/Plugins/APIDump/InfoFile.html b/MCServer/Plugins/APIDump/InfoFile.html new file mode 100644 index 000000000..3fff06d20 --- /dev/null +++ b/MCServer/Plugins/APIDump/InfoFile.html @@ -0,0 +1,246 @@ +<!DOCTYPE html> +<html> + <head> + <title>MCServer - Info.lua file</title> + <link rel="stylesheet" type="text/css" href="main.css" /> + <link rel="stylesheet" type="text/css" href="prettify.css" /> + <script src="prettify.js"></script> + <script src="lang-lua.js"></script> + <meta charset="UTF-8"> + </head> + <body> + <div id="content"> + <h1>Info.lua file</h1> + <h2>Contents</h2> + <ul> + <li><a href="#Introduction">Introduction</a></li> + <li><a href="#Overall">The overall structure</a></li> + <li><a href="#AdditionalInformation">AdditionalInformation table</a></li> + <li><a href="#Commands">Commands table</a></li> + <li><a href="#ConsoleCommands">ConsoleCommands table</a></li> + <li><a href="#Permissions">Permissions table</a></li> + <li><a href="#Using">Using the file in code</a></li> + <li><a href="#Examples">Examples</a></li> + </ul> + + + <hr /> + <a name="Introduction"><h2>Introduction</h2></a> + + <p>For a long time MCServer plugins were plagued by poor documentation. The plugins worked, people who wrote them knew how to use them, but for anyone new to the plugin it was a terrible ordeal learning how to use it. Most of the times, the plugin authors only wrote what commands the plugin supported, sometimes not even that. Then, there was a call to action to put an end to this, to make documenting the plugins easy and at the same time centralized. Thus, the Info.lua file was born.</p> + + <p>Most plugins have some parts that are the same across all the plugins. These are commands, console commands and their permissions. If a plugin implemented a command, it would practically copy & paste the same code over and over again. So it makes sense to extract only unique information, centralize it and automate all the parts around it. This was another reason for the Info.lua file - it is a central hub of commands, console commands and their permissions.</p> + + <p>Last, but not least, we want to make a plugin repository on the web in the future, a repository that would store plugins, their descriptions, comments. It makes sense that the centralized information can be parsed by the repository automatically, so that advanced things, such as searching for a plugin based on a command, or determining whether two plugins collide command-wise, are possible.</p> + + <p>After this file format has been devised, a tool has been written that allows for an easy generation of the documentation for the plugin in various formats. It outputs the documentation in a format that is perfect for pasting into the forum. It generates documentation in a Markup format to use in README.md on GitHub and similar sites. The clever thing is that you don't need to keep all those formats in sync manually - you edit the Info.lua file and this tool will re-generate the documentation for you.</p> + + <p>So to sum up, the Info.lua file contains the plugins' commands, console commands, their permissions and possibly the overall plugin documentation, in a structured manner that can be parsed by a program, yet is human readable and editable.</p> + + + <hr /> + <a name="Overall"><h2>The overall structure</h2></a> + + <p>The file consist of a declaration of a single Lua table, g_PluginInfo. This table contains all the information, structured, as its members. Each member can be a structure by itself. The entire file is a valid Lua source file, so any tool that syntax-checks Lua source can syntax-check this file. The file is somewhat forward- and backward- compatible, in the sense that it can be extended in any way without breaking.</p> + <p>Here's a skeleton of the file:</p> +<pre class="prettyprint lang-lua"> +g_PluginInfo = +{ + Name = "Example Plugin", + Date = "2014-06-12", + Description = "This is an example plugin that shows how to use the Info.lua file", + + -- The following members will be documented in greater detail later: + AdditionalInformation = {}, + Commands = {}, + ConsoleCommands = {}, + Permissions = {}, +} +</pre> + <p>As you can see, the structure is pretty straightforward. Note that the order of the elements inside the table is not important (Lua property).</p> + + <p>The first few elements are for book-keeping. They declare the plugin's name, the date in ISO-format, representing the version of the plugin, and the description. The idea is that the description sums up what the plugin is all about, within some two or three sentences.</p> + + + <hr /> + <a name="AdditionalInformation"><h2>AdditionalInformation table</h2></a> + + <p>This table is used for more detailed description of the plugin. If there is any non-trivial setup process, dependencies, describe them here. This is where the description should get detailed. Don't worry about using several paragraphs of text here, if it makes the plugin easier to understand.</p> + + <p>The table should have the following layout:</p> +<pre class="prettyprint lang-lua"> +AdditionalInformation = +{ + { + Title = "Chapter 1", + Contents = "Describe one big aspect of the plugin here", + }, + { + Title = "Chapter 2", + Contents = "Describe another big topic", + }, +} +</pre> + <p>The idea here is that the tool that is used to generate the documentation from the Info.lua file will create a linkified table of contents and then each of the information elements' contents. This information should be all that is needed to successfully configure, run and manage the plugin.</p> + + + <hr /> + <a name="Commands"><h2>Commands table</h2></a> + + <p>The commands table lists all the commands that the plugin implements, together with their handler functions, required permissions, help strings and further information. The table supports recursion, which allows plugins to create multi-word commands easily (such as "//schematic load" and "//schematic save"), each having its own separate handler.</p> + + <p>The table uses structure similar to the following:</p> +<pre class="prettyprint lang-lua"> +Commands = +{ + ["/cmd1"] = + { + HelpString = "Performs the first action", + Permission = "firstplugin.cmds.1", + Alias = "/c1", + Handler = HandleCmd1, + ParameterCombinations = + { + { + Params = "x y z", + Help = "Performs the first action at the specified coordinates", + }, + { + Params = "-p", + Help = "Performs the first action at the player's coordinates", + } + }, + }, + ["/cmd2"] = + { + Alias = {"/c2", "//c2" }, + Subcommands = + { + sub1 = -- This declares a "/cmd2 sub1" command + { + HelpString = "Performs the second action's first subcommand", + Permission = "firstplugin.cmds.2.1", + Alias = "1", + Handler = HandleCmd2Sub1, + ParameterCombinations = + { + { + Params = "x y z", + Help = "Performs the second action's first subcommand at the specified coordinates", + }, + { + Params = "-p", + Help = "Performs the second action's first subcommand at the player's coordinates", + } + }, + }, + sub2 = -- Declares a "/cmd2 sub2" command + { + HelpString = "Performs the second action's second subcommand", + Permission = "firstplugin.cmds.2.2", + Handler = HandleCmd2Sub2, + }, + }, + }, +} +</pre> + + <p>Although it may seem overwhelming at first, there is a "method to this madness". Each element of the Commands table defines one command. Most commands start with a slash, so the special Lua syntax for table elements with non-standard names needs to be applied (<code>["/cmd1"] =</code>). The command can either specify subcommands, or a handler function (specifying both is UndefinedBehavior). Subcommands uses the same structure as the entire Commands table, recursively.</p> + + <p>The permission element specifies that the command is only available with the specified permission. Note that the permission for subcommand's parent isn't checked when the subcommand is called. This means that specifying the permission for a command that has subcommands has no effect whatsoever, but is discouraged because we may add processing for that in the future.</p> + + <p>The ParameterCombinations table is used only for generating the documentation, it lists the various combinations of parameters that the command supports. It's worth specifying even if the command supports only one combination, because that combination will get documented this way.</p> + + <p>The Alias member specifies any possible aliases for the command. Each alias is registered separately and if there is a subcommand table, it is applied to all aliases, just as one would expect. You can specify either a single string as the value (if there's only one alias), or a table of strings for multiple aliases. Commands with no aliases do not need to specify this member at all.</p> + + + <hr /> + <a name="ConsoleCommands"><h2>ConsoleCommands table</h2> + + <p>This table serves a purpose similar to that of the Commands table, only these commands are provided for the server console. Therefore, there are no permissions specified for these commands. Since most console commands don't use a leading slash, the command names don't need the special syntax. Also, the handler function doesn't receive the Player parameter.</p> + + <p>Here's an example of a ConsoleCommands table:</p> +<pre class="prettyprint lang-lua"> +ConsoleCommands = +{ + concmd = + { + HelpString = "Performs the console action", + Subcommands = + { + sub1 = + { + HelpString = "Performs the console action's first subcommand", + Handler = HandleConCmdSub1, + ParameterCombinations = + { + { + Params = "x y z", + Help = "Performs the console action's first subcommand at the specified coordinates", + }, + }, + }, + sub2 = + { + HelpString = "Performs the console action's second subcommand", + Handler = HandleConCmdSub2, + }, + }, + }, +} +</pre> + + + <hr /> + <a name="Permissions"><h2>Permissions table</h2></a> + + <p>The purpose of this table is to document permissions that the plugin uses. The documentation generator automatically collects the permissions specified in the Command table; the Permissions table adds a description for these permissions and may declare other permissions that aren't specifically included in the Command table.</p> + +<pre class="prettyprint lang-lua"> +Permissions = +{ + ["firstplugin.cmd.1.1"] = + { + Description = "Allows the players to build high towers using the first action.", + RecommendedGroups = "players", + }, + ["firstplugin.cmd.2.1"] = + { + Description = "Allows the players to kill entities using the second action. Note that this may be misused to kill other players, too.", + RecommendedGroups = "admins, mods", + }, +} +</pre> + + <p>The RecommendedGroup element lists, in plain English, the intended groups for which the permission should be enabled on a typical server. Plugin authors are advised to create reasonable defaults, prefering security to openness, so that admins using these settings blindly don't expose their servers to malicious users.</p> + + + <hr /> + <a name="Using"><h2>Using the file in code</h2></a> + + <p>Just writing the Info.lua file and saving it to the plugin folder is not enough for it to actually be used. Your plugin needs to include the following boilerplate code, preferably in its Initialize() function:</p> +<pre class="prettyprint lang-lua"> +-- Use the InfoReg shared library to process the Info.lua file: +dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua") +RegisterPluginInfoCommands() +RegisterPluginInfoConsoleCommands() +</pre> + + <p>Of course, if your plugin doesn't have any console commands, it doesn't need to call the RegisterPluginInfoConsoleCommands() function, and similarly if it doesn't have any in-game commands, it doesn't need to call the RegisterPluginInfoCommands() function.</p> + + + <hr /> + <a name="Examples"><h2>Examples</h2></a> + + <p>There are several plugins that already implement this approach. You can visit them for inspiration and to see what the generated documentation looks like:</p> + <ul> + <li>Gallery plugin: <a href="https://github.com/mc-server/Gallery/blob/master/Info.lua">Info.lua</a>, <a href="http://forum.mc-server.org/showthread.php?tid=1306">Forum</a> documentation</li> + <li>WorldEdit plugin: <a href="https://github.com/mc-server/WorldEdit/blob/master/Info.lua">Info.lua</a>, <a href="http://forum.mc-server.org/showthread.php?tid=870">Forum</a> and <a href="https://github.com/mc-server/WorldEdit">MarkDown</a> documentation</li> + </ul> + + <script> + prettyPrint(); + </script> + </div> + </body> +</html> diff --git a/MCServer/Plugins/ChunkWorx/chunkworx_web.lua b/MCServer/Plugins/ChunkWorx/chunkworx_web.lua index 6c5eab676..9aec38b12 100644 --- a/MCServer/Plugins/ChunkWorx/chunkworx_web.lua +++ b/MCServer/Plugins/ChunkWorx/chunkworx_web.lua @@ -43,7 +43,7 @@ function HandleRequest_Generation( Request ) local Content = "" if (Request.PostParams["AGHRRRR"] ~= nil) then GENERATION_STATE = 0 - WW_instance:SaveAllChunks() + WW_instance:QueueSaveAllChunks() WW_instance:QueueUnloadUnusedChunks() LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin") end diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 064d5d772..534426d25 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -29,7 +29,8 @@ function Initialize(Plugin) PM:AddHook(cPluginManager.HOOK_WORLD_TICK, OnWorldTick); PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded); PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage); - PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined) + PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined); + PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock); -- _X: Disabled so that the normal operation doesn't interfere with anything -- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated); @@ -1379,3 +1380,14 @@ end + +function OnProjectileHitBlock(a_Projectile, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockHitPos) + local BlockX, BlockY, BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace) + local World = a_Projectile:GetWorld() + + World:SetBlock(BlockX, BlockY, BlockZ, E_BLOCK_FIRE, 0) +end + + + + diff --git a/MCServer/Plugins/Handy/handy_functions.lua b/MCServer/Plugins/Handy/handy_functions.lua index c142ffd08..af43f663a 100644 --- a/MCServer/Plugins/Handy/handy_functions.lua +++ b/MCServer/Plugins/Handy/handy_functions.lua @@ -6,7 +6,7 @@ function GetHandyVersion() return HANDY_VERSION end -- Checks if handy is in proper version -function CheckForRequiedVersion( inVersion ) +function CheckForRequiredVersion( inVersion ) if( inVersion > HANDY_VERSION ) then return false end return true end @@ -213,4 +213,4 @@ end function BoolToString( inValue ) if( inValue == true ) then return 1 end return 0 -end
\ No newline at end of file +end |