예제 #1
0
/**
 * Player requesting to change map-serv
 * @param fd: wich fd to parse from
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_reqchangemapserv(int fd){
	if (RFIFOREST(fd) < 39)
		return 0;
	{
		int map_id, map_fd = -1;
		struct mmo_charstatus* char_data;
		struct mmo_charstatus char_dat;
		DBMap* char_db_ = char_get_chardb();

		map_id = char_search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
		if (map_id >= 0)
			map_fd = map_server[map_id].fd;
		//Char should just had been saved before this packet, so this should be safe. [Skotlex]
		char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
		if (char_data == NULL) {	//Really shouldn't happen.
			char_mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
			char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
		}

		if( runflag == CHARSERVER_ST_RUNNING &&
			session_isActive(map_fd) &&
			char_data )
		{	//Send the map server the auth of this player.
			struct online_char_data* data;
			struct auth_node* node;
			DBMap*  auth_db = char_get_authdb();
			DBMap* online_char_db = char_get_onlinedb();

			int aid = RFIFOL(fd,2);

			//Update the "last map" as this is where the player must be spawned on the new map server.
			char_data->last_point.map = RFIFOW(fd,18);
			char_data->last_point.x = RFIFOW(fd,20);
			char_data->last_point.y = RFIFOW(fd,22);
			char_data->sex = RFIFOB(fd,30);

			// create temporary auth entry
			CREATE(node, struct auth_node, 1);
			node->account_id = aid;
			node->char_id = RFIFOL(fd,14);
			node->login_id1 = RFIFOL(fd,6);
			node->login_id2 = RFIFOL(fd,10);
			node->sex = RFIFOB(fd,30);
			node->expiration_time = 0; // FIXME (this thing isn't really supported we could as well purge it instead of fixing)
			node->ip = ntohl(RFIFOL(fd,31));
			node->group_id = RFIFOL(fd,35);
			node->changing_mapservers = 1;
			idb_put(auth_db, aid, node);

			data = idb_ensure(online_char_db, aid, char_create_online_data);
			data->char_id = char_data->char_id;
			data->server = map_id; //Update server where char is.

			//Reply with an ack.
			chmapif_changemapserv_ack(fd,0);
		} else { //Reply with nak
			chmapif_changemapserv_ack(fd,1);
		}
		RFIFOSKIP(fd,39);
	}
예제 #2
0
struct guild_storage *guild2storage(int guild_id)
{
	struct guild_storage *gs = NULL;
	if(guild_search(guild_id) != NULL)
		gs = idb_ensure(guild_storage_db,guild_id,create_guildstorage);
	return gs;
}
예제 #3
0
/**
 * Map-serv sent us all his users info, (aid and cid) so we can update online_char_db
 * @param fd: wich fd to parse from
 * @param id: wich map_serv id
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_regmapuser(int fd, int id){
	if (RFIFOREST(fd) < 6 || RFIFOREST(fd) < RFIFOW(fd,2))
		return 0;
	{
		//TODO: When data mismatches memory, update guild/party online/offline states.
		DBMap* online_char_db = char_get_onlinedb();
		int i;

		map_server[id].users = RFIFOW(fd,4);
		online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown'
		for(i = 0; i < map_server[id].users; i++) {
			int aid = RFIFOL(fd,6+i*8);
			int cid = RFIFOL(fd,6+i*8+4);
			struct online_char_data* character = idb_ensure(online_char_db, aid, char_create_online_data);
			if( character->server > -1 && character->server != id )
			{
				ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
					character->account_id, character->char_id, character->server, id, aid, cid);
				mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
			}
			character->server = id;
			character->char_id = cid;
		}
		//If any chars remain in -2, they will be cleaned in the cleanup timer.
		RFIFOSKIP(fd,RFIFOW(fd,2));
	}
	return 1;
}
예제 #4
0
int mapif_save_pet(int fd,int account_id,struct s_pet *data)
{
	struct s_pet *p;
	int pet_id, len;
	RFIFOHEAD(fd);
	len=RFIFOW(fd,2);
	
	if(sizeof(struct s_pet)!=len-8) {
		ShowError("inter pet: data size error %d %d\n",sizeof(struct s_pet),len-8);
	}
	else{
		pet_id = data->pet_id;
		if (pet_id == 0)
			pet_id = data->pet_id = pet_newid++;
		p = (struct s_pet*)idb_ensure(pet_db,pet_id,create_pet);
		if(data->hungry < 0)
			data->hungry = 0;
		else if(data->hungry > 100)
			data->hungry = 100;
		if(data->intimate < 0)
			data->intimate = 0;
		else if(data->intimate > 1000)
			data->intimate = 1000;
		memcpy(p,data,sizeof(struct s_pet));
		if(p->incuvate == 1)
			p->account_id = p->char_id = 0;

		mapif_save_pet_ack(fd,account_id,0);
	}

	return 0;
}
예제 #5
0
파일: login.cpp 프로젝트: AlmasB/rathena
/**
 * Receive info from char-serv that this user is online
 * This function will start a timer to recheck if that user still online
 * @param char_server : Serv id where account_id is connected
 * @param account_id : aid connected
 * @return the new online_login_data for that user
 */
