PLEASE NOTE: Windows servers treat playernames as case-insensitive (FunkySwerve is the same as funkyswerve). Linux servers treat them as case-sensitive. Because of this, I've added code to convert all playernames to lowercase. I'm putting the function calls in red (assuming the bioboard coloring systems don't revolt on me), because they're entirely optional and possibly even undesirable for Linux users.
=============================
Here's a system to link cd keys to playernames using the native bioware database.
When a character logs in, it will automatically check their cd key from oncliententer, and compare it to a Campaign variable stored in the database. If that variable is not set, this is the first time that playername has logged in (at least since this system was installed). The key will be linked to their account by setting that variable, and they can proceed with play as normal, unaware that anything has happened. If the variable is already set, however, and it does not match they key they are using, they are booted. This setup allows you to accumulate CD Key info as you go, and assumes that the first login of an account is ligit - an assumption that held true on our server. It's technically possible someone else could get to it first, but the chances are small, since most need to see the account name in use first in order to steal it (unless it's known already). Generally, I think this is far preferable to server passwording, as it's less of an impediment to players, an the chances of a ]addressed as soon as the legitimate logger posts on the forums of your server reporting the account lockout.
This system is a little more complex than that, though. It also allows addition of multiple keys, up to 7, for a playername - you'd be amazed at how many players use more than one. On our server, it's done via a conversation fired from a item they get when they enter the docks. The conditional checks to make sure they don't already have 7 keys added (this one returns FALSE if they do).
int StartingConditional()
{
object oPC = GetPCSpeaker();
string sPName = GetStringLowerCase(GetPCPlayerName(oPC));
string sStoredKey = GetCampaignString("PlayernameKey", sPName );
if (sStoredKey != "") {
int nLength = GetStringLength(sStoredKey);
if (nLength > 65) /* allow 7 keys max SET-key-key-key-key-key-key-key SET/ADD + 7 spacers + 7x8 keys = 66 */
return FALSE;
}
return TRUE;
}
If they do not have the maximum allowed already, their account is marked as ready to accept a new key, and they are asked to logout, swap to the new key, and log in again. This is the action taken script for that line:
void main()
{
object oPC = GetPCSpeaker();
string sPName = GetStringLowerCase(GetPCPlayerName(oPC));
string sStoredKey = GetCampaignString("PlayernameKey", sPName);
string sKeys = "ADD" + GetStringRight(sStoredKey, GetStringLength(sStoredKey) - 3);//mark as adding
SetCampaignString("PlayernameKey", sPName, sKeys);
}
Here is the oncliententer code I mentioned at the outset, which should make more sense now that you know the procedure for adding keys:
int VerifyPlayernameAgainstCDKey(object oPlayer) {
int nBoot = FALSE;
string sPName = GetStringLowerCase(GetPCPlayerName(oPlayer));
string sKey = GetPCPublicCDKey(oPlayer);
string sNewKey, sAddingKey, sStoredKey = GetCampaignString("PlayernameKey", sPName);
/* there's at least one key stored already */
if (sStoredKey != "") {
sAddingKey = GetStringLeft(sStoredKey, 3);
sStoredKey = GetStringRight(sStoredKey, GetStringLength(sStoredKey) - 3);
/* they indicated that they wanted to add a key this login */
if (sAddingKey == "ADD") {
/* their current key is not in the key string, add it unless at 7 keys already */
if (FindSubString(sStoredKey, sKey) == -1) {
int nKeyLength = GetStringLength(sStoredKey);
/* allow 7 keys max SET-key-key-key-key-key-key-key SET/ADD + 7 spacers + 7x8 keys = 66 */
if (nKeyLength > 65) {
nBoot = TRUE;
/* must mark as no longer adding */
SetCampaignString("PlayernameKey", sPName, "SET" + sStoredKey);
/* add the key to the string */
} else {
sNewKey = "SET" + sStoredKey + "-" + sKey;
SetCampaignString("PlayernameKey", sPName, sNewKey);
DelayCommand(25.0, FloatingTextStringOnCreature("New CD Key Successfully Added!", oPlayer, FALSE));
}
/* let them know they already had this key in their string */
} else {
DelayCommand(25.0,
FloatingTextStringOnCreature("CD Key Addition Failed! This key already listed for this account!", oPlayer,
FALSE));
/* must mark as no longer adding */
SetCampaignString("PlayernameKey", sPName, "SET" + sStoredKey);
}
/* they are not adding, and the cd key doesnt match those listed - boot and log */
} else if (FindSubString(sStoredKey, sKey) == -1) {
string sReport = "INCORRECT CD KEY DETECTED! ID: " + sPName + "; Name: " +
GetName(oPlayer) + "; CD Key: " + sKey + "; IP: " + GetPCIPAddress(oPlayer);
WriteTimestampedLogEntry(sReport);
SendMessageToAllDMs(sReport);
nBoot = TRUE;
}
/* new account, add the key */
} else {
SetCampaignString("PlayernameKey", sPName, "SET-" + sKey);
}
return nBoot;
}
void main() {
object oPC = GetEnteringObject();
/* verify CD keys and double logins to stop hackers */
if (VerifyPlayernameAgainstCDKey(oPC)) {
if (GetIsObjectValid(oPC))
BootPC(oPC);
return;
}
}
Here's an onplayerchat event script I wrote for DMs to use ingame to wipe cdkey-playername associations - inevitably, players lose their keys, and this allows you to reset the playername to accept a new key, by entering their playername after 'dm_wipekeys'. It is meant for native bioware database users - mysql and sqlite users should have command-line access that makes such a command unnecessary, but I can code one up if someone needs it.
Example command line spoken ingame:
dm_wipekeys Funky
would wipe the key listings for playername Funky ingame, allowing that player to log in using whatever cd key they have. This is important because players DO lose keys on occasion. It will also allow you to wipe a false association by an account thief, should one manage to log in before the true owner, as discussed above.
void main() {
string sMessage = GetPCChatMessage();
object oPC = GetPCChatSpeaker();
if (GetStringLeft(sMessage, 12) == "dm_wipekeys ") {
if (!GetIsDM(oPC))
FloatingTextStringOnCreature("Only DMs may use this command!", oPC, FALSE);
else {
string sPlayerName = GetStringRight(sMessage, GetStringLength(sMessage)-12);
sPlayerName = GetStringLowerCase(sPlayerName);
string sStoredKey = GetCampaignString("PlayernameKey", sPlayerName);
if (sStoredKey != "") {
DeleteCampaignVariable("PlayernameKey", sPlayerName);
FloatingTextStringOnCreature("CD Key bindings for Playername: '" + sPlayerName + "' erased.", oPC, FALSE);
} else {
FloatingTextStringOnCreature("No CD Key bindings for Playername: '" + sPlayerName +
"' were found! Please check to make sure you entered the right name.", oPC, FALSE);
}
}
}
}
Modifié par FunkySwerve, 14 décembre 2012 - 09:03 .





Retour en haut







