Example #1
0
int32 map_config_read(const int8* cfgName)
{
    int8 line[1024], w1[1024], w2[1024];
    FILE* fp;

    fp = fopen(cfgName, "r");
    if (fp == nullptr)
    {
        ShowError("Map configuration file not found at: %s\n", cfgName);
        return 1;
    }

    while (fgets(line, sizeof(line), fp))
    {
        int8* ptr;

        if (line[0] == '#')
        {
            continue;
        }
        if (sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2)
        {
            continue;
        }

        //Strip trailing spaces
        ptr = w2 + strlen(w2);
        while (--ptr >= w2 && *ptr == ' ');
        ptr++;
        *ptr = '\0';

        if (strcmpi(w1, "timestamp_format") == 0)
        {
            strncpy(timestamp_format, w2, 20);
        }
        else if (strcmpi(w1, "stdout_with_ansisequence") == 0)
        {
            stdout_with_ansisequence = config_switch(w2);
        }
        else if (strcmpi(w1, "console_silent") == 0)
        {
            ShowInfo("Console Silent Setting: %d", atoi(w2));
            msg_silent = atoi(w2);
        }
        else if (strcmpi(w1, "map_port") == 0)
        {
            map_config.usMapPort = (atoi(w2));
        }
        else if (strcmp(w1, "buff_maxsize") == 0)
        {
            map_config.buffer_size = atoi(w2);
        }
        else if (strcmp(w1, "max_time_lastupdate") == 0)
        {
            map_config.max_time_lastupdate = atoi(w2);
        }
        else if (strcmp(w1, "vanadiel_time_offset") == 0)
        {
            map_config.vanadiel_time_offset = atoi(w2);
        }
        else if (strcmp(w1, "lightluggage_block") == 0)
        {
            map_config.lightluggage_block = atoi(w2);
        }
        else if (strcmp(w1, "exp_rate") == 0)
        {
            map_config.exp_rate = atof(w2);
        }
        else if (strcmp(w1, "exp_loss_rate") == 0)
        {
            map_config.exp_loss_rate = atof(w2);
        }
        else if (strcmp(w1, "exp_party_gap_penalties") == 0)
        {
            map_config.exp_party_gap_penalties = atof(w2);
        }
        else if (strcmp(w1, "fov_party_gap_penalties") == 0)
        {
            map_config.fov_party_gap_penalties = atof(w2);
        }
        else if (strcmp(w1, "fov_allow_alliance") == 0)
        {
            map_config.fov_allow_alliance = atof(w2);
        }
        else if (strcmp(w1, "mob_tp_multiplier") == 0)
        {
            map_config.mob_tp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "player_tp_multiplier") == 0)
        {
            map_config.player_tp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "nm_hp_multiplier") == 0)
        {
            map_config.nm_hp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "mob_hp_multiplier") == 0)
        {
            map_config.mob_hp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "player_hp_multiplier") == 0)
        {
            map_config.player_hp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "nm_mp_multiplier") == 0)
        {
            map_config.nm_mp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "mob_mp_multiplier") == 0)
        {
            map_config.mob_mp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "player_mp_multiplier") == 0)
        {
            map_config.player_mp_multiplier = atof(w2);
        }
        else if (strcmp(w1, "sj_mp_divisor") == 0)
        {
            map_config.sj_mp_divisor = atof(w2);
        }
        else if (strcmp(w1, "nm_stat_multiplier") == 0)
        {
            map_config.nm_stat_multiplier = atof(w2);
        }
        else if (strcmp(w1, "mob_stat_multiplier") == 0)
        {
            map_config.mob_stat_multiplier = atof(w2);
        }
        else if (strcmp(w1, "player_stat_multiplier") == 0)
        {
            map_config.player_stat_multiplier = atof(w2);
        }
        else if (strcmp(w1, "drop_rate_multiplier") == 0)
        {
            map_config.drop_rate_multiplier = atof(w2);
        }
        else if (strcmp(w1, "all_mobs_gil_bonus") == 0)
        {
            map_config.all_mobs_gil_bonus = atoi(w2);
        }
        else if (strcmp(w1, "max_gil_bonus") == 0)
        {
            map_config.max_gil_bonus = atoi(w2);
        }
        else if (strcmp(w1, "exp_retain") == 0)
        {
            map_config.exp_retain = dsp_cap(atof(w2), 0.0f, 1.0f);
        }
        else if (strcmp(w1, "exp_loss_level") == 0)
        {
            map_config.exp_loss_level = atoi(w2);
        }
        else if (strcmp(w1, "level_sync_enable") == 0)
        {
            map_config.level_sync_enable = atoi(w2);
        }
        else if (strcmp(w1, "all_jobs_widescan") == 0)
        {
            map_config.all_jobs_widescan = atoi(w2);
        }
        else if (strcmp(w1, "speed_mod") == 0)
        {
            map_config.speed_mod = atoi(w2);
        }
        else if (strcmp(w1, "mob_speed_mod") == 0)
        {
            map_config.mob_speed_mod = atoi(w2);
        }
        else if (strcmp(w1, "skillup_chance_multiplier") == 0)
        {
            map_config.skillup_chance_multiplier = atof(w2);
        }
        else if (strcmp(w1, "craft_chance_multiplier") == 0)
        {
            map_config.craft_chance_multiplier = atof(w2);
        }
        else if (strcmp(w1, "skillup_amount_multiplier") == 0)
        {
            map_config.skillup_amount_multiplier = atof(w2);
        }
        else if (strcmp(w1, "craft_amount_multiplier") == 0)
        {
            map_config.craft_amount_multiplier = atof(w2);
        }
        else if (strcmp(w1, "craft_day_matters") == 0)
        {
            map_config.craft_day_matters = atof(w2);
        }
        else if (strcmp(w1, "craft_moonphase_matters") == 0)
        {
            map_config.craft_moonphase_matters = atof(w2);
        }
        else if (strcmp(w1, "craft_direction_matters") == 0)
        {
            map_config.craft_direction_matters = atof(w2);
        }
        else if (strcmp(w1, "mysql_host") == 0)
        {
            map_config.mysql_host = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_login") == 0)
        {
            map_config.mysql_login = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_password") == 0)
        {
            map_config.mysql_password = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_port") == 0)
        {
            map_config.mysql_port = atoi(w2);
        }
        else if (strcmp(w1, "mysql_database") == 0)
        {
            map_config.mysql_database = aStrdup(w2);
        }
        else if (strcmpi(w1, "import") == 0)
        {
            map_config_read(w2);
        }
        else if (strcmpi(w1, "newstyle_skillups") == 0)
        {
            map_config.newstyle_skillups = atoi(w2);
        }
        else if (strcmp(w1, "Battle_cap_tweak") == 0)
        {
            map_config.Battle_cap_tweak = atoi(w2);
        }
        else if (strcmp(w1, "CoP_Battle_cap") == 0)
        {
            map_config.CoP_Battle_cap = atoi(w2);
        }
        else if (strcmp(w1, "max_merit_points") == 0)
        {
            map_config.max_merit_points = atoi(w2);
        }
        else if (strcmp(w1, "yell_cooldown") == 0)
        {
            map_config.yell_cooldown = atoi(w2);
        }
        else if (strcmp(w1, "audit_chat") == 0)
        {
            map_config.audit_chat = atoi(w2);
        }
        else if (strcmp(w1, "audit_say") == 0)
        {
            map_config.audit_say = atoi(w2);
        }
        else if (strcmp(w1, "audit_shout") == 0)
        {
            map_config.audit_shout = atoi(w2);
        }
        else if (strcmp(w1, "audit_tell") == 0)
        {
            map_config.audit_tell = atoi(w2);
        }
        else if (strcmp(w1, "audit_yell") == 0)
        {
            map_config.audit_yell = atoi(w2);
        }
        else if (strcmp(w1, "audit_linkshell") == 0)
        {
            map_config.audit_linkshell = atoi(w2);
        }
        else if (strcmp(w1, "audit_party") == 0)
        {
            map_config.audit_party = atoi(w2);
        }
        else if (strcmp(w1, "msg_server_port") == 0)
        {
            map_config.msg_server_port = atoi(w2);
        }
        else if (strcmp(w1, "msg_server_ip") == 0)
        {
            map_config.msg_server_ip = aStrdup(w2);
        }
        else
        {
            ShowWarning(CL_YELLOW"Unknown setting '%s' in file %s\n" CL_RESET, w1, cfgName);
        }
    }

    fclose(fp);

    // Load the English server message..
    fp = fopen("./conf/server_message.conf", "rb");
    if (fp == nullptr)
    {
        ShowError("Could not read English server message from: ./conf/server_message.conf\n");
        return 1;
    }

    while (fgets(line, sizeof(line), fp))
    {
        string_t sline(line);
        map_config.server_message += sline;
    }

    fclose(fp);

    // Load the French server message..
    fp = fopen("./conf/server_message_fr.conf", "rb");
    if (fp == nullptr)
    {
        ShowError("Could not read English server message from: ./conf/server_message_fr.conf\n");
        return 1;
    }

    while (fgets(line, sizeof(line), fp))
    {
        string_t sline(line);
        map_config.server_message_fr += sline;
    }

    fclose(fp);

    // Ensure both messages have nullptr terminates..
    if (map_config.server_message.at(map_config.server_message.length() - 1) != 0x00)
    {
        map_config.server_message += (char)0x00;
    }
    if (map_config.server_message_fr.at(map_config.server_message_fr.length() - 1) != 0x00)
    {
        map_config.server_message_fr += (char)0x00;
    }

    return 0;
}
Example #2
0
void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count)
{
	int zeny = 0;
	unsigned int i, weight, listidx, k;
	struct map_session_data* pl_sd;

	if( count == 0 )
	{// nothing to do
		return;
	}

	if( !battle_config.feature_buying_store || pc_istrading(sd) )
	{// not allowed to sell
		clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
		return;
	}

	if( !pc->can_give_items(sd) )
	{// custom: GM is not allowed to sell
		clif->message(sd->fd, msg_txt(246));
		clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
		return;
	}

	if( ( pl_sd = iMap->id2sd(account_id) ) == NULL || !pl_sd->state.buyingstore || pl_sd->buyer_id != buyer_id )
	{// not online, not buying or not same store
		clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
		return;
	}

	if( !searchstore->queryremote(sd, account_id) && ( sd->bl.m != pl_sd->bl.m || !check_distance_bl(&sd->bl, &pl_sd->bl, AREA_SIZE) ) )
	{// out of view range
		clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
		return;
	}

	searchstore->clearremote(sd);

	if( pl_sd->status.zeny < pl_sd->buyingstore.zenylimit )
	{// buyer lost zeny in the mean time? fix the limit
		pl_sd->buyingstore.zenylimit = pl_sd->status.zeny;
	}
	weight = pl_sd->weight;

	// check item list
	for( i = 0; i < count; i++ )
	{// itemlist: <index>.W <name id>.W <amount>.W
		unsigned short nameid, amount;
		int index;

		index  = RBUFW(itemlist,i*6+0)-2;
		nameid = RBUFW(itemlist,i*6+2);
		amount = RBUFW(itemlist,i*6+4);

		if( i )
		{// duplicate check. as the client does this too, only malicious intent should be caught here
			ARR_FIND( 0, i, k, RBUFW(itemlist,k*6+0)-2 == index );
			if( k != i )
			{// duplicate
				ShowWarning("buyingstore_trade: Found duplicate item on selling list (prevnameid=%hu, prevamount=%hu, nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n",
					RBUFW(itemlist,k*6+2), RBUFW(itemlist,k*6+4), nameid, amount, sd->status.account_id, sd->status.char_id);
				clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
				return;
			}
		}

		if( index < 0 || index >= ARRAYLENGTH(sd->status.inventory) || sd->inventory_data[index] == NULL || sd->status.inventory[index].nameid != nameid || sd->status.inventory[index].amount < amount )
		{// invalid input
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
			return;
		}

		if( sd->status.inventory[index].expire_time || !itemdb_cantrade(&sd->status.inventory[index], pc->get_group_level(sd), pc->get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore_blankslots, sizeof(buyingstore_blankslots)) )
		{// non-tradable item
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
			return;
		}

		ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
		if( listidx == pl_sd->buyingstore.slots || pl_sd->buyingstore.items[listidx].amount == 0 )
		{// there is no such item or the buyer has already bought all of them
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
			return;
		}

		if( pl_sd->buyingstore.items[listidx].amount < amount )
		{// buyer does not need that much of the item
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_COUNT, nameid);
			return;
		}

		if( pc->checkadditem(pl_sd, nameid, amount) == ADDITEM_OVERAMOUNT )
		{// buyer does not have enough space for this item
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
			return;
		}

		if( amount*(unsigned int)sd->inventory_data[index]->weight > pl_sd->max_weight-weight )
		{// normally this is not supposed to happen, as the total weight is
		 // checked upon creation, but the buyer could have gained items
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid);
			return;
		}
		weight+= amount*sd->inventory_data[index]->weight;

		if( amount*pl_sd->buyingstore.items[listidx].price > pl_sd->buyingstore.zenylimit-zeny )
		{// buyer does not have enough zeny
			clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_ZENY, nameid);
			return;
		}
		zeny+= amount*pl_sd->buyingstore.items[listidx].price;
	}

	// process item list
	for( i = 0; i < count; i++ )
	{// itemlist: <index>.W <name id>.W <amount>.W
		unsigned short nameid, amount;
		int index;

		index  = RBUFW(itemlist,i*6+0)-2;
		nameid = RBUFW(itemlist,i*6+2);
		amount = RBUFW(itemlist,i*6+4);

		ARR_FIND( 0, pl_sd->buyingstore.slots, listidx, pl_sd->buyingstore.items[listidx].nameid == nameid );
		zeny = amount*pl_sd->buyingstore.items[listidx].price;

		// move item
		pc->additem(pl_sd, &sd->status.inventory[index], amount, LOG_TYPE_BUYING_STORE);
		pc->delitem(sd, index, amount, 1, 0, LOG_TYPE_BUYING_STORE);
		pl_sd->buyingstore.items[listidx].amount-= amount;

		// pay up
		pc->payzeny(pl_sd, zeny, LOG_TYPE_BUYING_STORE, sd);
		pc->getzeny(sd, zeny, LOG_TYPE_BUYING_STORE, pl_sd);
		pl_sd->buyingstore.zenylimit-= zeny;

		// notify clients
		clif->buyingstore_delete_item(sd, index, amount, pl_sd->buyingstore.items[listidx].price);
		clif->buyingstore_update_item(pl_sd, nameid, amount);
	}

	if( iMap->save_settings&128 ) {
		chrif_save(sd, 0);
		chrif_save(pl_sd, 0);
	}
	
	// check whether or not there is still something to buy
	ARR_FIND( 0, pl_sd->buyingstore.slots, i, pl_sd->buyingstore.items[i].amount != 0 );
	if( i == pl_sd->buyingstore.slots )
	{// everything was bought
		clif->buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_NO_ITEMS);
	}
	else if( pl_sd->buyingstore.zenylimit == 0 )
	{// zeny limit reached
		clif->buyingstore_trade_failed_buyer(pl_sd, BUYINGSTORE_TRADE_BUYER_ZENY);
	}
	else
	{// continue buying
		return;
	}

	// cannot continue buying
	buyingstore_close(pl_sd);

	// remove auto-trader
	if( pl_sd->state.autotrade )
	{
		iMap->quit(pl_sd);
	}
}
Example #3
0
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count)
{
	unsigned int i;
	struct map_session_data* pl_sd;
	struct DBIterator *iter;
	struct s_search_store_search s;
	searchstore_searchall_t store_searchall;
	time_t querytime;

	if( !battle_config.feature_search_stores ) {
		return;
	}

	if( !sd->searchstore.open ) {
		return;
	}

	if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL ) {
		ShowError("searchstore_query: Tipo de procura desconhecida %u (account_id=%d).\n", (unsigned int)type, sd->bl.id);
		return;
	}

	time(&querytime);

	if( sd->searchstore.nextquerytime > querytime ) {
		clif->search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME);
		return;
	}

	if( !sd->searchstore.uses ) {
		clif->search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT);
		return;
	}

	// validate lists
	for( i = 0; i < item_count; i++ ) {
		if( !itemdb->exists(itemlist[i]) ) {
			ShowWarning("searchstore_query: Item do Client determinado %hu nao se sabe.\n", itemlist[i]);
			clif->search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
			return;
		}
	}
	for( i = 0; i < card_count; i++ ) {
		if( !itemdb->exists(cardlist[i]) ) {
			ShowWarning("searchstore_query: Carta do Client determinado %hu nao se sabe.\n", cardlist[i]);
			clif->search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
			return;
		}
	}

	if( max_price < min_price ) {
		swap(min_price, max_price);
	}

	sd->searchstore.uses--;
	sd->searchstore.type = type;
	sd->searchstore.nextquerytime = querytime+battle_config.searchstore_querydelay;

	// drop previous results
	searchstore->clear(sd);

	// allocate max. amount of results
	sd->searchstore.items = (struct s_search_store_info_item*)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);

	// search
	s.search_sd  = sd;
	s.itemlist   = itemlist;
	s.cardlist   = cardlist;
	s.item_count = item_count;
	s.card_count = card_count;
	s.min_price  = min_price;
	s.max_price  = max_price;
	iter         = db_iterator(vending->db);

	for( pl_sd = dbi_first(iter); dbi_exists(iter);  pl_sd = dbi_next(iter) ) {
		if( sd == pl_sd ) {// skip own shop, if any
			continue;
		}

		if( !store_searchall(pl_sd, &s) ) {// exceeded result size
			clif->search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT);
			break;
		}
	}

	dbi_destroy(iter);

	if( sd->searchstore.count ) {
		// reclaim unused memory
		sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);

		// present results
		clif->search_store_info_ack(sd);

		// one page displayed
		sd->searchstore.pages++;
	} else {
		// cleanup
		searchstore->clear(sd);

		// update uses
		clif->search_store_info_ack(sd);

		// notify of failure
		clif->search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
	}
}
Example #4
0
/*==========================================
 * processes one itemdb entry
 *------------------------------------------*/
