From dac97826f7d0c9b9135c1a08c4d5f16b61494bd1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 26 Aug 2015 10:58:51 +0200 Subject: Renamed output directory to Server --- .../Plugins/APIDump/Writing-a-Cuberite-plugin.html | 255 --------------------- 1 file changed, 255 deletions(-) delete mode 100644 MCServer/Plugins/APIDump/Writing-a-Cuberite-plugin.html (limited to 'MCServer/Plugins/APIDump/Writing-a-Cuberite-plugin.html') diff --git a/MCServer/Plugins/APIDump/Writing-a-Cuberite-plugin.html b/MCServer/Plugins/APIDump/Writing-a-Cuberite-plugin.html deleted file mode 100644 index 2b6af0d82..000000000 --- a/MCServer/Plugins/APIDump/Writing-a-Cuberite-plugin.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - Cuberite Plugin Tutorial - - - - - - - -
-

Writing a Cuberite plugin

-

- This article will explain how to write a basic plugin. It details basic requirements - for a plugin, explains how to register a hook and bind a command, and gives plugin - standards details. -

-

- Let us begin. In order to begin development, we must firstly obtain a compiled copy - of Cuberite, and make sure that the Core plugin is within the Plugins folder, and activated. - Core handles much of the Cuberite end-user experience and gameplay will be very bland without it. -

-

Creating the basic template

-

- Plugins are written in Lua. Therefore, create a new Lua file. You can create as many files as you wish, with - any filename - Cuberite bungs them all together at runtime, however, let us create a file called main.lua for now. - Format it like so: -

-
-PLUGIN = nil
-
-function Initialize(Plugin)
-	Plugin:SetName("NewPlugin")
-	Plugin:SetVersion(1)
-
-	-- Hooks
-
-	PLUGIN = Plugin -- NOTE: only needed if you want OnDisable() to use GetName() or something like that
-
-	-- Command Bindings
-
-	LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
-	return true
-end
-
-function OnDisable()
-	LOG(PLUGIN:GetName() .. " is shutting down...")
-end
-			
-

- Now for an explanation of the basics. -

- Be sure to return true for this function, else Cuberite thinks you plugin had failed to initialise and prints a stacktrace with an error message. -

- -

Registering hooks

-

- Hooks are things that Cuberite calls when an internal event occurs. For example, a hook is fired when a player places a block, moves, - logs on, eats, and many other things. For a full list, see the API documentation. -

-

- A hook can be either informative or overridable. In any case, returning false will not trigger a response, but returning true will cancel - the hook and prevent it from being propagated further to other plugins. An overridable hook simply means that there is visible behaviour - to a hook's cancellation, such as a chest being prevented from being opened. There are some exceptions to this where only changing the value the - hook passes has an effect, and not the actual return value, an example being the HOOK_KILLING hook. See the API docs for details. -

-

- To register a hook, insert the following code template into the "-- Hooks" area in the previous code example. -

-
-cPluginManager.AddHook(cPluginManager.HOOK_NAME_HERE, FunctionNameToBeCalled)
-			
-

- What does this code do? -

- What about the third parameter, you ask? Well, it is the name of the function that Cuberite calls when the hook fires. It is in this - function that you should handle or cancel the hook. -

-

- So in total, this is a working representation of what we have so far covered. -

-
-function Initialize(Plugin)
-	Plugin:SetName("DerpyPlugin")
-	Plugin:SetVersion(1)
-
-	cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
-
-	LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
-	return true
-end
-
-function OnPlayerMoving(Player) -- See API docs for parameters of all hooks
-	return true -- Prohibit player movement, see docs for whether a hook is cancellable
-end
-			
-

- So, that code stops the player from moving. Not particularly helpful, but yes :P. Note that ALL documentation is available - on the main API docs page, so if ever in doubt, go there. -

-

Binding a command

-

Format

-

- So now we know how to hook into Cuberite, how do we bind a command, such as /explode, for a player to type? That is more complicated. - We firstly add this template to the "-- Command bindings" section of the initial example: -

-
--- ADD THIS IF COMMAND DOES NOT REQUIRE A PARAMETER (/explode)
-cPluginManager.BindCommand("/commandname", "permissionnode", FunctionToCall, " - Description of command")
-
--- ADD THIS IF COMMAND DOES REQUIRE A PARAMETER (/explode Notch)
-cPluginManager.BindCommand("/commandname", "permissionnode", FunctionToCall, " ~ Description of command and parameter(s)")
-			
-

- What does it do, and why are there two? -

- The command name is pretty self explanatory. The permission node is basically just a string that the player's group needs to have, so you can have anything in there, - though we recommend a style such as "derpyplugin.explode". The function to call is like the ones with Hooks, but with some fixed parameters which we will come on to later, - and the description is a description of the command which is shown when "/help" is typed. -

-

- So why are there two? Standards. A plugin that accepts a parameter MUST use a format for the description of " ~ Description of command and parms" - whereas a command that doesn't accept parameters MUST use " - Description of command" instead. Be sure to put a space before the tildes or dashes. - Additionally, try to keep the description brief and on one line on the client. -

