Example #1
0
/*==========================================
 * Search Char trough id on char serv
 *------------------------------------------*/
int chrif_searchcharid(int char_id) {
	
	if( !char_id )
		return -1;
	
	chrif_check(-1);

	WFIFOHEAD(char_fd,6);
	WFIFOW(char_fd,0) = 0x2b08;
	WFIFOL(char_fd,2) = char_id;
	WFIFOSET(char_fd,6);

	return 0;
}
Example #2
0
void mapif_send_quests(int fd, int char_id, struct quest *tmp_questlog, int num_quests)
{
	WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8);
	WFIFOW(fd,0) = 0x3860;
	WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8;
	WFIFOL(fd,4) = char_id;

	if (num_quests > 0) {
		nullpo_retv(tmp_questlog);
		memcpy(WFIFOP(fd,8), tmp_questlog, sizeof(struct quest)*num_quests);
	}

	WFIFOSET(fd,num_quests*sizeof(struct quest)+8);
}
Example #3
0
/*==========================================
 * Client Inbox Request
 *------------------------------------------*/
static void mapif_Mail_sendinbox(int fd, int char_id, unsigned char flag)
{
	struct mail_data md;
	mail_fromsql(char_id, &md);

	//FIXME: dumping the whole structure like this is unsafe [ultramage]
	WFIFOHEAD(fd, sizeof(md) + 9);
	WFIFOW(fd,0) = 0x3848;
	WFIFOW(fd,2) = sizeof(md) + 9;
	WFIFOL(fd,4) = char_id;
	WFIFOB(fd,8) = flag;
	memcpy(WFIFOP(fd,9),&md,sizeof(md));
	WFIFOSET(fd,WFIFOW(fd,2));
}
Example #4
0
/**
 * Packet send to all char-servers, except one. (wos: without our self)
 * @param fd: fd to send packet too
 * @param buf: packet to send in form of an array buffer
 * @param len: size of packet
 * @return : the number of map-serv the packet was sent to (O|1)
 */
int chmapif_send(int fd, unsigned char *buf, unsigned int len){
	if (fd >= 0) {
		int i;
		ARR_FIND( 0, ARRAYLENGTH(map_server), i, fd == map_server[i].fd );
		if( i < ARRAYLENGTH(map_server) )
		{
			WFIFOHEAD(fd,len);
			memcpy(WFIFOP(fd,0), buf, len);
			WFIFOSET(fd,len);
			return 1;
		}
	}
	return 0;
}
Example #5
0
// sends maps to char-server
int chrif_sendmap(int fd)
{
	int i;
	ShowStatus("Sending maps to char server...\n");
	// Sending normal maps, not instances
	WFIFOHEAD(fd, 4 + instance_start * 4);
	WFIFOW(fd,0) = 0x2afa;
	for(i = 0; i < instance_start; i++)
		WFIFOW(fd,4+i*4) = map[i].index;
	WFIFOW(fd,2) = 4 + i * 4;
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}
Example #6
0
// connects to char-server (plaintext)
int chrif_connect(int fd)
{
	ShowStatus("Logging in to char server...\n", char_fd);
	WFIFOHEAD(fd,60);
	WFIFOW(fd,0) = 0x2af8;
	memcpy(WFIFOP(fd,2), userid, NAME_LENGTH);
	memcpy(WFIFOP(fd,26), passwd, NAME_LENGTH);
	WFIFOL(fd,50) = 0;
	WFIFOL(fd,54) = htonl(clif_getip());
	WFIFOW(fd,58) = htons(clif_getport());
	WFIFOSET(fd,60);

	return 0;
}
Example #7
0
void chrif_update_ip(int fd)
{
	uint32 new_ip;
	WFIFOHEAD(fd,6);
	new_ip = host2ip(char_ip_str);
	if (new_ip && new_ip != char_ip)
		char_ip = new_ip; //Update char_ip

	new_ip = clif_refresh_ip();
	if (!new_ip) return; //No change
	WFIFOW(fd,0) = 0x2736;
	WFIFOL(fd,2) = htonl(new_ip);
	WFIFOSET(fd,6);
}
Example #8
0
/*==========================================
 * Request sc_data from charserver [Skotlex]
 *------------------------------------------*/