static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt)
{
	/*
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		| 00 |      01      |       02      |  03  |     04    |     05     |   06   |   07   |    08   |   09  |   10  |     11     |      12     |       13      |        14       |      15      |      16     |     17     |  18  |   19   |      20      |        21      |
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		| id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
	*/
	int nameid;
	struct item_data* id;
	
	nameid = atoi(str[0]);
	if( nameid <= 0 )
	{
		ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
		return false;
	}

	//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
	id = itemdb_load(nameid);
	safestrncpy(id->name, str[1], sizeof(id->name));
	safestrncpy(id->jname, str[2], sizeof(id->jname));

	id->type = atoi(str[3]);

	if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_DELAYCONSUME && id->type < IT_THROWWEAPON ) || id->type >= IT_MAX )
	{// catch invalid item types
		ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid);
		id->type = IT_ETC;
	}

	if (id->type == IT_DELAYCONSUME)
	{	//Items that are consumed only after target confirmation
		id->type = IT_USABLE;
		id->flag.delay_consume = 1;
	} else //In case of an itemdb reload and the item type changed.
		id->flag.delay_consume = 0;

	//When a particular price is not given, we should base it off the other one
	//(it is important to make a distinction between 'no price' and 0z)
	if ( str[4][0] )
		id->value_buy = atoi(str[4]);
	else
		id->value_buy = atoi(str[5]) * 2;

	if ( str[5][0] )
		id->value_sell = atoi(str[5]);
	else
		id->value_sell = id->value_buy / 2;
	/* 
	if ( !str[4][0] && !str[5][0])
	{  
		ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n",       nameid, id->jname);
		id->value_buy = 20;
		id->value_sell = 10;
	} else
	*/
	if (id->value_buy/124. < id->value_sell/75.)
		ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit  through buying/selling at discounted/overcharged prices!\n",
			id->value_buy, id->value_sell, nameid, id->jname);

	id->weight = atoi(str[6]);
#if REMODE
	itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
#else
	id->atk = atoi(str[7]);