struct online_login_data* login_add_online_user(int char_server, uint32 account_id){
	struct online_login_data* p;
	p = (struct online_login_data*)idb_ensure(online_db, account_id, login_create_online_user);
	p->char_server = char_server;
	if( p->waiting_disconnect != INVALID_TIMER ) {
		delete_timer(p->waiting_disconnect, login_waiting_disconnect_timer);
		p->waiting_disconnect = INVALID_TIMER;
	}
	return p;
}
예제 #6
0
/*==========================================
 * Loads (and creates if not found) an item from the db.
 *------------------------------------------
 */
struct item_data* itemdb_load(int nameid)
{
	struct item_data *id = idb_ensure(item_db,nameid,create_item_data);
	if (id == &dummy_item)
  	{	//Remove dummy_item, replace by real data.
		DBKey key;
		key.i = nameid;
		idb_remove(item_db,nameid);
		id = create_item_data(key, NULL);
		idb_put(item_db,nameid,id);
	}
	return id;
}
예제 #7
0
int mapif_save_homun(int fd,int account_id,struct s_homunculus *data)
{
	struct s_homunculus *p;
	int hom_id;
	
	if (data->hom_id == 0)
		data->hom_id = homun_newid++;
	hom_id = data->hom_id;
	p = (struct s_homunculus*)idb_ensure(homun_db,hom_id,create_homun);
	memcpy(p,data,sizeof(struct s_homunculus));
	mapif_save_homun_ack(fd,account_id,1);
	return 0;
}
예제 #8
0
/// Writes provided data into storage cache.
/// If data contains 0 items, any existing entry in cache is destroyed.
/// If data contains 1+ items and no cache entry exists, a new one is created.
bool storage_save(int account_id, struct storage_data* storage)
{
	if( storage->storage_amount > 0 )
	{
		struct storage_data* s = (struct storage_data*)idb_ensure(storage_db, account_id, create_storage);
		memcpy(s, storage, sizeof(*storage));
	}
	else
	{
		idb_remove(storage_db, account_id);
	}

	return true;
}
예제 #9
0
/**
 * Receive list of all online accounts.
 * @author  [Skotlex]
 * @param fd: fd to parse from (char-serv)
 * @param id: id of char-serv
 * @return 0 not enough info transmitted, 1 success
 */