int chrif_scdata_request(int account_id, int char_id) {
	
#ifdef ENABLE_SC_SAVING
	chrif_check(-1);

	WFIFOHEAD(char_fd,10);
	WFIFOW(char_fd,0) = 0x2afc;
	WFIFOL(char_fd,2) = account_id;
	WFIFOL(char_fd,6) = char_id;
	WFIFOSET(char_fd,10);
#endif
	
	return 0;
}
Example #9
0
/**
 * Map-serv requesting to send the list of sc_data the player has saved
 * @author [Skotlex]
 * @param fd: wich fd to parse from
 * @return : 0 not enough data received, 1 success
 */
int chmapif_parse_askscdata(int fd){
	if (RFIFOREST(fd) < 10)
		return 0;
	{
#ifdef ENABLE_SC_SAVING
		int aid, cid;
		aid = RFIFOL(fd,2);
		cid = RFIFOL(fd,6);
		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4 from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
			schema_config.scdata_db, aid, cid) )
		{
			Sql_ShowDebug(sql_handle);
			return 1;
		}
		if( Sql_NumRows(sql_handle) > 0 )
		{
			struct status_change_data scdata;
			int count;
			char* data;

			WFIFOHEAD(fd,14+50*sizeof(struct status_change_data));
			WFIFOW(fd,0) = 0x2b1d;
			WFIFOL(fd,4) = aid;
			WFIFOL(fd,8) = cid;
			for( count = 0; count < 50 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count )
			{
				Sql_GetData(sql_handle, 0, &data, NULL); scdata.type = atoi(data);
				Sql_GetData(sql_handle, 1, &data, NULL); scdata.tick = atoi(data);
				Sql_GetData(sql_handle, 2, &data, NULL); scdata.val1 = atoi(data);
				Sql_GetData(sql_handle, 3, &data, NULL); scdata.val2 = atoi(data);
				Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data);
				Sql_GetData(sql_handle, 5, &data, NULL); scdata.val4 = atoi(data);
				memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data));
			}
			if (count >= 50)
				ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid);
			if (count > 0)
			{
				WFIFOW(fd,2) = 14 + count*sizeof(struct status_change_data);
				WFIFOW(fd,12) = count;
				WFIFOSET(fd,WFIFOW(fd,2));
			}
		}
		Sql_FreeResult(sql_handle);
#endif
		RFIFOSKIP(fd, 10);
	}
	return 1;
}
Example #10
0
// sends maps to char-server
int chrif_sendmap(int fd) {
	int i;
	
	ShowStatus("Enviando mapas para o servidor de personagens...\n");
	
	// Sending normal maps, not instances
	WFIFOHEAD(fd, 4 + instance_start * 4);
	WFIFOW(fd,0) = 0x2afa;
	for(i = 0; i < instance_start; i++)
		WFIFOW(fd,4+i*4) = map[i].index;
	WFIFOW(fd,2) = 4 + i * 4;
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}
Example #11
0
/*==========================================
 * Delete Mail
 *------------------------------------------*/
static void mapif_Mail_delete(int fd, int char_id, int mail_id)
{
	bool failed = false;
	if(SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id)) {
		Sql_ShowDebug(sql_handle);
		failed = true;
	}

	WFIFOHEAD(fd,11);
	WFIFOW(fd,0) = 0x384b;
	WFIFOL(fd,2) = char_id;
	WFIFOL(fd,6) = mail_id;
	WFIFOB(fd,10) = failed;
	WFIFOSET(fd,11);
}
Example #12
0
static void mapif_homunculus_loaded(int fd, int account_id, struct s_homunculus *hd)
{
	WFIFOHEAD(fd, sizeof(struct s_homunculus)+9);
	WFIFOW(fd,0) = 0x3891;
	WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
	WFIFOL(fd,4) = account_id;
	if(hd != NULL) {
		WFIFOB(fd,8) = 1; // success
		memcpy(WFIFOP(fd,9), hd, sizeof(struct s_homunculus));
	} else {
		WFIFOB(fd,8) = 0; // not found.
		memset(WFIFOP(fd,9), 0, sizeof(struct s_homunculus));
	}
	WFIFOSET(fd, sizeof(struct s_homunculus)+9);
}
Example #13
0
/*==========================================
 * Client Inbox Request
 *------------------------------------------*/
