Fufi Menu


I've just updated Fufi Menu for MPAseco (Shootmania).

Pre alpha: http://www.mpaseco.org/uploads/plugins/fufi-menu-alpha.0.1.zip

v0.01 - 24.02.2012 recommended
  1. Added support for MPAeco

v2.04 - 16.10.2011
  1. Added support for undef's Third-Party Plugins UpToDate
  2. Added MX Entrys
  3. The Button can now be hidden on score screen(hideonscore @ fufi_menu_config.xml)

v2.03beta - 10.09.2011
  1. All Gamemode are available in the menu now
  2. Fixed "Info -> Server -> Xaseco"2 Command & Text
  3. Removed "HUD -> Style-> Off"
  4. Increased size of the close button

v2.02beta - 06.09.2011
  1. Updated all Map entrys in fufi_menu_config.xml

v2.01beta - 06.09.2011
  1. Updated entrys in fufi_menu_config.xml
  2. Fixed Gamemodes and disabled Laps/Stunts entrys temporary.

Some Screenshots

Quote of the original Post because there are no changes.

XAseco2 0.90 or better required

Since XAseco is lacking of a menu which already exists in the other controllers, I decided to write one exclusively for XAseco, so no I won't port it to Aseco since there is already the oliverde8 menu which works similar.


If you don't follow the steps carefully, the plugin will not be working properly.
  1. Unrar the archive into the ASECO folder
  2. Insert the following line into "plugins.xml" (after all other plugins (actually it can be placed before or after the Fufi Widgets, if you use them))<plugin>plugin.fufi.menu.php</plugin>
  3. Configure some stuff if you like to (see configuration section below)
  4. Done! Have fun!


Inside the main XAseco folder, you'll find a file called "fufi_menu_config.xml". Inside this file you can configure everything you want to customize the menu to your needs:
  1. menu_caption: the text in the menu button
  2. styles: all used styles and substyles for the menu graphics, feel free to play around
  3. size: the size of the menu button
  4. separatorheight: the height of a "separator" entry in the menu
  5. menutimeout: the amount of milliseconds until the menu closes automatically if nothing was clicked
  6. position: the position of the menu button and according to that the main starting point for the menu
  7. horizontalorientation: the way the menu arranges its submenus horizontally (1.. left-to-right, 2...right-to-left)
  8. verticalorientation: the way the menu arranges its submenus vertically (1.. top-to-bottom, 2...bottom-to-top)
  9. for the last three entries I included presets for all the four corners of the screen, you'll just have to take out the comments
  10. entries: for a detailed description on how the entries work, please have a look at the "Structure" section below


Now I'll come to the most interesting but also probably most confusing part of the menu: the menu structure. Once you understood the structure, it will be easy for you to add new submenus with your own entries or remove existing menus. The best way to understand the structure is to have a look at the entries section inside "fufi_menu_config.xml". I've built in a lot of features that won't be necessary for the majority of users, but I'll still try to write everything down here.

The maximum possibilities of the tag "entry" are like that:


The attributes of entry are used like that:

  1. type: [optional] if left out, the entry will ether be an extendable menu group or an actual clickable entry, if set to "help" it's basically the same as the beforementioned, but the icon next to the entry will be the help icon, if set to "separator" there will be some vertical space in the menu on this place, to make the structure more readable
  2. caption: [optional] this one is needed for every entry but the separators, it defines the text which is shown in the menu for this entry
  3. indicator: [optional] this one's a bit tricky. It is used for boolean properties which should already display their state inside the menu with the help of a red (false), green (true) or yellow (pending) icon.
    The "indicator" attribute has to be a valid function name that returns 0 for "false", 1 for "true" and 2 for "pending",every other value will disable the icon, I'll get back later to the usage of this functionality.
  4. params: [optional] With the help of the params you can pass values to the indicator function (comma separated)
  5. chatcmd: [optional] This is the heart of the menu, here you define the chat command which should be emulated, when a user clicks an entry in the menu, if left out, the entry will serve as a menu group which can hold subentries
  6. chatcmdparams: [optional] Setting this attribute only makes sense if you define an "indicator"-function and the entry therefore represents a boolean value, as most of you know, a lot of settings in XAseco can be activated by "/somechatcommand ON" and deactived by "/somechatcommand OFF", to make that possible, "chatcmdparams" in this case would be "OFF/ON" (slash separated), if left out, the menu would always perform "/somechatcommand"
  7. dependencies: [optional] comma separated list of plugins that have to be installed, so these menu entries will be displayed
  8. ability: [optional] since XAseco has the tiered admin system, every chat command can be limited to special user groups, if a user needs a special ability to execute this menu entry/chat command, you'll need to specify the ability in this attribute (all abilities can be found inside "adminops.xml")
    If a chat command starts with "/admin" or "/jfreu" the menu will automatically check for the abilities, so there's no need to define the "ability" attribute there.
  9. globalvariable: [optional] some features in XAseco like karma and voting are activated via global variables, so this attribute checks for the existence of the defined variable and if it's set to true and displays the entry if the condition is given
  10. unique: This attribute always has to be defined and contains a string that identifies the entry uniquely, it is mainly used to define entry points for plugin generated menu entries

