/**
* This source file is part of WZ Hybrid Bots
* For the latest information, see http://sourceforge.net/projects/wzhybridbots
*
* Copyright (c) 2006 - WzCtf
* For more information about WzCtf, see http://www.wzctf.net
* Also see the license in license.txt
*/
package plugins.PluginManager;
/** The imported classes/interfaces */
import java.util.Iterator;
import hybrid.core.HybridConnection;
import hybrid.core.consts.Events;
import hybrid.core.events.ConnectionClosed;
import hybrid.core.events.ConnectionOpened;
import hybrid.core.events.HybridEvent;
import hybrid.core.events.SpawnStarted;
import frontend.alphaspawn.ASConnection;
import frontend.alphaspawn.PluginAdapter;
import frontend.alphaspawn.tools.arena.ASArena;
import frontend.alphaspawn.tools.command.Command;
import frontend.alphaspawn.tools.command.CommandManager;
import plugins.PluginManager.tools.command.Plugin;
import wzhybridbots.security.BotOperatorSet;
import wzhybridbots.security.BotOperatorSetRetriever;
/**
* This plugin list/load/unload/reload other plugins at runtime.
* <br><br>
* To use this plugin, the bot that loads it <b>should</b> implement the
* following interface(s) or a ClassCastException may be thrown:
* <p>
* <br><b>Mandatory</b>:<br>
* {@link wzhybridbots.security.BotOperatorSetRetriever BotOperatorSetRetriever}<br>
* <br><b>Optional</b>:<br>
* None<br>
* </p>
*
* @author Witlospock
* @version 1.0
*/
public class PluginManager extends PluginAdapter {
/** A connection object used to track and handle commands */
protected ASConnection objConnection = null;
/** A set of the bot operators and their access level */
protected BotOperatorSet objBotOperators = null;
/** The plugin command*/
protected Command objPluginCmd = null;
/**
* Default class constructor.
*/
public PluginManager () {
super();
init();
}
/**
* Class constructor.
*
* @param pluginName The name of the plugin.
*/
public PluginManager ( String pluginName ) {
super( pluginName );
init();
}
/**
* Initialize the object.
*/
protected void init () {
// Try to set the BotOperatorSet object
setBotOperatorSet();
// Get the first available ASConnection that correspond to the plugin needs
for ( Iterator iter = this.objBotSpawn.getConnections().iterator() ; iter.hasNext() ; ) {
HybridConnection conn = (HybridConnection)iter.next();
// Sets the connection
if ( setConnection( conn ) ) {
break;
}
}
}
/**
* Returns true if the two objects are equals, false otherwise.
*
* @param o The object to compare with.
* @return see above.
*/
public boolean equals ( Object o ) {
// Compare the objects structure
if ( o == this ) { return true; }
if ( o == null ) { return false; }
if ( !(o instanceof PluginManager ) ) { return false; }
// Compare the objects data
if ( o.hashCode() != this.hashCode() ) { return false; }
// Must return true if plugins are of the same type
// so no 2 identical plugins are registered
return this.getClass().isInstance( o );
}
/**
* Returns the hash code of the object.
*
* @return see above.
*/
public int hashCode () {
return 0;
}
/**
* Called when the plugin is being loaded and is ready
* to receive events.
*/
protected void enable () {
// Continue the initialization + register the command(s)
activatePlugin();
}
/**
* Called when the plugin is being desactivated and won't
* receive anymore events until it is re-enable.
*/
protected void disable () {
// Remove commands
removeCommand();
}
/**
* Called when an event should be process by the plugin.
*
* @param event The event to process.
* @return The event itself so it can be process by other plugin. If null
* returned, the event won't be process by other plugins.
*/
protected HybridEvent processEvent ( HybridEvent event ) {
// Checks for a valid event
if ( event == null || !event.isAlive() ) { return event; }
// Checks the type of events
switch ( event.getGroupID() )
{
// Core Events
case Events.Group:
switch ( event.getEventID() )
{
// An HybridConnection has been open
case Events.ConnectionOpened:
setConnection( ((ConnectionOpened) event).getConnection() );
activatePlugin();
break;
// An HybridConnection has been close
case Events.ConnectionClosed:
removeConnection( ((ConnectionClosed) event).getConnection() );
removeCommand();
break;
// A bot is about to be activated
case Events.SpawnStarted:
if ( this.objBotSpawn.equals( ((SpawnStarted)event ).getBotSpawn() ) ) {
// The plugin's bot is about to start
// Activate the plugin
activatePlugin();
}
break;
}
break;
}
// Return the event to be process by the next plugin
return event;
}
/**
* Called when the bot is shutingdown. It should be use to do
* some cleanup.
*/
protected void deconstruct () {
}
/**
* Sets the connection object to use by this plugin.
*
* @param conn The connection object to use.
* @return true if the connection object will be use, false otherwise.
*/
protected boolean setConnection ( HybridConnection conn ) {
// Checks if a connection is already use
if ( this.objConnection != null ) { return false; }
// Checks if the connection object is of the right type
if ( !(conn instanceof ASConnection) ) { return false; }
// Sets the connection object
this.objConnection = (ASConnection)conn;
this.objConnection.registerArena( ASArena.getInstance() );
return true;
}
/**
* Remove the connection object used by this plugin.
*
* @param conn The connection object to remove.
* @return true if the connection object has been remove, false otherwise.
*/
protected boolean removeConnection ( HybridConnection conn ) {
// Checks if the connection is valid
if ( this.objConnection == null || conn == null ) { return false; }
// Checks if it is the same connection object
if ( this.objConnection == conn ) {
// Removes the connection object
this.objConnection.removeArena( ASArena.getInstance() );
this.objConnection = null;
return true;
}
return false;
}
/**
* Registers the command used by this plugin.
*/
protected void registerCommand () {
// Get the command manager
CommandManager cmdMgr = CommandManager.getInstance();
// Check if the plugin command can be registered
if ( this.objPluginCmd == null &&
this.objConnection != null &&
this.objBotOperators != null ) {
// Register the "plugin" command
this.objPluginCmd = new Plugin( this.objConnection, this.objPluginManager, this.objBotOperators );
cmdMgr.registerCommand( "!plugin", this.objPluginCmd );
}
}
/**
* Removes the command used by this plugin.
*/
protected void removeCommand () {
// Get the command manager
CommandManager cmdMgr = CommandManager.getInstance();
// Check if the plugin command can be remove
if ( this.objPluginCmd != null ) {
// Remove the "plugin" command
cmdMgr.removeCommand( "!plugin", this.objPluginCmd );
this.objPluginCmd = null;
}
}
/**
* Sets the BotOperatorSet of the plugin if available at the time.
*
* @return true if the BotOperatorSet object was set, false otherwise.
* @throws ClassCastException if the bot that loads this plugin doesn't
* support the {@link wzhybridbots.security.BotOperatorSetRetriever BotOperatorSetRetriever}
* interface.
*/
protected boolean setBotOperatorSet () {
// Check if the set has been already obtain
if ( this.objBotOperators != null ) { return true; }
// Check if the bot support the requiered interface
if ( !(this.objAdapter instanceof BotOperatorSetRetriever) ) {
// The bot doesn't implement the required interface
throw new ClassCastException();
}
// Get the set, null if not available at this time.
BotOperatorSetRetriever retriever = (BotOperatorSetRetriever)this.objAdapter;
this.objBotOperators = retriever.getBotOperatorSet();
return this.objBotOperators != null;
}
/**
* Finishes the initialization of the plugin if not in a ready state.
*/
protected void activatePlugin () {
// Try to set the BotOperatorSet object
setBotOperatorSet();
// Try to register the command(s) if not already registered
registerCommand();
}
}