#endif
	id->def = atoi(str[8]);
	id->range = atoi(str[9]);
	id->slot = atoi(str[10]);

	if (id->slot > MAX_SLOTS)
	{
		ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
		id->slot = MAX_SLOTS;
	}

	itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
	id->class_upper = atoi(str[12]);
	id->sex	= atoi(str[13]);
	id->equip = atoi(str[14]);

	if (!id->equip && itemdb_isequip2(id))
	{
		ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
		id->type = IT_ETC;
	}

	id->wlv = atoi(str[15]);
	id->elv = atoi(str[16]);
	id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
	id->look = atoi(str[18]);

	id->flag.available = 1;
	id->view_id = 0;
	id->sex = itemdb_gendercheck(id); //Apply gender filtering.

	if (id->script)
	{
		script_free_code(id->script);
		id->script = NULL;
	}
	if (id->equip_script)
	{
		script_free_code(id->equip_script);
		id->equip_script = NULL;
	}
	if (id->unequip_script)
	{
		script_free_code(id->unequip_script);
		id->unequip_script = NULL;
	}

	if (*str[19])
		id->script = parse_script(str[19], source, line, scriptopt);
	if (*str[20])
		id->equip_script = parse_script(str[20], source, line, scriptopt);
	if (*str[21])
		id->unequip_script = parse_script(str[21], source, line, scriptopt);

	return true;
}
Example #5
0
void netbuffer_init()
{
    char localsection[32];
    raconf conf;
    sysint i;

    // Initialize Statistic counters:
    l_nEmergencyAllocations = 0;

    // Set localsection name according to running serverype.
    switch(SERVER_TYPE) {
    case SERVER_TYPE_LOGIN:
        strcpy(localsection, "login-netbuffer");
        break;
    case SERVER_TYPE_CHAR:
        strcpy(localsection, "char-netbuffer");
        break;
    //case ATHENA_SERVER_INTER:	strcpy(localsection, "inter-netbuffer");		break;
    case SERVER_TYPE_MAP:
        strcpy(localsection, "map-netbuffer");
        break;
    default:
        strcpy(localsection, "unsupported_type");
        break;
    }


    conf = raconf_parse("conf/network.conf");
    if(conf == NULL) {
        ShowFatalError(read_message("Source.common.net_buffer_init"));
        exit(EXIT_FAILURE);
    }

    // Get Values from config file
    l_nPools = (sysint)raconf_getintEx(conf,  localsection,  "netbuffer", "num", 0);
    if(l_nPools == 0) {
        ShowFatalError(read_message("Source.common.net_buffer_init2"));
        exit(EXIT_FAILURE);
    }

    // Allocate arrays.
    l_poolElemSize = (sysint *)aCalloc(l_nPools, sizeof(sysint));
    l_pool = (mempool *)aCalloc(l_nPools, sizeof(mempool));


    for(i = 0; i < l_nPools; i++) {
        int64 num_prealloc, num_realloc;
        char key[32];

        sprintf(key, "pool_%u_size", (uint32)i+1);
        l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096);
        if(l_poolElemSize[i] < 32) {
            ShowWarning(read_message("Source.common.net_buffer_init3"));
            l_poolElemSize[i] = 32;
        }

        sprintf(key, "pool_%u_prealloc", (uint32)i+1);
        num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150);

        sprintf(key, "pool_%u_realloc_step", (uint32)i+1);
        num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100);

        // Create Pool!
        sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name.

        // Info
        ShowInfo(read_message("Source.net_buffer_init4"), l_poolElemSize[i], num_prealloc, num_realloc, (float)((sizeof(struct netbuf) + l_poolElemSize[i] - 32)* num_prealloc)/1024.0f/1024.0f);

        //
        // Size Calculation:
        //  struct netbuf  +  requested buffer size - 32 (because the struct already contains 32 byte buffer space at the end of struct)
        l_pool[i] = mempool_create(key, (sizeof(struct netbuf) + l_poolElemSize[i] - 32),  num_prealloc,  num_realloc, NULL, NULL);
        if(l_pool[i] == NULL) {
            ShowFatalError(read_message("Source.net_buffer_init5"), l_poolElemSize[i]);
            // @leak: clean everything :D
            exit(EXIT_FAILURE);
        }

    }//


    raconf_destroy(conf);

}//end: netbuffer_init()
Example #6
0
Plugin* plugin_open(const char* filename)
{
	Plugin* plugin;
	Plugin_Info* info;
	Plugin_Event_Table* events;
	void** procs;
	int init_flag = 1;

	//ShowDebug("plugin_open(%s)\n", filename);
	
	// Check if the plugin has been loaded before
	plugin = plugin_head;
	while (plugin) {
		// returns handle to the already loaded plugin
		if( plugin->state && strcmpi(plugin->filename, filename) == 0 ){
			ShowWarning("plugin_open: not loaded (duplicate) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
			return plugin;
		}
		plugin = plugin->next;
	}

	CREATE(plugin, Plugin, 1);
	plugin->state = -1;	// not loaded

	plugin->dll = DLL_OPEN(filename);
	if( !plugin->dll ){
		ShowWarning("plugin_open: not loaded (invalid file) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
		plugin_unload(plugin);
		return NULL;
	}

	// Retrieve plugin information
	plugin->state = 0;	// initialising
	info = (Plugin_Info*)DLL_SYM(plugin->dll, "plugin_info");
	// For high priority plugins (those that are explicitly loaded from the conf file)
	// we'll ignore them even (could be a 3rd party dll file)
	if( !info )
	{// foreign plugin
		//ShowDebug("plugin_open: plugin_info not found\n");
		if( load_priority == 0 )
		{// not requested
			//ShowDebug("plugin_open: not loaded (not requested) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
			plugin_unload(plugin);
			return NULL;
		}
	} else if( !plugin_iscompatible(info->req_version) )
	{// incompatible version
		ShowWarning("plugin_open: not loaded (incompatible version '%s' -> '%s') : '"CL_WHITE"%s"CL_RESET"'\n", info->req_version, PLUGIN_VERSION, filename);
		plugin_unload(plugin);
		return NULL;
	} else if( (info->type != PLUGIN_ALL && info->type != PLUGIN_CORE && info->type != SERVER_TYPE) ||
		(info->type == PLUGIN_CORE && SERVER_TYPE != PLUGIN_LOGIN && SERVER_TYPE != PLUGIN_CHAR && SERVER_TYPE != PLUGIN_MAP) )
	{// not for this server
		//ShowDebug("plugin_open: not loaded (incompatible) : '"CL_WHITE"%s"CL_RESET"'\n", filename);
		plugin_unload(plugin);
		return NULL;
	}

	plugin->info = ( info != NULL ? info : &default_info );
	plugin->filename = aStrdup(filename);

	// Initialise plugin call table (For exporting procedures)
	procs = (void**)DLL_SYM(plugin->dll, "plugin_call_table");
	if( procs )
		*procs = plugin_call_table;
	//else ShowDebug("plugin_open: plugin_call_table not found\n");

	// Register plugin events
	events = (Plugin_Event_Table*)DLL_SYM(plugin->dll, "plugin_event_table");
	if( events ){
		int i = 0;
		//ShowDebug("plugin_open: parsing plugin_event_table\n");
		while( events[i].func_name ){
			if( strcmpi(events[i].event_name, EVENT_PLUGIN_TEST) == 0 ){
				Plugin_Test_Func* test_func;
				test_func = (Plugin_Test_Func*)DLL_SYM(plugin->dll, events[i].func_name);
				//ShowDebug("plugin_open: invoking "EVENT_PLUGIN_TEST" with %s()\n", events[i].func_name);
				if( test_func && test_func() == 0 ){
					// plugin has failed test, disabling
					//ShowDebug("plugin_open: disabled (failed test) : %s\n", filename);
					init_flag = 0;
				}
			} else {
				Plugin_Event_Func* func;
				func = (Plugin_Event_Func*)DLL_SYM(plugin->dll, events[i].func_name);
				if (func)
					register_plugin_event(func, events[i].event_name);
			}
			i++;
		}
	}
	//else ShowDebug("plugin_open: plugin_event_table not found\n");

	plugin->next = plugin_head;
	plugin_head = plugin;

	plugin->state = init_flag;	// fully loaded
	ShowStatus("Done loading plugin '"CL_WHITE"%s"CL_RESET"'\n", (info) ? plugin->info->name : filename);

	return plugin;
}
/// opens accounts file, loads it, and starts a periodic saving timer
static bool account_db_txt_init(AccountDB* self)
{
	AccountDB_TXT* db = (AccountDB_TXT*)self;
	DBMap* accounts;
	FILE* fp;
	char line[2048];
	unsigned int version = 0;

	// create accounts database
	db->accounts = idb_alloc(DB_OPT_RELEASE_DATA);
	accounts = db->accounts;

	// open data file
	fp = fopen(db->account_db, "r");
	if( fp == NULL )
	{
		// no account file -> no account -> no login, including char-server (ERROR)
		ShowError(CL_RED"account_db_txt_init: Accounts file [%s] not found."CL_RESET"\n", db->account_db);
		return false;
	}

	// load data file
	while( fgets(line, sizeof(line), fp) != NULL )
	{
		int account_id, n;
		unsigned int v;
		struct mmo_account acc;
		struct mmo_account* tmp;
		struct DBIterator* iter;
		int (*compare)(const char* str1, const char* str2) = ( db->case_sensitive ) ? strcmp : stricmp;

		if( line[0] == '/' && line[1] == '/' )
			continue;

		n = 0;
		if( sscanf(line, "%d%n", &v, &n) == 1 && (line[n] == '\n' || line[n] == '\r') )
		{// format version definition
			version = v;
			continue;
		}

		n = 0;
		if( sscanf(line, "%d\t%%newid%%%n", &account_id, &n) == 1 && (line[n] == '\n' || line[n] == '\r') )
		{// auto-increment
			if( account_id > db->next_account_id )
				db->next_account_id = account_id;
			continue;
		}

		if( !mmo_auth_fromstr(&acc, line, version) )
		{
			ShowError("account_db_txt_init: skipping invalid data: %s", line);
			continue;
		}

		// apply constraints & checks here
		if( acc.sex != 'S' && (acc.account_id < START_ACCOUNT_NUM || acc.account_id > END_ACCOUNT_NUM) )
			ShowWarning("account_db_txt_init: account %d:'%s' has ID outside of the defined range for accounts (min:%d max:%d)!\n", acc.account_id, acc.userid, START_ACCOUNT_NUM, END_ACCOUNT_NUM);

		iter = accounts->iterator(accounts);
		for( tmp = (struct mmo_account*)iter->first(iter,NULL); iter->exists(iter); tmp = (struct mmo_account*)iter->next(iter,NULL) )
			if( compare(acc.userid, tmp->userid) == 0 )
					break;
		iter->destroy(iter);

		if( tmp != NULL )
		{// entry with identical username
			ShowWarning("account_db_txt_init: account %d:'%s' has same username as account %d. The account will be inaccessible!\n", acc.account_id, acc.userid, tmp->account_id);
		}

		if( idb_get(accounts, acc.account_id) != NULL )
		{// account id already occupied
			ShowError("account_db_txt_init: ID collision for account id %d! Discarding data for account '%s'...\n", acc.account_id, acc.userid);
			continue;
		}

		// record entry in db
		tmp = (struct mmo_account*)aMalloc(sizeof(struct mmo_account));
		memcpy(tmp, &acc, sizeof(struct mmo_account));
		idb_put(accounts, acc.account_id, tmp);

		if( acc.account_id >= db->next_account_id )
			db->next_account_id = acc.account_id + 1;
	}

	// close data file
	fclose(fp);

	// initialize data saving timer
	add_timer_func_list(mmo_auth_sync_timer, "mmo_auth_sync_timer");
	db->save_timer = add_timer_interval(gettick() + AUTH_SAVING_INTERVAL, mmo_auth_sync_timer, 0, (intptr)db, AUTH_SAVING_INTERVAL);

	return true;
}
Example #8
0
/*==========================================
 *
 *------------------------------------------*/
int chrif_parse(int fd) {
	int packet_len, cmd;

	// only process data from the char-server
	if ( fd != char_fd ) {
		ShowDebug("chrif_parse: Disconnecting invalid session #%d (is not the char-server)\n", fd);
		do_close(fd);
		return 0;
	}

	if ( session[fd]->flag.eof ) {
		do_close(fd);
		char_fd = -1;
		chrif_on_disconnect();
		return 0;
	} else if ( session[fd]->flag.ping ) {/* we've reached stall time */
		if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */
			set_eof(fd);
			return 0;
		} else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */
			chrif_keepalive(fd);
			session[fd]->flag.ping = 2;
		}
	}

	while ( RFIFOREST(fd) >= 2 ) {
		cmd = RFIFOW(fd,0);
		if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(packet_len_table) || packet_len_table[cmd-0x2af8] == 0) {
			int r = intif_parse(fd); // Passed on to the intif

			if (r == 1) continue;	// Treated in intif 
			if (r == 2) return 0;	// Didn't have enough data (len==-1)

			ShowWarning("chrif_parse: session #%d, intif_parse failed (unrecognized command 0x%.4x).\n", fd, cmd);
			set_eof(fd);
			return 0;
		}

		if ( ( packet_len = packet_len_table[cmd-0x2af8] ) == -1) { // dynamic-length packet, second WORD holds the length
			if (RFIFOREST(fd) < 4)
				return 0;
			packet_len = RFIFOW(fd,2);
		}

		if ((int)RFIFOREST(fd) < packet_len)
			return 0;

		//ShowDebug("Received packet 0x%4x (%d bytes) from char-server (connection %d)\n", RFIFOW(fd,0), packet_len, fd);

		switch(cmd) {
			case 0x2af9: chrif_connectack(fd); break;
			case 0x2afb: chrif_sendmapack(fd); break;
			case 0x2afd: chrif_authok(fd); break;
			case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
			case 0x2b03: clif->charselectok(RFIFOL(fd,2), RFIFOB(fd,6)); break;
			case 0x2b04: chrif_recvmap(fd); break;
			case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
			case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
			case 0x2b0a: socket_datasync(fd, false); break;
			case 0x2b0d: chrif_changedsex(fd); break;
			case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
			case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
			case 0x2b14: chrif_accountban(fd); break;
			case 0x2b1b: chrif_recvfamelist(fd); break;
			case 0x2b1d: chrif_load_scdata(fd); break;
			case 0x2b1e: chrif_update_ip(fd); break;
			case 0x2b1f: chrif_disconnectplayer(fd); break;
			case 0x2b20: chrif_removemap(fd); break;
			case 0x2b21: chrif_save_ack(fd); break;
			case 0x2b22: chrif_updatefamelist_ack(fd); break;
			case 0x2b24: chrif_keepalive_ack(fd); break;
			case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
			case 0x2b27: chrif_authfail(fd); break;
			default:
				ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
				set_eof(fd);
				return 0;
		}
		if ( fd == char_fd ) //There's the slight chance we lost the connection during parse, in which case this would segfault if not checked [Skotlex]
			RFIFOSKIP(fd, packet_len);
	}

	return 0;
}
Example #9
0
// Wisp/page request to send
int mapif_parse_WisRequest(int fd) {
	struct WisData* wd;
	static int wisid = 0;
	char name[NAME_LENGTH], t_name[NAME_LENGTH*2]; //Needs space to allocate names with escaped chars [Skotlex]

	if ( fd <= 0 ) {return 0;} // check if we have a valid fd

	if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
		ShowWarning("inter: Wis message size too long.\n");
		return 0;
	} else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
		ShowError("inter: Wis message doesn't exist.\n");
		return 0;
	}
	memcpy(name, RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]
	name[NAME_LENGTH-1]= '\0';
	
	sprintf (tmp_sql, "SELECT `name` FROM `%s` WHERE `name`='%s'",
		char_db, jstrescapecpy(t_name, name));
	if(mysql_query(&mysql_handle, tmp_sql) ) {
		ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
		ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
	}
	sql_res = mysql_store_result(&mysql_handle);

	// search if character exists before to ask all map-servers
	if (!(sql_row = mysql_fetch_row(sql_res))) {
		unsigned char buf[27];
		WBUFW(buf, 0) = 0x3802;
		memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
		WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
		mapif_send(fd, buf, 27);
	// Character exists. So, ask all map-servers
	} else {
		// to be sure of the correct name, rewrite it
		memset(name, 0, NAME_LENGTH);
		strncpy(name, sql_row[0], NAME_LENGTH);
		// if source is destination, don't ask other servers.
		if (strcmp((char*)RFIFOP(fd,4),name) == 0) {
			unsigned char buf[27];
			WBUFW(buf, 0) = 0x3802;
			memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
			WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
			mapif_send(fd, buf, 27);
		} else {

	CREATE(wd, struct WisData, 1);

			// Whether the failure of previous wisp/page transmission (timeout)
			check_ttl_wisdata();

			wd->id = ++wisid;
			wd->fd = fd;
			wd->len= RFIFOW(fd,2)-52;
			memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
			memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
			memcpy(wd->msg, RFIFOP(fd,52), wd->len);
			wd->tick = gettick();
			numdb_insert(wis_db, wd->id, wd);
			mapif_wis_message(wd);
		}
	}
	
	//Freeing ... O.o 
	if(sql_res){
		mysql_free_result(sql_res);
	}
	
	return 0;
}
Example #10
0
/**
* Read each line of Mercenary's database
**/
static bool mercenary_readdb_sub(char* str[], int columns, int current)
{
	int ele;
	uint16 i, class_ = atoi(str[0]);
	struct s_mercenary_db *db;
	struct status_data *status;

	//Find the ID, already exist or not in mercenary_db
	ARR_FIND(0,mercenary_count,i,mercenary_db[i].class_ == class_);
	if (i >= mercenary_count)
		db = &mercenary_db[mercenary_count];
	else
		db = &mercenary_db[i];

	db->class_ = class_;
	safestrncpy(db->sprite, str[1], NAME_LENGTH);
	safestrncpy(db->name, str[2], NAME_LENGTH);
	db->lv = atoi(str[3]);

	status = &db->status;
	db->vd.class_ = db->class_;

	status->max_hp = atoi(str[4]);
	status->max_sp = atoi(str[5]);
	status->rhw.range = atoi(str[6]);
	status->rhw.atk = atoi(str[7]);
	status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
	status->def = atoi(str[9]);
	status->mdef = atoi(str[10]);
	status->str = atoi(str[11]);
	status->agi = atoi(str[12]);
	status->vit = atoi(str[13]);
	status->int_ = atoi(str[14]);
	status->dex = atoi(str[15]);
	status->luk = atoi(str[16]);
	db->range2 = atoi(str[17]);
	db->range3 = atoi(str[18]);
	status->size = atoi(str[19]);
	status->race = atoi(str[20]);

	ele = atoi(str[21]);
	status->def_ele = ele%20;
	status->ele_lv = (unsigned char)floor(ele/20.);
	if( !CHK_ELEMENT(status->def_ele) )
	{
		ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_ALL - 1);
		status->def_ele = ELE_NEUTRAL;
	}
	if( !CHK_ELEMENT_LEVEL(status->ele_lv) )
	{
		ShowWarning("Mercenary %d has invalid element level %d (max is %d)\n", db->class_, status->ele_lv, MAX_ELE_LEVEL);
		status->ele_lv = 1;
	}

	status->aspd_rate = 1000;
	status->speed = atoi(str[22]);
	status->adelay = atoi(str[23]);
	status->amotion = atoi(str[24]);
	status->dmotion = atoi(str[25]);
	
	if (i >= mercenary_count)
		mercenary_count++;
	return true;
}
Example #11
0
void yaml_invalid_warning(const char* fmt, YAML::Node &node, std::string &file) {
	YAML::Emitter out;
	out << node;
	ShowWarning(fmt, file.c_str());
	ShowMessage("%s\n", out.c_str());
}
Example #12
0
void CZone::DecreaseZoneCounter(CCharEntity* PChar)
{
    DSP_DEBUG_BREAK_IF(PChar == NULL);
    DSP_DEBUG_BREAK_IF(PChar->loc.zone != this);

	//remove pets
	if(PChar->PPet != NULL)
    {
		charutils::BuildingCharPetAbilityTable(PChar,(CPetEntity*)PChar->PPet,0);//blank the pet commands
		if(PChar->PPet->isCharmed) {
			petutils::DespawnPet(PChar);
		}
		else {
			PChar->PPet->status = STATUS_DISAPPEAR;
			if( ((CPetEntity*)(PChar->PPet))->getPetType() == PETTYPE_AVATAR )
				PChar->setModifier(MOD_AVATAR_PERPETUATION, 0);
		}
		// It may have been nulled by DespawnPet
		if(PChar->PPet != NULL) {
			PChar->PPet->PBattleAI->SetCurrentAction(ACTION_NONE);
			DeletePET(PChar->PPet);//remove the TID for this pet

			for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it)
			{
				//inform other players of the pets removal
				CCharEntity* PCurrentChar = (CCharEntity*)it->second;
				SpawnIDList_t::iterator PET = PCurrentChar->SpawnPETList.find(PChar->PPet->id);

				if( PET != PCurrentChar->SpawnPETList.end() )
				{
					PCurrentChar->SpawnPETList.erase(PET);
					PCurrentChar->pushPacket(new CEntityUpdatePacket(PChar->PPet, ENTITY_DESPAWN));
				}
			}
			PChar->PPet = NULL;
		}
	}

	//remove bcnm status
	if(m_InstanceHandler != NULL && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_BATTLEFIELD))
    {
		if(m_InstanceHandler->disconnectFromBcnm(PChar)){
			ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n",PChar->GetName());
		}

		if(PChar->loc.destination==0){ //this player is disconnecting/logged out, so move them to the entrance
			//move depending on zone
			int pos[4] = {0,0,0,0};
			instanceutils::getStartPosition(m_zoneID,pos);
			if(pos!=NULL){
				PChar->loc.p.x = pos[0];
				PChar->loc.p.y = pos[1];
				PChar->loc.p.z = pos[2];
				PChar->loc.p.rotation = pos[3];
				charutils::SaveCharPosition(PChar);
			}
			else{
				ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n",PChar->GetName());
			}
		}
	}
	else if(m_InstanceHandler != NULL && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_DYNAMIS, 0))
    {
		if(m_InstanceHandler->disconnectFromDynamis(PChar)){
			ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n",PChar->GetName());
		}

		if(PChar->loc.destination==0){ //this player is disconnecting/logged out, so move them to the entrance
			//move depending on zone
			int pos[4] = {0,0,0,0};
			instanceutils::getStartPosition(m_zoneID,pos);
			if(pos!=NULL){
				PChar->loc.p.x = pos[0];
				PChar->loc.p.y = pos[1];
				PChar->loc.p.z = pos[2];
				PChar->loc.p.rotation = pos[3];
				charutils::SaveCharPosition(PChar);
			}
			else{
				ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n",PChar->GetName());
			}
		}
	}

	for (EntityList_t::const_iterator it = m_mobList.begin() ; it != m_mobList.end() ; ++it)
	{
		CMobEntity* PCurrentMob = (CMobEntity*)it->second;
		PCurrentMob->PEnmityContainer->Clear(PChar->id);
		if(PCurrentMob->m_OwnerID.id == PChar->id){
			PCurrentMob->m_OwnerID.clean();
		}
	}

    // TODO: могут возникать проблемы с переходом между одной и той же зоной (zone == prevzone)

	m_charList.erase(PChar->targid);

	ShowDebug(CL_CYAN"CZone:: %s DecreaseZoneCounter <%u> %s\n" CL_RESET, GetName(), m_charList.size(),PChar->GetName());

	if (ZoneTimer && m_charList.empty())
	{
		ZoneTimer->m_type = CTaskMgr::TASK_REMOVE;
		ZoneTimer = NULL;

        HealAllMobs();
	}
	else
	{
		for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it)
		{
			CCharEntity* PCurrentChar = (CCharEntity*)it->second;
			SpawnIDList_t::iterator PC = PCurrentChar->SpawnPCList.find(PChar->id);

			if( PC != PCurrentChar->SpawnPCList.end() )
			{
				PCurrentChar->SpawnPCList.erase(PC);
				PCurrentChar->pushPacket(new CCharPacket(PChar,ENTITY_DESPAWN));
			}
		}
	}
	if (PChar->m_LevelRestriction != 0)
	{
        if (PChar->PParty)
        {
            if (PChar->PParty->GetSyncTarget() == PChar || PChar->PParty->GetLeader() == PChar)
            {
                PChar->PParty->SetSyncTarget(NULL, 551);
            }
            if (PChar->PParty->GetSyncTarget() != NULL)
            {
                uint8 count = 0;
                for (uint32 i = 0; i < PChar->PParty->members.size(); ++i)
                {
                    if (PChar->PParty->members.at(i) != PChar && PChar->PParty->members.at(i)->getZone() == PChar->PParty->GetSyncTarget()->getZone())
                    {
                        count++;
                    }
                }
                if (count < 2) //3, because one is zoning out - thus at least 2 will be left
                {
                    PChar->PParty->SetSyncTarget(NULL, 552);
                }
            }
        }
		PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_LEVEL_SYNC);
		PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_LEVEL_RESTRICTION);
	}
	if (PChar->PTreasurePool != NULL) // TODO: условие для устранения проблем с MobHouse, надо блин решить ее раз и навсегда
	{
		PChar->PTreasurePool->DelMember(PChar);
	}
    for (regionList_t::const_iterator region = m_regionList.begin(); region != m_regionList.end(); ++region)
    {
        if ((*region)->GetRegionID() == PChar->m_InsideRegionID)
        {
            luautils::OnRegionLeave(PChar, *region);
            break;
        }
    }

    PChar->loc.zone = NULL;
    PChar->loc.prevzone = m_zoneID;

    PChar->SpawnPCList.clear();
	PChar->SpawnNPCList.clear();
	PChar->SpawnMOBList.clear();
	PChar->SpawnPETList.clear();
}
Example #13
0
int read_elemental_skilldb(void)
{
	FILE *fp;
	char line[1024], *p;
	char *str[4];
	struct s_elemental_db *db;
	int i, j = 0, k = 0, class_;
	int skillid, skilllv, skillmode;

	sprintf(line, "%s/%s", db_path, "elemental_skill_db.txt");
	fp = fopen(line, "r");
	if( !fp )
	{
		ShowError("read_elemental_skilldb : can't read elemental_skill_db.txt\n");
		return -1;
	}

	while( fgets(line, sizeof(line), fp) )
	{
		k++;
		if( line[0] == '/' && line[1] == '/' )
			continue;

		i = 0;
		p = strtok(line, ",");
		while( p != NULL && i < 4 )
		{
			str[i++] = p;
			p = strtok(NULL, ",");
		}
		if( i < 4 )
		{
			ShowError("read_elemental_skilldb : Incorrect number of columns at elemental_skill_db.txt line %d.\n", k);
			continue;
		}

		class_ = atoi(str[0]);
		ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
		if( i == MAX_ELEMENTAL_CLASS )
		{
			ShowError("read_elemental_skilldb : Class not found in elemental_db for skill entry, line %d.\n", k);
			continue;
		}
		
		skillid = atoi(str[1]);
		if( skillid < EL_SKILLBASE || skillid >= EL_SKILLBASE + MAX_ELEMENTALSKILL )
		{
			ShowError("read_elemental_skilldb : Skill out of range, line %d.\n", k);
			continue;
		}

		db = &elemental_db[i];
		skilllv = atoi(str[2]);

		skillmode = atoi(str[3]);
		if( skillmode < EL_SKILLMODE_PASIVE || skillmode > EL_SKILLMODE_AGGRESSIVE )
		{
			ShowError("read_elemental_skilldb : Skillmode out of range, line %d.\n",k);
			skillmode = EL_SKILLMODE_PASIVE;
			continue;
		}
		ARR_FIND( 0, MAX_ELESKILLTREE, i, db->skill[i].id == 0 || db->skill[i].id == skillid );
		if( i == MAX_ELESKILLTREE )
		{
			ShowWarning("Unable to load skill %d into Elemental %d's tree. Maximum number of skills per elemental has been reached.\n", skillid, class_);
			continue;
		}
		db->skill[i].id = skillid;
		db->skill[i].lv = skilllv;
		db->skill[i].mode = skillmode;
		j++;
	}

	fclose(fp);
	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/elemental_skill_db.txt"CL_RESET"'.\n",j);
	return 0;
}
Example #14
0
int read_elementaldb(void)
{
	FILE *fp;
	char line[1024], *p;
	char *str[26];
	int i, j = 0, k = 0, ele;
	struct s_elemental_db *db;
	struct status_data *status;

	sprintf(line, "%s/%s", db_path, "elemental_db.txt");
	memset(elemental_db,0,sizeof(elemental_db));

	fp = fopen(line, "r");
	if( !fp )
	{
		ShowError("read_elementaldb : can't read elemental_db.txt\n");
		return -1;
	}

	while( fgets(line, sizeof(line), fp) && j < MAX_ELEMENTAL_CLASS )
	{
		k++;
		if( line[0] == '/' && line[1] == '/' )
			continue;

		i = 0;
		p = strtok(line, ",");
		while( p != NULL && i < 26 )
		{
			str[i++] = p;
			p = strtok(NULL, ",");
		}
		if( i < 26 )
		{
			ShowError("read_elementaldb : Incorrect number of columns at elemental_db.txt line %d.\n", k);
			continue;
		}

		db = &elemental_db[j];
		db->class_ = atoi(str[0]);
		strncpy(db->sprite, str[1], NAME_LENGTH);
		strncpy(db->name, str[2], NAME_LENGTH);
		db->lv = atoi(str[3]);

		status = &db->status;
		db->vd.class_ = db->class_;

		status->max_hp = atoi(str[4]);
		status->max_sp = atoi(str[5]);
		status->rhw.range = atoi(str[6]);
		status->rhw.atk = atoi(str[7]);
		status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
		status->def = atoi(str[9]);
		status->mdef = atoi(str[10]);
		status->str = atoi(str[11]);
		status->agi = atoi(str[12]);
		status->vit = atoi(str[13]);
		status->int_ = atoi(str[14]);
		status->dex = atoi(str[15]);
		status->luk = atoi(str[16]);
		db->range2 = atoi(str[17]);
		db->range3 = atoi(str[18]);
		status->size = atoi(str[19]);
		status->race = atoi(str[20]);
	
		ele = atoi(str[21]);
		status->def_ele = ele%10;
		status->ele_lv = ele/20;
		if( status->def_ele >= ELE_MAX )
		{
			ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
			status->def_ele = ELE_NEUTRAL;
		}
		if( status->ele_lv < 1 || status->ele_lv > 4 )
		{
			ShowWarning("Elemental %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
			status->ele_lv = 1;
		}

		status->aspd_rate = 1000;
		status->speed = atoi(str[22]);
		status->adelay = atoi(str[23]);
		status->amotion = atoi(str[24]);
		status->dmotion = atoi(str[25]);

		j++;
	}

	fclose(fp);
	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' elementals in '"CL_WHITE"db/elemental_db.txt"CL_RESET"'.\n",j);

	return 0;
}
Example #15
0
/**
* Attempt to create new buying store
* @param sd
* @param zenylimit
* @param result
* @param storename
* @param *itemlist { <nameid>.W, <amount>.W, <price>.L }*
* @param count Number of item on the itemlist
* @return 0 If success, 1 - Cannot open, 2 - Manner penalty, 3 - Mapflag restiction, 4 - Cell restriction, 5 - Invalid count/result, 6 - Cannot give item, 7 - Will be overweight
*/
char buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count)
{
	unsigned int i, weight, listidx;
	char message_sql[MESSAGE_SIZE*2];

	nullpo_retr(1, sd);

	if( !result || count == 0 )
	{// canceled, or no items
		return 5;
	}

	if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] )
	{// disabled or invalid input
		sd->buyingstore.slots = 0;
		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
		return 1;
	}

	if( !pc_can_give_items(sd) )
	{// custom: GM is not allowed to buy (give zeny)
		sd->buyingstore.slots = 0;
		clif_displaymessage(sd->fd, msg_txt(sd,246));
		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
		return 6;
	}

	if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) )
	{// custom: mute limitation
		return 2;
	}

	if( map[sd->bl.m].flag.novending )
	{// custom: no vending maps
		clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map"
		return 3;
	}

	if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) )
	{// custom: no vending cells
		clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
		return 4;
	}

	weight = sd->weight;

	// check item list
	for( i = 0; i < count; i++ )
	{// itemlist: <name id>.W <amount>.W <price>.L
		unsigned short nameid, amount;
		int price, idx;
		struct item_data* id;

		nameid = RBUFW(itemlist,i*8+0);
		amount = RBUFW(itemlist,i*8+2);
		price  = RBUFL(itemlist,i*8+4);

		if( ( id = itemdb_exists(nameid) ) == NULL || amount == 0 )
		{// invalid input
			break;
		}

		if( price <= 0 || price > BUYINGSTORE_MAX_PRICE )
		{// invalid price: unlike vending, items cannot be bought at 0 Zeny
			break;
		}

		if( !id->flag.buyingstore || !itemdb_cantrade_sub(id, pc_get_group_level(sd), pc_get_group_level(sd)) || ( idx = pc_search_inventory(sd, nameid) ) == -1 )
		{// restrictions: allowed, no character-bound items and at least one must be owned
			break;
		}

		if( sd->status.inventory[idx].amount+amount > BUYINGSTORE_MAX_AMOUNT )
		{// too many items of same kind
			break;
		}

		if( i )
		{// duplicate check. as the client does this too, only malicious intent should be caught here
			ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
			if( listidx != i )
			{// duplicate
				ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
				break;
			}
		}

		weight+= id->weight*amount;
		sd->buyingstore.items[i].nameid = nameid;
		sd->buyingstore.items[i].amount = amount;
		sd->buyingstore.items[i].price  = price;
	}

	if( i != count )
	{// invalid item/amount/price
		sd->buyingstore.slots = 0;
		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
		return 5;
	}

	if( (sd->max_weight*90)/100 < weight )
	{// not able to carry all wanted items without getting overweight (90%)
		sd->buyingstore.slots = 0;
		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
		return 7;
	}

	// success
	sd->state.buyingstore = true;
	sd->buyer_id = buyingstore_getuid();
	sd->buyingstore.zenylimit = zenylimit;
	sd->buyingstore.slots = i;  // store actual amount of items
	safestrncpy(sd->message, storename, sizeof(sd->message));

	Sql_EscapeString( mmysql_handle, message_sql, sd->message );

	if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`,`account_id`,`char_id`,`sex`,`map`,`x`,`y`,`title`,`limit`,`autotrade`, `body_direction`, `head_direction`, `sit`) "
		"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, %d, '%d', '%d', '%d' );",
		buyingstores_db, sd->buyer_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->buyingstore.zenylimit, sd->state.autotrade, sd->ud.dir, sd->head_dir, pc_issit(sd) ) != SQL_SUCCESS ){
		Sql_ShowDebug(mmysql_handle);
	}

	for( i = 0; i < sd->buyingstore.slots; i++ ){
		if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`buyingstore_id`,`index`,`item_id`,`amount`,`price`) VALUES( %d, %d, %hu, %d, %d );", buyingstore_items_db, sd->buyer_id, i, sd->buyingstore.items[i].nameid, sd->buyingstore.items[i].amount, sd->buyingstore.items[i].price ) != SQL_SUCCESS ){
			Sql_ShowDebug(mmysql_handle);
		}
	}

	clif_buyingstore_myitemlist(sd);
	clif_buyingstore_entry(sd);
	idb_put(buyingstore_db, sd->status.char_id, sd);

	return 0;
}
Example #16
0
int log_config_read(const char* cfgName)
{
	static int count = 0;
	char line[1024], w1[1024], w2[1024];
	FILE *fp;

	if( count++ == 0 )
		log_set_defaults();

	if( ( fp = fopen(cfgName, "r") ) == NULL )
	{
		ShowError("Log configuration file not found at: %s\n", cfgName);
		return 1;
	}

	while( fgets(line, sizeof(line), fp) )
	{
		if( line[0] == '/' && line[1] == '/' )
			continue;

		if( sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 )
		{
			if( strcmpi(w1, "enable_logs") == 0 )
				log_config.enable_logs = (e_log_pick_type)config_switch(w2);
			else if( strcmpi(w1, "sql_logs") == 0 )
				log_config.sql_logs = (bool)config_switch(w2);
//start of common filter settings
			else if( strcmpi(w1, "rare_items_log") == 0 )
				log_config.rare_items_log = atoi(w2);
			else if( strcmpi(w1, "refine_items_log") == 0 )
				log_config.refine_items_log = atoi(w2);
			else if( strcmpi(w1, "price_items_log") == 0 )
				log_config.price_items_log = atoi(w2);
			else if( strcmpi(w1, "amount_items_log") == 0 )
				log_config.amount_items_log = atoi(w2);
//end of common filter settings
			else if( strcmpi(w1, "log_branch") == 0 )
				log_config.branch = config_switch(w2);
			else if( strcmpi(w1, "log_filter") == 0 )
				log_config.filter = config_switch(w2);
			else if( strcmpi(w1, "log_zeny") == 0 )
				log_config.zeny = config_switch(w2);
			else if( strcmpi( w1, "log_cash" ) == 0 )
				log_config.cash = config_switch( w2 );
			else if( strcmpi(w1, "log_commands") == 0 )
				log_config.commands = config_switch(w2);
			else if( strcmpi(w1, "log_npc") == 0 )
				log_config.npc = config_switch(w2);
			else if( strcmpi(w1, "log_chat") == 0 )
				log_config.chat = config_switch(w2);
			else if( strcmpi(w1, "log_mvpdrop") == 0 )
				log_config.mvpdrop = config_switch(w2);
			else if( strcmpi(w1, "log_chat_woe_disable") == 0 )
				log_config.log_chat_woe_disable = (bool)config_switch(w2);
			else if( strcmpi(w1, "log_branch_db") == 0 )
				safestrncpy(log_config.log_branch, w2, sizeof(log_config.log_branch));
			else if( strcmpi(w1, "log_pick_db") == 0 )
				safestrncpy(log_config.log_pick, w2, sizeof(log_config.log_pick));
			else if( strcmpi(w1, "log_zeny_db") == 0 )
				safestrncpy(log_config.log_zeny, w2, sizeof(log_config.log_zeny));
			else if( strcmpi(w1, "log_mvpdrop_db") == 0 )
				safestrncpy(log_config.log_mvpdrop, w2, sizeof(log_config.log_mvpdrop));
			else if( strcmpi(w1, "log_gm_db") == 0 )
				safestrncpy(log_config.log_gm, w2, sizeof(log_config.log_gm));
			else if( strcmpi(w1, "log_npc_db") == 0 )
				safestrncpy(log_config.log_npc, w2, sizeof(log_config.log_npc));
			else if( strcmpi(w1, "log_chat_db") == 0 )
				safestrncpy(log_config.log_chat, w2, sizeof(log_config.log_chat));
			else if( strcmpi( w1, "log_cash_db" ) == 0 )
				safestrncpy( log_config.log_cash, w2, sizeof( log_config.log_cash ) );
			//support the import command, just like any other config
			else if( strcmpi(w1,"import") == 0 )
				log_config_read(w2);
			else
				ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
		}
	}

	fclose(fp);

	if( --count == 0 )
	{// report final logging state
		const char* target = log_config.sql_logs ? "table" : "file";

		if( log_config.enable_logs && log_config.filter )
		{
			ShowInfo("Logging item transactions to %s '%s'.\n", target, log_config.log_pick);
		}
		if( log_config.branch )
		{
			ShowInfo("Logging monster summon item usage to %s '%s'.\n", target, log_config.log_pick);
		}
		if( log_config.chat )
		{
			ShowInfo("Logging chat to %s '%s'.\n", target, log_config.log_chat);
		}
		if( log_config.commands )
		{
			ShowInfo("Logging commands to %s '%s'.\n", target, log_config.log_gm);
		}
		if( log_config.mvpdrop )
		{
			ShowInfo("Logging MVP monster rewards to %s '%s'.\n", target, log_config.log_mvpdrop);
		}
		if( log_config.npc )
		{
			ShowInfo("Logging 'logmes' messages to %s '%s'.\n", target, log_config.log_npc);
		}
		if( log_config.zeny )
		{
			ShowInfo("Logging Zeny transactions to %s '%s'.\n", target, log_config.log_zeny);
		}
		if( log_config.cash ){
			ShowInfo( "Logging Cash transactions to %s '%s'.\n", target, log_config.log_cash );
		}
	}

	return 0;
}
Example #17
0
static void cevents_init() {
	if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE)
		ShowWarning ("Unable to install the console handler!\n");
}
Example #18
0
bool CStatusEffectContainer::AddStatusEffect(CStatusEffect* PStatusEffect, bool silent)
{
    if(PStatusEffect == nullptr){
        ShowWarning("status_effect_container::AddStatusEffect Status effect given was nullptr!\n");
        return false;
    }

    uint16 statusId = PStatusEffect->GetStatusID();

    if(statusId >= MAX_EFFECTID){
        ShowWarning("status_effect_container::AddStatusEffect statusId given is OVER limit %d\n", statusId);
        return false;
    }

	if(CanGainStatusEffect((EFFECT)statusId, PStatusEffect->GetPower()))
	{

            // check for minimum duration
            if(PStatusEffect->GetDuration() < effects::EffectsParams[statusId].MinDuration){
                PStatusEffect->SetDuration(effects::EffectsParams[statusId].MinDuration);
            }

        // remove clean up other effects
        OverwriteStatusEffect(PStatusEffect);

        PStatusEffect->SetOwner(m_POwner);

        SetEffectParams(PStatusEffect);

        // remove effects with same type
        DelStatusEffectsByType(PStatusEffect->GetType());

        PStatusEffect->SetStartTime(gettick());

        m_StatusEffectList.push_back(PStatusEffect);

        luautils::OnEffectGain(m_POwner, PStatusEffect);

        m_POwner->addModifiers(&PStatusEffect->modList);

        if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER &&
            PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER &&
            m_POwner->objtype == TYPE_PC)
        {
            puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), true);
        }

        if( m_POwner->health.maxhp != 0) //make sure we're not in the middle of logging in
        {
            m_POwner->UpdateHealth();
        }

        if (m_POwner->objtype == TYPE_PC)
        {
            CCharEntity* PChar = (CCharEntity*)m_POwner;

            if (PStatusEffect->GetIcon() != 0)
            {
                UpdateStatusIcons();
            }

			if( m_POwner->health.maxhp != 0) //make sure we're not in the middle of logging in
			{
				//check for latents
				PChar->PLatentEffectContainer->CheckLatentsFoodEffect();
				PChar->PLatentEffectContainer->CheckLatentsStatusEffect();
                PChar->PLatentEffectContainer->CheckLatentsRollSong(PStatusEffect->GetFlag() & (EFFECTFLAG_SONG | EFFECTFLAG_ROLL));
				PChar->UpdateHealth();

				PChar->pushPacket(new CCharHealthPacket(PChar));
			}
            PChar->pushPacket(new CCharSyncPacket(PChar));
        }
        m_POwner->updatemask |= UPDATE_HP;

        return true;
	}

    return false;
}
Example #19
0
static BOOL PrepareToConfig()
{
    BOOL bMustExit = FALSE;

    // Use a local copy of the config info to decide what should be configured
    // or unconfigured.  We do this so that if the user cancels for some reason,
    // the real config state will still be what the user expects (what was
    // previously read from the system plus the user's changes).
    CONFIG_STATE configFS = g_CfgData.configFS;     // File server
    CONFIG_STATE configDB = g_CfgData.configDB;     // Database server
    CONFIG_STATE configBak = g_CfgData.configBak;   // Backup server
    CONFIG_STATE configSCS = g_CfgData.configSCS;   // System Control server
    CONFIG_STATE configSCC = g_CfgData.configSCC;   // System Control client

    BOOL bWorkToDo = FALSE;

    bWorkToDo |= PrepareToConfig(configFS, bFsRunning, bFsOn, IDC_FS_SERVICE);
    bWorkToDo |= PrepareToConfig(configDB, bDbRunning, bDbOn, IDC_DB_SERVICE);
    bWorkToDo |= PrepareToConfig(configBak, bBakRunning, bBakOn, IDC_BK_SERVICE);
    bWorkToDo |= PrepareToConfig(configSCS, bScsRunning, bScsOn, IDC_SCS);
    bWorkToDo |= PrepareToConfig(configSCC, bSccRunning, bSccOn, IDC_SCC);

    // If there is nothing to do, then just return TRUE.
    if (!bWorkToDo)
        return TRUE;

    // If we are unconfiguring the last DB server:
    //		1) Warn user and ask for confirmation
    //		2) Unconfigure all other servers that are running on this machine
    //		3) Tell them (after unconfiguring) that they must run the Wizard if they
    //		   wish to reconfigure the machine, then exit the program.
    if (configDB == CS_UNCONFIGURE) {
	if (g_CfgData.bLastDBServer) {
	    int nChoice = MsgBox(hDlg, IDS_LAST_DB_SERVER, GetAppTitleID(), MB_YESNO | MB_ICONEXCLAMATION);
	    if (nChoice == IDNO)
		return FALSE;

	    // Make sure these all get unconfigured as well.  If they are not configured, then
	    // nothing bad will happen because the config calls are idempotent.
	    configFS = CS_UNCONFIGURE;
	    configBak = CS_UNCONFIGURE;
	    configSCS = CS_UNCONFIGURE;
	    configSCC = CS_UNCONFIGURE;
	}
    }

    // Get additional needed information from the user
    GET_ADMIN_INFO_OPTIONS eOptions;
    BOOL bDB = (ShouldConfig(configDB) || ShouldUnconfig(configDB));

    // Use this as our default
    eOptions = GAIO_LOGIN_ONLY;

    // If we already have a sys control machine, then we don't need to ask for it
    if (ShouldConfig(configSCC)) {
	if (szScMachine[0] == 0) {
	    ShowWarning(hDlg, IDS_MUST_ENTER_SCS_NAME);
	    return FALSE;
	}
	lstrcpy(g_CfgData.szSysControlMachine, szScMachine);
    } else if (bDB && !g_CfgData.bLastDBServer) {
        // We need to know the name of the SCM machine.  Are we the SCM machine?
        if (bScsRunning)
            lstrcpy(g_CfgData.szSysControlMachine, g_CfgData.szHostname);
        else	
	    eOptions = GAIO_GET_SCS;
    }	

    // If doing a login only and the admin info is reusable
    if ((eOptions != GAIO_LOGIN_ONLY) || !g_CfgData.bReuseAdminInfo) {
    	if (!GetAdminInfo(hDlg, eOptions))
	    return FALSE;

        // Use the admin info to get new handles
        if (!GetHandles(hDlg))
            return FALSE;
    }	

    // Now that we are ready to configure, copy our local config info
    // into the structure that the config engine uses.
    g_CfgData.configFS = configFS;
    g_CfgData.configDB = configDB;
    g_CfgData.configBak = configBak;
    g_CfgData.configSCS = configSCS;
    g_CfgData.configSCC = configSCC;

    // Configure the server
    BOOL bConfigSucceeded = Configure(hDlg, bMustExit);
    if (bConfigSucceeded) {
        if (bMustExit) {
	    PostQuitMessage(0);
	    return TRUE;
	}
        g_CfgData.bReuseAdminInfo = TRUE;
    } else
        g_CfgData.szAdminPW[0] = 0;

    // Get current config status
    BOOL bCanceled = FALSE;
    DWORD dwStatus = GetCurrentConfig(hDlg, bCanceled);
    if (dwStatus || bCanceled) {
	if (!bCanceled)
	    ErrorDialog(dwStatus, IDS_CONFIG_CHECK_FAILED);
    }	

    // Show the initial services config
    ShowInitialConfig();
    ShowServiceStates();

    return TRUE;
}
Example #20
0
static void cevents_init()
{
	if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE)
		ShowWarning ("Não foi possível instalar o manipulador do console!\n");
}
Example #21
0
// ギルドメンバデータ変更要求
int mapif_parse_GuildMemberInfoChange(int fd, int guild_id, int account_id, int char_id, int type, const char *data, int len) {
	int i;
	struct guild *g;

	g = idb_get(guild_db, guild_id);
	if(g == NULL)
		return 0;

	for(i = 0; i < g->max_member; i++)
		if (g->member[i].account_id == account_id && g->member[i].char_id == char_id)
			break;
	if (i == g->max_member) {
		ShowWarning("int_guild: GuildMemberChange: Not found %d,%d in %d[%s]\n", account_id, char_id, guild_id, g->name);
		return 0;
	}
	switch(type) {
	case GMI_POSITION:	// 役職
		g->member[i].position = *((int *)data);
		break;
	case GMI_EXP:	// EXP
	{
		unsigned int exp, old_exp=g->member[i].exp;
		g->member[i].exp=*((unsigned int *)data);
		if (g->member[i].exp > old_exp)
		{
			exp = g->member[i].exp - old_exp;
			if (guild_exp_rate != 100)
				exp = exp*guild_exp_rate/100;
			if (exp > UINT_MAX - g->exp)
				g->exp = UINT_MAX;
			else
				g->exp+=exp;
			guild_calcinfo(g);
			mapif_guild_basicinfochanged(guild_id,GBI_EXP,&g->exp,4);
		}
		break;
	}
	case GMI_HAIR:
	{
		g->member[i].hair=*((int *)data);
		mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
		break;
	}
	case GMI_HAIR_COLOR:
	{
		g->member[i].hair_color=*((int *)data);
		mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
		break;
	}
	case GMI_GENDER:
	{
		g->member[i].gender=*((int *)data);
		mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
		break;
	}
	case GMI_CLASS:
	{
		g->member[i].class_=*((int *)data);
		mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
		break;
	}
	case GMI_LEVEL:
	{
		g->member[i].lv=*((int *)data);
		mapif_guild_memberinfochanged(guild_id,account_id,char_id,type,data,len);
		break;
	}

	default:
		ShowError("int_guild: GuildMemberInfoChange: Unknown type %d\n", type);
		break;
	}
	mapif_guild_memberinfochanged(guild_id, account_id, char_id, type, data, len);

	return 0;
}
Example #22
0
int32 login_config_read(const char *cfgName)
{
    char line[1024], w1[1024], w2[1024];
    FILE *fp;

    fp = fopen(cfgName, "r");
    if (fp == nullptr)
    {
        ShowError("login configuration file not found at: %s\n", cfgName);
        return 1;
    }

    while (fgets(line, sizeof(line), fp))
    {
        char* ptr;

        if (line[0] == '#')
            continue;
        if (sscanf(line, "%[^:]: %[^\t\r\n]", w1, w2) < 2)
            continue;

        //Strip trailing spaces
        ptr = w2 + strlen(w2);
        while (--ptr >= w2 && *ptr == ' ');
        ptr++;
        *ptr = '\0';

        if (strcmpi(w1, "timestamp_format") == 0)
        {
            strncpy(timestamp_format, w2, 19);
        }
        else if (strcmpi(w1, "stdout_with_ansisequence") == 0)
        {
            stdout_with_ansisequence = config_switch(w2);
        }
        else if (strcmpi(w1, "console_silent") == 0)
        {
            ShowInfo("Console Silent Setting: %d\n", atoi(w2));
            msg_silent = atoi(w2);
        }
        else if (strcmp(w1, "mysql_host") == 0)
        {
            login_config.mysql_host = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_login") == 0)
        {
            login_config.mysql_login = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_password") == 0)
        {
            login_config.mysql_password = aStrdup(w2);
        }
        else if (strcmp(w1, "mysql_port") == 0)
        {
            login_config.mysql_port = atoi(w2);
        }
        else if (strcmp(w1, "mysql_database") == 0)
        {
            login_config.mysql_database = aStrdup(w2);
        }
        else if (strcmp(w1, "search_server_port") == 0)
        {
            login_config.search_server_port = atoi(w2);
        }
        else if (strcmp(w1, "expansions") == 0)
        {
            login_config.expansions = atoi(w2);
        }
        else if (strcmp(w1, "servername") == 0)
        {
            login_config.servername = aStrdup(w2);
        }
        else if (strcmpi(w1, "import") == 0)
        {
            login_config_read(w2);
        }
        else if (strcmp(w1, "msg_server_port") == 0)
        {
            login_config.msg_server_port = atoi(w2);
        }
        else if (strcmp(w1, "msg_server_ip") == 0)
        {
            login_config.msg_server_ip = aStrdup(w2);
        }
        else
        {
            ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
        }
    }

    fclose(fp);
    return 0;
}
Example #23
0
/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------*/
static int itemdb_readdb(void)
{
	const char* filename[] = {
#if REMODE
		"re/item_db.txt",
#else
		"pre-re/item_db.txt",
#endif
		"item_db2.txt" };

	int fi;

	for( fi = 0; fi < ARRAYLENGTH(filename); ++fi )
	{
		uint32 lines = 0, count = 0;
		char line[1024];

		char path[256];
		FILE* fp;

		sprintf(path, "%s/%s", db_path, filename[fi]);
		fp = fopen(path, "r");
		if( fp == NULL )
		{
			ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
			continue;
		}

		// process rows one by one
		while(fgets(line, sizeof(line), fp))
		{
			char *str[32], *p;
			int i;

			lines++;
			if(line[0] == '/' && line[1] == '/')
				continue;
			memset(str, 0, sizeof(str));

			p = line;
			while( ISSPACE(*p) )
				++p;
			if( *p == '\0' )
				continue;// empty line
			for( i = 0; i < 19; ++i )
			{
				str[i] = p;
				p = strchr(p,',');
				if( p == NULL )
					break;// comma not found
				*p = '\0';
				++p;
			}

			if( p == NULL )
			{
				ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
				continue;
			}

			// Script
			if( *p != '{' )
			{
				ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
				continue;
			}
			str[19] = p;
			p = strstr(p+1,"},");
			if( p == NULL )
			{
				ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
				continue;
			}
			p[1] = '\0';
			p += 2;

			// OnEquip_Script
			if( *p != '{' )
			{
				ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
				continue;
			}
			str[20] = p;
			p = strstr(p+1,"},");
			if( p == NULL )
			{
				ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
				continue;
			}
			p[1] = '\0';
			p += 2;

			// OnUnequip_Script (last column)
			if( *p != '{' )
			{
				ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
				continue;
			}
			str[21] = p;


			if (!itemdb_parse_dbrow(str, path, lines, 0))
				continue;

			count++;
		}

		fclose(fp);

		ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]);
	}

	return 0;
}
Example #24
0
/*==========================================
 *
 *------------------------------------------*/
int chrif_parse(int fd)
{
	int packet_len, cmd;

	// only process data from the char-server
	if (fd != char_fd)
	{
		ShowDebug("chrif_parse: Disconnecting invalid session #%d (is not the char-server)\n", fd);
		do_close(fd);
		return 0;
	}

	if (session[fd]->flag.eof)
	{
		if (chrif_connected == 1)
			chrif_disconnect(fd);

		do_close(fd);
		return 0;
	}

	while (RFIFOREST(fd) >= 2)
	{
		cmd = RFIFOW(fd,0);
		if (cmd < 0x2af8 || cmd >= 0x2af8 + ARRAYLENGTH(packet_len_table) || packet_len_table[cmd-0x2af8] == 0)
		{
			int r = intif_parse(fd); // intifに渡す

			if (r == 1) continue;	// intifで処理した
			if (r == 2) return 0;	// intifで処理したが、データが足りない

			ShowWarning("chrif_parse: session #%d, intif_parse failed (unrecognized command 0x%.4x).\n", fd, cmd);
			set_eof(fd);
			return 0;
		}

		packet_len = packet_len_table[cmd-0x2af8];
		if (packet_len == -1)
		{ // dynamic-length packet, second WORD holds the length
			if (RFIFOREST(fd) < 4)
				return 0;
			packet_len = RFIFOW(fd,2);
		}

		if ((int)RFIFOREST(fd) < packet_len)
			return 0;

		//ShowDebug("Received packet 0x%4x (%d bytes) from char-server (connection %d)\n", RFIFOW(fd,0), packet_len, fd);

		switch(cmd)
		{
		case 0x2af9: chrif_connectack(fd); break;
		case 0x2afb: chrif_sendmapack(fd); break;
		case 0x2afd: chrif_authok(fd); break;
		case 0x2b00: map_setusers(RFIFOL(fd,2)); chrif_keepalive(fd); break;
		case 0x2b03: clif_charselectok(RFIFOL(fd,2)); break;
		case 0x2b04: chrif_recvmap(fd); break;
		case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
		case 0x2b07: clif_updatemaxid(RFIFOL(fd,2), RFIFOL(fd,6)); break;
		case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
		case 0x2b0b: chrif_changedgm(fd); break;
		case 0x2b0d: chrif_changedsex(fd); break;
		case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
		case 0x2b12: chrif_divorce(RFIFOL(fd,2), RFIFOL(fd,6)); break;
		case 0x2b13: chrif_accountdeletion(fd); break;
		case 0x2b14: chrif_accountban(fd); break;
		case 0x2b15: chrif_recvgmaccounts(fd); break;
		case 0x2b1b: chrif_recvfamelist(fd); break;
		case 0x2b1d: chrif_load_scdata(fd); break;
		case 0x2b1e: chrif_update_ip(fd); break;
		case 0x2b1f: chrif_disconnectplayer(fd); break;
		case 0x2b20: chrif_removemap(fd); break;
		case 0x2b21: chrif_save_ack(fd); break;
		case 0x2b22: chrif_updatefamelist_ack(fd); break;
		case 0x2b24: chrif_keepalive_ack(fd); break;
		default:
			ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
			set_eof(fd);
			return 0;
		}
		if (fd == char_fd) //There's the slight chance we lost the connection during parse, in which case this would segfault if not checked [Skotlex]
			RFIFOSKIP(fd, packet_len);
	}

	return 0;
}
Example #25
0
/**
 * Loads group configuration from config file into memory.
 * @private
 */
static void read_config(void)
{
	config_setting_t *groups = NULL;
	const char *config_filename = "conf/groups.conf"; // FIXME hardcoded name
	int group_count = 0;
	
	if (conf_read_file(&pc_group_config, config_filename))
		return;

	groups = config_lookup(&pc_group_config, "groups");

	if (groups != NULL) {
		GroupSettings *group_settings = NULL;
		DBIterator *iter = NULL;
		int i, loop = 0;

		group_count = config_setting_length(groups);
		for (i = 0; i < group_count; ++i) {
			int id = 0, level = 0;
			const char *groupname = NULL;
			int log_commands = 0;
			config_setting_t *group = config_setting_get_elem(groups, i);

			if (!config_setting_lookup_int(group, "id", &id)) {
				ShowConfigWarning(group, "pc_groups:read_config: \"groups\" list member #%d has undefined id, removing...", i);
				config_setting_remove_elem(groups, i);
				--i;
				--group_count;
				continue;
			}

			if (id2group(id) != NULL) {
				ShowConfigWarning(group, "pc_groups:read_config: duplicate group id %d, removing...", i);
				config_setting_remove_elem(groups, i);
				--i;
				--group_count;
				continue;
			}

			config_setting_lookup_int(group, "level", &level);
			config_setting_lookup_bool(group, "log_commands", &log_commands);

			if (!config_setting_lookup_string(group, "name", &groupname)) {
				char temp[20];
				config_setting_t *name = NULL;
				snprintf(temp, sizeof(temp), "Group %d", id);
				if ((name = config_setting_add(group, "name", CONFIG_TYPE_STRING)) == NULL ||
				    !config_setting_set_string(name, temp)) {
					ShowError("pc_groups:read_config: failed to set missing group name, id=%d, skipping... (%s:%d)\n",
					          id, config_setting_source_file(group), config_setting_source_line(group));
					continue;
				}
				config_setting_lookup_string(group, "name", &groupname); // Retrieve the pointer
			}

			if (name2group(groupname) != NULL) {
				ShowConfigWarning(group, "pc_groups:read_config: duplicate group name %s, removing...", groupname);
				config_setting_remove_elem(groups, i);
				--i;
				--group_count;
				continue;
			}

			CREATE(group_settings, GroupSettings, 1);
			group_settings->id = id;
			group_settings->level = level;
			group_settings->name = groupname;
			group_settings->log_commands = (bool)log_commands;
			group_settings->inherit = config_setting_get_member(group, "inherit");
			group_settings->commands = config_setting_get_member(group, "commands");
			group_settings->permissions = config_setting_get_member(group, "permissions");
			group_settings->inheritance_done = false;
			group_settings->root = group;
			group_settings->group_pos = i;

			strdb_put(pc_groupname_db, groupname, group_settings);
			idb_put(pc_group_db, id, group_settings);
			
		}
		group_count = config_setting_length(groups); // Save number of groups
		
		// Check if all commands and permissions exist
		iter = db_iterator(pc_group_db);
		for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
			config_setting_t *commands = group_settings->commands, *permissions = group_settings->permissions;
			int count = 0, j;

			// Make sure there is "commands" group
			if (commands == NULL)
				commands = group_settings->commands = config_setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP);
			count = config_setting_length(commands);

			for (j = 0; j < count; ++j) {
				config_setting_t *command = config_setting_get_elem(commands, j);
				const char *name = config_setting_name(command);
				if (!atcommand_exists(name)) {
					ShowConfigWarning(command, "pc_groups:read_config: non-existent command name '%s', removing...", name);
					config_setting_remove(commands, name);
					--j;
					--count;
				}
			}

			// Make sure there is "permissions" group
			if (permissions == NULL)
				permissions = group_settings->permissions = config_setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP);
			count = config_setting_length(permissions);

			for(j = 0; j < count; ++j) {
				config_setting_t *permission = config_setting_get_elem(permissions, j);
				const char *name = config_setting_name(permission);
				int p;

				ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), p, strcmp(pc_g_permission_name[p].name, name) == 0);
				if (p == ARRAYLENGTH(pc_g_permission_name)) {
					ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name);
					config_setting_remove(permissions, name);
					--p;
					--count;
				}
			}
		}
		dbi_destroy(iter);

		// Apply inheritance
		i = 0; // counter for processed groups
		while (i < group_count) {
			iter = db_iterator(pc_group_db);
			for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
				config_setting_t *inherit = NULL,
				                 *commands = group_settings->commands,
					             *permissions = group_settings->permissions;
				int j, inherit_count = 0, done = 0;
				
				if (group_settings->inheritance_done) // group already processed
					continue; 

				if ((inherit = group_settings->inherit) == NULL ||
				    (inherit_count = config_setting_length(inherit)) <= 0) { // this group does not inherit from others
					++i;
					group_settings->inheritance_done = true;
					continue;
				}
				
				for (j = 0; j < inherit_count; ++j) {
					GroupSettings *inherited_group = NULL;
					const char *groupname = config_setting_get_string_elem(inherit, j);

					if (groupname == NULL) {
						ShowConfigWarning(inherit, "pc_groups:read_config: \"inherit\" array member #%d is not a name, removing...", j);
						config_setting_remove_elem(inherit,j);
						continue;
					}
					if ((inherited_group = name2group(groupname)) == NULL) {
						ShowConfigWarning(inherit, "pc_groups:read_config: non-existent group name \"%s\", removing...", groupname);
						config_setting_remove_elem(inherit,j);
						continue;
					}
					if (!inherited_group->inheritance_done)
						continue; // we need to do that group first

					// Copy settings (commands/permissions) that are not defined yet
					if (inherited_group->commands != NULL) {
						int l = 0, commands_count = config_setting_length(inherited_group->commands);
						for (l = 0; l < commands_count; ++l)
							config_setting_copy(commands, config_setting_get_elem(inherited_group->commands, l));
					}

					if (inherited_group->permissions != NULL) {
						int l = 0, permissions_count = config_setting_length(inherited_group->permissions);
						for (l = 0; l < permissions_count; ++l)
							config_setting_copy(permissions, config_setting_get_elem(inherited_group->permissions, l));
					}

					++done; // copied commands and permissions from one of inherited groups
				}
				
				if (done == inherit_count) { // copied commands from all of inherited groups
					++i;
					group_settings->inheritance_done = true; // we're done with this group
				}
			}
			dbi_destroy(iter);

			if (++loop > group_count) {
				ShowWarning("pc_groups:read_config: Could not process inheritance rules, check your config '%s' for cycles...\n",
				            config_filename);
				break;
			}
		} // while(i < group_count)

		// Pack permissions into GroupSettings.e_permissions for faster checking
		iter = db_iterator(pc_group_db);
		for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
			config_setting_t *permissions = group_settings->permissions;
			int c, count = config_setting_length(permissions);

			for (c = 0; c < count; ++c) {
				config_setting_t *perm = config_setting_get_elem(permissions, c);
				const char *name = config_setting_name(perm);
				int val = config_setting_get_bool(perm);
				int j;

				if (val == 0) // does not have this permission
					continue;
				ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0);
				group_settings->e_permissions |= pc_g_permission_name[j].permission;
			}
		}
		dbi_destroy(iter);
	}

	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' groups in '"CL_WHITE"%s"CL_RESET"'.\n", group_count, config_filename);

	
	if( ( pc_group_max = group_count ) ) {
		DBIterator *iter = db_iterator(pc_group_db);
		GroupSettings *group_settings = NULL;
		int* group_ids = aMalloc( pc_group_max * sizeof(int) );
		int i = 0;
		for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
			group_ids[i++] = group_settings->id;
		}
		
		atcommand_db_load_groups(group_ids);
		
		aFree(group_ids);
		
		dbi_destroy(iter);
	}
}
Example #26
0
int guild_recv_memberinfoshort(int guild_id,int account_id,int char_id,int online,int lv,int class_)
{ // cleaned up [LuzZza]
	
	int i,alv,c,idx=-1,om=0,oldonline=-1;
	struct guild *g = guild_search(guild_id);
	
	if(g == NULL)
		return 0;
	
	for(i=0,alv=0,c=0,om=0;i<g->max_member;i++){
		struct guild_member *m=&g->member[i];
		if(!m->account_id) continue;
		if(m->account_id==account_id && m->char_id==char_id ){
			oldonline=m->online;
			m->online=online;
			m->lv=lv;
			m->class_=class_;
			idx=i;
		}
		alv+=m->lv;
		c++;
		if(m->online)
			om++;
	}
	
	if(idx == -1 || c == 0) {
		// ギルドのメンバー外なので追放扱いする
		struct map_session_data *sd = map_id2sd(account_id);
		if(sd && sd->status.char_id == char_id) {
			sd->status.guild_id=0;
			sd->guild_emblem_id=0;
		}
		ShowWarning("guild: not found member %d,%d on %d[%s]\n",	account_id,char_id,guild_id,g->name);
		return 0;
	}
	
	g->average_lv=alv/c;
	g->connect_member=om;

	//Ensure validity of pointer (ie: player logs in/out, changes map-server)
	g->member[idx].sd = guild_sd_check(guild_id, account_id, char_id);

	if(oldonline!=online) 
		clif_guild_memberlogin_notice(g, idx, online);
	
	if(!g->member[idx].sd)
		return 0;

	//Send XY dot updates. [Skotlex]
	//Moved from guild_send_memberinfoshort [LuzZza]
	for(i=0; i < g->max_member; i++) {
		
		if(!g->member[i].sd || i == idx ||
			g->member[i].sd->bl.m != g->member[idx].sd->bl.m)
			continue;

		clif_guild_xy_single(g->member[idx].sd->fd, g->member[i].sd);
		clif_guild_xy_single(g->member[i].sd->fd, g->member[idx].sd);
	}

	return 0;
}
Example #27
0
void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count)
{
	unsigned int i, weight, listidx;
	struct item_data* id;

	if( !result || count == 0 )
	{// canceled, or no items
		return;
	}

	if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] )
	{// disabled or invalid input
		sd->buyingstore.slots = 0;
		clif->buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
		return;
	}

	if( !pc->can_give_items(sd) )
	{// custom: GM is not allowed to buy (give zeny)
		sd->buyingstore.slots = 0;
		clif->message(sd->fd, msg_txt(246));
		clif->buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
		return;
	}

	if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) )
	{// custom: mute limitation
		return;
	}

	if( map[sd->bl.m].flag.novending )
	{// custom: no vending maps
		clif->message(sd->fd, msg_txt(276)); // "You can't open a shop on this map"
		return;
	}

	if( iMap->getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) )
	{// custom: no vending cells
		clif->message(sd->fd, msg_txt(204)); // "You can't open a shop on this cell."
		return;
	}

	weight = sd->weight;

	// check item list
	for( i = 0; i < count; i++ )
	{// itemlist: <name id>.W <amount>.W <price>.L
		unsigned short nameid, amount;
		int price, idx;

		nameid = RBUFW(itemlist,i*8+0);
		amount = RBUFW(itemlist,i*8+2);
		price  = RBUFL(itemlist,i*8+4);

		if( ( id = itemdb->exists(nameid) ) == NULL || amount == 0 )
		{// invalid input
			break;
		}

		if( price <= 0 || price > BUYINGSTORE_MAX_PRICE )
		{// invalid price: unlike vending, items cannot be bought at 0 Zeny
			break;
		}

		if( !id->flag.buyingstore || !itemdb_cantrade_sub(id, pc->get_group_level(sd), pc->get_group_level(sd)) || ( idx = pc->search_inventory(sd, nameid) ) == -1 )
		{// restrictions: allowed, no character-bound items and at least one must be owned
			break;
		}

		if( sd->status.inventory[idx].amount+amount > BUYINGSTORE_MAX_AMOUNT )
		{// too many items of same kind
			break;
		}

		if( i )
		{// duplicate check. as the client does this too, only malicious intent should be caught here
			ARR_FIND( 0, i, listidx, sd->buyingstore.items[listidx].nameid == nameid );
			if( listidx != i )
			{// duplicate
				ShowWarning("buyingstore_create: Found duplicate item on buying list (nameid=%hu, amount=%hu, account_id=%d, char_id=%d).\n", nameid, amount, sd->status.account_id, sd->status.char_id);
				break;
			}
		}

		weight+= id->weight*amount;
		sd->buyingstore.items[i].nameid = nameid;
		sd->buyingstore.items[i].amount = amount;
		sd->buyingstore.items[i].price  = price;
	}

	if( i != count )
	{// invalid item/amount/price
		sd->buyingstore.slots = 0;
		clif->buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
		return;
	}

	if( (sd->max_weight*90)/100 < weight )
	{// not able to carry all wanted items without getting overweight (90%)
		sd->buyingstore.slots = 0;
		clif->buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
		return;
	}

	// success
	sd->state.buyingstore = true;
	sd->buyer_id = buyingstore_getuid();
	sd->buyingstore.zenylimit = zenylimit;
	sd->buyingstore.slots = i;  // store actual amount of items
	safestrncpy(sd->message, storename, sizeof(sd->message));
	clif->buyingstore_myitemlist(sd);
	clif->buyingstore_entry(sd);
}
Example #28
0
// Wisp/page request to send
int mapif_parse_WisRequest(int fd)
{
	struct WisData* wd;
	static int wisid = 0;
	char name[NAME_LENGTH];
	char esc_name[NAME_LENGTH*2+1];// escaped name
	char* data;
	size_t len;


	if ( fd <= 0 ) {return 0;} // check if we have a valid fd

	if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) {
		ShowWarning("inter: Wis message size too long.\n");
		return 0;
	} else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows...
		ShowError("inter: Wis message doesn't exist.\n");
		return 0;
	}

	safestrncpy(name, (char*)RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex]

	SQL->EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
	if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", char_db, esc_name) )
		Sql_ShowDebug(sql_handle);

	// search if character exists before to ask all map-servers
	if( SQL_SUCCESS != SQL->NextRow(sql_handle) )
	{
		unsigned char buf[27];
		WBUFW(buf, 0) = 0x3802;
		memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
		WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
		mapif_send(fd, buf, 27);
	}
	else
	{// Character exists. So, ask all map-servers
		// to be sure of the correct name, rewrite it
		SQL->GetData(sql_handle, 0, &data, &len);
		memset(name, 0, NAME_LENGTH);
		memcpy(name, data, min(len, NAME_LENGTH));
		// if source is destination, don't ask other servers.
		if( strncmp((const char*)RFIFOP(fd,4), name, NAME_LENGTH) == 0 )
		{
			uint8 buf[27];
			WBUFW(buf, 0) = 0x3802;
			memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH);
			WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
			mapif_send(fd, buf, 27);
		}
		else
		{

			CREATE(wd, struct WisData, 1);

			// Whether the failure of previous wisp/page transmission (timeout)
			check_ttl_wisdata();

			wd->id = ++wisid;
			wd->fd = fd;
			wd->len= RFIFOW(fd,2)-52;
			memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH);
			memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH);
			memcpy(wd->msg, RFIFOP(fd,52), wd->len);
			wd->tick = timer->gettick();
			idb_put(wis_db, wd->id, wd);
			mapif_wis_message(wd);
		}
	}

	SQL->FreeResult(sql_handle);
	return 0;
}
Example #29
0
void searchstore_click(struct map_session_data* sd, int account_id, int store_id, unsigned short nameid) {
	unsigned int i;
	struct map_session_data* pl_sd;
	searchstore_search_t store_search;

	if( !battle_config.feature_search_stores || !sd->searchstore.open || !sd->searchstore.count ) {
		return;
	}

	searchstore->clearremote(sd);

	ARR_FIND( 0, sd->searchstore.count, i,  sd->searchstore.items[i].store_id == store_id && sd->searchstore.items[i].account_id == account_id && sd->searchstore.items[i].nameid == nameid );
	if( i == sd->searchstore.count ) {// no such result, crafted
		ShowWarning("searchstore_click: Pedido recebido do item %hu da conta %d, que nao faz parte do conjunto de resultados atual (account_id=%d, char_id=%d).\n", nameid, account_id, sd->bl.id, sd->status.char_id);
		clif->search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
		return;
	}

	if( ( pl_sd = map->id2sd(account_id) ) == NULL ) {// no longer online
		clif->search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
		return;
	}

	if( !searchstore_hasstore(pl_sd, sd->searchstore.type) || searchstore_getstoreid(pl_sd, sd->searchstore.type) != store_id ) {
		// no longer vending/buying or not same shop
		clif->search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
		return;
	}

	store_search = searchstore_getsearchfunc(sd->searchstore.type);

	if( !store_search(pl_sd, nameid) ) {// item no longer being sold/bought
		clif->search_store_info_failed(sd, SSI_FAILED_SSILIST_CLICK_TO_OPEN_STORE);
		return;
	}

	switch( sd->searchstore.effect ) {
		case EFFECTTYPE_NORMAL:
			// display coords

			if( sd->bl.m != pl_sd->bl.m ) {// not on same map, wipe previous marker
				clif->search_store_info_click_ack(sd, -1, -1);
			} else {
				clif->search_store_info_click_ack(sd, pl_sd->bl.x, pl_sd->bl.y);
			}

			break;
		case EFFECTTYPE_CASH:
			// open remotely

			// to bypass range checks
			sd->searchstore.remote_id = account_id;

			switch( sd->searchstore.type ) {
				case SEARCHTYPE_VENDING:      vending->list(sd, account_id); break;
				case SEARCHTYPE_BUYING_STORE: buyingstore->open(sd, account_id);       break;
			}

			break;
		default:
			// unknown
			ShowError("searchstore_click: Efeito de procura de loja desconhecido %u (account_id=%d).\n", (unsigned int)sd->searchstore.effect, sd->bl.id);
	}
}
Example #30
0
int32 map_cleanup(uint32 tick, CTaskMgr::CTask* PTask)
{
    map_session_list_t::iterator it = map_session_list.begin();

    while (it != map_session_list.end())
    {
        map_session_data_t* map_session_data = it->second;

        CCharEntity* PChar = map_session_data->PChar;

        if ((time(nullptr) - map_session_data->last_update) > 5)
        {
            if (PChar != nullptr && !(PChar->nameflags.flags & FLAG_DC))
            {

                PChar->nameflags.flags |= FLAG_DC;
                PChar->updatemask |= UPDATE_HP;
                if (PChar->status == STATUS_NORMAL)
                {
                    PChar->loc.zone->SpawnPCs(PChar);
                }
            }
            if ((time(nullptr) - map_session_data->last_update) > map_config.max_time_lastupdate)
            {
                if (PChar != nullptr)
                {
                    if (map_session_data->shuttingDown == 0)
                    {
                        //[Alliance] fix to stop server crashing:
                        //if a party within an alliance only has 1 char (that char will be party leader)
                        //if char then disconnects we need to tell the server about the alliance change
                        if (PChar->PParty != nullptr && PChar->PParty->m_PAlliance != nullptr && PChar->PParty->GetLeader() == PChar)
                        {
                            if (PChar->PParty->members.size() == 1)
                            {
                                if (PChar->PParty->m_PAlliance->partyList.size() == 1)
                                {
                                    PChar->PParty->m_PAlliance->dissolveAlliance();
                                }
                                else
                                {
                                    PChar->PParty->m_PAlliance->removeParty(PChar->PParty);
                                }
                            }
                        }


                        // uncharm pet if player d/c
                        if (PChar->PPet != nullptr && PChar->PPet->objtype == TYPE_MOB)
                        {
                            petutils::DespawnPet(PChar);
                        }

                        PChar->StatusEffectContainer->SaveStatusEffects(true);
                        ShowDebug(CL_CYAN"map_cleanup: %s timed out, closing session\n" CL_RESET, PChar->GetName());

                        PChar->status = STATUS_SHUTDOWN;
                        PacketParser[0x00D](map_session_data, PChar, 0);
                    }
                    else
                    {
                        map_session_data->PChar->StatusEffectContainer->SaveStatusEffects(true);
                        Sql_Query(SqlHandle, "DELETE FROM accounts_sessions WHERE charid = %u;", map_session_data->PChar->id);

                        aFree(map_session_data->server_packet_data);
                        delete map_session_data->PChar;
                        delete map_session_data;
                        map_session_data = nullptr;

                        map_session_list.erase(it++);
                        continue;
                    }
                }
                else if (map_session_data->shuttingDown == 0)
                {

                    ShowWarning(CL_YELLOW"map_cleanup: WHITHOUT CHAR timed out, session closed\n" CL_RESET);

                    const int8* Query = "DELETE FROM accounts_sessions WHERE client_addr = %u AND client_port = %u";
                    Sql_Query(SqlHandle, Query, map_session_data->client_addr, map_session_data->client_port);

                    aFree(map_session_data->server_packet_data);
                    map_session_list.erase(it++);
                    delete map_session_data;
                    continue;
                }
            }
        }
        else if (PChar != nullptr && (PChar->nameflags.flags & FLAG_DC))
        {
            PChar->nameflags.flags &= ~FLAG_DC;
            PChar->updatemask |= UPDATE_HP;
            PChar->pushPacket(new CCharUpdatePacket(PChar));

            if (PChar->status == STATUS_NORMAL)
            {
                PChar->loc.zone->SpawnPCs(PChar);
            }
            charutils::SaveCharStats(PChar);
        }
        ++it;
    }
    return 0;
}