Accessing Private Data
I was talking to the crew on IRC the other day about my feature request, and they recommended I use an extension if I wanted this feature right away. I'm still new to this so hopefully I'm asking the right questions.
In my extension I have included IPlayerHelpers.h via Code:
/* smsdk_config.h */ Code:
/* PlayerManager.h */ Code:
/* PlayerManager.cpp */ Code:
static cell_t SetClientLanguage(IPluginContext *pContext, const cell_t *params) |
Re: Accessing Private Data
Uhhh, this is not a good situation :)
This is how it's supposed to work in C++ : the interface IGamePlayer would provide a public function SetLanguageId( id ). You would do Code:
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer( params[1] ); Other than that, if you really want to set the field anyway, you can hack. From here, you're using implementation details of sourcemod, which are not part of the "contract", ie. interface. This code can be broken on updates. First of all, you'd have to use your knowledge that what playerhelpers->GetGamePlayer( ... ) returns is actually a CPlayer instance. Code:
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer( params[1] ); You're not friend, so you have three possibilities: 1) Copy the CPlayer class declaration into your source file (and don't #include the .h file where CPlayer is declared) and change the private section containing m_LangId to public. OR 2) Copy the CPlayer class declaration into your source file and declare your class friend. OR 3) Copy the CPlayer class declaration into your source file and add a setter method OR 4) Don't use the CPlayer declaration at all and access the field by a pointer offset. I'd go with 3) which would result in the following code: Code:
// Warning: This code may break on sourcemod updates |
Re: Accessing Private Data
Compiles and works! :D
Before posting here I was checking out some snippets and I attempted to do what you had explained, but I was using structs. It compiled but it didn't look right at all, and it completely crashed the server. Thanks for taking the time to explain it. Quote:
|
Re: Accessing Private Data
Basically, the code will break when the position of the m_LangId field relative to the beginning of the CPlayer object in memory changes.
This could happen if someone changes the class or if it is compiled with other alignment options. Another situation that may happen would be a change in PlayerManager, so that it would not be returning CPlayer for some cases, but an instance of another class, for example a new class CBotPlayer, which would also inherit from IPlayerManager. I guess that none of this is likely to happen, but it could ;) Greetings, PM Edit: Just for completeness, a reason why the code using a self-defined struct could have failed: If a class itself or a class it inhertis from contains virtual functions, the first 4 (x86) or 8 (x64) bytes of the object's data will be a pointer to the 'virtual function table'. This is automatically added by the compiler and is used to resolve virtual function calls (ie. to make sure that if you call GetLanguageId on a IGamePlayer * variable, it will actually call CPlayer::GetLanguageId if the real object is a CPlayer). If you re-create the class yourself and don't have any virtual functions (here they come from inheriting from IGamePlayer), the member variable positions won't match the member variable positions in the real class with a virtual function table pointer, and you'll be overwriting something else. |
Re: Accessing Private Data
GoD-Tony: Whoa! If you're going this far to work around it, you might as well just submit a patch to Core. I can do a fast review & checkin. Something this hacky is bound to break and I don't think it's a good idea to distribute an extension like that.
You've got the native, so all you need is to put it in the right place (smn_lang.cpp). If you need help, let me know - I see messages on IRC or in the bug report faster than forums. |
Re: Accessing Private Data
Haha, yes I pretty much got the same response on IRC once they looked at the source of the extension :). I was told that if I submit a patch then this native could very well make it into 1.3.x.
I'll go that route since this native is already proving useful on my servers. |
All times are GMT -4. The time now is 15:48. |
Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.