void mapif_Mail_sendinbox(int fd, uint32 char_id, unsigned char flag, enum mail_inbox_type type)
{
	struct mail_data md;
	mail_fromsql(char_id, &md);

	//FIXME: dumping the whole structure like this is unsafe [ultramage]
	WFIFOHEAD(fd, sizeof(md) + 10);
	WFIFOW(fd,0) = 0x3848;
	WFIFOW(fd,2) = sizeof(md) + 10;
	WFIFOL(fd,4) = char_id;
	WFIFOB(fd,8) = flag;
	WFIFOB(fd,9) = type;
	memcpy(WFIFOP(fd,10),&md,sizeof(md));
	WFIFOSET(fd,WFIFOW(fd,2));
}
Example #14
0
/**
 * IZ 0x3857 <size>.W <count>.W <guild_id>.W { <item>.?B }.*MAX_INVENTORY
 * Send the retrieved guild bound items to map-server, store them to guild storage.
 * By using this method, stackable items will looks how it should be, and overflowed
 * item's stack won't disturbs the guild storage table and the leftover items (when
 * storage is full) will be discarded.
 * @param fd
 * @param guild_id
 * @param items[]
 * @param count
 * @author [Cydh]
 */
void mapif_itembound_store2gstorage(int fd, int guild_id, struct item items[], unsigned short count) {
	int size = 8 + sizeof(struct item) * MAX_INVENTORY, i;

	WFIFOHEAD(fd, size);
	WFIFOW(fd, 0) = 0x3857;
	WFIFOW(fd, 2) = size;
	WFIFOW(fd, 6) = guild_id;
	for (i = 0; i < count && i < MAX_INVENTORY; i++) {
		if (!&items[i])
			continue;
		memcpy(WFIFOP(fd, 8 + (i * sizeof(struct item))), &items[i], sizeof(struct item));
	}
	WFIFOW(fd, 4) = i;
	WFIFOSET(fd, size);
}
Example #15
0
/*------------------------------------------
 * Check Player
 *------------------------------------------*/
void mapif_rodex_checkname(int fd, int reqchar_id, int target_char_id, short target_class, int target_level, char *name)
{
	nullpo_retv(name);
	Assert_retv(reqchar_id > 0);
	Assert_retv(target_char_id >= 0);

	WFIFOHEAD(fd, 16 + NAME_LENGTH);
	WFIFOW(fd, 0) = 0x3898;
	WFIFOL(fd, 2) = reqchar_id;
	WFIFOL(fd, 6) = target_char_id;
	WFIFOW(fd, 10) = target_class;
	WFIFOL(fd, 12) = target_level;
	safestrncpy(WFIFOP(fd, 16), name, NAME_LENGTH);
	WFIFOSET(fd, 16 + NAME_LENGTH);
}
Example #16
0
void chrif_send_report(char* buf, int len) {
#ifndef STATS_OPT_OUT
	if( char_fd ) {
		WFIFOHEAD(char_fd,len + 2);
		
		WFIFOW(char_fd,0) = 0x3008;
		
		memcpy(WFIFOP(char_fd,2), buf, len);
		
		WFIFOSET(char_fd,len + 2);
		
		flush_fifo(char_fd); /* ensure it's sent now. */
	}
#endif
}
Example #17
0
/**
 * Client requests an md5key for his session: keys will be generated and sent back.
 * @param fd: file descriptor to parse from (client)
 * @param sd: client session
 * @return 1 success
 */
static int logclif_parse_reqkey(int fd, struct login_session_data *sd){
	RFIFOSKIP(fd,2);
	{
		memset(sd->md5key, '\0', sizeof(sd->md5key));
		sd->md5keylen = (uint16)(12 + rnd() % 4);
		MD5_Salt(sd->md5keylen, sd->md5key);

		WFIFOHEAD(fd,4 + sd->md5keylen);
		WFIFOW(fd,0) = 0x01dc;
		WFIFOW(fd,2) = 4 + sd->md5keylen;
		memcpy(WFIFOP(fd,4), sd->md5key, sd->md5keylen);
		WFIFOSET(fd,WFIFOW(fd,2));
	}
	return 1;
}
Example #18
0
/**
 * Transmit account data to char_server
 * S 2717 aid.W email.40B exp_time.L group_id.B char_slot.B birthdate.11B pincode.5B pincode_change.L
 *  isvip.1B char_vip.1B max_billing.1B (tot 75)  
 * @return -1 : account not found, 1:sucess
 */
