void MonsterBase::cleanAllMonster() { Monsters * monsters = Monsters::getInstance(); for(auto x = monsters->getMonsterVector().begin(); x != monsters->getMonsterVector().end(); x++) { (*x)->monsterDie(); } }
void Commands::reloadInfo(Player* player, const std::string& cmd, const std::string& param) { std::string tmpParam = asLowerCaseString(param); if (tmpParam == "action" || tmpParam == "actions") { g_actions->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded actions."); } else if (tmpParam == "config" || tmpParam == "configuration") { g_config.reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded config."); } else if (tmpParam == "command" || tmpParam == "commands") { reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded commands."); } else if (tmpParam == "creaturescript" || tmpParam == "creaturescripts") { g_creatureEvents->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded creature scripts."); } else if (tmpParam == "monster" || tmpParam == "monsters") { g_monsters.reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded monsters."); } else if (tmpParam == "move" || tmpParam == "movement" || tmpParam == "movements" || tmpParam == "moveevents" || tmpParam == "moveevent") { g_moveEvents->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded movements."); } else if (tmpParam == "npc" || tmpParam == "npcs") { g_npcs.reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded npcs."); } else if (tmpParam == "raid" || tmpParam == "raids") { Raids::getInstance()->reload(); Raids::getInstance()->startup(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded raids."); } else if (tmpParam == "spell" || tmpParam == "spells") { g_spells->reload(); g_monsters.reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded spells."); } else if (tmpParam == "talk" || tmpParam == "talkaction" || tmpParam == "talkactions") { g_talkActions->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded talk actions."); } else if (tmpParam == "items") { Item::items.reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded items."); } else if (tmpParam == "weapon" || tmpParam == "weapons") { g_weapons->reload(); g_weapons->loadDefaults(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded weapons."); } else if (tmpParam == "quest" || tmpParam == "quests") { Quests::getInstance()->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded quests."); } else if (tmpParam == "mount" || tmpParam == "mounts") { Mounts::getInstance()->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded mounts."); } else if (tmpParam == "globalevents" || tmpParam == "globalevent") { g_globalEvents->reload(); player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded globalevents."); } else { player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reload type not found."); } }
Monster* Monster::createMonster(const std::string& name) { unsigned long id = g_monsters.getIdByName(name); if(!id){ return NULL; } MonsterType* mtype = g_monsters.getMonsterType(id); if(!mtype) return NULL; Monster* new_monster = new Monster(mtype); return new_monster; }
static void init_game(int level) { int i = 0; monsters.clear(); for (i=0; i<level; i++) { Object m; m.x = rnd(1, 10); m.y = rnd(1, 10); m.life = 1; m.face = '@'; m.score = 10; monsters.push_back(Monsters::value_type(m)); } }
bool Spawn::addMonster(const std::string& _name, const Position& _pos, Direction _dir, uint32_t _interval) { if(!g_game.getTile(_pos)) { std::cout << "[Spawn::addMonster] NULL tile at spawn position (" << _pos << ")" << std::endl; return false; } MonsterType* mType = g_monsters.getMonsterType(_name); if(!mType) { std::cout << "[Spawn::addMonster] Cannot find \"" << _name << "\"" << std::endl; return false; } if(_interval < interval) interval = _interval; spawnBlock_t sb; sb.mType = mType; sb.pos = _pos; sb.direction = _dir; sb.interval = _interval; sb.lastSpawn = 0; uint32_t spawnId = (int32_t)spawnMap.size() + 1; spawnMap[spawnId] = sb; return true; }
static int monsters_round() { int ret = 0; int yoffset = 0; int xoffset = 0; for (unsigned i=0; i<monsters.size(); i++) { ret++; Object *m = &monsters[i]; mvwaddch(win_disp->win, m->y, m->x, ' '); yoffset = me.y - m->y; xoffset = me.x - m->x; if (abs(yoffset) > abs(xoffset)) { if (yoffset > 0) { m->y++; } else { m->y--; } } else { if (xoffset > 0) { m->x++; } else { m->x--; } } if (m->y == me.y && m->x == me.x) { me.life--; } mvwaddch(win_disp->win, m->y, m->x, m->face); wrefresh(win_disp->win); usleep(1000*200); } return ret; }
Monster* Monster::createMonster(const std::string& name, std::string customName /* = ""*/) { MonsterType* mType = g_monsters.getMonsterType(name); if(!mType) return NULL; return createMonster(mType, customName); }
Monster* Monster::createMonster(const std::string& name) { MonsterType* mType = g_monsters.getMonsterType(name); if (!mType) { return nullptr; } return new Monster(mType); }
Monster* Monster::createMonster(const std::string& name) { MonsterType* mType = g_monsters.getMonsterType(name); if(!mType) return NULL; return createMonster(mType); }
Monster* Monster::createMonsterNick(const std::string& name, const std::string& nick) { MonsterType* mType = g_monsters.getMonsterType(name); if(!mType) return NULL; mType->name = nick; mType->realName = name; return createMonster(mType); }
static int fire_fly() { int hit = 0; int ret = 0; for (unsigned i=0; i<fires.size(); i++) { ret++; hit = 0; Object *f = &fires[i]; mvwaddch(win_disp->win, f->y, f->x, ' '); // erase old face f->x += f->xstep; f->y += f->ystep; if (f->x < 0 || f->x >= win_disp->locate.w || f->y < 0 || f->y >= win_disp->locate.h) { fires.erase(fires.begin() + i); break; } // hit test for (unsigned j=0; j<monsters.size(); j++) { Object *m = &monsters[j]; if (f->x == m->x && f->y == m->y) { m->life--; if (m->life <= 0) { hit = 1; monsters.erase(monsters.begin() + j); me.score += m->score; break; } } } if (hit) { continue; } mvwaddch(win_disp->win, f->y, f->x, f->face); draw_me(); wrefresh(win_disp->win); usleep(1000*100); } return ret; }
Monster* Monster::createMonster(const std::string& name) { MonsterType* mType = g_monsters.getMonsterType(name); if(!mType) return NULL; mType->name = name; mType->realName = name; //-- sistema de shiny respawn mType->codenome = ""; mType->exists = false; std::string findText[] = {"Shiny", "Elite", "Elder", "shiny", "elite", "elder"}; for(int i = 0; i < 6; i++){ if(mType->name.find(findText[i]) != std::string::npos){ mType->codenome = findText[i]; mType->exists = true; break; } } if (mType->exists) { mType->realName = mType->name; std::string newName = mType->name; std::string from = mType->codenome + " "; std::string to = ""; size_t start_pos = 0; while((start_pos = newName.find(from, start_pos)) != std::string::npos) { newName.replace(start_pos, from.length(), to); start_pos += to.length(); // Handles case where 'to' is a substring of 'from' } mType->name = newName; } return createMonster(mType); }
bool Spawn::addMonster(const std::string& name, const Position& pos, Direction dir, uint32_t interval) { MonsterType* mType = g_monsters.getMonsterType(name); if (!mType) { std::cout << "[Spawn::addMonster] Can not find " << name << std::endl; return false; } this->interval = std::min(this->interval, interval); spawnBlock_t sb; sb.mType = mType; sb.pos = pos; sb.direction = dir; sb.interval = interval; sb.lastSpawn = 0; uint32_t spawnId = spawnMap.size() + 1; spawnMap[spawnId] = sb; return true; }
static void draw() { unsigned i = 0; if (NULL == win_disp) { return; } wclear(win_disp->win); char msg[16] = {0}; sprintf(msg, "L%d R%d Score:%d", level, round, me.score); mvwaddstr(win_disp->win, 0, 1, msg); mvwaddch(win_disp->win, me.y, me.x, me.face); for (i=0; i<monsters.size(); i++) { Object *m = &monsters[i]; mvwaddch(win_disp->win, m->y, m->x, m->face); } for (i=0; i<fires.size(); i++) { Object *f = &fires[i]; mvwaddch(win_disp->win, f->y, f->x, f->face); } wrefresh(win_disp->win); }
static int do_round(char *key) { unsigned i = 0; int ret = 0; int len = strlen(key); for (i=0; i<monsters.size(); i++) { ret++; Object *m = &monsters[i]; m->score += len*10; } for (i=0; i<len; i++) { char cmd = key[i]; switch(cmd) { case 'w': if (me.y > 1) { me.y--; } break; case 'a': if (me.x > 1) { me.x--; } break; case 's': if (me.y < win_disp->locate.h) { me.y++; } break; case 'd': if (me.x < win_disp->locate.w) { me.x++; } break; case 'h': new_fire(-1, 0); break; case 'j': new_fire(0, 1); break; case 'k': new_fire(0, -1); break; case 'l': new_fire(1, 0); break; default: break; } ret = monsters_round(); draw(); fire_fly(); if (me.life <= 0) { gameover(); return -1; } if (ret <= 0) { while (fire_fly() > 0); break; } usleep(1000*500); } return ret; }
void Signals::sighupHandler() { //Dispatcher thread std::cout << "SIGHUP received, reloading config files..." << std::endl; g_actions->reload(); std::cout << "Reloaded actions." << std::endl; g_config.reload(); std::cout << "Reloaded config." << std::endl; g_game.reloadCommands(); std::cout << "Reloaded commands." << std::endl; g_creatureEvents->reload(); std::cout << "Reloaded creature scripts." << std::endl; g_moveEvents->reload(); std::cout << "Reloaded movements." << std::endl; Npcs::reload(); std::cout << "Reloaded npcs." << std::endl; g_game.raids.reload(); g_game.raids.startup(); std::cout << "Reloaded raids." << std::endl; g_spells->reload(); std::cout << "Reloaded monsters." << std::endl; g_monsters.reload(); std::cout << "Reloaded spells." << std::endl; g_talkActions->reload(); std::cout << "Reloaded talk actions." << std::endl; Item::items.reload(); std::cout << "Reloaded items." << std::endl; g_weapons->reload(); g_weapons->loadDefaults(); std::cout << "Reloaded weapons." << std::endl; g_game.quests.reload(); std::cout << "Reloaded quests." << std::endl; g_game.mounts.reload(); std::cout << "Reloaded mounts." << std::endl; g_globalEvents->reload(); std::cout << "Reloaded globalevents." << std::endl; g_events->load(); std::cout << "Reloaded events." << std::endl; g_chat->load(); std::cout << "Reloaded chatchannels." << std::endl; g_luaEnvironment.loadFile("data/global.lua"); std::cout << "Reloaded global.lua." << std::endl; lua_gc(g_luaEnvironment.getLuaState(), LUA_GCCOLLECT, 0); }
void mainLoader(int, char*[], ServiceManager* services) { //dispatcher thread g_game.setGameState(GAME_STATE_STARTUP); srand(static_cast<unsigned int>(OTSYS_TIME())); #ifdef _WIN32 SetConsoleTitle(STATUS_SERVER_NAME); #endif std::cout << "The " << STATUS_SERVER_NAME << " Version: (" << STATUS_SERVER_VERSION << "." << MINOR_VERSION << " . " << REVISION_VERSION << ") - Codename: ( " << SOFTWARE_CODENAME << " )" << std::endl; std::cout << "Compiled with: " << BOOST_COMPILER << std::endl; std::cout << "Compiled on " << __DATE__ << ' ' << __TIME__ << " for platform "; #if defined(__amd64__) || defined(_M_X64) std::cout << "x64" << std::endl; #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) std::cout << "x86" << std::endl; #elif defined(__arm__) std::cout << "ARM" << std::endl; #else std::cout << "unknown" << std::endl; #endif std::cout << std::endl; std::cout << "A server developed by " << STATUS_SERVER_DEVELOPERS << "." << std::endl; std::cout << "Visit our forum for updates, support, and resources: " << GIT_REPO <<"." << std::endl; std::cout << std::endl; // read global config std::cout << ">> Loading config" << std::endl; if (!g_config.load()) { startupErrorMessage("Unable to load config.lua!"); return; } #ifdef _WIN32 const std::string& defaultPriority = g_config.getString(ConfigManager::DEFAULT_PRIORITY); if (strcasecmp(defaultPriority.c_str(), "high") == 0) { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } else if (strcasecmp(defaultPriority.c_str(), "above-normal") == 0) { SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); } #endif //set RSA key const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"); const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"); g_RSA.setKey(p, q); std::cout << ">> Establishing database connection..." << std::flush; Database* db = Database::getInstance(); if (!db->connect()) { startupErrorMessage("Failed to connect to database."); return; } std::cout << " MySQL " << Database::getClientVersion() << std::endl; // run database manager std::cout << ">> Running database manager" << std::endl; if (!DatabaseManager::isDatabaseSetup()) { startupErrorMessage("The database you have specified in config.lua is empty, please import the schema.sql to your database."); return; } g_databaseTasks.start(); DatabaseManager::updateDatabase(); if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !DatabaseManager::optimizeTables()) { std::cout << "> No tables were optimized." << std::endl; } //load vocations std::cout << ">> Loading vocations" << std::endl; if (!g_vocations.loadFromXml()) { startupErrorMessage("Unable to load vocations!"); return; } // load item data std::cout << ">> Loading items" << std::endl; if (Item::items.loadFromOtb("data/items/items.otb") != ERROR_NONE) { startupErrorMessage("Unable to load items (OTB)!"); return; } if (!Item::items.loadFromXml()) { startupErrorMessage("Unable to load items (XML)!"); return; } std::cout << ">> Loading script systems" << std::endl; if (!ScriptingManager::getInstance()->loadScriptSystems()) { startupErrorMessage("Failed to load script systems"); return; } std::cout << ">> Loading monsters" << std::endl; if (!g_monsters.loadFromXml()) { startupErrorMessage("Unable to load monsters!"); return; } std::cout << ">> Loading outfits" << std::endl; Outfits* outfits = Outfits::getInstance(); if (!outfits->loadFromXml()) { startupErrorMessage("Unable to load outfits!"); return; } std::cout << ">> Checking world type... " << std::flush; std::string worldType = asLowerCaseString(g_config.getString(ConfigManager::WORLD_TYPE)); if (worldType == "pvp") { g_game.setWorldType(WORLD_TYPE_PVP); } else if (worldType == "no-pvp") { g_game.setWorldType(WORLD_TYPE_NO_PVP); } else if (worldType == "pvp-enforced") { g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED); } else { std::cout << std::endl; std::ostringstream ss; ss << "> ERROR: Unknown world type: " << g_config.getString(ConfigManager::WORLD_TYPE) << ", valid world types are: pvp, no-pvp and pvp-enforced."; startupErrorMessage(ss.str()); return; } std::cout << asUpperCaseString(worldType) << std::endl; std::cout << ">> Loading map" << std::endl; if (!g_game.loadMainMap(g_config.getString(ConfigManager::MAP_NAME))) { startupErrorMessage("Failed to load map"); return; } std::cout << ">> Initializing gamestate" << std::endl; g_game.setGameState(GAME_STATE_INIT); // Game client protocols services->add<ProtocolGame>(g_config.getNumber(ConfigManager::GAME_PORT)); services->add<ProtocolLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); // OT protocols services->add<ProtocolStatus>(g_config.getNumber(ConfigManager::STATUS_PORT)); // Legacy login protocol services->add<ProtocolOld>(g_config.getNumber(ConfigManager::LOGIN_PORT)); RentPeriod_t rentPeriod; std::string strRentPeriod = asLowerCaseString(g_config.getString(ConfigManager::HOUSE_RENT_PERIOD)); if (strRentPeriod == "yearly") { rentPeriod = RENTPERIOD_YEARLY; } else if (strRentPeriod == "weekly") { rentPeriod = RENTPERIOD_WEEKLY; } else if (strRentPeriod == "monthly") { rentPeriod = RENTPERIOD_MONTHLY; } else if (strRentPeriod == "daily") { rentPeriod = RENTPERIOD_DAILY; } else { rentPeriod = RENTPERIOD_NEVER; } g_game.map.houses.payHouses(rentPeriod); IOMarket::checkExpiredOffers(); IOMarket::getInstance()->updateStatistics(); std::cout << ">> Loaded all modules, server starting up..." << std::endl; #ifndef _WIN32 if (getuid() == 0 || geteuid() == 0) { std::cout << "> Warning: " << STATUS_SERVER_NAME << " has been executed as root user, please consider running it as a normal user." << std::endl; } #endif g_game.start(services); g_game.setGameState(GAME_STATE_NORMAL); g_loaderSignal.notify_all(); }
bool Monsters::deserializeSpell(xmlNodePtr node, spellBlock_t& sb, const std::string& description) { sb.range = sb.minCombatValue = sb.maxCombatValue = 0; sb.combatSpell = sb.isMelee = false; sb.chance = 100; sb.speed = 2000; std::string name, scriptName; bool isScripted = false; if(readXMLString(node, "script", scriptName)) isScripted = true; else if(!readXMLString(node, "name", name)) return false; int32_t intValue; std::string strValue; if(readXMLInteger(node, "speed", intValue) || readXMLInteger(node, "interval", intValue)) sb.speed = std::max(1, intValue); if(readXMLInteger(node, "chance", intValue)) { if(intValue < 0 || intValue > 100) intValue = 100; sb.chance = intValue; } if(readXMLInteger(node, "range", intValue)) { if(intValue < 0) intValue = 0; if(intValue > Map::maxViewportX * 2) intValue = Map::maxViewportX * 2; sb.range = intValue; } if(readXMLInteger(node, "min", intValue)) sb.minCombatValue = intValue; if(readXMLInteger(node, "max", intValue)) sb.maxCombatValue = intValue; //normalize values if(std::abs(sb.minCombatValue) > std::abs(sb.maxCombatValue)) std::swap(sb.minCombatValue, sb.maxCombatValue); if((sb.spell = g_spells->getSpellByName(name))) return true; CombatSpell* combatSpell = NULL; bool needTarget = false, needDirection = false; if(isScripted) { if(readXMLString(node, "direction", strValue)) needDirection = booleanString(strValue); if(readXMLString(node, "target", strValue)) needTarget = booleanString(strValue); combatSpell = new CombatSpell(NULL, needTarget, needDirection); if(!combatSpell->loadScript(getFilePath(FILE_TYPE_OTHER, g_spells->getScriptBaseName() + "/scripts/" + scriptName), true)) { delete combatSpell; return false; } if(!combatSpell->loadScriptCombat()) { delete combatSpell; return false; } combatSpell->getCombat()->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0); } else { Combat* combat = new Combat; sb.combatSpell = true; if(readXMLInteger(node, "length", intValue)) { int32_t length = intValue; if(length > 0) { int32_t spread = 3; //need direction spell if(readXMLInteger(node, "spread", intValue)) spread = std::max(0, intValue); CombatArea* area = new CombatArea(); area->setupArea(length, spread); combat->setArea(area); needDirection = true; } } if(readXMLInteger(node, "radius", intValue)) { int32_t radius = intValue; //target spell if(readXMLInteger(node, "target", intValue)) needTarget = (intValue != 0); CombatArea* area = new CombatArea(); area->setupArea(radius); combat->setArea(area); } std::string tmpName = asLowerCaseString(name); if(tmpName == "melee" || tmpName == "distance") { int32_t attack = 0, skill = 0; if(readXMLInteger(node, "attack", attack) && readXMLInteger(node, "skill", skill)) { sb.minCombatValue = 0; sb.maxCombatValue = -Weapons::getMaxMeleeDamage(skill, attack); } uint32_t tickInterval = 2000; ConditionType_t conditionType = CONDITION_NONE; if(readXMLInteger(node, "physical", intValue)) conditionType = CONDITION_PHYSICAL; else if(readXMLInteger(node, "fire", intValue)) { conditionType = CONDITION_FIRE; tickInterval = 9000; } else if(readXMLInteger(node, "energy", intValue)) { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if(readXMLInteger(node, "earth", intValue)) { conditionType = CONDITION_POISON; tickInterval = 5000; } else if(readXMLInteger(node, "freeze", intValue)) { conditionType = CONDITION_FREEZING; tickInterval = 8000; } else if(readXMLInteger(node, "dazzle", intValue)) { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if(readXMLInteger(node, "curse", intValue)) { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if(readXMLInteger(node, "drown", intValue)) { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if(readXMLInteger(node, "poison", intValue)) { conditionType = CONDITION_POISON; tickInterval = 5000; } uint32_t damage = std::abs(intValue); if(readXMLInteger(node, "tick", intValue) && intValue > 0) tickInterval = intValue; if(conditionType != CONDITION_NONE) { Condition* condition = getDamageCondition(conditionType, damage, damage, 0, tickInterval); if(condition) combat->setCondition(condition); } sb.isMelee = true; sb.range = 1; combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBATPARAM_BLOCKEDBYSHIELD, 1); combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1); } else if(tmpName == "physical") { combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBATPARAM_BLOCKEDBYARMOR, 1); } else if(tmpName == "drown") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DROWNDAMAGE); else if(tmpName == "fire") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_FIREDAMAGE); else if(tmpName == "energy") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ENERGYDAMAGE); else if(tmpName == "poison" || tmpName == "earth") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_EARTHDAMAGE); else if(tmpName == "ice") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_ICEDAMAGE); else if(tmpName == "holy") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HOLYDAMAGE); else if(tmpName == "death") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_DEATHDAMAGE); else if(tmpName == "lifedrain") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_LIFEDRAIN); else if(tmpName == "manadrain") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_MANADRAIN); else if(tmpName == "healing") { bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_HEALING); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } else if(tmpName == "undefined") combat->setParam(COMBATPARAM_COMBATTYPE, COMBAT_UNDEFINEDDAMAGE); else if(tmpName == "speed") { int32_t speedChange = 0, duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; enum Aggressive { NO, YES, AUTO } aggressive = AUTO; if(readXMLInteger(node, "self", intValue)) aggressive = (Aggressive)intValue; if(readXMLInteger(node, "speedchange", intValue)) speedChange = std::max(-1000, intValue); //cant be slower than 100% std::vector<Outfit_t> outfits; for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next) { if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit")) continue; if(readXMLInteger(tmpNode, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(tmpNode, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(tmpNode, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(tmpNode, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(tmpNode, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(tmpNode, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(tmpNode, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } ConditionType_t conditionType = CONDITION_PARALYZE; if(speedChange > 0) { conditionType = CONDITION_HASTE; if(aggressive == AUTO) aggressive = NO; } else if(aggressive == AUTO) aggressive = YES; if(ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(Condition::createCondition( CONDITIONID_COMBAT, conditionType, duration))) { condition->setFormulaVars((speedChange / 1000.), 0, (speedChange / 1000.), 0); if(!outfits.empty()) condition->setOutfits(outfits); combat->setCondition(condition); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } } else if(tmpName == "outfit") { std::vector<Outfit_t> outfits; for(xmlNodePtr tmpNode = node->children; tmpNode; tmpNode = tmpNode->next) { if(xmlStrcmp(tmpNode->name,(const xmlChar*)"outfit")) continue; if(readXMLInteger(tmpNode, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(tmpNode, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(tmpNode, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(tmpNode, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(tmpNode, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(tmpNode, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(tmpNode, "typeex", intValue) || readXMLInteger(tmpNode, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(tmpNode, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } if(outfits.empty()) { if(readXMLInteger(node, "type", intValue)) { Outfit_t outfit; outfit.lookType = intValue; if(readXMLInteger(node, "head", intValue)) outfit.lookHead = intValue; if(readXMLInteger(node, "body", intValue)) outfit.lookBody = intValue; if(readXMLInteger(node, "legs", intValue)) outfit.lookLegs = intValue; if(readXMLInteger(node, "feet", intValue)) outfit.lookFeet = intValue; if(readXMLInteger(node, "addons", intValue)) outfit.lookAddons = intValue; outfits.push_back(outfit); } if(readXMLInteger(node, "typeex", intValue) || readXMLInteger(node, "item", intValue)) { Outfit_t outfit; outfit.lookTypeEx = intValue; outfits.push_back(outfit); } if(readXMLString(node, "monster", strValue)) { if(MonsterType* mType = g_monsters.getMonsterType(strValue)) outfits.push_back(mType->outfit); } } if(!outfits.empty()) { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; if(ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(Condition::createCondition( CONDITIONID_COMBAT, CONDITION_OUTFIT, duration))) { condition->setOutfits(outfits); combat->setCondition(condition); combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); } } } else if(tmpName == "invisible") { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; bool aggressive = false; if(readXMLInteger(node, "self", intValue)) aggressive = intValue; if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration)) { combat->setParam(COMBATPARAM_AGGRESSIVE, aggressive); combat->setCondition(condition); } } else if(tmpName == "drunk") { int32_t duration = 10000; if(readXMLInteger(node, "duration", intValue)) duration = intValue; if(Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration)) combat->setCondition(condition); } else if(tmpName == "skills" || tmpName == "attributes") { uint32_t duration = 10000, subId = 0; if(readXMLInteger(node, "duration", intValue)) duration = intValue; if(readXMLInteger(node, "subid", intValue)) subId = intValue; intValue = 0; ConditionParam_t param = CONDITIONPARAM_BUFF; //to know was it loaded if(readXMLInteger(node, "melee", intValue)) param = CONDITIONPARAM_SKILL_MELEE; else if(readXMLInteger(node, "fist", intValue)) param = CONDITIONPARAM_SKILL_FIST; else if(readXMLInteger(node, "club", intValue)) param = CONDITIONPARAM_SKILL_CLUB; else if(readXMLInteger(node, "axe", intValue)) param = CONDITIONPARAM_SKILL_AXE; else if(readXMLInteger(node, "sword", intValue)) param = CONDITIONPARAM_SKILL_SWORD; else if(readXMLInteger(node, "distance", intValue) || readXMLInteger(node, "dist", intValue)) param = CONDITIONPARAM_SKILL_DISTANCE; else if(readXMLInteger(node, "shielding", intValue) || readXMLInteger(node, "shield", intValue)) param = CONDITIONPARAM_SKILL_SHIELD; else if(readXMLInteger(node, "fishing", intValue) || readXMLInteger(node, "fish", intValue)) param = CONDITIONPARAM_SKILL_FISHING; else if(readXMLInteger(node, "meleePercent", intValue)) param = CONDITIONPARAM_SKILL_MELEEPERCENT; else if(readXMLInteger(node, "fistPercent", intValue)) param = CONDITIONPARAM_SKILL_FISTPERCENT; else if(readXMLInteger(node, "clubPercent", intValue)) param = CONDITIONPARAM_SKILL_CLUBPERCENT; else if(readXMLInteger(node, "axePercent", intValue)) param = CONDITIONPARAM_SKILL_AXEPERCENT; else if(readXMLInteger(node, "swordPercent", intValue)) param = CONDITIONPARAM_SKILL_SWORDPERCENT; else if(readXMLInteger(node, "distancePercent", intValue) || readXMLInteger(node, "distPercent", intValue)) param = CONDITIONPARAM_SKILL_DISTANCEPERCENT; else if(readXMLInteger(node, "shieldingPercent", intValue) || readXMLInteger(node, "shieldPercent", intValue)) param = CONDITIONPARAM_SKILL_SHIELDPERCENT; else if(readXMLInteger(node, "fishingPercent", intValue) || readXMLInteger(node, "fishPercent", intValue)) param = CONDITIONPARAM_SKILL_FISHINGPERCENT; else if(readXMLInteger(node, "maxhealth", intValue)) param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT; else if(readXMLInteger(node, "maxmana", intValue)) param = CONDITIONPARAM_STAT_MAXMANAPERCENT; else if(readXMLInteger(node, "soul", intValue)) param = CONDITIONPARAM_STAT_SOULPERCENT; else if(readXMLInteger(node, "magiclevel", intValue) || readXMLInteger(node, "maglevel", intValue)) param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT; else if(readXMLInteger(node, "maxhealthPercent", intValue)) param = CONDITIONPARAM_STAT_MAXHEALTHPERCENT; else if(readXMLInteger(node, "maxmanaPercent", intValue)) param = CONDITIONPARAM_STAT_MAXMANAPERCENT; else if(readXMLInteger(node, "soulPercent", intValue)) param = CONDITIONPARAM_STAT_SOULPERCENT; else if(readXMLInteger(node, "magiclevelPercent", intValue) || readXMLInteger(node, "maglevelPercent", intValue)) param = CONDITIONPARAM_STAT_MAGICLEVELPERCENT; if(param != CONDITIONPARAM_BUFF) { if(ConditionAttributes* condition = dynamic_cast<ConditionAttributes*>(Condition::createCondition( CONDITIONID_COMBAT, CONDITION_ATTRIBUTES, duration, false, subId))) { condition->setParam(param, intValue); combat->setCondition(condition); } } } else if(tmpName == "firefield") combat->setParam(COMBATPARAM_CREATEITEM, 1492); else if(tmpName == "poisonfield") combat->setParam(COMBATPARAM_CREATEITEM, 1496); else if(tmpName == "energyfield") combat->setParam(COMBATPARAM_CREATEITEM, 1495); else if(tmpName == "firecondition" || tmpName == "energycondition" || tmpName == "drowncondition" || tmpName == "poisoncondition" || tmpName == "earthcondition" || tmpName == "freezecondition" || tmpName == "cursecondition" || tmpName == "dazzlecondition") { ConditionType_t conditionType = CONDITION_NONE; uint32_t tickInterval = 2000; if(tmpName == "physicalcondition") conditionType = CONDITION_PHYSICAL; else if(tmpName == "firecondition") { conditionType = CONDITION_FIRE; tickInterval = 9000; } else if(tmpName == "energycondition") { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if(tmpName == "earthcondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } else if(tmpName == "freezecondition") { conditionType = CONDITION_FREEZING; tickInterval = 8000; } else if(tmpName == "cursecondition") { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if(tmpName == "dazzlecondition") { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if(tmpName == "drowncondition") { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if(tmpName == "poisoncondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } if(readXMLInteger(node, "tick", intValue) && intValue > 0) tickInterval = intValue; int32_t startDamage = 0, minDamage = std::abs(sb.minCombatValue), maxDamage = std::abs(sb.maxCombatValue); if(readXMLInteger(node, "start", intValue)) startDamage = std::max(std::abs(intValue), minDamage); if(Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval)) combat->setCondition(condition); } else if(tmpName == "strength") { //TODO: monster extra strength } else if(tmpName == "effect") {/*show some effect and bye bye!*/} else { delete combat; std::clog << "[Error - Monsters::deserializeSpell] " << description << " - Unknown spell name: " << name << std::endl; return false; } combat->setPlayerCombatValues(FORMULA_VALUE, sb.minCombatValue, 0, sb.maxCombatValue, 0, 0, 0, 0, 0, 0, 0); combatSpell = new CombatSpell(combat, needTarget, needDirection); for(xmlNodePtr attributeNode = node->children; attributeNode; attributeNode = attributeNode->next) { if(!xmlStrcmp(attributeNode->name, (const xmlChar*)"attribute")) { if(readXMLString(attributeNode, "key", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "shooteffect") { if(readXMLString(attributeNode, "value", strValue)) { ShootEffect_t shoot = getShootType(strValue); if(shoot != SHOOT_EFFECT_UNKNOWN) combat->setParam(COMBATPARAM_DISTANCEEFFECT, shoot); else std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown shootEffect: " << strValue << std::endl; } } else if(tmpStrValue == "areaeffect") { if(readXMLString(attributeNode, "value", strValue)) { MagicEffect_t effect = getMagicEffect(strValue); if(effect != MAGIC_EFFECT_UNKNOWN) combat->setParam(COMBATPARAM_EFFECT, effect); else std::clog << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << strValue << std::endl; } } else std::clog << "[Warning - Monsters::deserializeSpells] Effect type \"" << strValue << "\" does not exist." << std::endl; } } } } sb.spell = combatSpell; return true; }
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 Commands::reloadInfo(Player& player, const std::string& param) { std::string tmpParam = asLowerCaseString(param); if (tmpParam == "action" || tmpParam == "actions") { g_actions->reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded actions."); } else if (tmpParam == "config" || tmpParam == "configuration") { g_config.reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded config."); } else if (tmpParam == "command" || tmpParam == "commands") { reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded commands."); } else if (tmpParam == "creaturescript" || tmpParam == "creaturescripts") { g_creatureEvents->reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded creature scripts."); } else if (tmpParam == "monster" || tmpParam == "monsters") { g_monsters.reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded monsters."); } else if (tmpParam == "move" || tmpParam == "movement" || tmpParam == "movements" || tmpParam == "moveevents" || tmpParam == "moveevent") { g_moveEvents->reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded movements."); } else if (tmpParam == "npc" || tmpParam == "npcs") { Npcs::reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded npcs."); } else if (tmpParam == "raid" || tmpParam == "raids") { g_game.raids.reload(); g_game.raids.startup(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded raids."); } else if (tmpParam == "spell" || tmpParam == "spells") { g_spells->reload(); g_monsters.reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded spells."); } else if (tmpParam == "talk" || tmpParam == "talkaction" || tmpParam == "talkactions") { g_talkActions->reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded talk actions."); } else if (tmpParam == "items") { Item::items.reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded items."); } else if (tmpParam == "weapon" || tmpParam == "weapons") { g_weapons->reload(); g_weapons->loadDefaults(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded weapons."); } else if (tmpParam == "quest" || tmpParam == "quests") { g_game.quests.reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded quests."); } else if (tmpParam == "mount" || tmpParam == "mounts") { g_game.mounts.reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded mounts."); } else if (tmpParam == "globalevents" || tmpParam == "globalevent") { g_globalEvents->reload(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded globalevents."); } else if (tmpParam == "events") { g_events->load(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded events."); } else if (tmpParam == "chat" || tmpParam == "channel" || tmpParam == "chatchannels") { g_chat->load(); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded chatchannels."); } else if (tmpParam == "global") { g_luaEnvironment.loadFile("data/global.lua"); player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reloaded global.lua."); } else { player.sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reload type not found."); } lua_gc(g_luaEnvironment.getLuaState(), LUA_GCCOLLECT, 0); }
void mainLoader(int argc, char* argv[], ServiceManager* services) { //dispatcher thread g_game.setGameState(GAME_STATE_STARTUP); srand((unsigned int)OTSYS_TIME()); #ifdef WIN32 SetConsoleTitle(STATUS_SERVER_NAME); #endif std::cout << STATUS_SERVER_NAME << " - Version " << STATUS_SERVER_VERSION << std::endl; std::cout << "Compilied on " << __DATE__ << " " << __TIME__ << " for arch "; #if defined(__amd64__) || defined(_M_X64) std::cout << "x64" << std::endl; #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) std::cout << "x86" << std::endl; #else std::cout << "unk" << std::endl; #endif std::cout << std::endl; std::cout << "A server developed by " << STATUS_SERVER_DEVELOPERS << std::endl; std::cout << "Visit our forum for updates, support, and resources: http://otland.net/." << std::endl; std::cout << std::endl; // read global config std::cout << ">> Loading config" << std::endl; if (!g_config.loadFile("config.lua")) { startupErrorMessage("Unable to load config.lua!"); return; } #ifdef WIN32 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); } std::ostringstream mutexName; mutexName << "forgottenserver_" << g_config.getNumber(ConfigManager::LOGIN_PORT); 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 login port, please shut it down first or change ports for this one."); return; } #endif //set RSA key const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"); const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"); const char* d("46730330223584118622160180015036832148732986808519344675210555262940258739805766860224610646919605860206328024326703361630109888417839241959507572247284807035235569619173792292786907845791904955103601652822519121908367187885509270025388641700821735345222087940578381210879116823013776808975766851829020659073"); g_RSA.setKey(p, q, d); std::cout << ">> Establishing database connection..." << std::flush; Database* db = Database::getInstance(); if (!db->connect()) { startupErrorMessage("Failed to connect to database."); return; } std::cout << " MySQL " << db->getClientVersion() << std::endl; // run database manager std::cout << ">> Running database manager" << std::endl; DatabaseManager* dbManager = DatabaseManager::getInstance(); if (!dbManager->isDatabaseSetup()) { startupErrorMessage("The database you have specified in config.lua is empty, please import the schema to the database."); return; } for (uint32_t version = dbManager->updateDatabase(); version != 0; version = dbManager->updateDatabase()) { std::cout << "> Database has been updated to version " << version << "." << std::endl; } dbManager->checkTriggers(); dbManager->checkEncryption(); if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !dbManager->optimizeTables()) { std::cout << "> No tables were optimized." << std::endl; } //load vocations std::cout << ">> Loading vocations" << std::endl; if (!g_vocations.loadFromXml()) { startupErrorMessage("Unable to load vocations!"); return; } //load commands std::cout << ">> Loading commands" << std::endl; if (!commands.loadFromXml()) { startupErrorMessage("Unable to load commands!"); return; } // load item data std::cout << ">> Loading items" << std::endl; if (Item::items.loadFromOtb("data/items/items.otb")) { startupErrorMessage("Unable to load items (OTB)!"); return; } if (!Item::items.loadFromXml()) { startupErrorMessage("Unable to load items (XML)!"); return; } std::cout << ">> Loading script systems" << std::endl; if (!ScriptingManager::getInstance()->loadScriptSystems()) { startupErrorMessage("Failed to load script systems"); return; } std::cout << ">> Loading monsters" << std::endl; if (!g_monsters.loadFromXml()) { startupErrorMessage("Unable to load monsters!"); return; } std::cout << ">> Loading outfits" << std::endl; Outfits* outfits = Outfits::getInstance(); if (!outfits->loadFromXml()) { startupErrorMessage("Unable to load outfits!"); return; } g_adminConfig = new AdminProtocolConfig(); std::cout << ">> Loading admin protocol config" << std::endl; if (!g_adminConfig->loadXMLConfig()) { startupErrorMessage("Unable to load admin protocol config!"); return; } std::cout << ">> Loading experience stages" << std::endl; if (!g_game.loadExperienceStages()) { startupErrorMessage("Unable to load experience stages!"); return; } std::string passwordType = asLowerCaseString(g_config.getString(ConfigManager::PASSWORDTYPE)); if (passwordType == "md5") { g_config.setNumber(ConfigManager::PASSWORD_TYPE, PASSWORD_TYPE_MD5); std::cout << ">> Using MD5 passwords" << std::endl; } else if (passwordType == "sha1") { g_config.setNumber(ConfigManager::PASSWORD_TYPE, PASSWORD_TYPE_SHA1); std::cout << ">> Using SHA1 passwords" << std::endl; } else { g_config.setNumber(ConfigManager::PASSWORD_TYPE, PASSWORD_TYPE_PLAIN); std::cout << ">> Using plaintext passwords" << std::endl; } std::cout << ">> Checking world type... " << std::flush; std::string worldType = asLowerCaseString(g_config.getString(ConfigManager::WORLD_TYPE)); if (worldType == "pvp") { g_game.setWorldType(WORLD_TYPE_PVP); } else if (worldType == "no-pvp") { g_game.setWorldType(WORLD_TYPE_NO_PVP); } else if (worldType == "pvp-enforced") { g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED); } else { std::cout << std::endl; std::ostringstream ss; ss << "> ERROR: Unknown world type: " << g_config.getString(ConfigManager::WORLD_TYPE) << ", valid world types are: pvp, no-pvp and pvp-enforced."; startupErrorMessage(ss.str()); return; } std::cout << asUpperCaseString(worldType) << std::endl; std::cout << ">> Loading map" << std::endl; if (!g_game.loadMap(g_config.getString(ConfigManager::MAP_NAME))) { startupErrorMessage("Failed to load map"); return; } std::cout << ">> Initializing gamestate" << std::endl; g_game.setGameState(GAME_STATE_INIT); // Tibia protocols services->add<ProtocolGame>(g_config.getNumber(ConfigManager::GAME_PORT)); services->add<ProtocolLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); // OT protocols services->add<ProtocolAdmin>(g_config.getNumber(ConfigManager::ADMIN_PORT)); services->add<ProtocolStatus>(g_config.getNumber(ConfigManager::STATUS_PORT)); // Legacy protocols services->add<ProtocolOldLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); services->add<ProtocolOldGame>(g_config.getNumber(ConfigManager::LOGIN_PORT)); int32_t autoSaveEachMinutes = g_config.getNumber(ConfigManager::AUTO_SAVE_EACH_MINUTES); if (autoSaveEachMinutes > 0) { g_scheduler.addEvent(createSchedulerTask(autoSaveEachMinutes * 1000 * 60, boost::bind(&Game::autoSave, &g_game))); } if (g_config.getBoolean(ConfigManager::SERVERSAVE_ENABLED)) { int32_t serverSaveHour = g_config.getNumber(ConfigManager::SERVERSAVE_H); if (serverSaveHour >= 0 && serverSaveHour <= 24) { time_t timeNow = time(NULL); tm* timeinfo = localtime(&timeNow); if (serverSaveHour == 0) { serverSaveHour = 23; } else { serverSaveHour--; } timeinfo->tm_hour = serverSaveHour; timeinfo->tm_min = 55; timeinfo->tm_sec = 0; time_t difference = (time_t)difftime(mktime(timeinfo), timeNow); if (difference < 0) { difference += 86400; } g_scheduler.addEvent(createSchedulerTask(difference * 1000, boost::bind(&Game::prepareServerSave, &g_game))); } } Houses::getInstance().payHouses(); IOLoginData::getInstance()->updateHouseOwners(); g_npcs.reload(); if (g_config.getBoolean(ConfigManager::MARKET_ENABLED)) { g_game.checkExpiredMarketOffers(); IOMarket::getInstance()->updateStatistics(); } std::cout << ">> Loaded all modules, server starting up..." << std::endl; std::pair<uint32_t, uint32_t> IpNetMask; IpNetMask.first = inet_addr("127.0.0.1"); IpNetMask.second = 0xFFFFFFFF; serverIPs.push_back(IpNetMask); char szHostName[128]; if (gethostname(szHostName, 128) == 0) { hostent* he = gethostbyname(szHostName); if (he) { unsigned char** addr = (unsigned char**)he->h_addr_list; while (addr[0] != NULL) { IpNetMask.first = *(uint32_t*)(*addr); IpNetMask.second = 0xFFFFFFFF; serverIPs.push_back(IpNetMask); addr++; } } } std::string ip = g_config.getString(ConfigManager::IP); uint32_t resolvedIp = inet_addr(ip.c_str()); if (resolvedIp == INADDR_NONE) { struct hostent* he = gethostbyname(ip.c_str()); if (!he) { std::ostringstream ss; ss << "ERROR: Cannot resolve " << ip << "!" << std::endl; startupErrorMessage(ss.str()); return; } resolvedIp = *(uint32_t*)he->h_addr; } IpNetMask.first = resolvedIp; IpNetMask.second = 0; serverIPs.push_back(IpNetMask); #if !defined(WIN32) && !defined(__ROOT_PERMISSION__) if (getuid() == 0 || geteuid() == 0) { std::cout << "> WARNING: " << STATUS_SERVER_NAME << " has been executed as root user, it is recommended to execute is as a normal user." << std::endl; } #endif g_game.start(services); g_game.setGameState(GAME_STATE_NORMAL); g_loaderSignal.notify_all(); }
void mainLoader(int argc, char* argv[], ServiceManager* services) { //dispatcher thread g_game.setGameState(GAME_STATE_STARTUP); srand((unsigned int)OTSYS_TIME()); #ifdef _WIN32 SetConsoleTitle(STATUS_SERVER_NAME); #endif std::cout << STATUS_SERVER_NAME << " - Version " << STATUS_SERVER_VERSION << std::endl; std::cout << "Compilied on " << __DATE__ << ' ' << __TIME__ << " for arch "; #if defined(__amd64__) || defined(_M_X64) std::cout << "x64" << std::endl; #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) std::cout << "x86" << std::endl; #elif defined(__arm__) std::cout << "ARM" << std::endl; #elif defined(__mips__) std::cout << "MIPS" << std::endl; #else std::cout << "unk" << std::endl; #endif std::cout << std::endl; std::cout << "A server developed by " << STATUS_SERVER_DEVELOPERS << std::endl; std::cout << "Visit our forum for updates, support, and resources: http://otland.net/." << std::endl; std::cout << std::endl; // read global config std::cout << ">> Loading config" << std::endl; if (!g_config.load()) { startupErrorMessage("Unable to load config.lua!"); return; } #ifdef _WIN32 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); } std::ostringstream mutexName; mutexName << "forgottenserver_" << g_config.getNumber(ConfigManager::LOGIN_PORT); CreateMutex(nullptr, FALSE, mutexName.str().c_str()); if (GetLastError() == ERROR_ALREADY_EXISTS) { startupErrorMessage("Another instance of The Forgotten Server is already running with the same login port, please shut it down first or change ports for this one."); return; } #endif //set RSA key const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"); const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"); g_RSA.setKey(p, q); std::cout << ">> Establishing database connection..." << std::flush; Database* db = Database::getInstance(); if (!db->connect()) { startupErrorMessage("Failed to connect to database."); return; } std::cout << " MySQL " << Database::getClientVersion() << std::endl; // run database manager std::cout << ">> Running database manager" << std::endl; if (!DatabaseManager::isDatabaseSetup()) { startupErrorMessage("The database you have specified in config.lua is empty, please import the schema.sql to your database."); return; } DatabaseManager::updateDatabase(); DatabaseManager::checkEncryption(); if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !DatabaseManager::optimizeTables()) { std::cout << "> No tables were optimized." << std::endl; } //load vocations std::cout << ">> Loading vocations" << std::endl; if (!g_vocations.loadFromXml()) { startupErrorMessage("Unable to load vocations!"); return; } //load commands std::cout << ">> Loading commands" << std::endl; if (!g_commands.loadFromXml()) { startupErrorMessage("Unable to load commands!"); return; } // load item data std::cout << ">> Loading items" << std::endl; if (Item::items.loadFromOtb("data/items/items.otb")) { startupErrorMessage("Unable to load items (OTB)!"); return; } if (!Item::items.loadFromXml()) { startupErrorMessage("Unable to load items (XML)!"); return; } std::cout << ">> Loading script systems" << std::endl; if (!ScriptingManager::getInstance()->loadScriptSystems()) { startupErrorMessage("Failed to load script systems"); return; } std::cout << ">> Loading monsters" << std::endl; if (!g_monsters.loadFromXml()) { startupErrorMessage("Unable to load monsters!"); return; } std::cout << ">> Loading outfits" << std::endl; Outfits* outfits = Outfits::getInstance(); if (!outfits->loadFromXml()) { startupErrorMessage("Unable to load outfits!"); return; } g_adminConfig = new AdminProtocolConfig(); std::cout << ">> Loading admin protocol config" << std::endl; if (!g_adminConfig->loadXMLConfig()) { startupErrorMessage("Unable to load admin protocol config!"); return; } std::cout << ">> Loading experience stages" << std::endl; if (!g_game.loadExperienceStages()) { startupErrorMessage("Unable to load experience stages!"); return; } std::string passwordType = asLowerCaseString(g_config.getString(ConfigManager::PASSWORDTYPE)); if (passwordType == "sha1") { g_config.setNumber(ConfigManager::PASSWORD_TYPE, PASSWORD_TYPE_SHA1); std::cout << ">> Using SHA1 passwords" << std::endl; } else { g_config.setNumber(ConfigManager::PASSWORD_TYPE, PASSWORD_TYPE_PLAIN); std::cout << ">> Using plaintext passwords" << std::endl; } std::cout << ">> Checking world type... " << std::flush; std::string worldType = asLowerCaseString(g_config.getString(ConfigManager::WORLD_TYPE)); if (worldType == "pvp") { g_game.setWorldType(WORLD_TYPE_PVP); } else if (worldType == "no-pvp") { g_game.setWorldType(WORLD_TYPE_NO_PVP); } else if (worldType == "pvp-enforced") { g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED); } else { std::cout << std::endl; std::ostringstream ss; ss << "> ERROR: Unknown world type: " << g_config.getString(ConfigManager::WORLD_TYPE) << ", valid world types are: pvp, no-pvp and pvp-enforced."; startupErrorMessage(ss.str()); return; } std::cout << asUpperCaseString(worldType) << std::endl; std::cout << ">> Loading map" << std::endl; if (!g_game.loadMainMap(g_config.getString(ConfigManager::MAP_NAME))) { startupErrorMessage("Failed to load map"); return; } std::cout << ">> Initializing gamestate" << std::endl; g_game.setGameState(GAME_STATE_INIT); // Tibia protocols services->add<ProtocolGame>(g_config.getNumber(ConfigManager::GAME_PORT)); services->add<ProtocolLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); // OT protocols services->add<ProtocolAdmin>(g_config.getNumber(ConfigManager::ADMIN_PORT)); services->add<ProtocolStatus>(g_config.getNumber(ConfigManager::STATUS_PORT)); // Legacy protocols services->add<ProtocolOldLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); services->add<ProtocolOldGame>(g_config.getNumber(ConfigManager::LOGIN_PORT)); int32_t autoSaveEachMinutes = g_config.getNumber(ConfigManager::AUTO_SAVE_EACH_MINUTES); if (autoSaveEachMinutes > 0) { g_scheduler->addEvent(createSchedulerTask(autoSaveEachMinutes * 1000 * 60, std::bind(&Game::autoSave, &g_game))); } if (g_config.getBoolean(ConfigManager::SERVERSAVE_ENABLED)) { int32_t serverSaveHour = g_config.getNumber(ConfigManager::SERVERSAVE_H); if (serverSaveHour >= 0 && serverSaveHour <= 24) { time_t timeNow = time(nullptr); tm* timeinfo = localtime(&timeNow); if (serverSaveHour == 0) { serverSaveHour = 23; } else { serverSaveHour--; } timeinfo->tm_hour = serverSaveHour; timeinfo->tm_min = 55; timeinfo->tm_sec = 0; double difference = difftime(mktime(timeinfo), timeNow); if (difference < 0) { difference += 86400; } g_scheduler->addEvent(createSchedulerTask(difference * 1000, std::bind(&Game::prepareServerSave, &g_game))); } } Houses::getInstance().payHouses(); IOLoginData::updateHouseOwners(); g_game.checkExpiredMarketOffers(); IOMarket::getInstance()->updateStatistics(); std::cout << ">> Loaded all modules, server starting up..." << std::endl; #if !defined(WIN32) && !defined(__ROOT_PERMISSION__) if (getuid() == 0 || geteuid() == 0) { std::cout << "> WARNING: " << STATUS_SERVER_NAME << " has been executed as root user, it is recommended to execute is as a normal user." << std::endl; } #endif g_game.start(services); g_game.setGameState(GAME_STATE_NORMAL); g_loaderSignal.notify_all(); }
bool Commands::reloadInfo(Creature* creature, const std::string& cmd, const std::string& param) { Player* player = creature->getPlayer(); if(param == "actions" || param == "action"){ g_actions->reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded actions."); } else if(param == "commands" || param == "command"){ this->reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded commands."); } else if(param == "monsters" || param == "monster"){ g_monsters.reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded monsters."); } else if(param == "npc"){ g_npcs.reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded npcs."); } else if(param == "config"){ g_config.reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded config."); } else if(param == "talk" || param == "talkactions" || param == "talk actions" || param == "ta"){ g_talkactions->reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded talk actions."); } else if(param == "move" || param == "movement" || param == "movement actions"){ g_moveEvents->reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded movement actions."); } else if(param == "spells" || param == "spell"){ g_spells->reload(); g_monsters.reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded spells and monsters."); } else if(param == "raids" || param == "raid"){ Raids::getInstance()->reload(); Raids::getInstance()->startup(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded raids."); } /* else if(param == "weapons"){ g_weapons->reload(); } else if(param == "items"){ Item::items.reload(); } */ else if(param == "creaturescripts" || param == "creature scripts" || param == "cs"){ g_creatureEvents->reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded creature scripts."); } else if(param == "globalevent" || param == "global event" || param == "ge"){ g_globalEvents->reload(); if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Reloaded global events."); } else{ if(player) player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Option not found."); } return true; }
bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, const std::string& description) { std::string name; std::string scriptName; bool isScripted; pugi::xml_attribute attr; if ((attr = node.attribute("script"))) { scriptName = attr.as_string(); isScripted = true; } else if ((attr = node.attribute("name"))) { name = attr.as_string(); isScripted = false; } else { return false; } if ((attr = node.attribute("speed")) || (attr = node.attribute("interval"))) { sb.speed = std::max<int32_t>(1, pugi::cast<int32_t>(attr.value())); } if ((attr = node.attribute("chance"))) { uint32_t chance = pugi::cast<uint32_t>(attr.value()); if (chance > 100) { chance = 100; } sb.chance = chance; } if ((attr = node.attribute("range"))) { uint32_t range = pugi::cast<uint32_t>(attr.value()); if (range > (Map::maxViewportX * 2)) { range = Map::maxViewportX * 2; } sb.range = range; } if ((attr = node.attribute("min"))) { sb.minCombatValue = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("max"))) { sb.maxCombatValue = pugi::cast<int32_t>(attr.value()); //normalize values if (std::abs(sb.minCombatValue) > std::abs(sb.maxCombatValue)) { int32_t value = sb.maxCombatValue; sb.maxCombatValue = sb.minCombatValue; sb.minCombatValue = value; } } if (auto spell = g_spells->getSpellByName(name)) { sb.spell = spell; return true; } CombatSpell* combatSpell = nullptr; bool needTarget = false; bool needDirection = false; if (isScripted) { if ((attr = node.attribute("direction"))) { needDirection = attr.as_bool(); } if ((attr = node.attribute("target"))) { needTarget = attr.as_bool(); } std::unique_ptr<CombatSpell> combatSpellPtr(new CombatSpell(nullptr, needTarget, needDirection)); if (!combatSpellPtr->loadScript("data/" + g_spells->getScriptBaseName() + "/scripts/" + scriptName)) { return false; } if (!combatSpellPtr->loadScriptCombat()) { return false; } combatSpell = combatSpellPtr.release(); combatSpell->getCombat()->setPlayerCombatValues(COMBAT_FORMULA_DAMAGE, sb.minCombatValue, 0, sb.maxCombatValue, 0); } else { Combat* combat = new Combat; if ((attr = node.attribute("length"))) { int32_t length = pugi::cast<int32_t>(attr.value()); if (length > 0) { int32_t spread = 3; //need direction spell if ((attr = node.attribute("spread"))) { spread = std::max<int32_t>(0, pugi::cast<int32_t>(attr.value())); } AreaCombat* area = new AreaCombat(); area->setupArea(length, spread); combat->setArea(area); needDirection = true; } } if ((attr = node.attribute("radius"))) { int32_t radius = pugi::cast<int32_t>(attr.value()); //target spell if ((attr = node.attribute("target"))) { needTarget = attr.as_bool(); } AreaCombat* area = new AreaCombat(); area->setupArea(radius); combat->setArea(area); } std::string tmpName = asLowerCaseString(name); if (tmpName == "melee") { sb.isMelee = true; pugi::xml_attribute attackAttribute, skillAttribute; if ((attackAttribute = node.attribute("attack")) && (skillAttribute = node.attribute("skill"))) { sb.minCombatValue = 0; sb.maxCombatValue = -Weapons::getMaxMeleeDamage(pugi::cast<int32_t>(skillAttribute.value()), pugi::cast<int32_t>(attackAttribute.value())); } ConditionType_t conditionType = CONDITION_NONE; int32_t minDamage = 0; int32_t maxDamage = 0; uint32_t tickInterval = 2000; if ((attr = node.attribute("fire"))) { conditionType = CONDITION_FIRE; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 9000; } else if ((attr = node.attribute("poison"))) { conditionType = CONDITION_POISON; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 5000; } else if ((attr = node.attribute("energy"))) { conditionType = CONDITION_ENERGY; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 10000; } else if ((attr = node.attribute("drown"))) { conditionType = CONDITION_DROWN; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 5000; } else if ((attr = node.attribute("freeze"))) { conditionType = CONDITION_FREEZING; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 8000; } else if ((attr = node.attribute("dazzle"))) { conditionType = CONDITION_DAZZLED; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 10000; } else if ((attr = node.attribute("curse"))) { conditionType = CONDITION_CURSED; minDamage = pugi::cast<int32_t>(attr.value()); maxDamage = minDamage; tickInterval = 4000; } else if ((attr = node.attribute("bleed")) || (attr = node.attribute("physical"))) { conditionType = CONDITION_BLEEDING; tickInterval = 5000; } if ((attr = node.attribute("tick"))) { int32_t value = pugi::cast<int32_t>(attr.value()); if (value > 0) { tickInterval = value; } } if (conditionType != CONDITION_NONE) { Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, 0, tickInterval); combat->setCondition(condition); } sb.range = 1; combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1); combat->setParam(COMBAT_PARAM_BLOCKSHIELD, 1); combat->setOrigin(ORIGIN_MELEE); } else if (tmpName == "physical") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE); combat->setParam(COMBAT_PARAM_BLOCKARMOR, 1); combat->setOrigin(ORIGIN_RANGED); } else if (tmpName == "bleed") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE); } else if (tmpName == "poison" || tmpName == "earth") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE); } else if (tmpName == "fire") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE); } else if (tmpName == "energy") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE); } else if (tmpName == "drown") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DROWNDAMAGE); } else if (tmpName == "ice") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE); } else if (tmpName == "holy") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE); } else if (tmpName == "death") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE); } else if (tmpName == "lifedrain") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_LIFEDRAIN); } else if (tmpName == "manadrain") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_MANADRAIN); } else if (tmpName == "healing") { combat->setParam(COMBAT_PARAM_TYPE, COMBAT_HEALING); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); } else if (tmpName == "speed") { int32_t speedChange = 0; int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("speedchange"))) { speedChange = pugi::cast<int32_t>(attr.value()); if (speedChange < -1000) { //cant be slower than 100% speedChange = -1000; } } ConditionType_t conditionType; if (speedChange > 0) { conditionType = CONDITION_HASTE; combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); } else { conditionType = CONDITION_PARALYZE; } ConditionSpeed* condition = static_cast<ConditionSpeed*>(Condition::createCondition(CONDITIONID_COMBAT, conditionType, duration, 0)); condition->setFormulaVars(speedChange / 1000.0, 0, speedChange / 1000.0, 0); combat->setCondition(condition); } else if (tmpName == "outfit") { int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } if ((attr = node.attribute("monster"))) { MonsterType* mType = g_monsters.getMonsterType(attr.as_string()); if (mType) { ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); condition->setOutfit(mType->outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combat->setCondition(condition); } } else if ((attr = node.attribute("item"))) { Outfit_t outfit; outfit.lookTypeEx = pugi::cast<uint16_t>(attr.value()); ConditionOutfit* condition = static_cast<ConditionOutfit*>(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); condition->setOutfit(outfit); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combat->setCondition(condition); } } else if (tmpName == "invisible") { int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_INVISIBLE, duration, 0); combat->setParam(COMBAT_PARAM_AGGRESSIVE, 0); combat->setCondition(condition); } else if (tmpName == "drunk") { int32_t duration = 10000; if ((attr = node.attribute("duration"))) { duration = pugi::cast<int32_t>(attr.value()); } Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_DRUNK, duration, 0); combat->setCondition(condition); } else if (tmpName == "firefield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_FIREFIELD_PVP_FULL); } else if (tmpName == "poisonfield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_POISONFIELD_PVP); } else if (tmpName == "energyfield") { combat->setParam(COMBAT_PARAM_CREATEITEM, ITEM_ENERGYFIELD_PVP); } else if (tmpName == "firecondition" || tmpName == "energycondition" || tmpName == "earthcondition" || tmpName == "poisoncondition" || tmpName == "icecondition" || tmpName == "freezecondition" || tmpName == "deathcondition" || tmpName == "cursecondition" || tmpName == "holycondition" || tmpName == "dazzlecondition" || tmpName == "drowncondition" || tmpName == "bleedcondition" || tmpName == "physicalcondition") { ConditionType_t conditionType = CONDITION_NONE; uint32_t tickInterval = 2000; if (tmpName == "firecondition") { conditionType = CONDITION_FIRE; tickInterval = 10000; } else if (tmpName == "poisoncondition" || tmpName == "earthcondition") { conditionType = CONDITION_POISON; tickInterval = 5000; } else if (tmpName == "energycondition") { conditionType = CONDITION_ENERGY; tickInterval = 10000; } else if (tmpName == "drowncondition") { conditionType = CONDITION_DROWN; tickInterval = 5000; } else if (tmpName == "freezecondition" || tmpName == "icecondition") { conditionType = CONDITION_FREEZING; tickInterval = 10000; } else if (tmpName == "cursecondition" || tmpName == "deathcondition") { conditionType = CONDITION_CURSED; tickInterval = 4000; } else if (tmpName == "dazzlecondition" || tmpName == "holycondition") { conditionType = CONDITION_DAZZLED; tickInterval = 10000; } else if (tmpName == "physicalcondition" || tmpName == "bleedcondition") { conditionType = CONDITION_BLEEDING; tickInterval = 5000; } if ((attr = node.attribute("tick"))) { int32_t value = pugi::cast<int32_t>(attr.value()); if (value > 0) { tickInterval = value; } } int32_t minDamage = std::abs(sb.minCombatValue); int32_t maxDamage = std::abs(sb.maxCombatValue); int32_t startDamage = 0; if ((attr = node.attribute("start"))) { int32_t value = std::abs(pugi::cast<int32_t>(attr.value())); if (value <= minDamage) { startDamage = value; } } Condition* condition = getDamageCondition(conditionType, maxDamage, minDamage, startDamage, tickInterval); combat->setCondition(condition); } else if (tmpName == "strength") { // } else if (tmpName == "effect") { // } else { std::cout << "[Error - Monsters::deserializeSpell] - " << description << " - Unknown spell name: " << name << std::endl; delete combat; return false; } combat->setPlayerCombatValues(COMBAT_FORMULA_DAMAGE, sb.minCombatValue, 0, sb.maxCombatValue, 0); combatSpell = new CombatSpell(combat, needTarget, needDirection); for (auto attributeNode : node.children()) { if ((attr = attributeNode.attribute("key"))) { const char* value = attr.value(); if (strcasecmp(value, "shooteffect") == 0) { if ((attr = attributeNode.attribute("value"))) { ShootType_t shoot = getShootType(attr.as_string()); if (shoot != CONST_ANI_NONE) { combat->setParam(COMBAT_PARAM_DISTANCEEFFECT, shoot); } else { std::cout << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown shootEffect: " << attr.as_string() << std::endl; } } } else if (strcasecmp(value, "areaeffect") == 0) { if ((attr = attributeNode.attribute("value"))) { MagicEffectClasses effect = getMagicEffect(attr.as_string()); if (effect != CONST_ME_NONE) { combat->setParam(COMBAT_PARAM_EFFECT, effect); } else { std::cout << "[Warning - Monsters::deserializeSpell] " << description << " - Unknown areaEffect: " << attr.as_string() << std::endl; } } } else { std::cout << "[Warning - Monsters::deserializeSpells] Effect type \"" << attr.as_string() << "\" does not exist." << std::endl; } } } } sb.spell = combatSpell; if (combatSpell) { sb.combatSpell = true; } return true; }
void mainLoader(int, char*[], ServiceManager* services) { //dispatcher thread g_game.setGameState(GAME_STATE_STARTUP); srand(static_cast<unsigned int>(OTSYS_TIME())); #ifdef _WIN32 SetConsoleTitle(STATUS_SERVER_NAME); #endif std::cout << STATUS_SERVER_NAME << " - Versao " << STATUS_SERVER_VERSION << std::endl; std::cout << "Compilado com " << BOOST_COMPILER << std::endl; std::cout << "Compilado em " << __DATE__ << ' ' << __TIME__ << " para plataforma "; #if defined(__amd64__) || defined(_M_X64) std::cout << "x64" << std::endl; #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) std::cout << "x86" << std::endl; #elif defined(__arm__) std::cout << "ARM" << std::endl; #else std::cout << "desconhecida" << std::endl; #endif std::cout << std::endl; std::cout << "Este servidor foi desenvolvido por " << STATUS_SERVER_DEVELOPERS << std::endl; std::cout << "Visite nosso forum para updates, suporte e pedidos: http://xtibia.com/." << std::endl; std::cout << "Um oferecimento OTPanel, OTserv Cloud em 60s." << std::endl; std::cout << std::endl; // read global config std::cout << ">> Carregando configuracoes" << std::endl; if (!g_config.load()) { startupErrorMessage("Falha ao carregar o config.lua!"); return; } #ifdef _WIN32 const std::string& defaultPriority = g_config.getString(ConfigManager::DEFAULT_PRIORITY); if (strcasecmp(defaultPriority.c_str(), "high") == 0) { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } else if (strcasecmp(defaultPriority.c_str(), "above-normal") == 0) { SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); } #endif //set RSA key const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"); const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"); g_RSA.setKey(p, q); std::cout << ">> Estabilizando conexao com o banco de dados..." << std::flush; Database* db = Database::getInstance(); if (!db->connect()) { startupErrorMessage("Falha ao conectar-se com o banco de dados."); return; } std::cout << " MySQL " << Database::getClientVersion() << std::endl; // run database manager std::cout << ">> Carregando banco de dados" << std::endl; if (!DatabaseManager::isDatabaseSetup()) { startupErrorMessage("O banco de dados que especificou no config.lua esta vazio, por favor importar o schema.sql para seu banco de dados."); return; } g_databaseTasks.start(); DatabaseManager::updateDatabase(); if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !DatabaseManager::optimizeTables()) { std::cout << "> Nenhuma tabela foi otimizada." << std::endl; } //load vocations std::cout << ">> Carregando vocacoes" << std::endl; if (!g_vocations.loadFromXml()) { startupErrorMessage("Impossivel carregar vocacoes!"); return; } // load item data std::cout << ">> Carregando items" << std::endl; if (Item::items.loadFromOtb("data/items/items.otb") != ERROR_NONE) { startupErrorMessage("Impossivel carregar items (OTB)!"); return; } if (!Item::items.loadFromXml()) { startupErrorMessage("Impossivel carregar (XML)!"); return; } std::cout << ">> Carregando sistemas de scripts" << std::endl; if (!ScriptingManager::getInstance()->loadScriptSystems()) { startupErrorMessage("Impossivel carregar sistemas de scripts"); return; } std::cout << ">> Carregando criaturas" << std::endl; if (!g_monsters.loadFromXml()) { startupErrorMessage("Impossivel carregar criaturas!"); return; } std::cout << ">> Carregando outfits" << std::endl; Outfits* outfits = Outfits::getInstance(); if (!outfits->loadFromXml()) { startupErrorMessage("Impossivel carregar outfits!"); return; } std::cout << ">> Checando tipo do servidor... " << std::flush; std::string worldType = asLowerCaseString(g_config.getString(ConfigManager::WORLD_TYPE)); if (worldType == "pvp") { g_game.setWorldType(WORLD_TYPE_PVP); } else if (worldType == "no-pvp") { g_game.setWorldType(WORLD_TYPE_NO_PVP); } else if (worldType == "pvp-enforced") { g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED); } else { std::cout << std::endl; std::ostringstream ss; ss << "> ERRO: Tipo do servidor desconhecido: " << g_config.getString(ConfigManager::WORLD_TYPE) << ", os tipos validos sao: pvp, no-pvp and pvp-enforced."; startupErrorMessage(ss.str()); return; } std::cout << asUpperCaseString(worldType) << std::endl; std::cout << ">> Carregando mapa" << std::endl; if (!g_game.loadMainMap(g_config.getString(ConfigManager::MAP_NAME))) { startupErrorMessage("Impossivel carregar o mapa"); return; } std::cout << ">> Inicializando o servidor" << std::endl; g_game.setGameState(GAME_STATE_INIT); // Game client protocols services->add<ProtocolGame>(g_config.getNumber(ConfigManager::GAME_PORT)); services->add<ProtocolLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); // OT protocols services->add<ProtocolStatus>(g_config.getNumber(ConfigManager::STATUS_PORT)); // Legacy login protocol services->add<ProtocolOld>(g_config.getNumber(ConfigManager::LOGIN_PORT)); RentPeriod_t rentPeriod; std::string strRentPeriod = asLowerCaseString(g_config.getString(ConfigManager::HOUSE_RENT_PERIOD)); if (strRentPeriod == "yearly") { rentPeriod = RENTPERIOD_YEARLY; } else if (strRentPeriod == "weekly") { rentPeriod = RENTPERIOD_WEEKLY; } else if (strRentPeriod == "monthly") { rentPeriod = RENTPERIOD_MONTHLY; } else if (strRentPeriod == "daily") { rentPeriod = RENTPERIOD_DAILY; } else { rentPeriod = RENTPERIOD_NEVER; } g_game.map.houses.payHouses(rentPeriod); IOMarket::checkExpiredOffers(); IOMarket::getInstance()->updateStatistics(); std::cout << ">> Todos os modulos carregados, servidor iniciando..." << std::endl; #ifndef _WIN32 if (getuid() == 0 || geteuid() == 0) { std::cout << "> Aviso: O servidor foi executado com usuario root, por favor considere executa-lo como um usuario normal." << std::endl; } #endif g_game.start(services); g_game.setGameState(GAME_STATE_NORMAL); g_loaderSignal.notify_all(); }