Plugin Creation

Creating plugins for Mania++ is quite easy, most of the work of communicating with the controller is already available in the Plugin “interface”. With simple calls, you can add your functions to catch callbacks and call methods on the server. An example of a “complete”, but small Plugin can be found on the repository.

main.cpp

The main.cpp file contains just one simple function, namely ‘startPlugin’:

extern "C" Plugin* startPlugin()
{
    ExamplePlugin* plugin = new ExamplePlugin();
    return (Plugin*)plugin;
}

This function is called by the plugin manager to retrieve the plugin class, which is inherited of the class Plugin in the Mania++ package.

Your plugin class

The plugin class is just the base point to which Mania++ can rely information. You can structure your plugin the way you like, but make sure to follow a few restrictions/guidelines. Be aware that your plugin should inherit Plugin, which should be included via Plugins/Plugin.h.

Plugin constructor

The constructor should be setting the version and author variables of the Plugin interface:

  Version = "0.1.0";
  Author = "YOU";

The constructor is also responsible of adding the functions which should be called when a callback comes in from the server. You simply add your function to one of the vectors which contains all your plugin’s callbackhandlers. Only functions added in the constructor are taken into account by the system. Adding functions afterwards will have no effect. Because the std::function doesn’t work nicely with class methods, you can do the following:

  PlayerConnect.push_back([this](Player player) { OnPlayerConnect(player); });

In this case, OnPlayerConnect is the method you want to get called when a ManiaPlanet.PlayerConnect callback gets fired.

Adding chat commands also only works in the constructor and is simliar to subscribing on events. You can call the RegisterCommand (for /xxxx) and RegisterAdminCommand (for /admin xxxx) methods:

RegisterCommand("test", "This is just a testing command.", [this](Player player, std::vector<std::string> parameters) { OnTestCommand(player, parameters); });
RegisterAdminCommand("test", "This is just an admin testing command.", Permission::Operator, [this](Player player, std::vector<std::string> parameters) { OnAdminTestCommand(player, parameters); });

The parameters you receive in your chat-function are the remaining words (so seperated by spaces) in the chat line.

Plugin Init()

The Plugin interface demands you have an Init() method in your plugin class. This method is being called after all plugins have been loaded by the system. At this moment all needed instances have been set for your plugin and can be called.

Plugin CallBack methods

Almost all callbacks from the server are relayed to the plugins. The table indicates which callback can be received via which methods vector (on which to register your method) and which parameters you will receive in your method.

CallBack Methods vector Method parameters
Every second (from controller) EverySecond  
Every minute (from controller) EveryMinute  
ManiaPlanet.PlayerConnect PlayerConnect Player
ManiaPlanet.PlayerDisconnect PlayerDisconnect Player
ManiaPlanet.PlayerChat PlayerChat Player, std::string
ManiaPlanet.Echo Echo std::string, std::string
ManiaPlanet.BeginMatch BeginMatch  
ManiaPlanet.EndMatch EndMatch std::vector<PlayerRanking>, int
ManiaPlanet.BeginMap BeginMap Map
ManiaPlanet.EndMap EndMap Map
ManiaPlanet.StatusChanged StatusChanged int, std::string
TrackMania.PlayerCheckpoint PlayerCheckpoint Player, int, int, int
TrackMania.PlayerFinish PlayerFinish Player, int
TrackMania.PlayerIncoherence PlayerIncoherence Player
ManiaPlanet.BillUpdated BillUpdated int, int, std::string, int
ManiaPlanet.MapListModified MapListModified int, int, bool
ManiaPlanet.PlayerInfoChanged PlayerInfoChanged Player
ManiaPlanet.VoteUpdated VoteUpdated std::string, std::string, std::string, std::string

ManiaPlanet.PlayerManialinkPageAnswer callbacks are only available via the UIManager.

Accessing controller features

The controller features are accessible via a Controller struct, which is included in your plugin as controller->. From here, you can execute queries on the server, access the current playerlist and maplist (and make changes in them) and query the database.

Controller feature Variable Documentation
Querying dedicated server Server Methods
Current player list Players Simple vector with Player objects
Current map list Maps MapList
Database access Database MySQL C++ Connector
Interface Manager UI UIManager
Inter-plugin communication Plugins PluginHandler
Server information Info ServerInfo