Beispiel #1
0
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.");
	}
}
Beispiel #3
0
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;
}
Beispiel #4
0
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));
    }
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
Monster* Monster::createMonster(const std::string& name, std::string customName /* = ""*/)
{
	MonsterType* mType = g_monsters.getMonsterType(name);
	if(!mType)
		return NULL;

	return createMonster(mType, customName);
}
Beispiel #8
0
Monster* Monster::createMonster(const std::string& name)
{
	MonsterType* mType = g_monsters.getMonsterType(name);
	if (!mType) {
		return nullptr;
	}
	return new Monster(mType);
}
Beispiel #9
0
Monster* Monster::createMonster(const std::string& name)
{
	MonsterType* mType = g_monsters.getMonsterType(name);
	if(!mType)
		return NULL;

	return createMonster(mType);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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;
}
Beispiel #12
0
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);
}
Beispiel #13
0
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;
}
Beispiel #14
0
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);
}
Beispiel #15
0
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;
}
Beispiel #16
0
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);
}
Beispiel #17
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();
}
Beispiel #18
0
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;
}
Beispiel #19
0
bool ScriptManager::loadFromXml(const std::string& file, bool& enabled)
{
	enabled = false;
	xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_MOD, file).c_str());
	if(!doc)
	{
		std::clog << "[Error - ScriptManager::loadFromXml] Cannot load mod " << file << std::endl;
		std::clog << getLastXMLError() << std::endl;
		return false;
	}

	int32_t intValue;
	std::string strValue;

	xmlNodePtr p, root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"mod"))
	{
		std::clog << "[Error - ScriptManager::loadFromXml] Malformed mod " << file << std::endl;
		std::clog << getLastXMLError() << std::endl;

		xmlFreeDoc(doc);
		return false;
	}

	if(!readXMLString(root, "name", strValue))
		strValue = file;

	ModBlock mod;
	mod.enabled = true;
	mod.name = strValue;
	if(readXMLString(root, "enabled", strValue) && !booleanString(strValue))
		mod.enabled = false;

	mod.file = file;
	if(readXMLString(root, "author", strValue))
		mod.author = strValue;

	if(readXMLString(root, "version", strValue))
		mod.version = strValue;

	if(readXMLString(root, "contact", strValue))
		mod.contact = strValue;

	bool supported = true;
	for(p = root->children; p; p = p->next)
	{
		if(xmlStrcmp(p->name, (const xmlChar*)"server"))
			continue;

		supported = false;
		for(xmlNodePtr versionNode = p->children; versionNode; versionNode = versionNode->next)
		{
			std::string id = SOFTWARE_VERSION;
			if(readXMLString(versionNode, "id", strValue))
				id = asLowerCaseString(strValue);

			IntegerVec protocol;
			protocol.push_back(CLIENT_VERSION_MIN);
			if(readXMLString(versionNode, "protocol", strValue))
				protocol = vectorAtoi(explodeString(strValue, "-"));

			int16_t database = VERSION_DATABASE;
			if(readXMLInteger(versionNode, "database", intValue))
				database = intValue;

			if(id == asLowerCaseString(SOFTWARE_VERSION) && database >= VERSION_DATABASE
				&& protocol[0] >= CLIENT_VERSION_MIN && (protocol.size() < 2 || protocol[1] <= CLIENT_VERSION_MAX))
			{
				supported = true;
				break;
			}
		}
	}

	if(!supported)
	{
		std::clog << "[Warning - ScriptManager::loadFromXml] Your server is not supported by mod " << file << std::endl;
		xmlFreeDoc(doc);
		return false;
	}

	if(mod.enabled)
	{
		std::string scriptsPath = getFilePath(FILE_TYPE_MOD, "scripts/");
		for(p = root->children; p; p = p->next)
		{
			if(!xmlStrcmp(p->name, (const xmlChar*)"quest"))
				Quests::getInstance()->parseQuestNode(p, modsLoaded);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"outfit"))
				Outfits::getInstance()->parseOutfitNode(p);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"vocation"))
				Vocations::getInstance()->parseVocationNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution
			else if(!xmlStrcmp(p->name, (const xmlChar*)"group"))
				Groups::getInstance()->parseGroupNode(p); //duplicates checking is dangerous, shouldn't be performed until we find some good solution
			else if(!xmlStrcmp(p->name, (const xmlChar*)"raid"))
				Raids::getInstance()->parseRaidNode(p, modsLoaded, FILE_TYPE_MOD); //TODO: support mods path
			else if(!xmlStrcmp(p->name, (const xmlChar*)"spawn"))
				Spawns::getInstance()->parseSpawnNode(p, modsLoaded);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"channel"))
				g_chat.parseChannelNode(p); //TODO: duplicates- channel destructor needs to send closeChannel to users!
			else if(!xmlStrcmp(p->name, (const xmlChar*)"npc"))
				g_npcs.parseNpcNode(p, FILE_TYPE_MOD);
			else if(!xmlStrcmp(p->name, (const xmlChar*)"monster"))
			{
				std::string path, name;
				if((readXMLString(p, "file", path) || readXMLString(p, "path", path)) && readXMLString(p, "name", name))
					g_monsters.loadMonster(getFilePath(FILE_TYPE_MOD, "monster/" + path), name, true);
			}
			else if(!xmlStrcmp(p->name, (const xmlChar*)"item"))
			{
				if(readXMLInteger(p, "id", intValue))
					Item::items.parseItemNode(p, intValue);
			}
			if(!xmlStrcmp(p->name, (const xmlChar*)"description") || !xmlStrcmp(p->name, (const xmlChar*)"info"))
			{
				if(parseXMLContentString(p->children, strValue))
				{
					replaceString(strValue, "\t", "");
					mod.description = strValue;
				}
			}
			else if(!xmlStrcmp(p->name, (const xmlChar*)"lib") || !xmlStrcmp(p->name, (const xmlChar*)"config"))
			{
				if(!readXMLString(p, "name", strValue))
				{
					if(!xmlStrcmp(p->name, (const xmlChar*)"lib"))
						strValue = mod.name + "-lib";
					else if(!xmlStrcmp(p->name, (const xmlChar*)"config"))
						strValue = mod.name + "-config";
				}
				else
					toLowerCaseString(strValue);

				std::string strLib;
				if(parseXMLContentString(p->children, strLib))
				{
					LibMap::iterator it = libMap.find(strValue);
					if(it == libMap.end())
					{
						LibBlock lb;
						lb.first = file;
						lb.second = strLib;

						libMap[strValue] = lb;
					}
					else
						std::clog << "[Warning - ScriptManager::loadFromXml] Duplicated lib in mod "
							<< strValue << ", previously declared in " << it->second.first << std::endl;
				}
			}
			else if(!g_actions->parseEventNode(p, scriptsPath, modsLoaded))
			{
				if(!g_talkActions->parseEventNode(p, scriptsPath, modsLoaded))
				{
					if(!g_moveEvents->parseEventNode(p, scriptsPath, modsLoaded))
					{
						if(!g_creatureEvents->parseEventNode(p, scriptsPath, modsLoaded))
						{
							if(!g_globalEvents->parseEventNode(p, scriptsPath, modsLoaded))
							{
								if(!g_spells->parseEventNode(p, scriptsPath, modsLoaded))
									g_weapons->parseEventNode(p, scriptsPath, modsLoaded);
							}
						}
					}
				}
			}
		}
	}

	enabled = mod.enabled;
	modMap[mod.name] = mod;

	xmlFreeDoc(doc);
	return true;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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);
}
Beispiel #22
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();
}
Beispiel #23
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;
#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();
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
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 << 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();
}