int logchrif_send_accdata(int fd, uint32 aid) {
	struct mmo_account acc;
	time_t expiration_time = 0;
	char email[40] = "";
	int group_id = 0;
	char birthdate[10+1] = "";
	char pincode[PINCODE_LENGTH+1];
	char isvip = false;
	uint8 char_slots = MIN_CHARS, char_vip = 0, char_billing = 0;
	AccountDB* accounts = login_get_accounts_db();

	memset(pincode,0,PINCODE_LENGTH+1);
	if( !accounts->load_num(accounts, &acc, aid) )
		return -1;
	else {
		safestrncpy(email, acc.email, sizeof(email));
		expiration_time = acc.expiration_time;
		group_id = acc.group_id;

		safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
		safestrncpy(pincode, acc.pincode, sizeof(pincode));
#ifdef VIP_ENABLE
		char_vip = login_config.vip_sys.char_increase;
		if( acc.vip_time > time(NULL) ) {
			isvip = true;
			char_slots = login_config.char_per_account + char_vip;
		} else
			char_slots = login_config.char_per_account;
		char_billing = MAX_CHAR_BILLING; //TODO create a config for this
#endif
	}

	WFIFOHEAD(fd,75);
	WFIFOW(fd,0) = 0x2717;
	WFIFOL(fd,2) = aid;
	safestrncpy(WFIFOCP(fd,6), email, 40);
	WFIFOL(fd,46) = (uint32)expiration_time;
	WFIFOB(fd,50) = (unsigned char)group_id;
	WFIFOB(fd,51) = char_slots;
	safestrncpy(WFIFOCP(fd,52), birthdate, 10+1);
	safestrncpy(WFIFOCP(fd,63), pincode, 4+1 );
	WFIFOL(fd,68) = (uint32)acc.pincode_change;
	WFIFOB(fd,72) = isvip;
	WFIFOB(fd,73) = char_vip;
	WFIFOB(fd,74) = char_billing;
	WFIFOSET(fd,75);
	return 1;
}
Example #19
0
int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
	int u_fd; //user fd
	if (RFIFOREST(fd) < 79)
		return 0;

	// find the authenticated session with this account id
	ARR_FIND( 0, fd_max, u_fd, session[u_fd] && (sd = (struct char_session_data*)session[u_fd]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) );
	if( u_fd < fd_max )
	{
		int server_id;
		memcpy(sd->email, RFIFOP(fd,6), 40);
		sd->expiration_time = (time_t)RFIFOL(fd,46);
		sd->group_id = RFIFOB(fd,50);
		sd->char_slots = RFIFOB(fd,51);
		if( sd->char_slots > MAX_CHARS ) {
			ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.h! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots);
			sd->char_slots = MAX_CHARS;/* cap to maximum */
		} else if ( !sd->char_slots )/* no value aka 0 in sql */
			sd->char_slots = MIN_CHARS;/* cap to minimum */
		safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
                safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
                sd->pincode_change = (time_t)RFIFOL(fd,68);
                sd->bank_vault = RFIFOL(fd,72);
                sd->isvip = RFIFOB(fd,76);
                sd->chars_vip = RFIFOB(fd,77);
                sd->chars_billing = RFIFOB(fd,78);
		ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, map_server[server_id].fd > 0 && map_server[server_id].map[0] );
		// continued from char_auth_ok...
		if( server_id == ARRAYLENGTH(map_server) || //server not online, bugreport:2359
			(charserv_config.max_connect_user == 0 && sd->group_id != charserv_config.gm_allow_group) ||
			( charserv_config.max_connect_user > 0 && char_count_users() >= charserv_config.max_connect_user && sd->group_id != charserv_config.gm_allow_group ) ) {
			// refuse connection (over populated)
			WFIFOHEAD(u_fd,3);
			WFIFOW(u_fd,0) = 0x6c;
			WFIFOW(u_fd,2) = 0;
			WFIFOSET(u_fd,3);
		} else {
			// send characters to player
			chclif_mmo_char_send(u_fd, sd);
			if(sd->version >= date2version(20110309)){
				ShowInfo("Asking to start pincode\n");
				chlogif_pincode_start(u_fd,sd);
			}
		}
	}
	RFIFOSKIP(fd,79);
	return 1;
}
Example #20
0
/*==========================================
 * Return Mail
 *------------------------------------------*/
