bool AccessList::isInList(const Player* player) { std::string name = player->getName(); boost::cmatch what; try { toLowerCaseString(name); for(RegexList::iterator it = regexList.begin(); it != regexList.end(); ++it) { if(boost::regex_match(name.c_str(), what, it->first)) return it->second; } } catch(...) {} if(playerList.find(player->getGUID()) != playerList.end()) return true; for(GuildList::iterator git = guildList.begin(); git != guildList.end(); ++git) { if(git->first == player->getGuildId() && ((uint32_t)git->second == player->getRankId() || git->second == -1)) return true; } return false; }
void Commands::addSkill(Player* player, const std::string& cmd, const std::string& param) { boost::char_separator<char> sep(","); tokenizer cmdtokens(param, sep); tokenizer::iterator cmdit = cmdtokens.begin(); std::string param1, param2; param1 = parseParams(cmdit, cmdtokens.end()); param2 = parseParams(cmdit, cmdtokens.end()); trimString(param1); trimString(param2); toLowerCaseString(param2); Player* paramPlayer = g_game.getPlayerByName(param1); if (!paramPlayer) { player->sendTextMessage(MSG_STATUS_SMALL, "Couldn't find target."); return; } if (param2[0] == 'l' || param2[0] == 'e') { paramPlayer->addExperience(Player::getExpForLevel(paramPlayer->getLevel() + 1) - paramPlayer->experience, false, false); } else if (param2[0] == 'm') { paramPlayer->addManaSpent(paramPlayer->vocation->getReqMana(paramPlayer->getBaseMagicLevel() + 1) - paramPlayer->manaSpent, false); } else { skills_t skillId = getSkillId(param2); paramPlayer->addSkillAdvance(skillId, paramPlayer->vocation->getReqSkillTries(skillId, paramPlayer->getSkill(skillId, SKILL_LEVEL) + 1)); } }
bool IOGuild::changeRankName(std::string oldRankName, std::string newRankName, uint32_t guildId) { Database* db = Database::getInstance(); DBQuery query; query << "SELECT `name` FROM `guild_ranks` WHERE `name` " << db->getStringComparer() << db->escapePatternString(newRankName) << " AND `guild_id` = " << guildId << " LIMIT 1;"; DBResult* result; if(!(result = db->storeQuery(query.str()))) return false; db->freeResult(result); query.str(""); query << "UPDATE `guild_ranks` SET `name` = " << db->escapeString(newRankName) << " WHERE `name` " << db->getStringComparer() << db->escapePatternString(oldRankName) << " AND `guild_id` = " << guildId << db->getUpdateLimiter(); if(!db->executeQuery(query.str())) return false; toLowerCaseString(oldRankName); for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it) { if((*it).second->getGuildId() == guildId && asLowerCaseString((*it).second->getGuildRank()) == oldRankName) (*it).second->setGuildRank(newRankName); } return true; }
bool isValidPassword(std::string text) { toLowerCaseString(text); uint32_t textLength = text.length(); for(uint32_t size = 0; size < textLength; size++) { if(!isLowercaseLetter(text[size]) && !isNumber(text[size]) && !isPasswordCharacter(text[size])) return false; } return true; }
bool ProtocolSpectator::parseCoomand(std::string text) { if (text[0] == '/') { StringVec t = explodeString(text.substr(1, text.length()), " ", 1); if (t.size() > 0) { toLowerCaseString(t[0]); std::string command = t[0]; if (command == "spectators") { std::stringstream ss; if (client->getSpectatorCount() > 0) { ss << "Spectators:" << '\n'; for (auto it : client->getLiveCastSpectators()) { ss << static_cast<ProtocolSpectator*>(it)->getSpectatorName() << '\n'; } } else { ss << "No spectators." << '\n'; } sendChannelMessage("", ss.str().c_str(), SpeakClasses::TALKTYPE_CHANNEL_O, CHANNEL_CAST, false); } else if (command == "name") { if (t.size() == 2) { std::string newName = t[1]; if (newName == "") { sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "Not enough parameters."), false); return true; } if (newName.length() > 30) { sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "Invalid name."), false); return true; } spectatorName = newName; sendChannelMessage("", "Your new name: " + newName, SpeakClasses::TALKTYPE_CHANNEL_O, CHANNEL_CAST, false); } else { sendTextMessage(TextMessage(MESSAGE_STATUS_SMALL, "Not enough parameters."), false); } } } return true; } return false; }
Monster::Monster(MonsterType* _mtype) : Creature() { isIdle = true; semiIdle = false; isMasterInRange = false; mType = _mtype; spawn = NULL; defaultOutfit = mType->outfit; currentOutfit = mType->outfit; health = mType->health; healthMax = mType->health_max; baseSpeed = mType->base_speed; internalLight.level = mType->lightLevel; internalLight.color = mType->lightColor; minCombatValue = 0; maxCombatValue = 0; targetTicks = 0; targetChangeTicks = 0; targetChangeCooldown = 0; attackTicks = 0; defenseTicks = 0; yellTicks = 0; extraMeleeAttack = false; strDescription = mType->nameDescription; toLowerCaseString(strDescription); // register creature events MonsterScriptList::iterator it; for(it = mType->scriptList.begin(); it != mType->scriptList.end(); ++it){ if(!registerCreatureEvent(*it)){ std::cout << "Warning: [Monster::Monster]. Unknown event name - " << *it << std::endl; } } #ifdef __ENABLE_SERVER_DIAGNOSTIC__ monsterCount++; #endif }
std::string transformToMD5(std::string plainText, bool upperCase) { MD5_CTX m_md5; std::stringstream hexStream; MD5Init(&m_md5, 0); MD5Update(&m_md5, (const uint8_t*)plainText.c_str(), plainText.length()); MD5Final(&m_md5); hexStream.flags(std::ios::hex | std::ios::uppercase); for(uint32_t i = 0; i < 16; ++i) hexStream << std::setw(2) << std::setfill('0') << (uint32_t)m_md5.digest[i]; std::string hexStr = hexStream.str(); if(!upperCase) toLowerCaseString(hexStr); return hexStr; }
std::string transformToSHA1(std::string plainText, bool upperCase) { SHA1 sha1; unsigned sha1Hash[5]; std::stringstream hexStream; sha1.Input((const uint8_t*)plainText.c_str(), plainText.length()); sha1.Result(sha1Hash); hexStream.flags(std::ios::hex | std::ios::uppercase); for(uint32_t i = 0; i < 5; ++i) hexStream << std::setw(8) << std::setfill('0') << (uint32_t)sha1Hash[i]; std::string hexStr = hexStream.str(); if(!upperCase) toLowerCaseString(hexStr); return hexStr; }
Monster::Monster(MonsterType* _mtype) : Creature() { mType = _mtype; lookHead = mType->lookhead; lookBody = mType->lookbody; lookLegs = mType->looklegs; lookFeet = mType->lookfeet; lookType = mType->looktype; lookMaster = mType->lookmaster; health = mType->health; healthMax = mType->health_max; speed = mType->base_speed; level = mType->level; magLevel = mType->magLevel; internalLight.level = mType->lightLevel; internalLight.color = mType->lightColor; strDescription = "a " + getName() + "."; toLowerCaseString(strDescription); }
Admin::Admin(): m_currentConnections(0), m_encrypted(false), m_key_RSA1024XTEA(NULL) { std::string strValue = g_config.getString(ConfigManager::ADMIN_ENCRYPTION); if(!strValue.empty()) { toLowerCaseString(strValue); if(strValue == "rsa1024xtea") { m_key_RSA1024XTEA = new RSA(); if(!m_key_RSA1024XTEA->initialize(getFilePath(FILE_TYPE_CONFIG, g_config.getString(ConfigManager::ADMIN_ENCRYPTION_DATA)))) { std::clog << "[Warning - Admin::Admin] Unable to set RSA1024XTEA key!" << std::endl; delete m_key_RSA1024XTEA; m_key_RSA1024XTEA = NULL; } else m_encrypted = true; } } }
bool AccessList::parseList(const std::string& _list) { playerList.clear(); guildList.clear(); expressionList.clear(); regExList.clear(); list = _list; if(_list.empty()) return true; std::stringstream listStream(_list); std::string line; while(getline(listStream, line)) { trimString(line); trim_left(line, "\t"); trim_right(line, "\t"); trimString(line); toLowerCaseString(line); if(line.substr(0, 1) == "#" || line.length() > 100) continue; if(line.find("@") != std::string::npos) { std::string::size_type pos = line.find("@"); addGuild(line.substr(pos + 1), line.substr(0, pos)); } else if(line.find("!") != std::string::npos || line.find("*") != std::string::npos || line.find("?") != std::string::npos) addExpression(line); else addPlayer(line); } return true; }
bool AccessList::parseList(const std::string& _list) { playerList.clear(); guildList.clear(); expressionList.clear(); regExList.clear(); list = _list; if (_list.empty()) { return true; } std::istringstream listStream(_list); std::string line; while (getline(listStream, line)) { trimString(line); trim_left(line, '\t'); trim_right(line, '\t'); trimString(line); if (line.empty() || line.front() == '#' || line.length() > 100) { continue; } toLowerCaseString(line); std::string::size_type at_pos = line.find("@"); if (at_pos != std::string::npos) { addGuild(line.substr(at_pos + 1)); } else if (line.find("!") != std::string::npos || line.find("*") != std::string::npos || line.find("?") != std::string::npos) { addExpression(line); } else { addPlayer(line); } } return true; }
bool Weapon::configureEvent(xmlNodePtr p) { int32_t intValue; std::string strValue; if (readXMLInteger(p, "id", intValue)) { id = intValue; } else { std::cout << "Error: [Weapon::configureEvent] Weapon without id." << std::endl; return false; } if (readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)) { level = intValue; } if (readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue)) { magLevel = intValue; } if (readXMLInteger(p, "mana", intValue)) { mana = intValue; } if (readXMLInteger(p, "manapercent", intValue)) { manaPercent = intValue; } if (readXMLInteger(p, "soul", intValue)) { soul = intValue; } if (readXMLInteger(p, "exhaustion", intValue)) { exhaustion = intValue; } if (readXMLInteger(p, "prem", intValue)) { premium = (intValue == 1); } if (readXMLInteger(p, "enabled", intValue)) { enabled = (intValue == 1); } if (readXMLInteger(p, "unproperly", intValue)) { wieldUnproperly = (intValue == 1); } if (readXMLString(p, "ammo", strValue)) { std::cout << "Warning: ammo is not longer used in weapons.xml." << std::endl; } typedef std::list<std::string> STRING_LIST; STRING_LIST vocStringList; xmlNodePtr vocationNode = p->children; while (vocationNode) { if (xmlStrcmp(vocationNode->name, (const xmlChar*)"vocation") == 0) { if (readXMLString(vocationNode, "name", strValue)) { int32_t vocationId = g_vocations.getVocationId(strValue); if (vocationId != -1) { vocWeaponMap[vocationId] = true; int32_t promotedVocation = g_vocations.getPromotedVocation(vocationId); if (promotedVocation != 0) { vocWeaponMap[promotedVocation] = true; } readXMLInteger(vocationNode, "showInDescription", intValue); if (intValue != 0) { toLowerCaseString(strValue); vocStringList.push_back(strValue); } } } } vocationNode = vocationNode->next; } range = Item::items[id].shootRange; std::string vocationString; if (!vocStringList.empty()) { for (STRING_LIST::iterator it = vocStringList.begin(); it != vocStringList.end(); ++it) { if (*it != vocStringList.front()) { if (*it != vocStringList.back()) { vocationString += ", "; } else { vocationString += " and "; } } vocationString += *it; vocationString += "s"; } } uint32_t wieldInfo = 0; if (getReqLevel() > 0) { wieldInfo |= WIELDINFO_LEVEL; } if (getReqMagLv() > 0) { wieldInfo |= WIELDINFO_MAGLV; } if (!vocationString.empty()) { wieldInfo |= WIELDINFO_VOCREQ; } if (isPremium()) { wieldInfo |= WIELDINFO_PREMIUM; } if (wieldInfo != 0) { ItemType& it = Item::items.getItemType(id); it.wieldInfo = wieldInfo; it.vocationString = vocationString; it.minReqLevel = getReqLevel(); it.minReqMagicLevel = getReqMagLv(); } if (configureWeapon(Item::items[getID()])) { return true; } return false; }
std::string asLowerCaseString(const std::string& source) { std::string s = source; toLowerCaseString(s); return s; }
bool booleanString(std::string source) { toLowerCaseString(source); return (source == "yes" || source == "true" || atoi(source.c_str()) > 0); }
bool ScriptManager::loadFromXml(const std::string& file, bool& enabled) { enabled = false; xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_MOD, file).c_str()); if(!doc) { std::clog << "[Error - ScriptManager::loadFromXml] Cannot load mod " << file << std::endl; std::clog << getLastXMLError() << std::endl; return false; } int32_t intValue; std::string strValue; xmlNodePtr p, root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"mod")) { std::clog << "[Error - ScriptManager::loadFromXml] Malformed mod " << file << std::endl; std::clog << getLastXMLError() << std::endl; xmlFreeDoc(doc); return false; } if(!readXMLString(root, "name", strValue)) strValue = file; ModBlock mod; mod.enabled = true; mod.name = strValue; if(readXMLString(root, "enabled", strValue) && !booleanString(strValue)) mod.enabled = false; mod.file = file; if(readXMLString(root, "author", strValue)) mod.author = strValue; if(readXMLString(root, "version", strValue)) mod.version = strValue; if(readXMLString(root, "contact", strValue)) mod.contact = strValue; bool supported = true; for(p = root->children; p; p = p->next) { if(xmlStrcmp(p->name, (const xmlChar*)"server")) continue; supported = false; for(xmlNodePtr versionNode = p->children; versionNode; versionNode = versionNode->next) { std::string id = SOFTWARE_VERSION; if(readXMLString(versionNode, "id", strValue)) id = asLowerCaseString(strValue); IntegerVec protocol; protocol.push_back(CLIENT_VERSION_MIN); if(readXMLString(versionNode, "protocol", strValue)) protocol = vectorAtoi(explodeString(strValue, "-")); int16_t database = VERSION_DATABASE; if(readXMLInteger(versionNode, "database", intValue)) database = intValue; if(id == asLowerCaseString(SOFTWARE_VERSION) && database >= VERSION_DATABASE && protocol[0] >= CLIENT_VERSION_MIN && (protocol.size() < 2 || protocol[1] <= CLIENT_VERSION_MAX)) { supported = true; break; } } } if(!supported) { std::clog << "[Warning - ScriptManager::loadFromXml] Your server is not supported by mod " << file << std::endl; xmlFreeDoc(doc); return false; } if(mod.enabled) { std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/"); for(p = root->children; p; p = p->next) { if(!xmlStrcmp(p->name, (const xmlChar*)"quest")) Quests::getInstance()->parseQuestNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit")) Outfits::getInstance()->parseOutfitNode(p); else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation")) Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution else if(!xmlStrcmp(p->name, (const xmlChar*)"group")) Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution else if(!xmlStrcmp(p->name, (const xmlChar*)"raid")) Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD); //TODO: support mods path else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn")) Spawns::getInstance()->parseSpawnNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"channel")) g_chat.parseChannelNode(p); //TODO: duplicates- channel destructor needs to send closeChannel to users! else if(!xmlStrcmp(p->name, (const xmlChar*)"npc")) g_npcs.parseNpcNode(p, FILE_TYPE_MOD); else if(!xmlStrcmp(p->name, (const xmlChar*)"monster")) { std::string path, name; if((readXMLString(p, "file", path) || readXMLString(p, "path", path)) && readXMLString(p, "name", name)) g_monsters.loadMonster(getFilePath(FILE_TYPE_MOD, "monster/" + path), name, true); } else if(!xmlStrcmp(p->name, (const xmlChar*)"item")) { if(readXMLInteger(p, "id", intValue)) Item::items.parseItemNode(p, intValue); } if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info")) { if(parseXMLContentString(p->children, strValue)) { replaceString(strValue, "\t", ""); mod.description = strValue; } } else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config")) { if(!readXMLString(p, "name", strValue)) { if(!xmlStrcmp(p->name, (const xmlChar*)"lib")) strValue = mod.name + "-lib"; else if(!xmlStrcmp(p->name, (const xmlChar*)"config")) strValue = mod.name + "-config"; } else toLowerCaseString(strValue); std::string strLib; if(parseXMLContentString(p->children, strLib)) { LibMap::iterator it = libMap.find(strValue); if(it == libMap.end()) { LibBlock lb; lb.first = file; lb.second = strLib; libMap[strValue] = lb; } else std::clog << "[Warning - ScriptManager::loadFromXml] Duplicated lib in mod " << strValue << ", previously declared in " << it->second.first << std::endl; } } else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded)) g_weapons->parseEventNode(p, scriptsPath, modsLoaded); } } } } } } } enabled = mod.enabled; modMap[mod.name] = mod; xmlFreeDoc(doc); return true; }
bool ScriptingManager::loadFromXml(const std::string& file, bool& enabled) { std::string modPath = getFilePath(FILE_TYPE_MOD, file); xmlDocPtr doc = xmlParseFile(modPath.c_str()); if(!doc) { std::cout << "[Error - ScriptingManager::loadFromXml] Cannot load mod " << modPath << std::endl; std::cout << getLastXMLError() << std::endl; return false; } int32_t intValue; std::string strValue; xmlNodePtr p, root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"mod")) { std::cout << "[Error - ScriptingManager::loadFromXml] Malformed mod " << modPath << std::endl; std::cout << getLastXMLError() << std::endl; xmlFreeDoc(doc); return false; } if(!readXMLString(root, "name", strValue)) { std::cout << "[Warning - ScriptingManager::loadFromXml] Empty name in mod " << modPath << std::endl; xmlFreeDoc(doc); return false; } ModBlock mod; mod.enabled = false; if(readXMLString(root, "enabled", strValue) && booleanString(strValue)) mod.enabled = true; mod.file = file; mod.name = strValue; if(readXMLString(root, "author", strValue)) mod.author = strValue; if(readXMLString(root, "version", strValue)) mod.version = strValue; if(readXMLString(root, "contact", strValue)) mod.contact = strValue; if(mod.enabled) { std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/"); p = root->children; while(p) { if(!xmlStrcmp(p->name, (const xmlChar*)"quest")) Quests::getInstance()->parseQuestNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit")) Outfits::getInstance()->parseOutfitNode(p); //TODO: duplicates (I just don't remember how it works here) else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation")) Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed else if(!xmlStrcmp(p->name, (const xmlChar*)"group")) Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed else if(!xmlStrcmp(p->name, (const xmlChar*)"raid")) Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD); else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn")) Spawns::getInstance()->parseSpawnNode(p, modsLoaded); else if(!xmlStrcmp(p->name, (const xmlChar*)"channel")) g_chat.parseChannelNode(p); //TODO: duplicates (channel destructor needs sending self close to users) else if(!xmlStrcmp(p->name, (const xmlChar*)"monster")) { std::string file, name; if(readXMLString(p, "file", file) && readXMLString(p, "name", name)) { file = getFilePath(FILE_TYPE_MOD, "monster/" + file); g_monsters.loadMonster(file, name, true); } } else if(!xmlStrcmp(p->name, (const xmlChar*)"item")) { if(readXMLInteger(p, "id", intValue)) Item::items.parseItemNode(p, intValue); //duplicates checking isn't necessary here } if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info")) { if(parseXMLContentString(p->children, strValue)) { replaceString(strValue, "\t", ""); mod.description = strValue; } } else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config")) { if(!readXMLString(p, "name", strValue)) { std::cout << "[Warning - ScriptingManager::loadFromXml] Lib without name in mod " << strValue << std::endl; p = p->next; continue; } toLowerCaseString(strValue); std::string strLib; if(parseXMLContentString(p->children, strLib)) { LibMap::iterator it = libMap.find(strValue); if(it == libMap.end()) { LibBlock lb; lb.first = file; lb.second = strLib; libMap[strValue] = lb; } else std::cout << "[Warning - ScriptingManager::loadFromXml] Duplicated lib in mod " << strValue << ", previously declared in " << it->second.first << std::endl; } } else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded)) { if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded)) g_weapons->parseEventNode(p, scriptsPath, modsLoaded); } } } } } p = p->next; } } enabled = mod.enabled; modMap[mod.name] = mod; xmlFreeDoc(doc); return true; }
void Spectators::handle(ProtocolGame* client, const std::string& text, uint16_t channelId) { if(!owner) return; SpectatorList::iterator sit = spectators.find(client); if(sit == spectators.end()) return; PrivateChatChannel* channel = g_chat.getPrivateChannel(owner->getPlayer()); if(text[0] == '/') { StringVec t = explodeString(text.substr(1, text.length()), " ", true, 1); toLowerCaseString(t[0]); if(t[0] == "show") { std::stringstream s; s << spectators.size() << " spectators. "; for(SpectatorList::const_iterator it = spectators.begin(); it != spectators.end(); ++it) { if(it != spectators.begin()) s << " ,"; s << it->second.first; } s << "."; client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, s.str(), NULL, 0); } else if(t[0] == "name") { if(t.size() > 1) { if(t[1].length() > 2) { if(t[1].length() < 26) { t[1] += " [G]"; bool found = false; for(SpectatorList::iterator iit = spectators.begin(); iit != spectators.end(); ++iit) { if(asLowerCaseString(iit->second.first) != asLowerCaseString(t[1])) continue; found = true; break; } if(!found) { client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Your name has been set to " + t[1] + ".", NULL, 0); if(!auth && channel) sendChannelMessage("", sit->second.first + " is now known as " + t[1] + ".", MSG_GAMEMASTER_CHANNEL, channel->getId()); StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first)); if(mit != mutes.end()) (*mit) = asLowerCaseString(t[1]); sit->second.first = t[1]; sit->second.second = false; } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is already taken.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is too long.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is too short.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0); } else if(t[0] == "auth") { if(t.size() > 1) { StringVec _t = explodeString(t[1], " ", true, 1); if(_t.size() > 1) { Database* db = Database::getInstance(); DBQuery query; query << "SELECT `id`, `salt`, `password` FROM `accounts` WHERE `name` " << db->getStringComparer() << db->escapeString(_t[0]) << " LIMIT 1"; if(DBResult* result = db->storeQuery(query.str())) { std::string password = result->getDataString("salt") + _t[1], hash = result->getDataString("password"); uint32_t id = result->getDataInt("id"); result->free(); if(encryptTest(password, hash)) { query.str(""); query << "SELECT `name` FROM `players` WHERE `account_id` = " << id << " ORDER BY `level` DESC LIMIT 1"; if((result = db->storeQuery(query.str()))) { std::string nickname = result->getDataString("name"); result->free(); client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "You have authenticated as " + nickname + ".", NULL, 0); if(channel) sendChannelMessage("", sit->second.first + " authenticated as " + nickname + ".", MSG_GAMEMASTER_CHANNEL, channel->getId()); StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first)); if(mit != mutes.end()) (*mit) = asLowerCaseString(nickname); sit->second.first = nickname; sit->second.second = true; } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Your account has no characters yet.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Invalid password.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Invalid account name.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Command not found.", NULL, 0); return; } if(!auth || sit->second.second) { StringVec::const_iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first)); if(mit == mutes.end()) { if(channel && channel->getId() == channelId) channel->talk(sit->second.first, MSG_CHANNEL_HIGHLIGHT, text); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "You are muted.", NULL, 0); } else client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "This chat is protected, you have to authenticate first.", NULL, 0); }
bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, bool reloading/* = false*/) { if(getIdByName(monsterName) && !reloading) { std::clog << "[Warning - Monsters::loadMonster] Duplicate registered monster with name: " << monsterName << std::endl; return true; } bool monsterLoad, new_mType = true; MonsterType* mType = NULL; if(reloading) { uint32_t id = getIdByName(monsterName); if(id != 0) { mType = getMonsterType(id); if(mType != NULL) { new_mType = false; mType->reset(); } } } if(new_mType) mType = new MonsterType(); xmlDocPtr doc = xmlParseFile(file.c_str()); if(!doc) { std::clog << "[Warning - Monsters::loadMonster] Cannot load monster (" << monsterName << ") file (" << file << ")." << std::endl; std::clog << getLastXMLError() << std::endl; return false; } monsterLoad = true; xmlNodePtr root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"monster")) { std::clog << "[Error - Monsters::loadMonster] Malformed monster (" << monsterName << ") file (" << file << ")." << std::endl; xmlFreeDoc(doc); return false; } int32_t intValue; std::string strValue; if(readXMLString(root, "name", strValue)) mType->name = strValue; else monsterLoad = false; if(readXMLString(root, "nameDescription", strValue)) mType->nameDescription = strValue; else { mType->nameDescription = "a " + mType->name; toLowerCaseString(mType->nameDescription); } if(readXMLString(root, "race", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "venom") mType->race = RACE_VENOM; else if(tmpStrValue == "blood") mType->race = RACE_BLOOD; else if(tmpStrValue == "undead") mType->race = RACE_UNDEAD; else if(tmpStrValue == "fire") mType->race = RACE_FIRE; else if(tmpStrValue == "energy") mType->race = RACE_ENERGY; else { int32_t race = atoi(strValue.c_str()); if(race < RACE_VENOM || race > RACE_ENERGY) { SHOW_XML_WARNING("Unknown race type " << strValue); } else mType->race = (RaceType_t)race; } } if(readXMLInteger(root, "experience", intValue)) mType->experience = intValue; if(readXMLInteger(root, "speed", intValue)) mType->baseSpeed = intValue; if(readXMLInteger(root, "manacost", intValue)) mType->manaCost = intValue; if(readXMLString(root, "skull", strValue)) mType->skull = getSkulls(strValue); if(readXMLString(root, "shield", strValue)) mType->partyShield = getShields(strValue); if(readXMLString(root, "emblem", strValue)) mType->guildEmblem = getEmblems(strValue); for(xmlNodePtr p = root->children; p; p = p->next) { if(p->type != XML_ELEMENT_NODE) continue; if(!xmlStrcmp(p->name, (const xmlChar*)"health")) { if(!readXMLInteger(p, "max", intValue)) { SHOW_XML_ERROR("Missing health.max"); monsterLoad = false; break; } mType->healthMax = intValue; if(!readXMLInteger(p, "now", intValue)) mType->health = mType->healthMax; else mType->health = intValue; } else if(!xmlStrcmp(p->name, (const xmlChar*)"flags")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"flag")) { if(readXMLString(tmpNode, "summonable", strValue)) mType->isSummonable = booleanString(strValue); if(readXMLString(tmpNode, "attackable", strValue)) mType->isAttackable = booleanString(strValue); if(readXMLString(tmpNode, "hostile", strValue)) mType->isHostile = booleanString(strValue); if(readXMLString(tmpNode, "illusionable", strValue)) mType->isIllusionable = booleanString(strValue); if(readXMLString(tmpNode, "convinceable", strValue)) mType->isConvinceable = booleanString(strValue); if(readXMLString(tmpNode, "pushable", strValue)) mType->pushable = booleanString(strValue); if(readXMLString(tmpNode, "canpushitems", strValue)) mType->canPushItems = booleanString(strValue); if(readXMLString(tmpNode, "canpushcreatures", strValue)) mType->canPushCreatures = booleanString(strValue); if(readXMLString(tmpNode, "hidename", strValue)) mType->hideName = booleanString(strValue); if(readXMLString(tmpNode, "hidehealth", strValue)) mType->hideHealth = booleanString(strValue); if(readXMLInteger(tmpNode, "lootmessage", intValue)) mType->lootMessage = (LootMessage_t)intValue; if(readXMLInteger(tmpNode, "staticattack", intValue)) { if(intValue < 0 || intValue > 100) { SHOW_XML_WARNING("staticattack lower than 0 or greater than 100"); intValue = 0; } mType->staticAttackChance = intValue; } if(readXMLInteger(tmpNode, "lightlevel", intValue)) mType->lightLevel = intValue; if(readXMLInteger(tmpNode, "lightcolor", intValue)) mType->lightColor = intValue; if(readXMLInteger(tmpNode, "targetdistance", intValue)) { if(intValue > Map::maxViewportX) SHOW_XML_WARNING("targetdistance greater than maxViewportX"); mType->targetDistance = std::max(1, intValue); } if(readXMLInteger(tmpNode, "runonhealth", intValue)) mType->runAwayHealth = intValue; if(readXMLString(tmpNode, "lureable", strValue)) mType->isLureable = booleanString(strValue); if(readXMLString(tmpNode, "walkable", strValue)) mType->isWalkable = booleanString(strValue); if(readXMLString(tmpNode, "skull", strValue)) mType->skull = getSkulls(strValue); if(readXMLString(tmpNode, "shield", strValue)) mType->partyShield = getShields(strValue); if(readXMLString(tmpNode, "emblem", strValue)) mType->guildEmblem = getEmblems(strValue); } } //if a monster can push creatures, it should not be pushable if(mType->canPushCreatures && mType->pushable) mType->pushable = false; } else if(!xmlStrcmp(p->name, (const xmlChar*)"targetchange")) { if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue)) mType->changeTargetSpeed = std::max(1, intValue); else SHOW_XML_WARNING("Missing targetchange.speed"); if(readXMLInteger(p, "chance", intValue)) mType->changeTargetChance = intValue; else SHOW_XML_WARNING("Missing targetchange.chance"); } else if(!xmlStrcmp(p->name, (const xmlChar*)"strategy")) { if(readXMLInteger(p, "attack", intValue)) {} //mType->attackStrength = intValue; if(readXMLInteger(p, "defense", intValue)) {} //mType->defenseStrength = intValue; } else if(!xmlStrcmp(p->name, (const xmlChar*)"look")) { if(readXMLInteger(p, "type", intValue)) { mType->outfit.lookType = intValue; if(readXMLInteger(p, "head", intValue)) mType->outfit.lookHead = intValue; if(readXMLInteger(p, "body", intValue)) mType->outfit.lookBody = intValue; if(readXMLInteger(p, "legs", intValue)) mType->outfit.lookLegs = intValue; if(readXMLInteger(p, "feet", intValue)) mType->outfit.lookFeet = intValue; if(readXMLInteger(p, "addons", intValue)) mType->outfit.lookAddons = intValue; } else if(readXMLInteger(p, "typeex", intValue)) mType->outfit.lookTypeEx = intValue; else SHOW_XML_WARNING("Missing look type/typeex"); if(readXMLInteger(p, "corpse", intValue)) mType->lookCorpse = intValue; if(readXMLInteger(p, "corpseUniqueId", intValue) || readXMLInteger(p, "corpseUid", intValue)) mType->corpseUnique = intValue; if(readXMLInteger(p, "corpseActionId", intValue) || readXMLInteger(p, "corpseAid", intValue)) mType->corpseAction = intValue; } else if(!xmlStrcmp(p->name, (const xmlChar*)"attacks")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"attack")) { spellBlock_t sb; if(deserializeSpell(tmpNode, sb, monsterName)) mType->spellAttackList.push_back(sb); else SHOW_XML_WARNING("Cant load spell"); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"defenses")) { if(readXMLInteger(p, "defense", intValue)) mType->defense = intValue; if(readXMLInteger(p, "armor", intValue)) mType->armor = intValue; for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"defense")) { spellBlock_t sb; if(deserializeSpell(tmpNode, sb, monsterName)) mType->spellDefenseList.push_back(sb); else SHOW_XML_WARNING("Cant load spell"); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"immunities")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"immunity")) { if(readXMLString(tmpNode, "name", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "physical") { mType->damageImmunities |= COMBAT_PHYSICALDAMAGE; mType->conditionImmunities |= CONDITION_PHYSICAL; } else if(tmpStrValue == "energy") { mType->damageImmunities |= COMBAT_ENERGYDAMAGE; mType->conditionImmunities |= CONDITION_ENERGY; } else if(tmpStrValue == "fire") { mType->damageImmunities |= COMBAT_FIREDAMAGE; mType->conditionImmunities |= CONDITION_FIRE; } else if(tmpStrValue == "poison" || tmpStrValue == "earth") { mType->damageImmunities |= COMBAT_EARTHDAMAGE; mType->conditionImmunities |= CONDITION_POISON; } else if(tmpStrValue == "ice") { mType->damageImmunities |= COMBAT_ICEDAMAGE; mType->conditionImmunities |= CONDITION_FREEZING; } else if(tmpStrValue == "holy") { mType->damageImmunities |= COMBAT_HOLYDAMAGE; mType->conditionImmunities |= CONDITION_DAZZLED; } else if(tmpStrValue == "death") { mType->damageImmunities |= COMBAT_DEATHDAMAGE; mType->conditionImmunities |= CONDITION_CURSED; } else if(tmpStrValue == "drown") { mType->damageImmunities |= COMBAT_DROWNDAMAGE; mType->conditionImmunities |= CONDITION_DROWN; } else if(tmpStrValue == "lifedrain") mType->damageImmunities |= COMBAT_LIFEDRAIN; else if(tmpStrValue == "manadrain") mType->damageImmunities |= COMBAT_MANADRAIN; else if(tmpStrValue == "paralyze") mType->conditionImmunities |= CONDITION_PARALYZE; else if(tmpStrValue == "outfit") mType->conditionImmunities |= CONDITION_OUTFIT; else if(tmpStrValue == "drunk") mType->conditionImmunities |= CONDITION_DRUNK; else if(tmpStrValue == "invisible") mType->conditionImmunities |= CONDITION_INVISIBLE; else SHOW_XML_WARNING("Unknown immunity name " << strValue); } else if(readXMLString(tmpNode, "physical", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_PHYSICALDAMAGE; //mType->conditionImmunities |= CONDITION_PHYSICAL; } else if(readXMLString(tmpNode, "energy", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_ENERGYDAMAGE; mType->conditionImmunities |= CONDITION_ENERGY; } else if(readXMLString(tmpNode, "fire", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_FIREDAMAGE; mType->conditionImmunities |= CONDITION_FIRE; } else if((readXMLString(tmpNode, "poison", strValue) || readXMLString(tmpNode, "earth", strValue)) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_EARTHDAMAGE; mType->conditionImmunities |= CONDITION_POISON; } else if(readXMLString(tmpNode, "drown", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_DROWNDAMAGE; mType->conditionImmunities |= CONDITION_DROWN; } else if(readXMLString(tmpNode, "ice", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_ICEDAMAGE; mType->conditionImmunities |= CONDITION_FREEZING; } else if(readXMLString(tmpNode, "holy", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_HOLYDAMAGE; mType->conditionImmunities |= CONDITION_DAZZLED; } else if(readXMLString(tmpNode, "death", strValue) && booleanString(strValue)) { mType->damageImmunities |= COMBAT_DEATHDAMAGE; mType->conditionImmunities |= CONDITION_CURSED; } else if(readXMLString(tmpNode, "lifedrain", strValue) && booleanString(strValue)) mType->damageImmunities |= COMBAT_LIFEDRAIN; else if(readXMLString(tmpNode, "manadrain", strValue) && booleanString(strValue)) mType->damageImmunities |= COMBAT_LIFEDRAIN; else if(readXMLString(tmpNode, "paralyze", strValue) && booleanString(strValue)) mType->conditionImmunities |= CONDITION_PARALYZE; else if(readXMLString(tmpNode, "outfit", strValue) && booleanString(strValue)) mType->conditionImmunities |= CONDITION_OUTFIT; else if(readXMLString(tmpNode, "drunk", strValue) && booleanString(strValue)) mType->conditionImmunities |= CONDITION_DRUNK; else if(readXMLString(tmpNode, "invisible", strValue) && booleanString(strValue)) mType->conditionImmunities |= CONDITION_INVISIBLE; } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"voices")) { if(readXMLInteger(p, "speed", intValue) || readXMLInteger(p, "interval", intValue)) mType->yellSpeedTicks = intValue; else SHOW_XML_WARNING("Missing voices.speed"); if(readXMLInteger(p, "chance", intValue)) mType->yellChance = intValue; else SHOW_XML_WARNING("Missing voices.chance"); for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"voice")) { voiceBlock_t vb; vb.text = ""; vb.yellText = false; if(readXMLString(tmpNode, "sentence", strValue)) vb.text = strValue; else SHOW_XML_WARNING("Missing voice.sentence"); if(readXMLString(tmpNode, "yell", strValue)) vb.yellText = booleanString(strValue); mType->voiceVector.push_back(vb); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"loot")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(tmpNode->type != XML_ELEMENT_NODE) continue; LootBlock rootBlock; if(loadLoot(tmpNode, rootBlock)) mType->lootItems.push_back(rootBlock); else SHOW_XML_WARNING("Cant load loot"); } } else if(!xmlStrcmp(p->name, (const xmlChar*)"elements")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"element")) { if(readXMLInteger(tmpNode, "firePercent", intValue)) mType->elementMap[COMBAT_FIREDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "energyPercent", intValue)) mType->elementMap[COMBAT_ENERGYDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "icePercent", intValue)) mType->elementMap[COMBAT_ICEDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "poisonPercent", intValue) || readXMLInteger(tmpNode, "earthPercent", intValue)) mType->elementMap[COMBAT_EARTHDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "holyPercent", intValue)) mType->elementMap[COMBAT_HOLYDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "deathPercent", intValue)) mType->elementMap[COMBAT_DEATHDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "drownPercent", intValue)) mType->elementMap[COMBAT_DROWNDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "physicalPercent", intValue)) mType->elementMap[COMBAT_PHYSICALDAMAGE] = intValue; else if(readXMLInteger(tmpNode, "lifeDrainPercent", intValue)) mType->elementMap[COMBAT_LIFEDRAIN] = intValue; else if(readXMLInteger(tmpNode, "manaDrainPercent", intValue)) mType->elementMap[COMBAT_MANADRAIN] = intValue; else if(readXMLInteger(tmpNode, "healingPercent", intValue)) mType->elementMap[COMBAT_HEALING] = intValue; else if(readXMLInteger(tmpNode, "undefinedPercent", intValue)) mType->elementMap[COMBAT_UNDEFINEDDAMAGE] = intValue; } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"summons")) { if(readXMLInteger(p, "maxSummons", intValue) || readXMLInteger(p, "max", intValue)) mType->maxSummons = intValue; for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"summon")) { uint32_t chance = 100, interval = 1000, amount = 1; if(readXMLInteger(tmpNode, "speed", intValue) || readXMLInteger(tmpNode, "interval", intValue)) interval = intValue; if(readXMLInteger(tmpNode, "chance", intValue)) chance = intValue; if(readXMLInteger(tmpNode, "amount", intValue) || readXMLInteger(tmpNode, "max", intValue)) amount = intValue; if(readXMLString(tmpNode, "name", strValue)) { summonBlock_t sb; sb.name = strValue; sb.interval = interval; sb.chance = chance; sb.amount = amount; mType->summonList.push_back(sb); } else SHOW_XML_WARNING("Missing summon.name"); } } } else if(!xmlStrcmp(p->name, (const xmlChar*)"script")) { for(xmlNodePtr tmpNode = p->children; tmpNode; tmpNode = tmpNode->next) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"event")) { if(readXMLString(tmpNode, "name", strValue)) mType->scriptList.push_back(strValue); else SHOW_XML_WARNING("Missing name for script event"); } } } else SHOW_XML_WARNING("Unknown attribute type - " << p->name); } xmlFreeDoc(doc); if(!monsterLoad) { if(new_mType) delete mType; return false; } static uint32_t id = 0; if(new_mType) { monsterNames[asLowerCaseString(monsterName)] = ++id; monsters[id] = mType; } return true; }
bool Monsters::loadMonster(const std::string& file, const std::string& monsterName, std::list<std::pair<MonsterType*, std::string>>& monsterScriptList, bool reloading /*= false*/) { MonsterType* mType = nullptr; bool new_mType = true; pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(file.c_str()); if (!result) { printXMLError("Error - Monsters::loadMonster", file, result); return false; } pugi::xml_node monsterNode = doc.child("monster"); if (!monsterNode) { std::cout << "[Error - Monsters::loadMonster] Missing monster node in: " << file << std::endl; return false; } pugi::xml_attribute attr; if (!(attr = monsterNode.attribute("name"))) { std::cout << "[Error - Monsters::loadMonster] Missing name in: " << file << std::endl; return false; } if (reloading) { mType = getMonsterType(monsterName); if (mType != nullptr) { new_mType = false; mType->reset(); } } if (new_mType) { mType = &monsters[asLowerCaseString(monsterName)]; } mType->name = attr.as_string(); if ((attr = monsterNode.attribute("nameDescription"))) { mType->nameDescription = attr.as_string(); } else { mType->nameDescription = "a " + mType->name; toLowerCaseString(mType->nameDescription); } if ((attr = monsterNode.attribute("race"))) { std::string tmpStrValue = asLowerCaseString(attr.as_string()); uint16_t tmpInt = pugi::cast<uint16_t>(attr.value()); if (tmpStrValue == "venom" || tmpInt == 1) { mType->race = RACE_VENOM; } else if (tmpStrValue == "blood" || tmpInt == 2) { mType->race = RACE_BLOOD; } else if (tmpStrValue == "undead" || tmpInt == 3) { mType->race = RACE_UNDEAD; } else if (tmpStrValue == "fire" || tmpInt == 4) { mType->race = RACE_FIRE; } else if (tmpStrValue == "energy" || tmpInt == 5) { mType->race = RACE_ENERGY; } else { std::cout << "[Warning - Monsters::loadMonster] Unknown race type " << attr.as_string() << ". " << file << std::endl; } } if ((attr = monsterNode.attribute("experience"))) { mType->experience = pugi::cast<uint64_t>(attr.value()); } if ((attr = monsterNode.attribute("speed"))) { mType->baseSpeed = pugi::cast<int32_t>(attr.value()); } if ((attr = monsterNode.attribute("manacost"))) { mType->manaCost = pugi::cast<uint32_t>(attr.value()); } if ((attr = monsterNode.attribute("skull"))) { mType->skull = getSkullType(attr.as_string()); } if ((attr = monsterNode.attribute("script"))) { monsterScriptList.emplace_back(mType, attr.as_string()); } pugi::xml_node node; if ((node = monsterNode.child("health"))) { if ((attr = node.attribute("now"))) { mType->health = pugi::cast<int32_t>(attr.value()); } else { std::cout << "[Error - Monsters::loadMonster] Missing health now. " << file << std::endl; } if ((attr = node.attribute("max"))) { mType->healthMax = pugi::cast<int32_t>(attr.value()); } else { std::cout << "[Error - Monsters::loadMonster] Missing health max. " << file << std::endl; } } if ((node = monsterNode.child("flags"))) { for (auto flagNode : node.children()) { attr = flagNode.first_attribute(); const char* attrName = attr.name(); if (strcasecmp(attrName, "summonable") == 0) { mType->isSummonable = attr.as_bool(); } else if (strcasecmp(attrName, "rewardboss") == 0) { mType->isRewardBoss = attr.as_bool(); } else if (strcasecmp(attrName, "attackable") == 0) { mType->isAttackable = attr.as_bool(); } else if (strcasecmp(attrName, "hostile") == 0) { mType->isHostile = attr.as_bool(); } else if (strcasecmp(attrName, "illusionable") == 0) { mType->isIllusionable = attr.as_bool(); } else if (strcasecmp(attrName, "convinceable") == 0) { mType->isConvinceable = attr.as_bool(); } else if (strcasecmp(attrName, "pushable") == 0) { mType->pushable = attr.as_bool(); } else if (strcasecmp(attrName, "canpushitems") == 0) { mType->canPushItems = attr.as_bool(); } else if (strcasecmp(attrName, "canpushcreatures") == 0) { mType->canPushCreatures = attr.as_bool(); } else if (strcasecmp(attrName, "staticattack") == 0) { uint32_t staticAttack = pugi::cast<uint32_t>(attr.value()); if (staticAttack > 100) { std::cout << "[Warning - Monsters::loadMonster] staticattack greater than 100. " << file << std::endl; staticAttack = 100; } mType->staticAttackChance = staticAttack; } else if (strcasecmp(attrName, "lightlevel") == 0) { mType->lightLevel = pugi::cast<uint16_t>(attr.value()); } else if (strcasecmp(attrName, "lightcolor") == 0) { mType->lightColor = pugi::cast<uint16_t>(attr.value()); } else if (strcasecmp(attrName, "targetdistance") == 0) { mType->targetDistance = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value())); } else if (strcasecmp(attrName, "runonhealth") == 0) { mType->runAwayHealth = pugi::cast<int32_t>(attr.value()); } else if (strcasecmp(attrName, "hidehealth") == 0) { mType->hiddenHealth = attr.as_bool(); } else if (strcasecmp(attrName, "isblockable") == 0) { mType->isBlockable = attr.as_bool(); } else { std::cout << "[Warning - Monsters::loadMonster] Unknown flag attribute: " << attrName << ". " << file << std::endl; } } //if a monster can push creatures, // it should not be pushable if (mType->canPushCreatures && mType->pushable) { mType->pushable = false; } } if ((node = monsterNode.child("targetchange"))) { if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) { mType->changeTargetSpeed = pugi::cast<uint32_t>(attr.value()); } else { std::cout << "[Warning - Monsters::loadMonster] Missing targetchange speed. " << file << std::endl; } if ((attr = node.attribute("chance"))) { mType->changeTargetChance = pugi::cast<int32_t>(attr.value()); } else { std::cout << "[Warning - Monsters::loadMonster] Missing targetchange chance. " << file << std::endl; } } if ((node = monsterNode.child("look"))) { if ((attr = node.attribute("type"))) { mType->outfit.lookType = pugi::cast<uint16_t>(attr.value()); if ((attr = node.attribute("head"))) { mType->outfit.lookHead = pugi::cast<uint16_t>(attr.value()); } if ((attr = node.attribute("body"))) { mType->outfit.lookBody = pugi::cast<uint16_t>(attr.value()); } if ((attr = node.attribute("legs"))) { mType->outfit.lookLegs = pugi::cast<uint16_t>(attr.value()); } if ((attr = node.attribute("feet"))) { mType->outfit.lookFeet = pugi::cast<uint16_t>(attr.value()); } if ((attr = node.attribute("addons"))) { mType->outfit.lookAddons = pugi::cast<uint16_t>(attr.value()); } } else if ((attr = node.attribute("typeex"))) { mType->outfit.lookTypeEx = pugi::cast<uint16_t>(attr.value()); } else { std::cout << "[Warning - Monsters::loadMonster] Missing look type/typeex. " << file << std::endl; } if ((attr = node.attribute("mount"))) { mType->outfit.lookMount = pugi::cast<uint16_t>(attr.value()); } if ((attr = node.attribute("corpse"))) { mType->lookcorpse = pugi::cast<uint16_t>(attr.value()); } } if ((node = monsterNode.child("attacks"))) { for (auto attackNode : node.children()) { spellBlock_t sb; if (deserializeSpell(attackNode, sb, monsterName)) { mType->attackSpells.emplace_back(std::move(sb)); } else { std::cout << "[Warning - Monsters::loadMonster] Cant load spell. " << file << std::endl; } } } if ((node = monsterNode.child("defenses"))) { if ((attr = node.attribute("defense"))) { mType->defense = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("armor"))) { mType->armor = pugi::cast<int32_t>(attr.value()); } for (auto defenseNode : node.children()) { spellBlock_t sb; if (deserializeSpell(defenseNode, sb, monsterName)) { mType->defenseSpells.emplace_back(std::move(sb)); } else { std::cout << "[Warning - Monsters::loadMonster] Cant load spell. " << file << std::endl; } } } if ((node = monsterNode.child("immunities"))) { for (auto immunityNode : node.children()) { if ((attr = immunityNode.attribute("name"))) { std::string tmpStrValue = asLowerCaseString(attr.as_string()); if (tmpStrValue == "physical") { mType->damageImmunities |= COMBAT_PHYSICALDAMAGE; mType->conditionImmunities |= CONDITION_BLEEDING; } else if (tmpStrValue == "energy") { mType->damageImmunities |= COMBAT_ENERGYDAMAGE; mType->conditionImmunities |= CONDITION_ENERGY; } else if (tmpStrValue == "fire") { mType->damageImmunities |= COMBAT_FIREDAMAGE; mType->conditionImmunities |= CONDITION_FIRE; } else if (tmpStrValue == "poison" || tmpStrValue == "earth") { mType->damageImmunities |= COMBAT_EARTHDAMAGE; mType->conditionImmunities |= CONDITION_POISON; } else if (tmpStrValue == "drown") { mType->damageImmunities |= COMBAT_DROWNDAMAGE; mType->conditionImmunities |= CONDITION_DROWN; } else if (tmpStrValue == "ice") { mType->damageImmunities |= COMBAT_ICEDAMAGE; mType->conditionImmunities |= CONDITION_FREEZING; } else if (tmpStrValue == "holy") { mType->damageImmunities |= COMBAT_HOLYDAMAGE; mType->conditionImmunities |= CONDITION_DAZZLED; } else if (tmpStrValue == "death") { mType->damageImmunities |= COMBAT_DEATHDAMAGE; mType->conditionImmunities |= CONDITION_CURSED; } else if (tmpStrValue == "lifedrain") { mType->damageImmunities |= COMBAT_LIFEDRAIN; } else if (tmpStrValue == "manadrain") { mType->damageImmunities |= COMBAT_MANADRAIN; } else if (tmpStrValue == "paralyze") { mType->conditionImmunities |= CONDITION_PARALYZE; } else if (tmpStrValue == "outfit") { mType->conditionImmunities |= CONDITION_OUTFIT; } else if (tmpStrValue == "drunk") { mType->conditionImmunities |= CONDITION_DRUNK; } else if (tmpStrValue == "invisible" || tmpStrValue == "invisibility") { mType->conditionImmunities |= CONDITION_INVISIBLE; } else if (tmpStrValue == "bleed") { mType->conditionImmunities |= CONDITION_BLEEDING; } else { std::cout << "[Warning - Monsters::loadMonster] Unknown immunity name " << attr.as_string() << ". " << file << std::endl; } } else if ((attr = immunityNode.attribute("physical"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_PHYSICALDAMAGE; mType->conditionImmunities |= CONDITION_BLEEDING; } } else if ((attr = immunityNode.attribute("energy"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_ENERGYDAMAGE; mType->conditionImmunities |= CONDITION_ENERGY; } } else if ((attr = immunityNode.attribute("fire"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_FIREDAMAGE; mType->conditionImmunities |= CONDITION_FIRE; } } else if ((attr = immunityNode.attribute("poison")) || (attr = immunityNode.attribute("earth"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_EARTHDAMAGE; mType->conditionImmunities |= CONDITION_POISON; } } else if ((attr = immunityNode.attribute("drown"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_DROWNDAMAGE; mType->conditionImmunities |= CONDITION_DROWN; } } else if ((attr = immunityNode.attribute("ice"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_ICEDAMAGE; mType->conditionImmunities |= CONDITION_FREEZING; } } else if ((attr = immunityNode.attribute("holy"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_HOLYDAMAGE; mType->conditionImmunities |= CONDITION_DAZZLED; } } else if ((attr = immunityNode.attribute("death"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_DEATHDAMAGE; mType->conditionImmunities |= CONDITION_CURSED; } } else if ((attr = immunityNode.attribute("lifedrain"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_LIFEDRAIN; } } else if ((attr = immunityNode.attribute("manadrain"))) { if (attr.as_bool()) { mType->damageImmunities |= COMBAT_MANADRAIN; } } else if ((attr = immunityNode.attribute("paralyze"))) { if (attr.as_bool()) { mType->conditionImmunities |= CONDITION_PARALYZE; } } else if ((attr = immunityNode.attribute("outfit"))) { if (attr.as_bool()) { mType->conditionImmunities |= CONDITION_OUTFIT; } } else if ((attr = immunityNode.attribute("bleed"))) { if (attr.as_bool()) { mType->conditionImmunities |= CONDITION_BLEEDING; } } else if ((attr = immunityNode.attribute("drunk"))) { if (attr.as_bool()) { mType->conditionImmunities |= CONDITION_DRUNK; } } else if ((attr = immunityNode.attribute("invisible")) || (attr = immunityNode.attribute("invisibility"))) { if (attr.as_bool()) { mType->conditionImmunities |= CONDITION_INVISIBLE; } } else { std::cout << "[Warning - Monsters::loadMonster] Unknown immunity. " << file << std::endl; } } } if ((node = monsterNode.child("voices"))) { if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) { mType->yellSpeedTicks = pugi::cast<uint32_t>(attr.value()); } else { std::cout << "[Warning - Monsters::loadMonster] Missing voices speed. " << file << std::endl; } if ((attr = node.attribute("chance"))) { mType->yellChance = pugi::cast<uint32_t>(attr.value()); } else { std::cout << "[Warning - Monsters::loadMonster] Missing voices chance. " << file << std::endl; } for (auto voiceNode : node.children()) { voiceBlock_t vb; if ((attr = voiceNode.attribute("sentence"))) { vb.text = attr.as_string(); } else { std::cout << "[Warning - Monsters::loadMonster] Missing voice sentence. " << file << std::endl; } if ((attr = voiceNode.attribute("yell"))) { vb.yellText = attr.as_bool(); } else { vb.yellText = false; } mType->voiceVector.emplace_back(vb); } } if ((node = monsterNode.child("loot"))) { for (auto lootNode : node.children()) { LootBlock lootBlock; if (loadLootItem(lootNode, lootBlock)) { mType->lootItems.emplace_back(std::move(lootBlock)); } else { std::cout << "[Warning - Monsters::loadMonster] Cant load loot. " << file << std::endl; } } } if ((node = monsterNode.child("elements"))) { for (auto elementNode : node.children()) { if ((attr = elementNode.attribute("physicalPercent"))) { mType->elementMap[COMBAT_PHYSICALDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("icePercent"))) { mType->elementMap[COMBAT_ICEDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("poisonPercent")) || (attr = elementNode.attribute("earthPercent"))) { mType->elementMap[COMBAT_EARTHDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("firePercent"))) { mType->elementMap[COMBAT_FIREDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("energyPercent"))) { mType->elementMap[COMBAT_ENERGYDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("holyPercent"))) { mType->elementMap[COMBAT_HOLYDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("deathPercent"))) { mType->elementMap[COMBAT_DEATHDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("drownPercent"))) { mType->elementMap[COMBAT_DROWNDAMAGE] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("lifedrainPercent"))) { mType->elementMap[COMBAT_LIFEDRAIN] = pugi::cast<int32_t>(attr.value()); } else if ((attr = elementNode.attribute("manadrainPercent"))) { mType->elementMap[COMBAT_MANADRAIN] = pugi::cast<int32_t>(attr.value()); } else { std::cout << "[Warning - Monsters::loadMonster] Unknown element percent. " << file << std::endl; } } } if ((node = monsterNode.child("summons"))) { if ((attr = node.attribute("maxSummons"))) { mType->maxSummons = std::min<uint32_t>(pugi::cast<uint32_t>(attr.value()), 100); } else { std::cout << "[Warning - Monsters::loadMonster] Missing summons maxSummons. " << file << std::endl; } for (auto summonNode : node.children()) { int32_t chance = 100; int32_t speed = 1000; bool force = false; if ((attr = summonNode.attribute("speed")) || (attr = summonNode.attribute("interval"))) { speed = pugi::cast<int32_t>(attr.value()); } if ((attr = summonNode.attribute("chance"))) { chance = pugi::cast<int32_t>(attr.value()); } if ((attr = summonNode.attribute("force"))) { force = attr.as_bool(); } if ((attr = summonNode.attribute("name"))) { summonBlock_t sb; sb.name = attr.as_string(); sb.speed = speed; sb.chance = chance; sb.force = force; mType->summons.emplace_back(sb); } else { std::cout << "[Warning - Monsters::loadMonster] Missing summon name. " << file << std::endl; } } } if ((node = monsterNode.child("script"))) { for (auto eventNode : node.children()) { if ((attr = eventNode.attribute("name"))) { mType->scripts.emplace_back(attr.as_string()); } else { std::cout << "[Warning - Monsters::loadMonster] Missing name for script event. " << file << std::endl; } } } mType->summons.shrink_to_fit(); mType->lootItems.shrink_to_fit(); mType->attackSpells.shrink_to_fit(); mType->defenseSpells.shrink_to_fit(); mType->voiceVector.shrink_to_fit(); mType->scripts.shrink_to_fit(); return true; }
bool MoveEvent::configureEvent(xmlNodePtr p) { std::string str; int intValue; if(readXMLString(p, "event", str)){ if(asLowerCaseString(str) == "stepin"){ m_eventType = MOVE_EVENT_STEP_IN; } else if(asLowerCaseString(str) == "stepout"){ m_eventType = MOVE_EVENT_STEP_OUT; } else if(asLowerCaseString(str) == "equip"){ m_eventType = MOVE_EVENT_EQUIP; } else if(asLowerCaseString(str) == "deequip"){ m_eventType = MOVE_EVENT_DEEQUIP; } else if(asLowerCaseString(str) == "additem"){ m_eventType = MOVE_EVENT_ADD_ITEM; } else if(asLowerCaseString(str) == "removeitem"){ m_eventType = MOVE_EVENT_REMOVE_ITEM; } else{ std::cout << "Error: [MoveEvent::configureMoveEvent] No valid event name " << str << std::endl; return false; } if(m_eventType == MOVE_EVENT_EQUIP || m_eventType == MOVE_EVENT_DEEQUIP){ if(readXMLString(p, "slot", str)){ if(asLowerCaseString(str) == "head"){ slot = SLOT_HEAD; } else if(asLowerCaseString(str) == "necklace"){ slot = SLOT_NECKLACE; } else if(asLowerCaseString(str) == "backpack"){ slot = SLOT_BACKPACK; } else if(asLowerCaseString(str) == "armor"){ slot = SLOT_ARMOR; } else if(asLowerCaseString(str) == "right-hand"){ slot = SLOT_RIGHT; } else if(asLowerCaseString(str) == "left-hand"){ slot = SLOT_LEFT; } else if(asLowerCaseString(str) == "legs"){ slot = SLOT_LEGS; } else if(asLowerCaseString(str) == "feet"){ slot = SLOT_FEET; } else if(asLowerCaseString(str) == "ring"){ slot = SLOT_RING; } else if(asLowerCaseString(str) == "ammo"){ slot = SLOT_AMMO; } else{ std::cout << "Warning: [MoveEvent::configureMoveEvent] " << "Unknown slot type " << str << std::endl; } } wieldInfo = 0; if(readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)){ reqLevel = intValue; if(reqLevel > 0){ wieldInfo |= WIELDINFO_LEVEL; } } if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue)){ reqMagLevel = intValue; if(reqMagLevel > 0){ wieldInfo |= WIELDINFO_MAGLV; } } if(readXMLInteger(p, "prem", intValue) || readXMLInteger(p, "premium", intValue)){ premium = (intValue != 0); if(premium){ wieldInfo |= WIELDINFO_PREMIUM; } } //Gather vocation information typedef std::list<std::string> STRING_LIST; STRING_LIST vocStringList; xmlNodePtr vocationNode = p->children; while(vocationNode){ if(xmlStrcmp(vocationNode->name,(const xmlChar*)"vocation") == 0){ if(readXMLString(vocationNode, "name", str)){ int32_t vocationId = g_vocations.getVocationId(str); if(vocationId != -1){ vocEquipMap[vocationId] = true; intValue = 1; readXMLInteger(vocationNode, "showInDescription", intValue); if(intValue != 0){ toLowerCaseString(str); vocStringList.push_back(str); } } } } vocationNode = vocationNode->next; } if(!vocStringList.empty()){ for(STRING_LIST::iterator it = vocStringList.begin(); it != vocStringList.end(); ++it){ if(*it != vocStringList.front()){ if(*it != vocStringList.back()){ vocationString += ", "; } else{ vocationString += " and "; } } vocationString += *it; vocationString += "s"; } wieldInfo |= WIELDINFO_VOCREQ; } } } else{ std::cout << "Error: [MoveEvent::configureMoveEvent] No event found." << std::endl; return false; } return true; }
void Actor::updateNameDescription() { strDescription = cType.nameDescription(); toLowerCaseString(strDescription); }