-

Parameters

-

- What parameters are in the function Cuberite calls when the command is executed? A 'Split' array and a 'Player' object. -

-

The Split Array

-

- The Split array is an array of all text submitted to the server, including the actual command. Cuberite automatically splits the text into the array, - so plugin authors do not need to worry about that. An example of a Split array passed for the command, "/derp zubby explode" would be:

-    /derp (Split[1])
-    zubby (Split[2])
-    explode (Split[3])
-
-    The total amount of parameters passed were: 3 (#Split) -

-

The Player Object and sending them messages

-

- The Player object is basically a pointer to the player that has executed the command. You can do things with them, but most common is sending - a message. Again, see the API documentation for fuller details. But, you ask, how do we send a message to the client? -

-

- There are dedicated functions used for sending a player formatted messages. By format, I refer to coloured prefixes/coloured text (depending on configuration) - that clearly categorise what type of message a player is being sent. For example, an informational message has a yellow coloured [INFO] prefix, and a warning message - has a rose coloured [WARNING] prefix. A few of the most used functions are listed here, but see the API docs for more details. Look in the cRoot, cWorld, and cPlayer sections - for functions that broadcast to the entire server, the whole world, and a single player, respectively. -

-
--- Format: §yellow[INFO] §white%text% (yellow [INFO], white text following it)
--- Use: Informational message, such as instructions for usage of a command
-Player:SendMessageInfo("Usage: /explode [player]")
-
--- Format: §green[INFO] §white%text% (green [INFO] etc.)
--- Use: Success message, like when a command executes successfully
-Player:SendMessageSuccess("Notch was blown up!")
-
--- Format: §rose[INFO] §white%text% (rose coloured [INFO] etc.)
--- Use: Failure message, like when a command was entered correctly but failed to run, such as when the destination player wasn't found in a /tp command
-Player:SendMessageFailure("Player Salted was not found")
-			
-

- Those are the basics. If you want to output text to the player for a reason other than the three listed above, and you want to colour the text, simply concatenate - "cChatColor.*colorhere*" with your desired text, concatenate being "..". See the API docs for more details of all colours, as well as details on logging to console with - LOG("Text"). -

-

Final example and conclusion

-

- So, a working example that checks the validity of a command, and blows up a player, and also refuses pickup collection to players with >100ms ping. -

-
-function Initialize(Plugin)
-	Plugin:SetName("DerpyPluginThatBlowsPeopleUp")
-	Plugin:SetVersion(9001)
-
-	cPluginManager.BindCommand("/explode", "derpyplugin.explode", Explode, " ~ Explode a player");
-
-	cPluginManager:AddHook(cPluginManager.HOOK_COLLECTING_PICKUP, OnCollectingPickup)
-
-	LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
-	return true
-end
-
-function Explode(Split, Player)
-	if (#Split ~= 2) then
-		-- There was more or less than one argument (excluding the "/explode" bit)
-		-- Send the proper usage to the player and exit
-		Player:SendMessage("Usage: /explode [playername]")
-		return true
-	end
-
-	-- Create a callback ExplodePlayer with parameter Explodee, which Cuberite calls for every player on the server
-	local HasExploded = false
-	local ExplodePlayer = function(Explodee)
-		-- If the player we are currently at is the one we specified as the parameter
-		if (Explodee:GetName() == Split[2]) then
-			-- Create an explosion at the same position as they are; see API docs for further details of this function
-			Player:GetWorld():DoExplosionAt(Explodee:GetPosX(), Explodee:GetPosY(), Explodee:GetPosZ(), false, esPlugin)
-			Player:SendMessageSuccess(Split[2] .. " was successfully exploded")
-			HasExploded = true;
-			return true -- Signalize to Cuberite that we do not need to call this callback for any more players
-		end
-	end
-
-	-- Tell Cuberite to loop through all players and call the callback above with the Player object it has found
-	cRoot:Get():FindAndDoWithPlayer(Split[2], ExplodePlayer)
-
-	if not(HasExploded) then
-		-- We have not broken out so far, therefore, the player must not exist, send failure
-		Player:SendMessageFailure(Split[2] .. " was not found")
-	end
-
-	return true
-end
-
-function OnCollectingPickup(Player, Pickup) -- Again, see the API docs for parameters of all hooks. In this case, it is a Player and Pickup object
-	if (Player:GetClientHandle():GetPing() > 100) then -- Get ping of player, in milliseconds
-		return true -- Discriminate against high latency - you don't get drops :D
-	else
-		return false -- You do get the drops! Yay~
-	end
-end
-			
-

- Make sure to read the comments for a description of what everything does. Also be sure to return true for all command handlers, unless you want Cuberite to print out an "Unknown command" message - when the command gets executed :P. Make sure to follow standards - use CoreMessaging.lua functions for messaging, dashes for no parameter commands and tildes for vice versa, - and finally, the API documentation is your friend! -

-

- Happy coding ;) -

- - -
- - -- cgit v1.2.3