Structural Example

For an example that should cover all the possibilities, I'll try to rip out some code from the original menu mixed with some imaginary code (the code itself, especially the structure makes no sense at all, but it's good enough for an example):

01 <entry caption='Music' dependencies='plugin.musicserver.php' unique='music'>
02 <entry caption='List' chatcmd='/music list' unique='musiclist'/>
03 <entry caption='Administration' ability='chat_musicadmin' unique='musicadmin'>
04 <entry caption='Track Override' indicator='fufi_getMusicOverrideIndicator' chatcmd='/music override' chatcmdparams='off/on' unique='musicoverride'/>
05 </entry>
06 <entry caption='10 Coppers' chatcmd='/donate 10' dependencies='plugin.donate.php' rights='TMUF' unique='don10'/>
07 <entry caption='Game Mode' unique='admingamemode'>
08 <entry caption='Rounds' indicator='fufi_getGameModeIndicator' params='0' chatcmd='/admin setgamemode rounds' unique='admingmrounds'/>
09 <entry caption='Time Attack' indicator='fufi_getGameModeIndicator' params='1' chatcmd='/admin setgamemode ta' unique='admingmtimeattack'/>
10 </entry>
11 <entry type='separator' unique='musicsep1'/>
12 <entry type='help' caption='Help' chatcmd='/helpall' unique='helpall1'/>
13 <entry caption='Track Karma' globalvariable='feature_karma' chatcmd='/karma' unique='karma'/>
14 </entry>

So what will happen in these lines? (the numbers in the list correspond to the line numbers)
  1. a new submenu with the caption "Music" is created, it will only show up in the actual menu, if the plugin "plugin.musicserver.php" is in the list of the active plugins, the unique key is "music"

  2. creates a simple clickable entry with the caption "List" which executes the chat command "/music list", I'm not gonna tell you any more about the unique key, it should be obvious that it's always there and always different

  3. here a new submenu under the "Music" menu is created (caption is "Administration"), the ability tag says that this menu and all its submenus and entries will only be visible to players, that have the ability "chat_musicadmin" inside the "adminops.xml"

  4. creates a clickable entry that is bound to a boolean value, the indicator points to a function name:
    That means, whenever this menu will be accessed, the function "function fufi_getMusicOverrideIndicator()" will be called and the result of this function determines on how this entry will be marked. The function in fact checks if MusicOverride is on or off and will return true or false which then results in a green or red icon next to the entry (see the simple source of this function inside "plugins/plugin.fufi.menu.php"), of course you can define your own indicator functions inside your plugins, I just defined the ones for functinalities included in the original XAseco release

  5. closing tag for the "Administration" submenu

  6. creates a Donation entry (only works with active plugin "plugin.donate.php" and will only be shown to United users because of the "rights" attribute)

  7. a new submenu with the caption "Game Mode" is created

  8. at the first view this looks quite similar to the "Track Override" entry, but it's got one difference: the indicator function "fufi_getGameModeIndicator" now also takes a parameter defined in the attribute "params":
    That results in a method call like this: fufi_getGameModeIndicator(0)
    The function then checks if GameMode 0 (which means "Rounds") is currently active or will be active in the next round, the result of the function then determines the icon which is shown next to the entry (again, double check with the source of this function inside "plugins/plugin.fufi.menu.php")

  9. similar to line 8, but results in a function call like this: fufi_getGameModeIndicator(1)

  10. closing tag for the "Game Mode" submenu

  11. creates a vertical gap (separator) in the menu

  12. similar to all other entries, this one creates a simple clickable entry which executes the chat command "/helpall", the only difference is that with the attribute "type='help'" the icon of this entry will be a help icon

  13. this entry will only be shown if the global variable "feature_karma" is defined and set to true

  14. closing tag for the "Music" submenu