int logchrif_parse_updonlinedb(int fd, int id){
	if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
		return 0;
	else{
		uint32 i, users;
		online_db->foreach(online_db, login_online_db_setoffline, id); //Set all chars from this char-server offline first
		users = RFIFOW(fd,4);
		for (i = 0; i < users; i++) {
			int aid = RFIFOL(fd,6+i*4);
			struct online_login_data *p = (struct online_login_data*)idb_ensure(online_db, aid, login_create_online_user);
			p->char_server = id;
			if (p->waiting_disconnect != INVALID_TIMER){
				delete_timer(p->waiting_disconnect, login_waiting_disconnect_timer);
				p->waiting_disconnect = INVALID_TIMER;
			}
		}
		RFIFOSKIP(fd,RFIFOW(fd,2));
	}
	return 1;
}
예제 #10
0
// 情報所得
int party_recv_info(struct party *sp)
{
	struct map_session_data *sd;
	struct party *p;
	int i;
	
	nullpo_retr(0, sp);

	p= idb_ensure(party_db, sp->party_id, create_party);
	if (!p->party_id) //party just received.
		party_check_member(sp);
	memcpy(p,sp,sizeof(struct party));
	
	for(i=0;i<MAX_PARTY;i++){	// sdの設定
		if (!p->member[i].account_id) {
			p->member[i].sd=NULL;
			continue;
		}
		sd = map_id2sd(p->member[i].account_id);
		p->member[i].sd = (sd!=NULL && sd->status.party_id==p->party_id && sd->status.char_id == p->member[i].char_id && !sd->state.waitingdisconnect)?sd:NULL;
	}


	for(i=0;i<MAX_PARTY;i++){	// 設定情報の送信
		sd = p->member[i].sd;
		if(!sd)
			continue;
		// Refresh hp/xy state [LuzZza]
		clif_party_hp(sd);
		clif_party_xy(sd);
		if(sd->state.party_sent==0){
			clif_party_main_info(p,-1);
			clif_party_option(p,sd,0x100);
			clif_party_info(p,-1);
			sd->state.party_sent=1;
		}
	}
	
	return 0;
}
예제 #11
0
int party_recv_info(struct party *sp)
{
	struct party_data *p;
	int i;
	bool party_new = false;
	
	nullpo_retr(0, sp);

	p = (struct party_data*)idb_ensure(party_db, sp->party_id, create_party);
	if (!p->party.party_id) //party just received.
	{
		party_new = true;
		party_check_member(sp);
	}
	memcpy(&p->party,sp,sizeof(struct party));
	memset(&p->state, 0, sizeof(p->state));
	memset(&p->data, 0, sizeof(p->data));
	for(i=0;i<MAX_PARTY;i++){
		if (!p->party.member[i].account_id)
			continue;
		p->data[i].sd = party_sd_check(p->party.party_id, p->party.member[i].account_id, p->party.member[i].char_id);
	}
	party_check_state(p);
	if (party_new) {
		//Send party data to all players.
		struct map_session_data *sd;
		for(i=0;i<MAX_PARTY;i++){
			sd = p->data[i].sd;
			if(!sd) continue;
			clif_charnameupdate(sd); //Update other people's display. [Skotlex]
			clif_party_member_info(p,sd);
			clif_party_option(p,sd,0x100);
			clif_party_info(p,NULL);
		}
	}
	
	return 0;
}
예제 #12
0
int party_recv_info(struct party *sp)
{
	struct map_session_data *sd;
	struct party_data *p;
	int i;
	
	nullpo_retr(0, sp);

	p= idb_ensure(party_db, sp->party_id, create_party);
	if (!p->party.party_id) //party just received.
		party_check_member(sp);
	memcpy(&p->party,sp,sizeof(struct party));
	memset(&p->state, 0, sizeof(p->state));
	memset(&p->data, 0, sizeof(p->data));
	for(i=0;i<MAX_PARTY;i++){
		if (!p->party.member[i].account_id)
			continue;
		sd = map_id2sd(p->party.member[i].account_id);
		if (sd && sd->status.party_id==p->party.party_id
			&& sd->status.char_id == p->party.member[i].char_id
			&& !sd->state.waitingdisconnect)
			p->data[i].sd = sd;
	}
	party_check_state(p);
	for(i=0;i<MAX_PARTY;i++){
		sd = p->data[i].sd;
		if(!sd || sd->state.party_sent)
			continue;
		clif_party_member_info(p,sd);
		clif_party_option(p,sd,0x100);
		clif_party_info(p,NULL);
		sd->state.party_sent=1;
	}
	
	return 0;
}
예제 #13
0
/*==========================================
 * Loads an item from the db. If not found, it will return the dummy item.
 *------------------------------------------
 */
struct item_data* itemdb_search(int nameid)
{
	return idb_ensure(item_db,nameid,return_dummy_data);
}
예제 #14
0
struct storage *account2storage(int account_id)
{
	return idb_ensure(storage_db,account_id,create_storage);
}
예제 #15
0
/*==========================================
 * Loads (and creates if not found) an item from the db.
 *------------------------------------------
 */
struct item_data* itemdb_load(int nameid)
{
	return idb_ensure(item_db,nameid,create_item_data);
}
예제 #16
0
// アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
struct storage *account2storage(int account_id)
{
	struct storage *s;
	s= idb_ensure(storage_db, account_id, create_storage);
	return s;
}