bool Monsters::loadLoot(xmlNodePtr node, LootBlock& lootBlock) { std::string strValue; if(readXMLString(node, "id", strValue) || readXMLString(node, "ids", strValue)) { IntegerVec idsVec; parseIntegerVec(strValue, idsVec); for(IntegerVec::iterator it = idsVec.begin(); it != idsVec.end(); ++it) { lootBlock.ids.push_back(*it); if(Item::items[(*it)].isContainer()) loadChildLoot(node, lootBlock); } } else if(readXMLString(node, "name", strValue) || readXMLString(node, "names", strValue)) { StringVec names = explodeString(strValue, ";"); for(StringVec::iterator it = names.begin(); it != names.end(); ++it) { uint16_t tmp = Item::items.getItemIdByName(strValue); if(!tmp) continue; lootBlock.ids.push_back(tmp); if(Item::items[tmp].isContainer()) loadChildLoot(node, lootBlock); } } if(lootBlock.ids.empty()) return false; int32_t intValue; if(readXMLInteger(node, "count", intValue) || readXMLInteger(node, "countmax", intValue)) lootBlock.count = intValue; else lootBlock.count = 1; if(readXMLInteger(node, "chance", intValue) || readXMLInteger(node, "chance1", intValue)) lootBlock.chance = std::min(MAX_LOOTCHANCE, intValue); else lootBlock.chance = MAX_LOOTCHANCE; if(readXMLInteger(node, "subtype", intValue) || readXMLInteger(node, "subType", intValue)) lootBlock.subType = intValue; if(readXMLInteger(node, "actionId", intValue) || readXMLInteger(node, "actionid", intValue) || readXMLInteger(node, "aid", intValue)) lootBlock.actionId = intValue; if(readXMLInteger(node, "uniqueId", intValue) || readXMLInteger(node, "uniqueid", intValue) || readXMLInteger(node, "uid", intValue)) lootBlock.uniqueId = intValue; if(readXMLString(node, "text", strValue)) lootBlock.text = strValue; return true; }
IntegerVec vectorAtoi(const StringVec& stringVector) { IntegerVec returnVector; for (const auto& string : stringVector) { returnVector.push_back(atoi(string.c_str())); } return returnVector; }
IntegerVec vectorAtoi(StringVec stringVector) { IntegerVec returnVector; for(StringVec::iterator it = stringVector.begin(); it != stringVector.end(); ++it) returnVector.push_back(atoi((*it).c_str())); return returnVector; }
IntegerVec vectorAtoi(const StringVec& stringVector) { IntegerVec returnVector; for (auto it = stringVector.begin(); it != stringVector.end(); ++it) { returnVector.push_back(atoi(it->c_str())); } return returnVector; }
bool EffectEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; int32_t intValue; std::string strValue; if(!readXMLInteger(eventNode, "id", intValue)) { if(!readXMLString(eventNode, "name", strValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] id (or name) tag missing for effect event." << std::endl; return false; } else m_effect = getMagicEffect(strValue); } else m_effect = (MagicEffect_t)intValue; if(!readXMLString(eventNode, "pos", strValue)) { if(!readXMLInteger(eventNode, "x", intValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] x tag missing for effect event." << std::endl; return false; } m_position.x = intValue; if(!readXMLInteger(eventNode, "y", intValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] y tag missing for effect event." << std::endl; return false; } m_position.y = intValue; if(!readXMLInteger(eventNode, "z", intValue)) { std::clog << "[Error - EffectEvent::configureRaidEvent] z tag missing for effect event." << std::endl; return false; } m_position.z = intValue; } else { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - EffectEvent::configureRaidEvent] Malformed pos tag for effect event." << std::endl; return false; } m_position = Position(posList[0], posList[1], posList[2]); } return true; }
IntegerVec vectorAtoi(StringVec stringVector) { IntegerVec returnVector; for(StringVec::iterator it = stringVector.begin(); it != stringVector.end(); ++it) { int32_t number = atoi((*it).c_str()); if(number || (*it) == "0") returnVector.push_back(number); } return returnVector; }
bool SingleSpawnEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; std::string strValue; if(!readXMLString(eventNode, "name", strValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] name tag missing for singlespawn event." << std::endl; return false; } m_monsterName = strValue; if(!readXMLString(eventNode, "pos", strValue)) { int32_t intValue; if(!readXMLInteger(eventNode, "x", intValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] x tag missing for singlespawn event." << std::endl; return false; } m_position.x = intValue; if(!readXMLInteger(eventNode, "y", intValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] y tag missing for singlespawn event." << std::endl; return false; } m_position.y = intValue; if(!readXMLInteger(eventNode, "z", intValue)) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] z tag missing for singlespawn event." << std::endl; return false; } m_position.z = intValue; } else { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - SingleSpawnEvent::configureRaidEvent] Malformed pos tag for singlespawn event." << std::endl; return false; } m_position = Position(posList[0], posList[1], posList[2]); } return true; }
bool parseIntegerVec(std::string str, IntegerVec& intVector) { StringVec strVector = explodeString(str, ";"); IntegerVec tmpIntVector; for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) { tmpIntVector = vectorAtoi(explodeString((*it), "-")); if(!tmpIntVector[0] && it->substr(0, 1) != "0") continue; intVector.push_back(tmpIntVector[0]); if(tmpIntVector.size() > 1) { while(tmpIntVector[0] < tmpIntVector[1]) intVector.push_back(++tmpIntVector[0]); } } return true; }
bool Mailbox::getDepotId(const std::string& townString, uint32_t& depotId) { Town* town = Towns::getInstance()->getTown(townString); if(!town) return false; std::string disabledTowns = g_config.getString(ConfigManager::MAILBOX_DISABLED_TOWNS); if(disabledTowns.size()) { IntegerVec tmpVec = vectorAtoi(explodeString(disabledTowns, ",")); if(tmpVec[0] != 0) { for(IntegerVec::iterator it = tmpVec.begin(); it != tmpVec.end(); ++it) { if(town->getID() == uint32_t(*it)) return false; } } } depotId = town->getID(); return true; }
bool parseVocationNode(xmlNodePtr vocationNode, VocationMap& vocationMap, StringVec& vocStringVec, std::string& errorStr) { if(xmlStrcmp(vocationNode->name,(const xmlChar*)"vocation")) return true; int32_t vocationId = -1; std::string strValue, tmpStrValue; if(readXMLString(vocationNode, "name", strValue)) { vocationId = Vocations::getInstance()->getVocationId(strValue); if(vocationId != -1) { vocationMap[vocationId] = true; int32_t promotedVocation = Vocations::getInstance()->getPromotedVocation(vocationId); if(promotedVocation != -1) vocationMap[promotedVocation] = true; } else { errorStr = "Wrong vocation name: " + strValue; return false; } } else if(readXMLString(vocationNode, "id", strValue)) { IntegerVec intVector; if(!parseIntegerVec(strValue, intVector)) { errorStr = "Invalid vocation id - '" + strValue + "'"; return false; } size_t size = intVector.size(); for(size_t i = 0; i < size; ++i) { Vocation* vocation = Vocations::getInstance()->getVocation(intVector[i]); if(vocation && vocation->getName() != "") { vocationId = vocation->getId(); strValue = vocation->getName(); vocationMap[vocationId] = true; int32_t promotedVocation = Vocations::getInstance()->getPromotedVocation(vocationId); if(promotedVocation != -1) vocationMap[promotedVocation] = true; } else { std::stringstream ss; ss << "Wrong vocation id: " << intVector[i]; errorStr = ss.str(); return false; } } } if(vocationId != -1 && (!readXMLString(vocationNode, "showInDescription", tmpStrValue) || booleanString(tmpStrValue))) vocStringVec.push_back(asLowerCaseString(strValue)); return true; }
void otserv( #if !defined(WINDOWS) || defined(__CONSOLE__) StringVec args, #endif ServiceManager* services) { srand((uint32_t)OTSYS_TIME()); #if defined(WINDOWS) #if defined(__CONSOLE__) SetConsoleTitle(STATUS_SERVER_NAME); #else GUI::getInstance()->m_connections = false; #endif #endif g_game.setGameState(GAME_STATE_STARTUP); std::cout << STATUS_SERVER_NAME << ", version " << STATUS_SERVER_VERSION << " (" << STATUS_SERVER_CODENAME << ")" << std::endl; std::cout << "Compiled with " << BOOST_COMPILER << " at " << __DATE__ << ", " << __TIME__ << "." << std::endl; std::cout << "A server developed by Gesior." << std::endl; std::stringstream ss; #ifdef __DEBUG__ ss << " GLOBAL"; #endif #ifdef __DEBUG_MOVESYS__ ss << " MOVESYS"; #endif #ifdef __DEBUG_CHAT__ ss << " CHAT"; #endif #ifdef __DEBUG_EXCEPTION_REPORT__ ss << " EXCEPTION-REPORT"; #endif #ifdef __DEBUG_HOUSES__ ss << " HOUSES"; #endif #ifdef __DEBUG_LUASCRIPTS__ ss << " LUA-SCRIPTS"; #endif #ifdef __DEBUG_MAILBOX__ ss << " MAILBOX"; #endif #ifdef __DEBUG_NET__ ss << " NET"; #endif #ifdef __DEBUG_NET_DETAIL__ ss << " NET-DETAIL"; #endif #ifdef __DEBUG_RAID__ ss << " RAIDS"; #endif #ifdef __DEBUG_SCHEDULER__ ss << " SCHEDULER"; #endif #ifdef __DEBUG_SPAWN__ ss << " SPAWNS"; #endif #ifdef __SQL_QUERY_DEBUG__ ss << " SQL-QUERIES"; #endif std::string debug = ss.str(); if(!debug.empty()) { std::cout << ">> Debugging:"; #if defined(WINDOWS) && !defined(__CONSOLE__) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Displaying debugged components"); #endif std::cout << debug << "." << std::endl; } std::cout << ">> Loading config (" << g_config.getString(ConfigManager::CONFIG_FILE) << ")" << std::endl; #if defined(WINDOWS) && !defined(__CONSOLE__) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Loading config"); #endif if(!g_config.load()) startupErrorMessage("Unable to load " + g_config.getString(ConfigManager::CONFIG_FILE) + "!"); Logger::getInstance()->open(); IntegerVec cores = vectorAtoi(explodeString(g_config.getString(ConfigManager::CORES_USED), ",")); if(cores[0] != -1) { #ifdef WINDOWS int32_t mask = 0; for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) mask += 1 << (*it); SetProcessAffinityMask(GetCurrentProcess(), mask); } std::stringstream mutexName; mutexName << "forgottenserver_" << g_config.getNumber(ConfigManager::WORLD_ID); CreateMutex(NULL, FALSE, mutexName.str().c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) startupErrorMessage("Another instance of The Forgotten Server is already running with the same worldId.\nIf you want to run multiple servers, please change the worldId in configuration file."); std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY)); if(defaultPriority == "realtime") SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); else if(defaultPriority == "high") SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); else if(defaultPriority == "higher") SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); #else cpu_set_t mask; CPU_ZERO(&mask); for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) CPU_SET((*it), &mask); sched_setaffinity(getpid(), (int32_t)sizeof(mask), &mask); }
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 AreaSpawnEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; int32_t intValue; std::string strValue; if(readXMLInteger(eventNode, "radius", intValue)) { int32_t radius = intValue; Position centerPos; if(readXMLString(eventNode, "centerPosition", strValue) || readXMLString(eventNode, "centerpos", strValue)) { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] Malformed centerPosition tag for areaspawn event." << std::endl; return false; } centerPos = Position(posList[0], posList[1], posList[2]); } else { if(!readXMLInteger(eventNode, "centerx", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] centerx tag missing for areaspawn event." << std::endl; return false; } centerPos.x = intValue; if(!readXMLInteger(eventNode, "centery", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] centery tag missing for areaspawn event." << std::endl; return false; } centerPos.y = intValue; if(!readXMLInteger(eventNode, "centerz", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] centerz tag missing for areaspawn event." << std::endl; return false; } centerPos.z = intValue; } m_fromPos.x = centerPos.x - radius; m_fromPos.y = centerPos.y - radius; m_fromPos.z = centerPos.z; m_toPos.x = centerPos.x + radius; m_toPos.y = centerPos.y + radius; m_toPos.z = centerPos.z; } else { if(readXMLString(eventNode, "fromPosition", strValue) || readXMLString(eventNode, "frompos", strValue)) { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] Malformed fromPosition tag for areaspawn event." << std::endl; return false; } m_fromPos = Position(posList[0], posList[1], posList[2]); } else { if(!readXMLInteger(eventNode, "fromx", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] fromx tag missing for areaspawn event." << std::endl; return false; } m_fromPos.x = intValue; if(!readXMLInteger(eventNode, "fromy", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] fromy tag missing for areaspawn event." << std::endl; return false; } m_fromPos.y = intValue; if(!readXMLInteger(eventNode, "fromz", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] fromz tag missing for areaspawn event." << std::endl; return false; } m_fromPos.z = intValue; } if(readXMLString(eventNode, "toPosition", strValue) || readXMLString(eventNode, "topos", strValue)) { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] Malformed toPosition tag for areaspawn event." << std::endl; return false; } m_toPos = Position(posList[0], posList[1], posList[2]); } else { if(!readXMLInteger(eventNode, "tox", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] tox tag missing for areaspawn event." << std::endl; return false; } m_toPos.x = intValue; if(!readXMLInteger(eventNode, "toy", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] toy tag missing for areaspawn event." << std::endl; return false; } m_toPos.y = intValue; if(!readXMLInteger(eventNode, "toz", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] toz tag missing for areaspawn event." << std::endl; return false; } m_toPos.z = intValue; } } xmlNodePtr monsterNode = eventNode->children; while(monsterNode) { if(!xmlStrcmp(monsterNode->name, (const xmlChar*)"monster")) { if(!readXMLString(monsterNode, "name", strValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] name tag missing for monster node." << std::endl; return false; } std::string name = strValue; int32_t min = 0, max = 0; if(readXMLInteger(monsterNode, "min", intValue) || readXMLInteger(monsterNode, "minamount", intValue)) min = intValue; if(readXMLInteger(monsterNode, "max", intValue) || readXMLInteger(monsterNode, "maxamount", intValue)) max = intValue; if(!min && !max) { if(!readXMLInteger(monsterNode, "amount", intValue)) { std::clog << "[Error - AreaSpawnEvent::configureRaidEvent] amount tag missing for monster node." << std::endl; return false; } min = max = intValue; } addMonster(name, min, max); } monsterNode = monsterNode->next; } return true; }
bool ItemSpawnEvent::configureRaidEvent(xmlNodePtr eventNode) { if(!RaidEvent::configureRaidEvent(eventNode)) return false; int32_t intValue; std::string strValue; if(!readXMLInteger(eventNode, "id", intValue)) { if(!readXMLString(eventNode, "name", strValue)) { std::clog << "[Error - ItemSpawnEvent::configureRaidEvent] id (or name) tag missing for itemspawn event." << std::endl; return false; } else m_itemId = Item::items.getItemIdByName(strValue); } else m_itemId = intValue; if(readXMLInteger(eventNode, "chance", intValue)) m_chance = intValue; if(readXMLInteger(eventNode, "subType", intValue)) m_subType = intValue; if(!readXMLString(eventNode, "pos", strValue)) { if(!readXMLInteger(eventNode, "x", intValue)) { std::clog << "[Error - ItemSpawnEvent::configureRaidEvent] x tag missing for itemspawn event." << std::endl; return false; } m_position.x = intValue; if(!readXMLInteger(eventNode, "y", intValue)) { std::clog << "[Error - ItemSpawnEvent::configureRaidEvent] y tag missing for itemspawn event." << std::endl; return false; } m_position.y = intValue; if(!readXMLInteger(eventNode, "z", intValue)) { std::clog << "[Error - ItemSpawnEvent::configureRaidEvent] z tag missing for itemspawn event." << std::endl; return false; } m_position.z = intValue; } else { IntegerVec posList = vectorAtoi(explodeString(strValue, ";")); if(posList.size() < 3) { std::clog << "[Error - ItemSpawnEvent::configureRaidEvent] Malformed pos tag for itemspawn event." << std::endl; return false; } m_position = Position(posList[0], posList[1], posList[2]); } return true; }
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) { if( #if defined(WINDOWS) && !defined(_CONSOLE) !GUI::getInstance()->m_connections || #endif g_game.getGameState() == GAMESTATE_SHUTDOWN) { getConnection()->close(); return; } uint32_t clientIp = getConnection()->getIP(); msg.get<uint16_t>(); uint16_t version = msg.get<uint16_t>(); msg.skip(12); #ifdef _MULTIPLATFORM77 if(!RSA_decrypt(msg)) { getConnection()->close(); return; } uint32_t key[4] = {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()}; enableXTEAEncryption(); setXTEAKey(key); #endif uint32_t name = msg.get<uint32_t>(); std::string password = msg.getString(); if(!name) { if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER)) { disconnectClient(0x0A, "Invalid account name."); return; } name = 1; password = "******"; } if(!g_config.getBool(ConfigManager::MANUAL_ADVANCED_CONFIG)) { if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { disconnectClient(0x0A, CLIENT_VERSION_STRING); return; } else if(version < g_config.getNumber(ConfigManager::VERSION_MIN) || version > g_config.getNumber(ConfigManager::VERSION_MAX)) { disconnectClient(0x0A, g_config.getString(ConfigManager::VERSION_MSG).c_str()); return; } } #ifdef CLIENT_VERSION_DATA if(sprSignature != CLIENT_VERSION_SPR) { disconnectClient(0x0A, CLIENT_VERSION_DATA); return; } if(datSignature != CLIENT_VERSION_DAT) { disconnectClient(0x0A, CLIENT_VERSION_DATA); return; } if(picSignature != CLIENT_VERSION_PIC) { disconnectClient(0x0A, CLIENT_VERSION_DATA); return; } #endif if(g_game.getGameState() < GAMESTATE_NORMAL) { disconnectClient(0x0A, "Server is just starting up, please wait."); return; } if(g_game.getGameState() == GAMESTATE_MAINTAIN) { disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while."); return; } if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId)) { disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later."); return; } if(IOBan::getInstance()->isIpBanished(clientIp)) { disconnectClient(0x0A, "Your IP is banished!"); return; } uint32_t id = 1; if(!IOLoginData::getInstance()->getAccountId(name, id)) { ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false); disconnectClient(0x0A, "Invalid account id."); return; } Account account = IOLoginData::getInstance()->loadAccount(id); if(!encryptTest(account.salt + password, account.password)) { ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false); disconnectClient(0x0A, "Invalid password."); return; } Ban ban; ban.value = account.number; ban.type = BAN_ACCOUNT; if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account.number, PlayerFlag_CannotBeBanned)) { bool deletion = ban.expires < 0; std::string name_ = "Automatic "; if(!ban.adminId) name_ += (deletion ? "deletion" : "banishment"); else IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true); std::stringstream ss; ss << "Your account has been " << (deletion ? "deleted" : "banished") << " at:\n" << formatDateEx(ban.added, "%d %b %Y").c_str() << " by: " << name_.c_str() << "\nReason:\n" << getReason(ban.reason).c_str() << ".\nComment:\n" << ban.comment.c_str() << ".\nYour " << (deletion ? "account won't be undeleted" : "banishment will be lifted at:\n") << (deletion ? "" : formatDateEx(ban.expires).c_str()); disconnectClient(0x0A, ss.str().c_str()); return; } // remove premium days #ifndef __LOGIN_SERVER__ IOLoginData::getInstance()->removePremium(account); if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size()) { disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the " + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str()); return; } #else Characters charList; for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it) { if(version >= it->second.server->getVersionMin() && version <= it->second.server->getVersionMax()) charList[it->first] = it->second; } IOLoginData::getInstance()->removePremium(account); if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size()) { disconnectClient(0x0A, std::string("This account does not contain any character on this client yet.\nCreate a new character on the " + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str()); return; } #endif ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true); if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false)) { TRACK_MESSAGE(output); output->put<char>(0x14); uint32_t serverIp = serverIps.front().first; for(std::list<std::pair<uint32_t, uint32_t> >::iterator it = serverIps.begin(); it != serverIps.end(); ++it) { if((it->first & it->second) != (clientIp & it->second)) continue; serverIp = it->first; break; } char motd[1300]; sprintf(motd, "%d\n%s", g_game.getMotdId(), g_config.getString(ConfigManager::MOTD).c_str()); output->putString(motd); //Add char list output->put<char>(0x64); if(g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && account.number != 1) { output->put<char>(account.charList.size() + 1); output->putString("Account Manager"); output->putString(g_config.getString(ConfigManager::SERVER_NAME)); output->put<uint32_t>(serverIp); output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT)); } else output->put<char>((uint8_t)account.charList.size()); #ifndef __LOGIN_SERVER__ for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it) { output->putString((*it)); if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) && !g_config.getBool(ConfigManager::CHARLIST_INFO)) { if(g_game.getPlayerByName((*it))) output->putString("Online"); else output->putString("Offline"); } else if(g_config.getBool(ConfigManager::CHARLIST_INFO)) { std::stringstream str; Player *player = g_game.getPlayerByName((*it)); bool v = false; if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST)) { if(player) str << "On"; else str << "Off"; str << "/"; } if(!player) { v = true; player = g_game.getPlayerByNameEx((*it)); } str << player->getLevel(); str << "/"; str << player->getVocation()->getName(); output->putString(str.str()); if(v) delete player; } else output->putString(g_config.getString(ConfigManager::SERVER_NAME)); output->put<uint32_t>(serverIp); output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT)); } #else for(Characters::iterator it = charList.begin(); it != charList.end(); ++it) { output->putString(it->second.name); if(!g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) || it->second.status < 0) output->putString(it->second.server->getName()); else if(it->second.status) output->putString("Online"); else output->putString("Offline"); output->put<uint32_t>(it->second.server->getAddress()); IntegerVec games = it->second.server->getPorts(); output->put<uint16_t>(games[random_range(0, games.size() - 1)]); } #endif //Add premium days if(g_config.getBool(ConfigManager::FREE_PREMIUM)) output->put<uint16_t>(GRATIS_PREMIUM); else output->put<uint16_t>(account.premiumDays); OutputMessagePool::getInstance()->send(output); } getConnection()->close(); }
bool Spawns::parseSpawnNode(xmlNodePtr p, bool checkDuplicate) { if(xmlStrcmp(p->name, (const xmlChar*)"spawn")) return false; int32_t intValue; std::string strValue; Position centerPos; if(!readXMLString(p, "centerpos", strValue)) { if(!readXMLInteger(p, "centerx", intValue)) return false; centerPos.x = intValue; if(!readXMLInteger(p, "centery", intValue)) return false; centerPos.y = intValue; if(!readXMLInteger(p, "centerz", intValue)) return false; centerPos.z = intValue; } else { IntegerVec posVec = vectorAtoi(explodeString(",", strValue)); if(posVec.size() < 3) return false; centerPos = Position(posVec[0], posVec[1], posVec[2]); } if(!readXMLInteger(p, "radius", intValue)) return false; int32_t radius = intValue; Spawn* spawn = new Spawn(centerPos, radius); if(checkDuplicate) { for(SpawnList::iterator it = spawnList.begin(); it != spawnList.end(); ++it) { if((*it)->getPosition() == centerPos) delete *it; } } spawnList.push_back(spawn); xmlNodePtr tmpNode = p->children; while(tmpNode) { if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"monster")) { std::string name; if(!readXMLString(tmpNode, "name", strValue)) { tmpNode = tmpNode->next; continue; } name = strValue; int32_t interval = MINSPAWN_INTERVAL / 1000; if(readXMLInteger(tmpNode, "spawntime", intValue) || readXMLInteger(tmpNode, "interval", intValue)) { if(intValue <= interval) { std::cout << "[Warning - Spawns::loadFromXml] " << name << " " << centerPos << " spawntime cannot"; std::cout << " be less than " << interval << " seconds." << std::endl; tmpNode = tmpNode->next; continue; } interval = intValue; } interval *= 1000; Position placePos = centerPos; if(readXMLInteger(tmpNode, "x", intValue)) placePos.x += intValue; if(readXMLInteger(tmpNode, "y", intValue)) placePos.y += intValue; if(readXMLInteger(tmpNode, "z", intValue)) placePos.z /*+*/= intValue; Direction direction = NORTH; if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST) direction = (Direction)intValue; spawn->addMonster(name, placePos, direction, interval); } else if(!xmlStrcmp(tmpNode->name, (const xmlChar*)"npc")) { std::string name; if(!readXMLString(tmpNode, "name", strValue)) { tmpNode = tmpNode->next; continue; } name = strValue; Position placePos = centerPos; if(readXMLInteger(tmpNode, "x", intValue)) placePos.x += intValue; if(readXMLInteger(tmpNode, "y", intValue)) placePos.y += intValue; if(readXMLInteger(tmpNode, "z", intValue)) placePos.z /*+*/= intValue; Direction direction = NORTH; if(readXMLInteger(tmpNode, "direction", intValue) && direction >= EAST && direction <= WEST) direction = (Direction)intValue; Npc* npc = Npc::createNpc(name); if(!npc) { tmpNode = tmpNode->next; continue; } npc->setMasterPos(placePos, radius); npc->setDirection(direction); npcList.push_back(npc); } tmpNode = tmpNode->next; } return true; }
void otserv( #if !defined(WINDOWS) || defined(_CONSOLE) StringVec, #endif ServiceManager* services) { std::srand((uint32_t)OTSYS_TIME()); #if defined(WINDOWS) #if defined(_CONSOLE) SetConsoleTitle(SOFTWARE_NAME); #else GUI::getInstance()->m_connections = false; #endif #endif g_game.setGameState(GAMESTATE_STARTUP); #if !defined(WINDOWS) && !defined(__ROOT_PERMISSION__) if(!getuid() || !geteuid()) { std::clog << "> WARNING: " "The " << SOFTWARE_NAME << " has been executed as super user! It is " << "recommended to run as a normal user." << std::endl << "Continue? (y/N)" << std::endl; char buffer = OTSYS_getch(); if(buffer != 121 && buffer != 89) startupErrorMessage("Aborted."); } #endif std::clog << "The " << SOFTWARE_NAME << " Version: (" << SOFTWARE_VERSION << "." << MINOR_VERSION << PATCH_VERSION << " - " << REVISION_VERSION << ") - Codename: (" << SOFTWARE_CODENAME << ")" << std::endl << "Compilied with " << BOOST_COMPILER << " for arch " #if defined(__amd64__) || defined(_M_X64) "64 Bits" #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) "32 Bits" #else "unk" #endif " at " << __DATE__ << " " << __TIME__ << std::endl << std::endl << "A server developed by: "SOFTWARE_DEVELOPERS"." << std::endl << "Visit our forums for updates, support, and resources:" << std::endl << ""FORUMS"" << std::endl; std::stringstream ss; #ifdef __DEBUG__ ss << " GLOBAL"; #endif #ifdef __DEBUG_MOVESYS__ ss << " MOVESYS"; #endif #ifdef __DEBUG_CHAT__ ss << " CHAT"; #endif #ifdef __DEBUG_HOUSES__ ss << " HOUSES"; #endif #ifdef __DEBUG_LUASCRIPTS__ ss << " LUA-SCRIPTS"; #endif #ifdef __DEBUG_MAILBOX__ ss << " MAILBOX"; #endif #ifdef __DEBUG_NET__ ss << " NET"; #endif #ifdef __DEBUG_NET_DETAIL__ ss << " NET-DETAIL"; #endif #ifdef __DEBUG_RAID__ ss << " RAIDS"; #endif #ifdef __DEBUG_SCHEDULER__ ss << " SCHEDULER"; #endif #ifdef __DEBUG_SPAWN__ ss << " SPAWNS"; #endif #ifdef __SQL_QUERY_DEBUG__ ss << " SQL-QUERIES"; #endif std::string debug = ss.str(); if(!debug.empty()) { std::clog << ">> Debugging:"; #if defined(WINDOWS) && !defined(_CONSOLE) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Debugging:"); #endif std::clog << debug << "." << std::endl; } std::clog << std::endl; std::clog << ">> Loading config (" << g_config.getString(ConfigManager::CONFIG_FILE) << ")" << std::endl; #if defined(WINDOWS) && !defined(_CONSOLE) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Loading config"); #endif if(!g_config.load()) startupErrorMessage("Unable to load " + g_config.getString(ConfigManager::CONFIG_FILE) + "!"); #ifndef WINDOWS if(g_config.getBool(ConfigManager::DAEMONIZE)) { std::clog << "> Daemonization... "; if(fork()) { std::clog << "succeed, bye!" << std::endl; exit(0); } else std::clog << "failed, continuing." << std::endl; } #endif // silently append trailing slash std::string path = g_config.getString(ConfigManager::DATA_DIRECTORY); g_config.setString(ConfigManager::DATA_DIRECTORY, path.erase(path.find_last_not_of("/") + 1) + "/"); path = g_config.getString(ConfigManager::LOGS_DIRECTORY); g_config.setString(ConfigManager::LOGS_DIRECTORY, path.erase(path.find_last_not_of("/") + 1) + "/"); std::clog << ">> Opening logs" << std::endl; #if defined(WINDOWS) && !defined(_CONSOLE) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Opening logs"); #endif Logger::getInstance()->open(); IntegerVec cores = vectorAtoi(explodeString(g_config.getString(ConfigManager::CORES_USED), ",")); if(cores[0] != -1) { #ifdef WINDOWS int32_t mask = 0; for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) mask += 1 << (*it); SetProcessAffinityMask(GetCurrentProcess(), mask); } std::stringstream mutexName; mutexName << "otxserver_" << g_config.getNumber(ConfigManager::WORLD_ID); CreateMutex(NULL, FALSE, mutexName.str().c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) startupErrorMessage("Another instance of The OTX Server is already running with the same worldId.\nIf you want to run multiple servers, please change the worldId in configuration file."); std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY)); if(defaultPriority == "realtime" || defaultPriority == "real") SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); else if(defaultPriority == "high" || defaultPriority == "regular") SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); else if(defaultPriority == "higher" || defaultPriority == "above" || defaultPriority == "normal") SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); #else #ifndef __APPLE__ cpu_set_t mask; CPU_ZERO(&mask); for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) CPU_SET((*it), &mask); sched_setaffinity(getpid(), (int32_t)sizeof(mask), &mask); }
void otserv(StringVec, ServiceManager* services) { srand((uint32_t)OTSYS_TIME()); #if defined(WINDOWS) SetConsoleTitle(SOFTWARE_NAME); #endif g_game.setGameState(GAMESTATE_STARTUP); #if !defined(WINDOWS) && !defined(__ROOT_PERMISSION__) if(!getuid() || !geteuid()) { std::clog << "> WARNING: " << SOFTWARE_NAME << " has been executed as super user! It is " << "recommended to run as a normal user." << std::endl << "Continue? (y/N)" << std::endl; char buffer = getch(); if(buffer != 121 && buffer != 89) startupErrorMessage("Aborted."); } #endif std::clog << SOFTWARE_NAME << " " << SOFTWARE_VERSION << std::endl << std::endl; std::stringstream ss; #ifdef __DEBUG__ ss << " GLOBAL"; #endif #ifdef __DEBUG_MOVESYS__ ss << " MOVESYS"; #endif #ifdef __DEBUG_CHAT__ ss << " CHAT"; #endif #ifdef __DEBUG_EXCEPTION_REPORT__ ss << " EXCEPTION-REPORT"; #endif #ifdef __DEBUG_HOUSES__ ss << " HOUSES"; #endif #ifdef __DEBUG_LUASCRIPTS__ ss << " LUA-SCRIPTS"; #endif #ifdef __DEBUG_MAILBOX__ ss << " MAILBOX"; #endif #ifdef __DEBUG_NET__ ss << " NET"; #endif #ifdef __DEBUG_NET_DETAIL__ ss << " NET-DETAIL"; #endif #ifdef __DEBUG_RAID__ ss << " RAIDS"; #endif #ifdef __DEBUG_SCHEDULER__ ss << " SCHEDULER"; #endif #ifdef __DEBUG_SPAWN__ ss << " SPAWNS"; #endif #ifdef __SQL_QUERY_DEBUG__ ss << " SQL-QUERIES"; #endif std::string debug = ss.str(); if(!debug.empty()) std::clog << ">> Debugging:" << debug << "." << std::endl; std::clog << ">> Loading config (" << g_config.getString(ConfigManager::CONFIG_FILE) << ")" << std::endl; if(!g_config.load()) startupErrorMessage("Unable to load " + g_config.getString(ConfigManager::CONFIG_FILE) + "!"); // silently append trailing slash std::string path = g_config.getString(ConfigManager::DATA_DIRECTORY); g_config.setString(ConfigManager::DATA_DIRECTORY, path.erase(path.find_last_not_of("/") + 1) + "/"); path = g_config.getString(ConfigManager::LOGS_DIRECTORY); g_config.setString(ConfigManager::LOGS_DIRECTORY, path.erase(path.find_last_not_of("/") + 1) + "/"); std::clog << ">> Opening logs" << std::endl; Logger::getInstance()->open(); IntegerVec cores = vectorAtoi(explodeString(g_config.getString(ConfigManager::CORES_USED), ",")); if(cores[0] != -1) { #ifdef WINDOWS int32_t mask = 0; for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) mask += 1 << (*it); SetProcessAffinityMask(GetCurrentProcess(), mask); } std::stringstream mutexName; mutexName << "forgottenserver_" << g_config.getNumber(ConfigManager::WORLD_ID); CreateMutex(NULL, FALSE, mutexName.str().c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) startupErrorMessage("Another instance of The Forgotten Server is already running with the same worldId.\nIf you want to run multiple servers, please change the worldId in configuration file."); std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY)); if(defaultPriority == "realtime") SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); else if(defaultPriority == "high") SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); else if(defaultPriority == "higher") SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); #else #ifndef MACOS cpu_set_t mask; CPU_ZERO(&mask); for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) CPU_SET((*it), &mask); sched_setaffinity(getpid(), (int32_t)sizeof(mask), &mask); }