void mapif_Mail_return(int fd, uint32 char_id, int mail_id)
{
	struct mail_message msg;
	int new_mail = 0;

	if( mail_loadmessage(mail_id, &msg) )
	{
		if( msg.dest_id != char_id)
			return;
		else if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", schema_config.mail_db, mail_id)
			|| SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", schema_config.mail_attachment_db, mail_id) )
			Sql_ShowDebug(sql_handle);
		// If it was not sent by the server, since we do not want to return mails to the server
		else if( msg.send_id != 0 )
		{
			char temp_[MAIL_TITLE_LENGTH + 3];

			// swap sender and receiver
			SWAP(msg.send_id, msg.dest_id);
			safestrncpy(temp_, msg.send_name, NAME_LENGTH);
			safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH);
			safestrncpy(msg.dest_name, temp_, NAME_LENGTH);

			// set reply message title
			snprintf(temp_, sizeof(temp_), "RE:%s", msg.title);
			safestrncpy(msg.title, temp_, sizeof(temp_));

			msg.status = MAIL_NEW;
			msg.type = MAIL_INBOX_RETURNED;
			msg.timestamp = time(NULL);

			new_mail = mail_savemessage(&msg);
			mapif_Mail_new(&msg);
		}
	}

	// Only if the request came from a map-server and was not timer triggered for an offline character
	if( fd <= 0 ){
		return;
	}

	WFIFOHEAD(fd,11);
	WFIFOW(fd,0) = 0x384c;
	WFIFOL(fd,2) = char_id;
	WFIFOL(fd,6) = mail_id;
	WFIFOB(fd,10) = (new_mail == 0);
	WFIFOSET(fd,11);
}
Example #21
0
/*==========================================
 * Change Email
 *------------------------------------------*/
int chrif_changeemail(int id, const char *actual_email, const char *new_email)
{
	if (battle_config.etc_log)
		ShowInfo("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email);

	chrif_check(-1);

	WFIFOHEAD(char_fd,86);
	WFIFOW(char_fd,0) = 0x2b0c;
	WFIFOL(char_fd,2) = id;
	memcpy(WFIFOP(char_fd,6), actual_email, 40);
	memcpy(WFIFOP(char_fd,46), new_email, 40);
	WFIFOSET(char_fd,86);

	return 0;
}
Example #22
0
/*==========================================
 * GMに変化要求
 *------------------------------------------*/
int chrif_changegm(int id, const char *pass, int len)
{
	if (battle_config.etc_log)
		ShowInfo("chrif_changegm: account: %d, password: '******'.\n", id, pass);

	chrif_check(-1);

	WFIFOHEAD(char_fd, len + 8);
	WFIFOW(char_fd,0) = 0x2b0a;
	WFIFOW(char_fd,2) = len + 8;
	WFIFOL(char_fd,4) = id;
	memcpy(WFIFOP(char_fd,8), pass, len);
	WFIFOSET(char_fd, len + 8);

	return 0;
}
Example #23
0
/**
 * Packet send to all map-servers, except one. (wos: without our self) attach to ourself
 * @param sfd: fd to discard sending to
 * @param buf: packet to send in form of an array buffer
 * @param len: size of packet
 * @return : the number of map-serv the packet was sent to
 */
int chmapif_sendallwos(int sfd, unsigned char *buf, unsigned int len){
	int i, c;

	c = 0;
	for(i = 0; i < ARRAYLENGTH(map_server); i++) {
		int fd;
		if ((fd = map_server[i].fd) > 0 && fd != sfd) {
			WFIFOHEAD(fd,len);
			memcpy(WFIFOP(fd,0), buf, len);
			WFIFOSET(fd,len);
			c++;
		}
	}

	return c;
}
Example #24
0
//------------------------------------------------------
int mapif_pet_created(int fd, int account_id, struct s_pet *p)
{
	WFIFOHEAD(fd,12);
	WFIFOW(fd,0) = 0x3880;
	WFIFOL(fd,2) = account_id;
	if( p != NULL ) {
		WFIFOW(fd,6) = p->class_;
		WFIFOL(fd,8) = p->pet_id;
		ShowInfo("int_pet: created pet %d - %s\n", p->pet_id, p->name);
	} else {
		WFIFOW(fd,6) = 0;
		WFIFOL(fd,8) = 0;
	}
	WFIFOSET(fd,12);
	return 0;
}
Example #25
0
/// @param result
/// 0 (0x718): An unknown error has occurred.
/// 1: none/success
/// 2 (0x71c): Due to system settings can not be deleted.
/// 3 (0x719): A database error occurred.
/// 4 (0x71d): Deleting not yet possible time.
/// 5 (0x71e): Date of birth do not match.
/// Any (0x718): An unknown error has occurred.
/// HC: <082a>.W <char id>.L <Msg:0-5>.L
void chclif_char_delete2_accept_ack(int fd, uint32 char_id, uint32 result) {
	if(result == 1 ){
		struct char_session_data* sd;
		sd = (struct char_session_data*)session[fd]->session_data;

		if( sd->version >= date2version(20130000) ){
			chclif_mmo_char_send(fd, sd);
		}
	}

	WFIFOHEAD(fd,10);
	WFIFOW(fd,0) = 0x82a;
	WFIFOL(fd,2) = char_id;
	WFIFOL(fd,6) = result;
	WFIFOSET(fd,10);
}
Example #26
0
int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex]

