diff options
Diffstat (limited to 'npc/functions/player-cache.txt')
-rw-r--r-- | npc/functions/player-cache.txt | 501 |
1 files changed, 0 insertions, 501 deletions
diff --git a/npc/functions/player-cache.txt b/npc/functions/player-cache.txt deleted file mode 100644 index f134f953..00000000 --- a/npc/functions/player-cache.txt +++ /dev/null @@ -1,501 +0,0 @@ -// Player cache system -// -// Holds a cache of online players in-memory even after logout. This greatly -// reduces the need to query the SQL database for data that is frequently -// accessed. -// -// NOTE: This NPC uses the new public/private function call system to avoid -// polluting the global function namespace -// -// Example usage: -// .@account_id = "playerCache"::name2account("Reid"); -// - -- script playerCache FAKE_NPC,{ - /** - * "playerCache"::name2account("char name") => account id - * - * Searches through the player cache to convert a char name to a account ID. - * If the player is not found, checks the SQL table. If the player doesn't - * exist, returns false. - * - * @param 0 - the char name to search - * @return the account id of the char - */ - public function name2account { - if (getarg(0) == "") { - return false; - } - - if (.@acc = getcharid(CHAR_ID_ACCOUNT, getarg(0))) { - // player is currently online - return .@acc; - } - - if (.@acc = htget(.name_to_account, getarg(0), 0)) { - // player found in the hash table - return .@acc; - } - - // player still not found: now we try SQL - .@name$ = escape_sql(getarg(0)); - - if (SERVER_USES_VAULT) { - query_sql(sprintf("SELECT c.account_id, c.char_id, r.value " - "FROM `char` c " - "JOIN `global_acc_reg_num_db` r ON r.account_id = c.account_id " - "WHERE r.key = '##VAULT' AND r.index = 0 AND c.name = '%s' " - "LIMIT 1;", .@name$), - .@acc, .@char, .@vault); - - if (.@vault > 0) { - .vault_to_account[.@vault] = .@acc; - .account_to_vault[.@acc] = .@vault; - } - } else { - query_sql(sprintf("SELECT account_id, char_id FROM `char` WHERE `name`='%s' LIMIT 1;", .@name$), .@acc, .@char); - } - - if (.@acc > 0) { - // player found: add to our cache - htput(.name_to_account, getarg(0), .@acc); - .account_to_name$[.@acc] = getarg(0); - htput(.name_to_char, getarg(0), .@char); - .char_to_name$[.@char] = getarg(0); - - return .@acc; - } - - // player doesn't exist - return false; - } - - /** - * "playerCache"::name2char("char name") => char id - * - * Searches through the player cache to convert a char name to a char ID. - * If the player is not found, checks the SQL table. If the player doesn't - * exist, returns false. - * - * @param 0 - the char name to search - * @return the char id of the char - */ - public function name2char { - if ((.@acc = name2account(getarg(0))) != 0) { - return htget(.name_to_char, getarg(0), false); - } - - return false; - } - - /** - * "playerCache"::char2account(char id) => account id - * - * Searches through the player cache to convert a char ID to an account ID. - * If the player is not found, checks the SQL table. If the player doesn't - * exist, returns false. - * - * @param 0 - the char ID to search - * @return the account id of the char - */ - public function char2account { - if (getarg(0) == 0) { - return false; - } - - .@name$ = .char_to_name$[getarg(0)]; - - if (.@name$ != "") { - if (.@acc = getcharid(CHAR_ID_ACCOUNT, .@name$)) { - // player is currently online - return .@acc; - } - - if (.@acc = htget(.name_to_account, .@name$, 0)) { - // player found in the hash table - return .@acc; - } - } - - // player still not found: now we try SQL - if (SERVER_USES_VAULT) { - query_sql(sprintf("SELECT c.account_id, c.name, r.value " - "FROM `char` c " - "JOIN `global_acc_reg_num_db` r ON r.account_id = c.account_id " - "WHERE r.key = '##VAULT' AND r.index = 0 AND c.char_id = '%d' " - "LIMIT 1;", getarg(0)), - .@acc, .@name$, .@vault); - - if (.@vault > 0) { - .vault_to_account[.@vault] = .@acc; - .account_to_vault[.@acc] = .@vault; - } - } else { - query_sql(sprintf("SELECT account_id, name FROM `char` WHERE `char_id`='%d' LIMIT 1;", getarg(0)), .@acc, .@name$); - } - - if (.@acc > 0) { - // player found: add to our cache - htput(.name_to_account, .@name$, .@acc); - .account_to_name$[.@acc] = .@name$; - htput(.name_to_char, .@name$, getarg(0)); - .char_to_name$[getarg(0)] = .@name$; - - return .@acc; - } - - // player doesn't exist - return false; - } - - /** - * "playerCache"::account2char(account id) => char id - * - * Searches through the player cache to convert an account ID into a - * char ID. If the player is not found, returns false. - * - * NOTE: this is a weak reference; an account ID does not uniquely identify - * a character - * - * @param 0 - the account ID to search for - * @return the char ID of the char - */ - public function account2char { - if (getarg(0) == 0) { - return false; - } - - if ((.@name$ = strcharinfo(PC_NAME, "", getarg(0))) != "") { - // player is online - return getcharid(CHAR_ID_CHAR, .@name$); - } else if ((.@name$ = .account_to_name$[getarg(0)]) != "") { - // found in our cache - return htget(.name_to_char, .@name$, false); - } - - // player still not found: now we try SQL - if (SERVER_USES_VAULT) { - query_sql(sprintf("SELECT c.char_id, c.name, r.value " - "FROM `char` c " - "JOIN `global_acc_reg_num_db` r ON r.account_id = c.account_id " - "WHERE r.key = '##VAULT' AND r.index = 0 AND c.account_id = '%d' " - "ORDER BY c.last_login DESC LIMIT 1;", getarg(0)), - .@char, .@name$, .@vault); - - if (.@vault > 0) { - .vault_to_account[.@vault] = getarg(0); - .account_to_vault[getarg(0)] = .@vault; - } - } else { - query_sql(sprintf("SELECT char_id, name FROM `char` WHERE account_id='%d' ORDER BY last_login DESC LIMIT 1;", getarg(0)), .@char, .@name$); - } - - if (.@char > 0) { - // player found: add to our cache - htput(.name_to_account, .@name$, getarg(0)); - .account_to_name$[getarg(0)] = .@name$; - htput(.name_to_char, .@name$, .@char); - .char_to_name$[.@char] = .@name$; - - return .@char; - } - - // not found - return false; - } - - /** - * "playerCache"::account2name(account id) => char name - * - * Searches through the player cache to convert an account ID into a - * char name. If the account is not found, returns an empty string. - * - * NOTE: this is a weak reference; an account ID does not uniquely identify - * a character - * - * @param 0 - the account ID to search for - * @return the name of the char - */ - public function account2name { - if ((.@char = account2char(getarg(0))) != false) { - return .char_to_name$[.@char]; - } - - return ""; - } - - /** - * "playerCache"::char2name(char id) => char name - * - * Searches through the player cache to convert a char ID to a char name. - * If the player is not found, checks the SQL table. If the player doesn't - * exist, returns an empty string. - * - * @param 0 - the char ID to search - * @return the name of the char - */ - public function char2name { - if ((.@acc = char2account(getarg(0))) != 0) { - return .account_to_name$[.@acc]; - } - - // player not found - return ""; - } - - /** - * "playerCache"::vault2account(vault id) => account id - * - * Searches through the player cache to convert a Vault account ID into a - * game account ID. If the account is not found, returns false - * - * NOTE: this is a weak reference; a Vault ID does not uniquely identify - * a game account - * - * @param 0 - the Vault ID to search for - * @return the account id of the char - */ - public function vault2account { - if (getarg(0) == 0) { - return false; - } - - if (!SERVER_USES_VAULT) { - return getarg(0); - } else if (.@acc = .vault_to_account[getarg(0)]) { - // found in the cache - return .@acc; - } - - // player still not found: now we try SQL - query_sql(sprintf("SELECT c.account_id, c.char_id, c.name " - "FROM `char` c " - "JOIN `global_acc_reg_num_db` r ON r.account_id = c.account_id " - "WHERE r.key = '##VAULT' AND r.index = 0 AND r.value = %d " - "ORDER BY c.`last_login` DESC LIMIT 1;", getarg(0)), - .@acc, .@char, .@name$); - - if (.@char > 0) { - // player found: add to our cache - htput(.name_to_account, .@name$, .@acc); - .account_to_name$[.@acc] = .@name$; - htput(.name_to_char, .@name$, .@char); - .char_to_name$[.@char] = .@name$; - .vault_to_account[getarg(0)] = .@acc; - .account_to_vault[.@acc] = getarg(0); - - return .@acc; - } - - return false; - } - - /** - * "playerCache"::vault2char(vault id) => char id - * - * Searches through the player cache to convert a Vault account ID into a - * char id. If the player is not found, returns false - * - * NOTE: this is a weak reference; a Vault ID does not uniquely identify - * a character - * - * @param 0 - the Vault ID to search for - * @return the char id - */ - public function vault2char { - if ((.@acc = vault2account(getarg(0))) != 0) { - return account2char(.@acc); - } - - // player not found - return false; - } - - /** - * "playerCache"::vault2name(vault id) => account id - * - * Searches through the player cache to convert a Vault account ID into a - * char name. If the player is not found, returns an empty string - * - * NOTE: this is a weak reference; a Vault ID does not uniquely identify - * a character - * - * @param 0 - the Vault ID to search for - * @return the name of the char - */ - public function vault2name { - if ((.@acc = vault2account(getarg(0))) != 0) { - return account2name(.@acc); - } - - // player not found - return ""; - } - - /** - * "playerCache"::account2vault(account id) => vault id - * - * Searches through the player cache to convert a game account ID into a - * Vault account ID. If the account is not found, returns false - * - * @param 0 - the account ID to search for - * @return the Vault ID associated with the account - */ - public function account2vault { - if (!SERVER_USES_VAULT) { - return getarg(0); - } - - account2char(getarg(0)); // will fetch vault id - return .account_to_vault[getarg(0)]; - } - - /** - * "playerCache"::name2vault(char name) => vault id - * - * Searches through the player cache to convert a character name into a - * Vault account ID. If the account is not found, returns false - * - * @param 0 - the char name to search for - * @return the Vault ID associated with the account - */ - public function name2vault { - return account2vault(name2account(getarg(0))); - } - - /** - * "playerCache"::char2vault(char id) => vault id - * - * Searches through the player cache to convert a char id into a - * Vault account ID. If the account is not found, returns false - * - * @param 0 - the char id to search for - * @return the Vault ID associated with the account - */ - public function char2vault { - return account2vault(char2account(getarg(0))); - } - - /** - * Registers a public local function that will be called when the char name - * associated with an account changes. The previous account ID will be - * passed as first argument to the provided function. - * - * @param 0 - the public local function - */ - public function addNameHandler { - return addEventListener(.name_handlers, getarg(0)); - } - - /** - * Registers a public local function that will be called when the account - * associated with a Vault account changes. The previous account id will be - * passed as first argument to the provided function and the previous - * char name will be passed as second argument. - * - * @param 0 - the public local function - */ - public function addVaultHandler { - return addEventListener(.vault_handlers, getarg(0)); - } - - - -//////////////////////////////////////////////////////////////////////////////// - - /** - * updates the char name cache and fires event handlers when the name - * associated with an account changes (such as when switching char) - */ - private function updateName { - // get the cached name: - .@old$ = .account_to_name$[playerattached()]; - - // now update the cache: - htput(.name_to_account, strcharinfo(PC_NAME), playerattached()); - .account_to_name$[playerattached()] = strcharinfo(PC_NAME); - htput(.name_to_char, strcharinfo(PC_NAME), getcharid(CHAR_ID_CHAR)); - .char_to_name$[getcharid(CHAR_ID_CHAR)] = strcharinfo(PC_NAME); - - if (.@old$ != "" && .@old$ != .account_to_name$[playerattached()]) { - // fire event handlers - dispatchEvent(.name_handlers, .@old$); - return true; - } - - return false; - } - - /** - * updates the Vault account cache and fires event handlers when the account - * associated with a Vault account changes (different game account on same - * Vault account) - */ - private function updateVault { - // get the cached id: - .@old = .vault_to_account[getvaultid()]; - .@old$ = .account_to_name$[.@old]; - - // now update the cache: - .vault_to_account[getvaultid()] = playerattached(); - .account_to_vault[playerattached()] = getvaultid(); - - if (.@old > 0 && .@old != .vault_to_account[getvaultid()]) { - // fire event handlers - dispatchEvent(.vault_handlers, .@old, .@old$); - return true; - } - - return false; - } - - /** - * adds/updates the player to the player cache - */ - private function updateCache { - updateName(); - - if (SERVER_USES_VAULT) { - updateVault(); - } - - return; - } - - /** - * force-add all online players to the cache (used on init and reload) - */ - private function forceCache { - .@count = getunits(BL_PC, .@units, false); - - for (.@i = 0; .@i < .@count; ++.@i) { - attachrid(.@units[.@i]); - updateCache(); - detachrid(); - } - - return; - } - -OnPCLoginEvent: - updateCache(); - end; - -OnInit: - .name_to_account = htnew(); // Map<char name, account id> - .account_to_name$[0] = ""; // sparse Array<char name> indexed by account id - .name_to_char = htnew(); // Map<char name, char id> - .char_to_name$[0] = ""; // sparse Array<char name> indexed by char id - - if (SERVER_USES_VAULT) { - .vault_to_account[0] = 0; // sparse Array<vault id> indexed by account id - .account_to_vault[0] = 0; // sparse Array<account id> indexed by vault id - } - - // event handlers: - .vault_handlers = htnew(); - .name_handlers = htnew(); - - // reloadscript handler: - forceCache(); -} |