I have managed to sort of "repair" the event interface in server plugins (I mean make the plugin able to hook ANY event, known or unknown).
Code:
// global variables
KeyValues *GameEvents;
KeyValues *EngineEvents;
KeyValues *ModEvents;
void CPlugin::LevelInit (const char *pMapName)
{
KeyValues *pEvent;
// read the game events
GameEvents = new KeyValues ("GameEventsFile");
if (GameEvents->LoadFromFile (filesystem, "resource/gameevents.res", "GAME"))
{
// loop through all events in this file and record ourselves as listener for each
for (pEvent = GameEvents->GetFirstSubKey (); pEvent; pEvent = pEvent->GetNextKey ())
gameeventmanager->AddListener (this, pEvent->GetName (), true);
}
else
ServerConsole_printf ("Unable to read game events from file\n");
// read the engine events
EngineEvents = new KeyValues ("EngineEventsFile");
if (EngineEvents->LoadFromFile (filesystem, "resource/serverevents.res", "GAME"))
{
// loop through all events in this file and record ourselves as listener for each
for (pEvent = EngineEvents->GetFirstSubKey (); pEvent; pEvent = pEvent->GetNextKey ())
gameeventmanager->AddListener (this, pEvent->GetName (), true);
}
else
ServerConsole_printf ("Unable to read engine events from file\n");
// read the MOD events
ModEvents = new KeyValues ("ModEventsFile");
if (ModEvents->LoadFromFile (filesystem, "resource/modevents.res", "MOD"))
{
// loop through all events in this file and record ourselves as listener for each
for (pEvent = ModEvents->GetFirstSubKey (); pEvent; pEvent = pEvent->GetNextKey ())
gameeventmanager->AddListener (this, pEvent->GetName (), true);
}
else
ServerConsole_printf ("Unable to read MOD events from file\n");
return;
}
void CPlugin::LevelShutdown (void)
{
// forget about game, engine and mod events
GameEvents->deleteThis ();
EngineEvents->deleteThis ();
ModEvents->deleteThis ();
gameeventmanager->RemoveListener (this); // and stop listening to them
}
void CPlugin::FireGameEvent (IGameEvent *event)
{
// do we want to display game events on the fly ?
if (hook_events.GetInt () > 0)
{
printf ("Event \"%s\" received\n", event->GetName ()); // notify the player on his HUD
PrintEvent (event);
}
return; // finished
}
CON_COMMAND (listevt, "List all the events matching a given pattern")
{
KeyValues *pEventAsKey;
int event_count;
char arg1[128]; // no way, I hate pointers...
sprintf (arg1, engine->Cmd_Argv (1)); // get any argument to the command
// tell people what we are going to do
if (arg1[0] == 0)
ServerConsole_printf ("Printing out ALL game, server and MOD events...\n");
else
ServerConsole_printf ("Printing out game, server and MOD events matching \"%s\"...\n", arg1);
ServerConsole_printf ("Game events:\n");
event_count = 0;
for (pEventAsKey = GameEvents->GetFirstSubKey (); pEventAsKey; pEventAsKey = pEventAsKey->GetNextKey ())
{
// if we want a particular pattern AND this event does not match
if ((arg1[0] != 0) && (strstr (pEventAsKey->GetName (), arg1) == NULL))
continue; // then skip it
PrintEventStructure (pEventAsKey); // display this event's structure
event_count++;
}
ServerConsole_printf ("%d game event%s.\n", event_count, (event_count > 1 ? "s" : ""));
ServerConsole_printf ("Engine events:\n");
event_count = 0;
for (pEventAsKey = EngineEvents->GetFirstSubKey (); pEventAsKey; pEventAsKey = pEventAsKey->GetNextKey ())
{
// if we want a particular pattern AND this event does not match
if ((arg1[0] != 0) && (strstr (pEventAsKey->GetName (), arg1) == NULL))
continue; // then skip it
PrintEventStructure (pEventAsKey); // display this event's structure
event_count++;
}
ServerConsole_printf ("%d engine event%s.\n", event_count, (event_count > 1 ? "s" : ""));
ServerConsole_printf ("MOD events:\n");
event_count = 0;
for (pEventAsKey = ModEvents->GetFirstSubKey (); pEventAsKey; pEventAsKey = pEventAsKey->GetNextKey ())
{
// if we want a particular pattern AND this event does not match
if ((arg1[0] != 0) && (strstr (pEventAsKey->GetName (), arg1) == NULL))
continue; // then skip it
PrintEventStructure (pEventAsKey); // display this event's structure
event_count++;
}
ServerConsole_printf ("%d MOD event%s.\n", event_count, (event_count > 1 ? "s" : ""));
return;
}
void PrintEvent (IGameEvent *pEvent)
{
KeyValues *pEventAsKey;
KeyValues *pKey;
ServerConsole_printf ("Got event \"%s\"\n", pEvent->GetName ()); // event name
ServerConsole_printf ("{\n"); // print the open brace
// find the key/value corresponding to this event
pEventAsKey = NULL;
// look in the game events first...
if (pEventAsKey == NULL)
for (pEventAsKey = GameEvents->GetFirstSubKey (); pEventAsKey; pEventAsKey = pEventAsKey->GetNextKey ())
if (strcmp (pEventAsKey->GetName (), pEvent->GetName ()) == 0)
break;
// if not found, then look in the engine events...
if (pEventAsKey == NULL)
for (pEventAsKey = EngineEvents->GetFirstSubKey (); pEventAsKey; pEventAsKey = pEventAsKey->GetNextKey ())
if (strcmp (pEventAsKey->GetName (), pEvent->GetName ()) == 0)
break;
// and finally look for it in the mod events
if (pEventAsKey == NULL)
for (pEventAsKey = ModEvents->GetFirstSubKey (); pEventAsKey; pEventAsKey = pEventAsKey->GetNextKey ())
if (strcmp (pEventAsKey->GetName (), pEvent->GetName ()) == 0)
break;
// display the whole key/value tree for this event
for (pKey = pEventAsKey->GetFirstSubKey (); pKey; pKey = pKey->GetNextKey ())
{
// given the data type, print out the data
if (strcmp (pKey->GetString (), "none") == 0)
ServerConsole_printf (" \"%s\" = no value (TYPE_NONE)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "string") == 0)
ServerConsole_printf (" \"%s\" = \"%s\" (TYPE_STRING)\n", pKey->GetName (), pEvent->GetString (pKey->GetName ()));
else if (strcmp (pKey->GetString (), "bool") == 0)
ServerConsole_printf (" \"%s\" = %s (TYPE_BOOL)\n", pKey->GetName (), (pEvent->GetBool (pKey->GetName ()) ? "true" : "false"));
else if (strcmp (pKey->GetString (), "byte") == 0)
ServerConsole_printf (" \"%s\" = %d (TYPE_BYTE)\n", pKey->GetName (), pEvent->GetInt (pKey->GetName ()));
else if (strcmp (pKey->GetString (), "short") == 0)
ServerConsole_printf (" \"%s\" = %d (TYPE_SHORT)\n", pKey->GetName (), pEvent->GetInt (pKey->GetName ()));
else if (strcmp (pKey->GetString (), "long") == 0)
ServerConsole_printf (" \"%s\" = %d (TYPE_LONG)\n", pKey->GetName (), pEvent->GetInt (pKey->GetName ()));
else if (strcmp (pKey->GetString (), "float") == 0)
ServerConsole_printf (" \"%s\" = %f (TYPE_FLOAT)\n", pKey->GetName (), pEvent->GetFloat (pKey->GetName ()));
}
ServerConsole_printf ("}\n"); // print the closing brace
return;
}
void PrintEventStructure (KeyValues *pEventAsKey)
{
KeyValues *pKey;
ServerConsole_printf ("Event \"%s\"\n", pEventAsKey->GetName ()); // event name
ServerConsole_printf ("{\n"); // print the open brace
// display the whole key/value tree for this event
for (pKey = pEventAsKey->GetFirstSubKey (); pKey; pKey = pKey->GetNextKey ())
{
// given the data type, print out the data
if (strcmp (pKey->GetString (), "none") == 0)
ServerConsole_printf (" \"%s\", no value (TYPE_NONE)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "string") == 0)
ServerConsole_printf (" \"%s\" (TYPE_STRING)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "bool") == 0)
ServerConsole_printf (" \"%s\" (TYPE_BOOL)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "byte") == 0)
ServerConsole_printf (" \"%s\" (TYPE_BYTE)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "short") == 0)
ServerConsole_printf (" \"%s\" (TYPE_SHORT)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "long") == 0)
ServerConsole_printf (" \"%s\" (TYPE_LONG)\n", pKey->GetName ());
else if (strcmp (pKey->GetString (), "float") == 0)
ServerConsole_printf (" \"%s\" (TYPE_FLOAT)\n", pKey->GetName ());
}
ServerConsole_printf ("}\n"); // print the closing brace
return;
}
Here are code bits from PMTools2, you should have enough to do something usable with them