#ifdef ENABLE_SC_SAVING
	int i, count=0;
	unsigned int tick;
	struct status_change_data data;
	struct status_change *sc = &sd->sc;
	const struct TimerData *timer;

	chrif_check(-1);
	tick = gettick();
	
	WFIFOHEAD(char_fd, 14 + SC_MAX*sizeof(struct status_change_data));
	WFIFOW(char_fd,0) = 0x2b1c;
	WFIFOL(char_fd,4) = sd->status.account_id;
	WFIFOL(char_fd,8) = sd->status.char_id;
	
	for (i = 0; i < SC_MAX; i++) {
		if (!sc->data[i])
			continue;
		if (sc->data[i]->timer != INVALID_TIMER) {
			timer = get_timer(sc->data[i]->timer);
			if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
				continue;
			data.tick = DIFF_TICK(timer->tick,tick); //Duration that is left before ending.
		} else
			data.tick = -1; //Infinite duration
		data.type = i;
		data.val1 = sc->data[i]->val1;
		data.val2 = sc->data[i]->val2;
		data.val3 = sc->data[i]->val3;
		data.val4 = sc->data[i]->val4;
		memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)),
			&data, sizeof(struct status_change_data));
		count++;
	}
	
	if (count == 0)
		return 0; //Nothing to save.
	
	WFIFOW(char_fd,12) = count;
	WFIFOW(char_fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size
	WFIFOSET(char_fd,WFIFOW(char_fd,2));
#endif
	
	return 0;
}
Example #27
0
/**
 * Handles the save request from mapserver for a character's questlog.
 *
 * Received quests are saved, and an ack is sent back to the map server.
 *
 * @see inter_parse_frommap
 */
