/* * proxy.cpp * Source file for proxy access * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Permission to use, modify and distribute is granted via the * Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License * http://creativecommons.org/licenses/by-nc-sa/3.0/ * * Copyright (C) 2007-2012 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ #include "mud.h" #include <sstream> #include <iomanip> #include <locale> #include <iostream> #include <fstream> #include "boost/format.hpp" //********************************************************************* // CmdProxy //********************************************************************* // Allows a player to view, grant, or revoke proxy access // to their character int cmdProxy(Player* player, cmd* cmnd) { if(cmnd->num == 1) { bstring proxyList = gConfig->getProxyList(player); if(proxyList.empty()) *player << "No proxy access currently allowed.\n"; else *player << proxyList; return(0); } if(player->getProxyName() != "") { *player << "You cannot change the proxy access of a proxied character.\n"; return(0); } if(player->isStaff()) { *player << "You cannot allow proxy access to a staff character!\n"; return(0); } bool online=true; Player* target=0; bstring name = cmnd->str[1]; if(name.length() > 1 && name.getAt(0) == 'p' && isdigit(name.getAt(1))) { target = gServer->lookupPlyId(name); } if(!target && name.length() > 1 && name.getAt(0) == 'p' && isdigit(name.getAt(1))) { // Dealing with an ID name.setAt(0, up(name.getAt(0))); // TODO: Print success/failure if(gConfig->removeProxyAccess(name, player) ) *player << "Proxy access removed for PlayerID: " << name << "\n"; else *player << "PlayerID: " << name << " does not have proxy access to your character.\n"; return(0); } else { // We're dealing with a player if(!target) { name = name.toLower(); name.setAt(0, up(name.getAt(0))); target = gServer->findPlayer(name); } if(!target) { if(!loadPlayer(name.c_str(), &target)) { *player << "Player does not exist.\n"; return(0); } online = false; } if(target->isStaff()) { if(!online) free_crt(target); *player << "You cannot give staff proxy access!.\n"; return(0); } if(target->getId() == player->getId()) { *player << "That's just silly.\n"; if(!online) free_crt(target); return(0); } if(gConfig->hasProxyAccess(target, player)) { *player << "You remove " << target->getName() << "'s proxy access to your character.\n"; gConfig->removeProxyAccess(target, player); if(online) *target << "Your proxy access to " << player->getName() << " has been revoked.\n"; else free_crt(target); } else { *player << "You grant " << target->getName() << " proxy access to your character.\n"; gConfig->grantProxyAccess(target, player); if(online) *target << "Your now have been granted proxy access to " << player->getName() << ".\n"; else free_crt(target); } } return(0); } //********************************************************************* // Config proxy functions //********************************************************************* //********************************************************************* // HasProxyAccess //********************************************************************* // Does (proxy) have access to (proxied) bool Config::hasProxyAccess(Player* proxy, Player* proxied) { return(proxyManager->hasProxyAccess(proxy, proxied)); } //********************************************************************* // getProxyList //********************************************************************* // Returns a bstring showing proxy access for the given player // or all players if player is NULL bstring Config::getProxyList(Player* player) { std::ostringstream oStr; bstring lastId = ""; oStr.setf(std::ios::left, std::ios::adjustfield); boost::format format("%1% %|15t|%2% %|45t|%3%\n"); oStr << format % "" % "Character Name" % "Proxy Access"; for(ProxyMultiMap::value_type p : proxyManager->proxies) { ProxyAccess &proxy = p.second; if(player && proxy.getProxiedId() != player->getId()) continue; format.exceptions( boost::io::all_error_bits ^ ( boost::io::too_many_args_bit | boost::io::too_few_args_bit ) ); if(proxy.getProxiedId() != lastId) { lastId = proxy.getProxiedId(); oStr << format % "Character: " % (proxy.getProxiedName() + "(" + proxy.getProxiedId() + ")") % (bstring("- ") + proxy.getProxyName() + "(" + proxy.getProxyId() + ")"); } else { oStr << format % "" % "" % (bstring("- ") + proxy.getProxyName() + "(" + proxy.getProxyId() + ")"); } } return(oStr.str()); } //********************************************************************* // GrantProxyAccess //********************************************************************* // Grant proxy access to (proxied) for (proxy) void Config::grantProxyAccess(Player* proxy, Player* proxied) { proxyManager->grantProxyAccess(proxy, proxied); } //********************************************************************* // RemoveProxyAccess //********************************************************************* // Remove proxy access to (proxied) for (proxy) bool Config::removeProxyAccess(Player* proxy, Player* proxied) { return(proxyManager->removeProxyAccess(proxy, proxied)); } //********************************************************************* // RemoveProxyAccess //********************************************************************* // Remove proxy access to (proxied) for (id) bool Config::removeProxyAccess(bstring id, Player* proxied) { return(proxyManager->removeProxyAccess(id, proxied)); } //********************************************************************* // LoadProxyAccess //********************************************************************* // Reset the proxy manager if necessary and load in proxy access void Config::loadProxyAccess() { if(proxyManager) proxyManager->clear(); proxyManager = new ProxyManager; } //********************************************************************* // SaveProxyAccess //********************************************************************* // Save proxy access list void Config::saveProxyAccess() { proxyManager->save(); } //********************************************************************* // Player proxy functions //********************************************************************* //********************************************************************* // SetProxy //********************************************************************* // Set's player as the current proxy user void Player::setProxy(Player* proxy) { proxyName = proxy->getName(); proxyId = proxy->getId(); } //********************************************************************* // SetProxy //********************************************************************* // Set's proxyName & proxyId as the current proxy user & ID void Player::setProxy(bstring pProxyName, bstring pProxyId) { proxyName = pProxyName; proxyId = pProxyId; } //********************************************************************* // SetProxyName //********************************************************************* // Set's proxyName as the current proxy user void Player::setProxyName(bstring pProxyName) { proxyName = pProxyName; } //********************************************************************* // SetProxyID //********************************************************************* // Set's proxyId as the current proxy ID void Player::setProxyId(bstring pProxyId) { proxyId = pProxyId; } bstring Player::getProxyName() const { return(proxyName); } bstring Player::getProxyId() const { return(proxyId); } //********************************************************************* // ProxyManager proxy functions //********************************************************************* ProxyManager::ProxyManager() { loadProxies(); } void ProxyManager::clear() { proxies.clear(); delete this; } //********************************************************************* // grantProxyAccess //********************************************************************* // Grant proxy access to (proxied) for (proxy) void ProxyManager::grantProxyAccess(Player* proxy, Player* proxied) { if(hasProxyAccess(proxy, proxied)) return; proxies.insert(ProxyMultiMap::value_type(proxied->getId(), ProxyAccess(proxy, proxied))); gConfig->saveProxyAccess(); } //********************************************************************* // removeProxyAccess //********************************************************************* // Remove proxy access to (proxied) for (proxy) bool ProxyManager::removeProxyAccess(Player* proxy, Player* proxied) { return(removeProxyAccess(proxy->getId(), proxied)); } //********************************************************************* // removeProxyAccess //********************************************************************* // Remove proxy access to (proxied) for (proxy) bool ProxyManager::removeProxyAccess(bstring id, Player* proxied) { ProxyMultiMapRange range = proxies.equal_range(proxied->getId()); for(ProxyMultiMap::iterator it = range.first ; it != range.second ; it++) { ProxyAccess& proxyAccess = it->second; if(proxyAccess.getProxyId() == id) { proxies.erase(it); gConfig->saveProxyAccess(); return(true); } } return(false); } //********************************************************************* // hasProxyAccess //********************************************************************* // True if (proxy) has proxy access to (proxied) bool ProxyManager::hasProxyAccess(Player* proxy, Player* proxied) { if(!proxy || !proxied) return(false); ProxyMultiMapRange range = proxies.equal_range(proxied->getId()); for(ProxyMultiMap::iterator it = range.first ; it != range.second ; it++) { ProxyAccess& proxyAccess = it->second; if(proxyAccess.hasProxyAccess(proxy, proxied)) return(true); } return(false); } void ProxyManager::save() { xmlDocPtr xmlDoc; xmlNodePtr rootNode; char filename[80]; xmlDoc = xmlNewDoc(BAD_CAST "1.0"); rootNode = xmlNewDocNode(xmlDoc, NULL, BAD_CAST "Proxies", NULL); xmlDocSetRootElement(xmlDoc, rootNode); for(ProxyMultiMap::value_type p : proxies) { p.second.save(rootNode); } sprintf(filename, "%s/proxies.xml", Path::PlayerData); xml::saveFile(filename, xmlDoc); xmlFreeDoc(xmlDoc); } void ProxyManager::loadProxies() { xmlDocPtr xmlDoc; xmlNodePtr rootNode; xmlNodePtr curNode; char filename[80]; sprintf(filename, "%s/proxies.xml", Path::PlayerData); if(!file_exists(filename)) return; if((xmlDoc = xml::loadFile(filename, "Proxies")) == NULL) return; rootNode = xmlDocGetRootElement(xmlDoc); curNode = rootNode->children; while(curNode) { if(NODE_NAME(curNode, "ProxyAccess")) { ProxyAccess access(curNode); proxies.insert(ProxyMultiMap::value_type(access.getProxiedId(), access)); } curNode = curNode->next; } xmlFreeDoc(xmlDoc); xmlCleanupParser(); } //********************************************************************* // ProxyAccess proxy functions //********************************************************************* ProxyAccess::ProxyAccess(xmlNodePtr rootNode) { xmlNodePtr curNode = rootNode->children; while(curNode) { if(NODE_NAME(curNode, "ProxyId")) xml::copyToBString(proxyId, curNode); else if (NODE_NAME(curNode, "ProxyName")) xml::copyToBString(proxyName, curNode); else if (NODE_NAME(curNode, "ProxiedId")) xml::copyToBString(proxiedId, curNode); else if (NODE_NAME(curNode, "ProxiedName")) xml::copyToBString(proxiedName, curNode); curNode = curNode->next; } } ProxyAccess::ProxyAccess(Player* proxy, Player* proxied) { proxyName = proxy->getName(); proxyId = proxy->getId(); proxiedName = proxied->getName(); proxiedId = proxied->getId(); } void ProxyAccess::save(xmlNodePtr rootNode) { xmlNodePtr curNode = xml::newStringChild(rootNode, "ProxyAccess"); xml::newStringChild(curNode, "ProxiedId", proxiedId); xml::newStringChild(curNode, "ProxiedName", proxiedName); xml::newStringChild(curNode, "ProxyId", proxyId); xml::newStringChild(curNode, "ProxyName", proxyName); } //********************************************************************* // hasProxyAccess //********************************************************************* // True if (proxy) has proxy access to (proxied) bool ProxyAccess::hasProxyAccess(Player* proxy, Player* proxied) { if(proxiedId == proxied->getId() && proxiedName == proxied->getName() && proxyId == proxy->getId() && proxyName == proxy->getName()) return(true); return(false); } bstring ProxyAccess::getProxiedId() const { return proxiedId; } bstring ProxyAccess::getProxiedName() const { return proxiedName; } bstring ProxyAccess::getProxyId() const { return proxyId; } bstring ProxyAccess::getProxyName() const { return proxyName; }