Wiki

Clone wiki

asss / Entry_Point

Entry Points

The entry point is the beginning and end of all C modules. It is the only function that the module loader is directly aware of, and all module to server communication, such as interfaces, callbacks, advisers, are set up and cleaned up here.

All Entry Point functions are named MM_yourmodulename. The name of the entry point directly controls what the name of the module is when referred to in modules.conf or ?insmod.

Conventions

Declared as the following:

EXPORT int MM_yourmodulename(int action, Imodman *, Arena *);

Entry points either return MM_OK when an action succeeds or MM_FAIL when an action does not succeed.

Actions

action is passed one of several different values based on what the module manager is trying to do with your module:

  • MM_LOAD: The first action called on a module. The module should take care of things it only needs to do once here, as well as register anything that applies globally (in all arenas.)
  • MM_UNLOAD: The last action called on a module before it is unloaded from memory. Generally it is implemented as the inverse of MM_LOAD, as well as cleaning up any other dynamically allocated memory, or any other tools registered since MM_LOAD.
  • MM_ATTACH: When the module is attached to an arena. Only useful to modules that want to provide arena-level functionality that does not affect the entire zone. Handle this action by registering that applies to the arena. The arena is passed as one of the MM function paramaters. If your module isn't attachable, then it should return MM_FAIL from this action.
  • MM_DETACH: The inverse of MM_ATTACH. The module should clean up any data it has made on the arena, and unregister everything else it registered before. If your module isn't attachable, then it should return MM_FAIL from this action.
  • MM_POSTLOAD: Called after all modules from modules.conf are loaded on startup, or after the MM_LOAD subfunction has finished when using ?insmod. Typically this is only used when modules want to get interfaces from a module they know won't be loaded before them. There is no requirement to handle this action.
  • MM_PREUNLOAD: Called before MM_UNLOAD, and also before the server begins unloading modules for shutdown. It's the inverse of MM_POSTLOAD, if you did not handle MM_POSTLOAD you don't need to handle this either.

Example

/* create the entry point for the 'help' module */
EXPORT int MM_help(int action, Imodman *mm, Arena *arena)
{
	if (action == MM_LOAD)
	{
		/* obtain the interface for sending messages to players */
		chat = mm->GetInterface(I_CHAT, ALLARENAS); //get a reference to the implemented Ichat interface
		/* obtain the interface for registering commands */
		cmd = mm->GetInterface(I_CMDMAN, ALLARENAS); //get a reference to the implemented Icmdman interface

		if (!chat || !cmd)
		{
			/* we couldn't get one of our required interfaces
			 * we'll release whichever ones we did get and then return failure. */
			mm->ReleaseInterface(chat);
			mm->ReleaseInterface(cmd);
			return MM_FAIL;
		}

		/* use the Icmdman interface to register the ?help command
		 * ?help will trigger the Chelp function to be called in all arenas,
		 * with help_syntax registered as a text string for users to look up information on the command. */
		cmd->AddCommand("help", Chelp, ALLARENAS, help_syntax);

		/* we made it, return success */
		return MM_OK;
	}
	else if (action == MM_UNLOAD)
	{
		/* unregister the ?help command we registered in MM_LOAD. */
		cmd->RemoveCommand("help", Chelp, ALLARENAS);

		/* release the interfaces we obtained */
		mm->ReleaseInterface(chat);
		mm->ReleaseInterface(cmd);
		
		/* we're done now, return success */
		return MM_OK;
	}
	
	/* we don't care about attaching, or any of the other steps, we can blanket return MM_FAIL. */
	return MM_FAIL;
}

Updated