This helper library provides synchronization and helper functions for interacting with players and their characters.
Features include:
- Keeping character locations persistent between server restarts.
- Keeping a unique fingerprint of every player to log into your server.
- Allowing logs of certain player or character actions.
- Set/unset persistent variable flags on characters.
- ... some other random functions thrown into the mix, outlined below.
- Ensuring that player accounts are protected now that the authentication servers are down.
This REQUIRES NWNX's SQL module. It was tested on MySQL, but might work on SQLite as well.
An example OnPCLoaded script can be found here: LINK.
= fb4a_lib_misc - Misc Library = This library holds functions that don't fit into any other areas.
HasFlag : Checks to see if a character has a flag. Flags are persistent and stored in the database.
HasFlags : Checks to see if a character has multiple flags. Otherwise same as above.
ResetFlags : Removes all flags from a character.
UnsetFlag : Removes a single flag from a character.
SetFlag : Adds a single flag to a character.
TeleportToWaypointByTag : Teleports the character to a waypoint, found by tag.
TeleportToLocation : Teleports a character to a waypoint, by location.
ColorText : Colors text surrounded by a particular flag. Handy for coloring emotes pink.
= fb4a_lib_player - Player Library = LogEventByPlayerName : Inputs a log event by a player name.
LogEventByPlayer : Redirects to LogEventByPlayerName.
RegisterPlayer : Registers a unique ip address, cd key, and gamespy account name to the 'accounts' table. Stores the first and latest. Can be used to locate player alternative accounts, to ensure banned players stay banned.
CDKeyLock : Boots a player if they are not logging in from the same CD keys as they usually are, and logs the discrepancy.
= fb4a_lib_character - Character Library = GetFormattedName : Returns a string in the format "Firstname Lastname (( Playername ))".
LogEventByCharacter : As with LogEventByPlayerName, but for characters. Used to log character activity (house selling, specific item usage, etc.) activities, as opposed to player-specific activities.
SaveToServervault : Synchronizes player with the servervault.
SaveToDatabase : Synchronizes the player with the database.
SyncCharacter: Synchronizes the player with both the servervault and database.
SaveCharacterHeartbeat : Timed event to synch character every X seconds. Amount of time between saves is configurable as a global constant variable.
ReturnToDatabasePosition : Reads the area, position, and rotation of the character from their last SaveToDatabase call, and returns them there.
RegisterCharacter : Must be called OnPCLoaded, before any save/return calls, to ensure the character is registered in the database. Also sets their unique character ID as a local variable, for other call checks.
GetRootCharacter : Gets the actual player character, as opposed to a companion or familiar.
GetID : Gets the unique ID (created on RegisterCharacter) of the player.
GetCharacterByID : Gets a character by their unique character ID, or OBJECT_INVALID if they are not logged in.
IsValidCharacter : Returns TRUE if a character is a player character, not a DM, and has a valid unique character ID.
== Change Log ==
2011-05-29 : v1.0 : Initial release.
2011-05-31 : v1.1 : Fixed a bug where flags were not loaded correctly.
2011-05-31 : v1.2 : Fixed an SQL syntax error and updated documentation.
2011-10-09 : v1.3 : Added CD key checking for player authentication.
== Need Help? ==
Feel free to send me an email or instant message. I would be happy to help you integrate one or any of my works into your PW.
SQL file. Execute it onto your database to create the necessary tables. Tables are `accounts`, `characters`, `log_events_player` and `log_events_character`.
5 sec is plenty of time for someone logging into someone's account to do some damage. I did consider this, but as I was writing this to respond to hacking, I opted not to. Do wish there was more of a channel to send messages on a BOOT().
- Bar
Posted by Artevere at 2011-10-15 22:00:53 Voted 10.00 on 10/15/11
Nice. Giving you a rating, since everyone (including other devs) love to leach without bothering to rate.
Also find it hilarious that we have spam bots on nwvault.
Anyway, SQLite should theoretically work fine (if not better for smaller instances).
As a suggestion to Bar: throw up a window with a 5 (or so) second timeout so the player can read that. In the chance that someone is wrongfully booted, it can help track down the problem.
Wrote a quick piece of code to create a cdkeylock based on this system.
Will boot anyone trying to enter on an unknown cd-key for that player. (New players get in and are cdlocked on your register.)
To be placed near the beginning of onPCLoaded handler
Some management issues with dealing with legitimate new keys, reinstalls and new laptops, etc. Best advice I have now is to either allow administrative disabling of this code, or be prepared to make manual entries to the SQL DB.
Thanks to the base code, does support multiple cdkeys per name.
Base code was first written for NWNHaven.com which does not use Foam's scripts but instead older similar work, and this was adapted and is in use on Rigilia.com, which does.
[code]
/**
* Code to lock existing names to known existing cd-keys, matched to the names.
*/
void CDKeyLock(object oPC)
{
string q = "SELECT DISTINCT player FROM accounts where player='" +SQLEncodeSpecialChars(GetPCPlayerName(oPC))+"'";
SQLExecDirect(q); SQLFetch();
int bNewPlayerName = (SQLGetData(1) == ""); // Case new playername
if ( ! bNewPlayerName ) {
q = "SELECT DISTINCT cdkey FROM accounts where cdkey='"+GetPCPublicCDKey(oPC)+"'AND player='" +SQLEncodeSpecialChars(GetPCPlayerName(oPC))+"'";
SQLExecDirect(q); SQLFetch();
//WriteTimestampedLogEntry("onpcloaded:CDKeyLock: CDKey checked: " + GetPCPublicCDKey(oPC) );
string sCDKey = SQLGetData(1);
//WriteTimestampedLogEntry("onpcloaded:CDKeyLock: CDKey found: " + sCDKey );
if (sCDKey == "") { // Case new cdkey for old name.
WriteTimestampedLogEntry("onpcloaded:CDKeyLock: Player booted due to unrecognized cdkey: " + GetPCPlayerName(oPC) +"/" + GetPCPublicCDKey(oPC) + ":" + GetPCIPAddress(oPC));
SendMessageToPC(oPC,"Unrecognized CD-Key for old playername, please contact administrators");
// Yes we are about to boot them and they won't get a chance to read the above message
// ... unless they are running Skywing's client extension.
BootPC(oPC); return;
}
} else { // case new player name
WriteTimestampedLogEntry("onpcloaded:CDKeyLock: New Playername: " + GetPCPlayerName(oPC));
}
}
[/code]
Posted by nicethugbert at 2011-06-01 19:56:03 Voted 10.00 on 06/01/11
10 - A Masterpiece, Genuinely Groundbreaking 9 - Outstanding, a Must Have 8 - Excellent, Recommended to Anyone 7 - Very Good, Deserves a Look 6 - Good, Qualified Recommendation 5 - Fair, Solid yet Unremarkable 4 - Some Merit, Requires Improvements 3 - Poor Execution, Potential Unrealized 2 - Very Little Appeal 1 - Not Recommended to Anyone