Please don't be scared of all those attributes, if you really want to work with the menu you'll get a hold of its functionality very soon.

And now let's proceed to the really cool part, using the menu from within your own plugins.

Plugin Access

This section will cover how to access the menu if you want to add your own groups and entries for your plugins. You should have read the sections about the structure to understand this one, but basically it's very easy.

To see a tiny working example, have a look at the Fufi Widgets, I implemented the menu function there.

First of all you'll need to react on an event called "onMenuLoaded" just like you react on all the other events, XAseco releases.
Aseco::registerEvent('onMenuLoaded', 'myplugin_initMenu');

Then of course you'll need to implement the function "myplugin_initMenu".
function myplugin_initMenu($aseco, $menu){

Inside this function (which will only be called once at the start of the server when the menu is loaded) you can now work with the $menu variable to access the menu.
Therefore there are two methods, the first one is called "addEntry" and looks like this:
function addEntry($insertInGroup, $entryPoint, $insertAfter='true', $caption, $unique, $chatcmd='', $chatcmdparams='', $ability='', $indicator='', $params='', $type='', $rights='')

Now that's the beautiful part of it, nearly all of those parameters directly correspond to the XML structure I described before:
  1. $insertInGroup - That's the moment, where you'll need the unique key of the group where you want to insert your entry, if left empty, your entry will be inserted into the root menu
  2. $entryPoint - Here you'll have to enter the unique key of the entry in the menu where you want to insert your entry, depending on the next parameter, our entry will be positioned before or after the "entryPoint", if left out or the key is unknown, your entry will be inserted at the very beginning or the very end of the group
  3. $insertAfter - This is a boolean value, if set to true your entry will be placed after the one specified in the parameter before, if set to false it will be placed before the other entry
  4. $caption - similar to XML attribute caption
  5. $unique - similar to XML attribute unique
  6. $chatcmd - similar to XML attribute chatcmd
  7. $chatcmdparams - similar to XML attribute chatcmdparams
  8. $ability - similar to XML attribute ability
  9. $indicator - similar to XML attribute indicator
  10. $params - similar to XML attribute params
  11. $type - similar to XML attribute type
  12. $rights - similar to XML attribute rights

The other function which is actually just a shortcut to "addEntry" is called "addSeparator" and looks like this:
addSeparator($insertInGroup, $entryPoint, $insertAfter, $unique)
The parameters are similar to the ones of "addEntry" just less^^.

And now the fun part, I'll use those two functions to make up a menu for my imaginary plugin. I'm aware of the fact, that the order in which I add the entries is a bit chaotic, but I wanted to display the possibilities of the $insertAfter parameter. The comments describe the funtionality of the corresponding function calls.

function myplugin_initMenu($aseco, $menu){

// creates a menu group with the caption "My Plugin" in the root menu, after all other entries
$menu->addEntry('', '', 'My Plugin', 'myplugin');

// creates an entry inside the new group which executes the chatcommand "/myplugin list"
$menu->addEntry('myplugin', '', 'Show List', 'mypluginlist', '/myplugin list');

// adds an entry at the beginning of the "My Plugin" group, which will only be shown to players with the ability "chat_mypluginadmin"
$menu->addEntry('myplugin', -1, 'Do Weird Admin Stuff', 'mypluginadminstuff', '/myplugin adminstuff', '', 'chat_mypluginadmin');

// adds a simple chat command at the end of the menu, also the type is "help" so the icon will be the help icon
$menu->addEntry('myplugin', '', 'Help', 'mypluginhelp', '/myplugin help', '', '', '', '', 'help');

// adds a separator after the "Show List" entry
$menu->addSeparator('myplugin', 'mypluginlist', 'mypluginsep1');