View Single Post
Re: the new event interface...
Old
  (#3)
Pierre-Marie Baty
Roi de France
 
Pierre-Marie Baty's Avatar
 
Status: Offline
Posts: 5,049
Join Date: Nov 2003
Location: 46°43'60N 0°43'0W 0.187A
Default Re: the new event interface... - 22-02-2005

thank you botman

*edit* WHOA!
  1. get 3 files from the Steam cache
  2. parse them and build ourselves an array of the event list
  3. register ourselves as listener successively for every single event
  4. for every single event received, match it against our array and use this info to request each of its subkeys
  5. display!
quite an overhead o_O

We've also had a conversation with Alfred regarding the Source interface. For me I see a major flaw in their current design. They use version numbers as if the interface providers were capable of backwards compatibility whereas it's not, which means that
  1. I can't use the same plugin DLL on different Source games
  2. I need to maintain one version of the SDK for each of these games
  3. Anytime Valve changes one single interface, all hell breaks loose.
Quote:
Originally Posted by PMB
Hello,

Not sure where I should have sent this, so please forward to whom may be concerned with my apologies if it's not to you.

I am developing Source server plugins and I found a bug in the engine's interfaceFactory related to the new game event manager interface.

In my plugins I am using an interface loader macro, that tries to find the right version number automatically for each interface I load. This enables me to run the same plugin DLL on different games (such as CS:Source and HL2DM). This macro first assumes a high interface version and builds the corresponding version string, and downgrades successively until it finds the right version and the interface can be attached.

This used to work fine for all the interfaces, but since the latest source SDK update relative to HL2DM, it happens that if you don't ask interfaceFactory() the right version number for the IGameEventManager interface, instead of just refusing to attach the interface it makes HL2DM crash. This is annoying because I can't use my macro anymore.

I believe it should be fairly simple to fix it for the next HL2DM engine update.

Thanks in advance for your time.
Quote:
Originally Posted by Alfred
Can you be more precise about the problem. Does it crash if you load the new interface? Or only the old interface (with HL2MP loading the new one)?
Quote:
Originally Posted by PMB
I can load the old interface *only* if I ask the correct version number, but not with my macro that tries to guess the version numbers. Instead of returning a NULL pointer when the version number I ask isn't the right one (which is what it does for all the other interfaces BUT this one), interfaceFactory() makes the game crash. To me, it's most likely because the old IGameEventManager and the new IGameEventManager2 are completely different classes but with similar version strings. Perhaps it would have been wiser to make IGameEventManager2 a separate interface, using a different version string (such as "GAMEEVENTSMANAGER2_001" for example).

I needed the old interface because until another solution is found, I want to be able to hook any event without needing to register it explicitly, and be able to iterate through all its key/values in order to display them, even if I don't know their name.

Perhaps it would be wise to update the sample server plugin project of the SDK to show how to use the new event manager interface.

Thanks for your time, anyway.
Quote:
Originally Posted by Alfred
The version string doesn't effect anything. Are you querying for the old interface but using the new IGameEventManager2 class defn against it? (or vice-versa, old IGameEventManager with new interface) Because that would never work (and is just plain bad code). Could you send me a snippet of (un macro'd) code that causes the crash so I can better understand what you are doing
Quote:
Originally Posted by PMB
I beg to differ: that's precisely the problem. My macro takes out the 3 last digits of the version string and appends arbitrary ones, forming a number which goes decreasing until the interface can be loaded. And since the IGameEventManager and IGameEventManager2 classes have similar version strings, I can't use this method anymore, and thus my plugins cannot be used on different game/mods.

This is what the macro does (simplified), which makes the game crash (you'll see why at first sight I suppose):
Code:
char ifv_string[64]; // version string, last 3 digits stripped
int ifv_number; // version number to append to the above
char interface_version[64]; // resulting string
 
// copy the version string in a new string, strip out the last 3 digits
strcpy (ifv_string, INTERFACEVERSION_GAMEEVENTSMANAGER);
ifv_string[strlen (INTERFACEVERSION_GAMEEVENTSMANAGER) - 3] = 0;
 
// build a new version string
// downgrade from 100 to 1 until the interface can be loaded
for (ifv_number = 100; ifv_number > 0; ifv_number--)
{
sprintf (interface_version, "%s%03d", ifv_string, ifv_number);
if (gameevents = (IGameEventManager *) interfaceFactory (interface_version, NULL))
	 break; // stop trying as soon as the interface is found
}
...and this causes the crash, because interfaceFactory returns a pointer to a IGameEventManager2 when ifv_number reaches 2, because interface_version is then "GAMEEVENTSMANAGER002". Like I said, the problem comes from the use of similar version strings for returning different interface classes. It makes further guessing of the interface version, and hence cross-game reusability, impossible

I hope this can be sorted out in some way
Quote:
Originally Posted by Alfred
Your method of walking interfaces is flawed, there is not guarantee (or even expectation) that two versions of an interface will have a compatible vtable representation (hence the use of versions). You should only use versions your plugin knows about (hard coded versions), with special cases for supporting older interfaces.
Quote:
Originally Posted by PMB
Well thanks. I was expecting you would be doing like with HL1, and only add new class members at the end of the vtable to ensure backwards compatibility to a certain extent, but if that's not the case, guessing the interface number is indeed pointless.

Now I will need to maintain one version of the SDK for each Steam game I intend to use my plugins with. Needless to say I preferred the HL1 method.

I don't get it. Even the use of version strings is pointless, since when a plugin *requires* an interface and that interface cannot be loaded, returning false in CPlugin::Load() only makes the server crash. I don't understand you people at Valve. What's the point of using version numbers if there's no backwards compatibility ? :-/
I hope I can get an answer, but still, the way they designed their interfaces is incomprehensible to me



RACC home - Bots-United: beer, babies & bots (especially the latter)
"Learn to think by yourself, else others will do it for you."

Last edited by Pierre-Marie Baty; 22-02-2005 at 16:07..
  
Reply With Quote