Most of the Bioware database functions like SetCampaignInt() allow an object oPlayer parameter to be passed. That's handy, as storing information specific to a player is otherwise difficult (a player name can be up to 255 characters long and the variable names for DB variables are limited to 32 characters).
But, the lexicon has the following warning
Not a bug, but a caveat: The database uses information about the player to store PC specific information. Thus, you can't use the PC as the oPlayer parameter in the database functions. This one is a little harder to work around. One thing you could perhaps do is ignore the oPlayer parameter, and then construct a variable name based on some of the info stored about the player OnClientEnter (see the workaround).
And here is the mentioned workaround
//Workaround for the caveat above
void main()
{
object oPC=GetEnteringObject();
string sPlayerName=GetPCPlayerName(oPC);
string sIP=GetPCIPAddress(oPC);
string sKey=GetPCPublicCDKey(oPC);
SetLocalString(oPC, "player_name", sPlayerName);
SetLocalString(oPC, "player_ip", sIP);
SetLocalString(oPC, "player_cdkey", sKey);
}
So, the player name and some other strings are saved on the PC object and would be available during the OnClientLeave event. But, of course, the player name is not the same as the player object and I don't know how to get the player object to use at that time. So, I am not sure how to pass the player object to functions during the OnClientExit event. And, in fact, I don't even really know how to get the actual player object (as opposed to the PC object) at any point; all I can get is the player name using GetPCPlayerName().
Now, the obvious thing I looked at was how does Bioware use the oPlayer parameter. But, despite the "Thus, you can't use the PC as the oPlayer parameter in the database functions." warning above, it seems they are happily just passing in the PC object for that. (For example, look at how SetCampaignDBInt() is implemented in x0_i0_campaign.) I assume that all the calls to those functions that specify oPlayer are actually just passing the PC object. Or, at least my quick search didn't find any calls that didn't do that. The actual player name is stored in the DB files, so the game is presumably grabbing the player info from the PC object if the DB write is made while the player is still logged.
So, what happens when this is tried during OnClientLeave? As best I can tell, no player information is stored, the same as if one had not supplied anything for that parameter.
Is there a nice way to save player-specific information to the Bioware DB during OnClientLeave? (Keeping in mind that the player name can be very long, so just adding it to the variable name is a non-starter.) Right now I am contemplating a hash to deal with this, but that is a mess and slows down an already slow operation.