int mapif_parse_quest_save(int fd) {
	int i, j, k, old_n, new_n = (RFIFOW(fd,2)-8)/sizeof(struct quest);
	int char_id = RFIFOL(fd,4);
	struct quest *old_qd = NULL, *new_qd = NULL;
	bool success = true;

	if (new_n > 0)
		new_qd = (struct quest*)RFIFOP(fd,8);

	old_qd = mapif_quests_fromsql(char_id, &old_n);

	for (i = 0; i < new_n; i++) {
		ARR_FIND( 0, old_n, j, new_qd[i].quest_id == old_qd[j].quest_id );
		if (j < old_n) {
			// Update existing quests

			// Only states and counts are changeable.
			ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, new_qd[i].count[k] != old_qd[j].count[k] );
			if (k != MAX_QUEST_OBJECTIVES || new_qd[i].state != old_qd[j].state)
				success &= mapif_quest_update(char_id, new_qd[i]);

			if (j < (--old_n)) {
				// Compact array
				memmove(&old_qd[j],&old_qd[j+1],sizeof(struct quest)*(old_n-j));
				memset(&old_qd[old_n], 0, sizeof(struct quest));
			}
		} else {
			// Add new quests
			success &= mapif_quest_add(char_id, new_qd[i]);
		}
	}

	for (i = 0; i < old_n; i++) // Quests not in new_qd but in old_qd are to be erased.
		success &= mapif_quest_delete(char_id, old_qd[i].quest_id);

	if (old_qd)
		aFree(old_qd);

	// Send ack
	WFIFOHEAD(fd,7);
	WFIFOW(fd,0) = 0x3861;
	WFIFOL(fd,2) = char_id;
	WFIFOB(fd,6) = success?1:0;
	WFIFOSET(fd,7);

	return 0;
}
Example #28
0
//------------------------------------------------------
int mapif_pet_created(int fd, int account_id, struct s_pet *p)
{
	WFIFOHEAD(fd, 12);
	WFIFOW(fd, 0) = 0x3880;
	WFIFOL(fd, 2) = account_id;
	if(p!=NULL){
		WFIFOW(fd, 6) = p->class_;
		WFIFOL(fd, 8) = p->pet_id;
		ShowInfo("Mascote criado! (PETID:%d | Nome:%s)\n", p->pet_id, p->name);
	}else{
		WFIFOB(fd, 6) = 0;
		WFIFOL(fd, 8) = 0;
	}
	WFIFOSET(fd, 12);

	return 0;
}
/**
 * Timered function to send all account_id connected to login-serv
 * @param tid : Timer id
 * @param tick : Scheduled tick
 * @param id : GID linked to that timered call
 * @param data : data transmited for delayed function
 * @return 
 */
int chlogif_send_acc_tologin(int tid, unsigned int tick, int id, intptr_t data) {
	if ( chlogif_isconnected() ){
		DBMap*  online_char_db = char_get_onlinedb();
		// send account list to login server
		int users = online_char_db->size(online_char_db);
		int i = 0;

		WFIFOHEAD(login_fd,8+users*4);
		WFIFOW(login_fd,0) = 0x272d;
		online_char_db->foreach(online_char_db, chlogif_send_acc_tologin_sub, &i, users);
		WFIFOW(login_fd,2) = 8+ i*4;
		WFIFOL(login_fd,4) = i;
		WFIFOSET(login_fd,WFIFOW(login_fd,2));
		return 1;
	}
	return 0;
}
Example #30
0
//Request skillcooldown data 0x2b0a
int chmapif_parse_req_skillcooldown(int fd){
	if (RFIFOREST(fd) < 10)
		return 0;
	else {
		int aid, cid;
		aid = RFIFOL(fd,2);
		cid = RFIFOL(fd,6);
		RFIFOSKIP(fd, 10);
		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT skill, tick FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
			schema_config.skillcooldown_db, aid, cid) )
		{
			Sql_ShowDebug(sql_handle);
			return 1;
		}
		if( Sql_NumRows(sql_handle) > 0 )
		{
			int count;
			char* data;
			struct skill_cooldown_data scd;

			WFIFOHEAD(fd,14 + MAX_SKILLCOOLDOWN * sizeof(struct skill_cooldown_data));
			WFIFOW(fd,0) = 0x2b0b;
			WFIFOL(fd,4) = aid;
			WFIFOL(fd,8) = cid;
			for( count = 0; count < MAX_SKILLCOOLDOWN && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count )
			{
				Sql_GetData(sql_handle, 0, &data, NULL); scd.skill_id = atoi(data);
				Sql_GetData(sql_handle, 1, &data, NULL); scd.tick = atoi(data);
				memcpy(WFIFOP(fd,14+count*sizeof(struct skill_cooldown_data)), &scd, sizeof(struct skill_cooldown_data));
			}
			if( count >= MAX_SKILLCOOLDOWN )
				ShowWarning("Too many skillcooldowns for %d:%d, some of them were not loaded.\n", aid, cid);
			if( count > 0 )
			{
				WFIFOW(fd,2) = 14 + count * sizeof(struct skill_cooldown_data);
				WFIFOW(fd,12) = count;
				WFIFOSET(fd,WFIFOW(fd,2));
				//Clear the data once loaded.
				if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", schema_config.skillcooldown_db, aid, cid) )
					Sql_ShowDebug(sql_handle);
			}
		}
		Sql_FreeResult(sql_handle);
	}
	return 1;
}