From 5697031dce0f02a55044504077775b909a42982d Mon Sep 17 00:00:00 2001 From: Haru Date: Sat, 28 Sep 2013 18:15:23 +0200 Subject: Provided argument-list equivalent for several variadic functions This is necessary for the upcoming HPM hooking system --- src/char/inter.c | 101 ++++++++---- src/char/inter.h | 1 + src/common/db.c | 18 ++- src/common/db.h | 13 +- src/map/map.c | 474 +++++++++++++++++++++++++++++++++++++++++++------------ src/map/map.h | 15 ++ src/map/party.c | 34 +++- src/map/party.h | 1 + 8 files changed, 509 insertions(+), 148 deletions(-) diff --git a/src/char/inter.c b/src/char/inter.c index 353d3e009..2dc15933b 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -414,16 +414,19 @@ const char* geoip_getcountry(uint32 ipnum){ } return geoip_countryname[0]; } -/* sends a mesasge to map server (fd) to a user (u_fd) although we use fd we keep aid for safe-check */ -/* extremely handy I believe it will serve other uses in the near future */ -void inter_to_fd(int fd, int u_fd, int aid, char* msg, ...) { + +/** + * Argument-list version of inter_msg_to_fd + * @see inter_msg_to_fd + */ +void inter_vmsg_to_fd(int fd, int u_fd, int aid, char* msg, va_list ap) { char msg_out[512]; - va_list ap; + va_list apcopy; int len = 1;/* yes we start at 1 */ - va_start(ap,msg); - len += vsnprintf(msg_out, 512, msg, ap); - va_end(ap); + va_copy(apcopy, ap); + len += vsnprintf(msg_out, 512, msg, apcopy); + va_end(apcopy); WFIFOHEAD(fd,12 + len); @@ -437,6 +440,23 @@ void inter_to_fd(int fd, int u_fd, int aid, char* msg, ...) { return; } + +/** + * Sends a message to map server (fd) to a user (u_fd) although we use fd we + * keep aid for safe-check. + * @param fd Mapserver's fd + * @param u_fd Recipient's fd + * @param aid Recipient's expected for sanity checks on the mapserver + * @param msg Message format string + * @param ... Additional parameters for (v)sprinf + */ +void inter_msg_to_fd(int fd, int u_fd, int aid, char* msg, ...) { + va_list ap; + va_start(ap,msg); + inter_vmsg_to_fd(fd, u_fd, aid, msg, ap); + va_end(ap); +} + /* [Dekamaster/Nightroad] */ void mapif_parse_accinfo(int fd) { int u_fd = RFIFOL(fd,2), aid = RFIFOL(fd,6), castergroup = RFIFOL(fd,10); @@ -454,10 +474,10 @@ void mapif_parse_accinfo(int fd) { if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name`,`class`,`base_level`,`job_level`,`online` FROM `%s` WHERE `name` LIKE '%s' LIMIT 10", char_db, query_esq) || SQL->NumRows(sql_handle) == 0 ) { if( SQL->NumRows(sql_handle) == 0 ) { - inter_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query); + inter_msg_to_fd(fd, u_fd, aid, "No matches were found for your criteria, '%s'",query); } else { Sql_ShowDebug(sql_handle); - inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it."); + inter_msg_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it."); } SQL->FreeResult(sql_handle); return; @@ -467,7 +487,7 @@ void mapif_parse_accinfo(int fd) { SQL->GetData(sql_handle, 0, &data, NULL); account_id = atoi(data); SQL->FreeResult(sql_handle); } else {// more than one, listing... [Dekamaster/Nightroad] - inter_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(sql_handle)); + inter_msg_to_fd(fd, u_fd, aid, "Your query returned the following %d results, please be more specific...",(int)SQL->NumRows(sql_handle)); while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { int class_; short base_level, job_level, online; @@ -480,7 +500,7 @@ void mapif_parse_accinfo(int fd) { SQL->GetData(sql_handle, 4, &data, NULL); job_level = atoi(data); SQL->GetData(sql_handle, 5, &data, NULL); online = atoi(data); - inter_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline"); + inter_msg_to_fd(fd, u_fd, aid, "[AID: %d] %s | %s | Level: %d/%d | %s", account_id, name, job_name(class_), base_level, job_level, online?"Online":"Offline"); } SQL->FreeResult(sql_handle); return; @@ -497,9 +517,9 @@ void mapif_parse_accinfo(int fd) { if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `userid`, `user_pass`, `email`, `last_ip`, `group_id`, `lastlogin`, `logincount`, `state`,`pincode`,`birthdate` FROM `login` WHERE `account_id` = '%d' LIMIT 1", account_id) || SQL->NumRows(sql_handle) == 0 ) { if( SQL->NumRows(sql_handle) == 0 ) { - inter_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id ); + inter_msg_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id ); } else { - inter_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it."); + inter_msg_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it."); Sql_ShowDebug(sql_handle); } } else { @@ -521,29 +541,29 @@ void mapif_parse_accinfo(int fd) { if (level == -1) return; - inter_to_fd(fd, u_fd, aid, "-- Account %d --", account_id ); - inter_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state ); + inter_msg_to_fd(fd, u_fd, aid, "-- Account %d --", account_id ); + inter_msg_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state ); if (level < castergroup) { /* only show pass if your gm level is greater than the one you're searching for */ if( strlen(pin_code) ) - inter_to_fd(fd, u_fd, aid, "Password: %s (PIN:%s)", user_pass, pin_code ); + inter_msg_to_fd(fd, u_fd, aid, "Password: %s (PIN:%s)", user_pass, pin_code ); else - inter_to_fd(fd, u_fd, aid, "Password: %s", user_pass ); + inter_msg_to_fd(fd, u_fd, aid, "Password: %s", user_pass ); } - inter_to_fd(fd, u_fd, aid, "Account e-mail: %s | Birthdate: %s", email, birthdate); - inter_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) ); - inter_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin ); - inter_to_fd(fd, u_fd, aid, "-- Character Details --" ); + inter_msg_to_fd(fd, u_fd, aid, "Account e-mail: %s | Birthdate: %s", email, birthdate); + inter_msg_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) ); + inter_msg_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin ); + inter_msg_to_fd(fd, u_fd, aid, "-- Character Details --" ); if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS) || SQL->NumRows(sql_handle) == 0 ) { if( SQL->NumRows(sql_handle) == 0 ) - inter_to_fd(fd, u_fd, aid,"This account doesn't have characters."); + inter_msg_to_fd(fd, u_fd, aid,"This account doesn't have characters."); else { - inter_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it."); + inter_msg_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it."); Sql_ShowDebug(sql_handle); } @@ -561,7 +581,7 @@ void mapif_parse_accinfo(int fd) { SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data); SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data); - inter_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off"); + inter_msg_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off"); } } SQL->FreeResult(sql_handle); @@ -743,16 +763,18 @@ static int inter_config_read(const char* cfgName) return 0; } -// Save interlog into sql -int inter_log(char* fmt, ...) -{ +/** + * Save interlog into sql (arglist version) + * @see inter_log + */ +int inter_vlog(char* fmt, va_list ap) { char str[255]; char esc_str[sizeof(str)*2+1];// escaped str - va_list ap; + va_list apcopy; - va_start(ap,fmt); - vsnprintf(str, sizeof(str), fmt, ap); - va_end(ap); + va_copy(apcopy, ap); + vsnprintf(str, sizeof(str), fmt, apcopy); + va_end(apcopy); SQL->EscapeStringLen(sql_handle, esc_str, str, strnlen(str, sizeof(str))); if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`time`, `log`) VALUES (NOW(), '%s')", interlog_db, esc_str) ) @@ -761,6 +783,23 @@ int inter_log(char* fmt, ...) return 0; } +/** + * Save interlog into sql + * @param fmt Message's format string + * @param ... Additional (printf-like) arguments + * @return Always 0 // FIXME + */ +int inter_log(char* fmt, ...) { + va_list ap; + int ret; + + va_start(ap,fmt); + ret = inter_vlog(fmt, ap); + va_end(ap); + + return ret; +} + // initialize int inter_init_sql(const char *file) { diff --git a/src/char/inter.h b/src/char/inter.h index f6663813a..88501c9a0 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -17,6 +17,7 @@ int mapif_send_gmaccounts(void); int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason); int inter_log(char *fmt,...); +int inter_vlog(char *fmt, va_list ap); #define inter_cfgName "conf/inter-server.conf" diff --git a/src/common/db.c b/src/common/db.c index bd2bea424..b3a58e0a4 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -2730,20 +2730,26 @@ void linkdb_insert( struct linkdb_node** head, void *key, void* data) node->data = data; } -void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... ) -{ +void linkdb_vforeach( struct linkdb_node** head, LinkDBFunc func, va_list ap) { struct linkdb_node *node; if( head == NULL ) return; node = *head; while ( node ) { - va_list args; - va_start(args, func); - func( node->key, node->data, args ); - va_end(args); + va_list argscopy; + va_copy(argscopy, ap); + func(node->key, node->data, argscopy); + va_end(argscopy); node = node->next; } } +void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ...) { + va_list ap; + va_start(ap, func); + linkdb_vforeach(head, func, ap); + va_end(ap); +} + void* linkdb_search( struct linkdb_node** head, void *key) { int n = 0; diff --git a/src/common/db.h b/src/common/db.h index aa4bfb054..dffd2356d 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -882,12 +882,13 @@ struct linkdb_node { typedef void (*LinkDBFunc)(void* key, void* data, va_list args); -void linkdb_insert ( struct linkdb_node** head, void *key, void* data); // 重複を考慮しない -void linkdb_replace( struct linkdb_node** head, void *key, void* data); // 重複を考慮する -void* linkdb_search ( struct linkdb_node** head, void *key); -void* linkdb_erase ( struct linkdb_node** head, void *key); -void linkdb_final ( struct linkdb_node** head ); -void linkdb_foreach( struct linkdb_node** head, LinkDBFunc func, ... ); +void linkdb_insert (struct linkdb_node** head, void *key, void* data); // 重複を考慮しない +void linkdb_replace (struct linkdb_node** head, void *key, void* data); // 重複を考慮する +void* linkdb_search (struct linkdb_node** head, void *key); +void* linkdb_erase (struct linkdb_node** head, void *key); +void linkdb_final (struct linkdb_node** head); +void linkdb_vforeach(struct linkdb_node** head, LinkDBFunc func, va_list ap); +void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...); diff --git a/src/map/map.c b/src/map/map.c index 899f6b963..ea40d9979 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -596,13 +596,12 @@ static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m, * @param ... Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, ...) -{ - int returnCount = 0; +int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, ...) { + int returnCount; va_list ap; va_start(ap, type); - returnCount = map_vforeachinmap(func, m, type, ap); + returnCount = map->vforeachinmap(func, m, type, ap); va_end(ap); return returnCount; @@ -616,25 +615,46 @@ int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type * @param func Function to be applied * @param m Map id * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, ...) -{ +int map_vforeachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, va_list ap) { int i; int returnCount = 0; for (i = 0; i < instance->list[instance_id].num_map; i++) { int m = instance->list[instance_id].map[i]; - va_list ap; - va_start(ap, type); - returnCount += map_vforeachinmap(func, m, type, ap); - va_end(ap); + va_list apcopy; + va_copy(apcopy, ap); + returnCount += map->vforeachinmap(func, m, type, apcopy); + va_end(apcopy); } return returnCount; } +/** + * Applies func to every block_list object of bl_type type on all maps + * of instance instance_id. + * Returns the sum of values returned by func. + * @see map_vforeachininstance. + * @param func Function to be applied + * @param m Map id + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, ...) { + int returnCount; + va_list ap; + + va_start(ap, type); + returnCount = map->vforeachininstance(func, instance_id, type, ap); + va_end(ap); + + return returnCount; +} + /** * Retrieves all map objects in area that are matched by the type * and func. Appends them at the end of global bl_list array. @@ -740,21 +760,43 @@ static int bl_vgetall_inrange(struct block_list *bl, va_list args) * @param center Center of the selection area * @param range Range in cells from center * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) -{ +int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; if (range < 0) range *= -1; bl_getall_area(type, center->m, center->x - range, center->y - range, center->x + range, center->y + range, bl_vgetall_inrange, center, range); + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy); + va_end(ap); + + return returnCount; +} + +/** + * Applies func to every block_list object of bl_type type within range cells from center. + * Area is rectangular, unless CIRCULAR_AREA is defined. + * Returns the sum of values returned by func. + * @see map_vforeachinrange + * @param func Function to be applied + * @param center Center of the selection area + * @param range Range in cells from center + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, INT_MAX, ap); + returnCount = map->vforeachinrange(func, center, range, type, ap); va_end(ap); return returnCount; @@ -770,21 +812,45 @@ int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_li * @param range Range in cells from center * @param count Maximum sum of values returned by func (usually max number of func calls) * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_forcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, ...) -{ +int map_vforcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; if (range < 0) range *= -1; bl_getall_area(type, center->m, center->x - range, center->y - range, center->x + range, center->y + range, bl_vgetall_inrange, center, range); + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, count, apcopy); + va_end(apcopy); + + return returnCount; +} + +/** + * Applies func to some block_list objects of bl_type type within range cells from center. + * Limit is set by count parameter. + * Area is rectangular, unless CIRCULAR_AREA is defined. + * Returns the sum of values returned by func. + * @see map_vforcountinrange + * @param func Function to be applied + * @param center Center of the selection area + * @param range Range in cells from center + * @param count Maximum sum of values returned by func (usually max number of func calls) + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_forcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, count, ap); + returnCount = map->vforcountinrange(func, center, range, count, type, ap); va_end(ap); return returnCount; @@ -819,21 +885,43 @@ static int bl_vgetall_inshootrange(struct block_list *bl, va_list args) * @param center Center of the selection area * @param range Range in cells from center * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) -{ +int map_vforeachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; if (range < 0) range *= -1; bl_getall_area(type, center->m, center->x - range, center->y - range, center->x + range, center->y + range, bl_vgetall_inshootrange, center, range); - va_start(ap, type); + va_copy(apcopy, ap); returnCount = bl_vforeach(func, blockcount, INT_MAX, ap); + va_end(apcopy); + + return returnCount; +} + +/** + * Applies func to every block_list object of bl_type type within shootable range from center. + * There must be a shootable path between bl and center. + * Area is rectangular, unless CIRCULAR_AREA is defined. + * Returns the sum of values returned by func. + * @param func Function to be applied + * @param center Center of the selection area + * @param range Range in cells from center + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) { + int returnCount; + va_list ap; + + va_start(ap, type); + returnCount = map->vforeachinshootrange(func, center, range, type, ap); va_end(ap); return returnCount; @@ -850,19 +938,44 @@ int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct blo * @param x1 Ending X-coordinate * @param y1 Ending Y-coordinate * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...) -{ +int map_vforeachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; bl_getall_area(type, m, x0, y0, x1, y1, NULL); + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy); + va_end(apcopy); + + return returnCount; +} + +/** + * Applies func to every block_list object of bl_type type in + * rectangular area (x0,y0)~(x1,y1) on map m. + * Returns the sum of values returned by func. + * @see map_vforeachinarea + * @param func Function to be applied + * @param m Map id + * @param x0 Starting X-coordinate + * @param y0 Starting Y-coordinate + * @param x1 Ending X-coordinate + * @param y1 Ending Y-coordinate + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, INT_MAX, ap); + returnCount = map->vforeachinarea(func, m, x0, y0, x1, y1, type, ap); va_end(ap); return returnCount; @@ -881,19 +994,46 @@ int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x * @param y1 Ending Y-coordinate * @param count Maximum sum of values returned by func (usually max number of func calls) * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...) -{ +int map_vforcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; bl_getall_area(type, m, x0, y0, x1, y1, NULL); + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, count, apcopy); + va_end(apcopy); + + return returnCount; +} + +/** + * Applies func to some block_list objects of bl_type type in + * rectangular area (x0,y0)~(x1,y1) on map m. + * Limit is set by @count parameter. + * Returns the sum of values returned by func. + * @see map_vforcountinarea + * @param func Function to be applied + * @param m Map id + * @param x0 Starting X-coordinate + * @param y0 Starting Y-coordinate + * @param x1 Ending X-coordinate + * @param y1 Ending Y-coordinate + * @param count Maximum sum of values returned by func (usually max number of func calls) + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, count, ap); + returnCount = map->vforcountinarea(func, m, x0, y0, x1, y1, count, type, ap); va_end(ap); return returnCount; @@ -939,15 +1079,14 @@ static int bl_vgetall_inmovearea(struct block_list *bl, va_list args) * @param dx Center's movement on X-axis * @param dy Center's movement on Y-axis * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...) -{ +int map_vforeachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; int m, x0, x1, y0, y1; + va_list apcopy; if (!range) return 0; if (!dx && !dy) return 0; // No movement. @@ -974,8 +1113,39 @@ int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block bl_getall_area(type, m, x0, y0, x1, y1, bl_vgetall_inmovearea, dx, dy, center, range); } + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy); + va_end(apcopy); + + return returnCount; +} + +/** + * Applies func to every block_list object of bl_type type in + * area that was covered by range cells from center, but is no + * longer after center is moved by (dx,dy) cells (i.e. area that + * center has lost sight of). + * If used after center has reached its destination and with + * opposed movement vector (-dx,-dy), selection corresponds + * to new area in center's view). + * Uses rectangular area. + * Returns the sum of values returned by func. + * @see map_vforeachinmovearea + * @param func Function to be applied + * @param center Center of the selection area + * @param range Range in cells from center + * @param dx Center's movement on X-axis + * @param dy Center's movement on Y-axis + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, INT_MAX, ap); + returnCount = map->vforeachinmovearea(func, center, range, dx, dy, type, ap); va_end(ap); return returnCount; @@ -990,19 +1160,41 @@ int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block * @param x Target cell X-coordinate * @param y Target cell Y-coordinate * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, ...) -{ +int map_vforeachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, va_list ap) { int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; bl_getall_area(type, m, x, y, x, y, NULL); + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy); + va_end(apcopy); + + return returnCount; +} + +/** + * Applies func to every block_list object of bl_type type in + * cell (x,y) on map m. + * Returns the sum of values returned by func. + * @param func Function to be applied + * @param m Map id + * @param x Target cell X-coordinate + * @param y Target cell Y-coordinate + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, INT_MAX, ap); + returnCount = map->vforeachincell(func, m, x, y, type, ap); va_end(ap); return returnCount; @@ -1069,11 +1261,10 @@ static int bl_vgetall_inpath(struct block_list *bl, va_list args) * @param x Target cell X-coordinate * @param y Target cell Y-coordinate * @param type enum bl_type - * @param ... Extra arguments for func + * @param ap Extra arguments for func * @return Sum of the values returned by func */ -int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...) -{ +int map_vforeachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, va_list ap) { // [Skotlex] // check for all targets in the square that // contains the initial and final positions (area range increased to match the @@ -1090,7 +1281,7 @@ int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x int returnCount = 0; int blockcount = bl_list_count; - va_list ap; + va_list apcopy; //method specific variables int magnitude2, len_limit; //The square of the magnitude @@ -1127,13 +1318,40 @@ int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x bl_getall_area(type, m, mx0, my0, mx1, my1, bl_vgetall_inpath, m, x0, y0, x1, y1, range, len_limit, magnitude2); + va_copy(apcopy, ap); + returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy); + va_end(apcopy); + + return returnCount; +} +#undef MAGNITUDE2 + +/** + * Applies func to every block_list object of bl_type type in + * path on a line between (x0,y0) and (x1,y1) on map m. + * Path starts at (x0,y0) and is \a length cells long and \a range cells wide. + * Objects beyond the initial (x1,y1) ending point are checked + * for walls in the path. + * Returns the sum of values returned by func. + * @see map_vforeachinpath + * @param func Function to be applied + * @param m Map id + * @param x Target cell X-coordinate + * @param y Target cell Y-coordinate + * @param type enum bl_type + * @param ... Extra arguments for func + * @return Sum of the values returned by func + */ +int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...) { + int returnCount; + va_list ap; + va_start(ap, type); - returnCount = bl_vforeach(func, blockcount, INT_MAX, ap); + returnCount = map->vforeachinpath(func, m, x0, y0, x1, y1, range, length, type, ap); va_end(ap); return returnCount; } -#undef MAGNITUDE2 /** @} */ @@ -1304,11 +1522,10 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1 continue; if(flag&4) { if (spawn >= 100) return 0; //Limit of retries reached. - if (spawn++ < battle_config.no_spawn_on_player && - map_foreachinarea(map_count_sub, m, - *x-AREA_SIZE, *y-AREA_SIZE, - *x+AREA_SIZE, *y+AREA_SIZE, BL_PC) - ) + if (spawn++ < battle_config.no_spawn_on_player + && map->foreachinarea(map_count_sub, m, *x-AREA_SIZE, *y-AREA_SIZE, + *x+AREA_SIZE, *y+AREA_SIZE, BL_PC) + ) continue; } return 1; @@ -1784,66 +2001,83 @@ struct mob_data * map_id2boss(int id) /// Applies func to all the players in the db. /// Stops iterating if func returns -1. -void map_map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) { +void map_vmap_foreachpc(int (*func)(struct map_session_data* sd, va_list args), va_list args) { DBIterator* iter; struct map_session_data* sd; iter = db_iterator(pc_db); for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) ) { - va_list args; + va_list argscopy; int ret; - va_start(args, func); - ret = func(sd, args); - va_end(args); + va_copy(argscopy, args); + ret = func(sd, argscopy); + va_end(argscopy); if( ret == -1 ) break;// stop iterating } dbi_destroy(iter); } +/// Applies func to all the players in the db. +/// Stops iterating if func returns -1. +/// @see map_vmap_foreachpc +void map_map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) { + va_list args; + + va_start(args, func); + map->vmap_foreachpc(func, args); + va_end(args); +} + /// Applies func to all the mobs in the db. /// Stops iterating if func returns -1. -void map_map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) -{ +void map_vmap_foreachmob(int (*func)(struct mob_data* md, va_list args), va_list args) { DBIterator* iter; struct mob_data* md; iter = db_iterator(mobid_db); - for( md = (struct mob_data*)dbi_first(iter); dbi_exists(iter); md = (struct mob_data*)dbi_next(iter) ) - { - va_list args; + for( md = (struct mob_data*)dbi_first(iter); dbi_exists(iter); md = (struct mob_data*)dbi_next(iter) ) { + va_list argscopy; int ret; - va_start(args, func); - ret = func(md, args); - va_end(args); + va_copy(argscopy, args); + ret = func(md, argscopy); + va_end(argscopy); if( ret == -1 ) break;// stop iterating } dbi_destroy(iter); } +/// Applies func to all the mobs in the db. +/// Stops iterating if func returns -1. +/// @see map_vmap_foreachmob +void map_map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) { + va_list args; + + va_start(args, func); + map->vmap_foreachmob(func, args); + va_end(args); +} + /// Applies func to all the npcs in the db. /// Stops iterating if func returns -1. -void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) -{ +void map_vmap_foreachnpc(int (*func)(struct npc_data* nd, va_list args), va_list args) { DBIterator* iter; struct block_list* bl; iter = db_iterator(id_db); - for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) - { - if( bl->type == BL_NPC ) - { + for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) { + if( bl->type == BL_NPC ) { struct npc_data* nd = (struct npc_data*)bl; - va_list args; + va_list argscopy; int ret; - va_start(args, func); - ret = func(nd, args); - va_end(args); + va_copy(argscopy, args); + ret = func(nd, argscopy); + va_end(argscopy); if( ret == -1 ) break;// stop iterating } @@ -1851,50 +2085,79 @@ void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) dbi_destroy(iter); } +/// Applies func to all the npcs in the db. +/// Stops iterating if func returns -1. +/// @see map_vmap_foreachnpc +void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) { + va_list args; + + va_start(args, func); + map->vmap_foreachnpc(func, args); + va_end(args); +} + /// Applies func to everything in the db. /// Stops iteratin gif func returns -1. -void map_map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) -{ +void map_vmap_foreachregen(int (*func)(struct block_list* bl, va_list args), va_list args) { DBIterator* iter; struct block_list* bl; iter = db_iterator(regen_db); - for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) - { - va_list args; + for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) { + va_list argscopy; int ret; - va_start(args, func); - ret = func(bl, args); - va_end(args); + va_copy(argscopy, args); + ret = func(bl, argscopy); + va_end(argscopy); if( ret == -1 ) break;// stop iterating } dbi_destroy(iter); } +/// Applies func to everything in the db. +/// Stops iteratin gif func returns -1. +/// @see map_vmap_foreachregen +void map_map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) { + va_list args; + + va_start(args, func); + map->vmap_foreachregen(func, args); + va_end(args); +} + /// Applies func to everything in the db. /// Stops iterating if func returns -1. -void map_map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) -{ +void map_vmap_foreachiddb(int (*func)(struct block_list* bl, va_list args), va_list args) { DBIterator* iter; struct block_list* bl; iter = db_iterator(id_db); - for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) - { - va_list args; + for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) { + va_list argscopy; int ret; - va_start(args, func); - ret = func(bl, args); - va_end(args); + va_copy(argscopy, args); + ret = func(bl, argscopy); + va_end(argscopy); if( ret == -1 ) break;// stop iterating } dbi_destroy(iter); } +/// Applies func to everything in the db. +/// Stops iterating if func returns -1. +/// @see map_vmap_foreachiddb +void map_map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) { + va_list args; + + va_start(args, func); + map->vmap_foreachiddb(func, args); + va_end(args); +} + /// Iterator. /// Can filter by bl type. struct s_mapiterator @@ -2128,7 +2391,7 @@ int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data) if (maplist[m].users > 0) //Map not empty! return 1; - count = map_foreachinmap(map_removemobs_sub, m, BL_MOB); + count = map->foreachinmap(map_removemobs_sub, m, BL_MOB); if (battle_config.etc_log && count > 0) ShowStatus("Map %s: Removed '"CL_WHITE"%d"CL_RESET"' mobs.\n",maplist[m].name, count); @@ -4888,7 +5151,7 @@ void do_final(void) for (i = 0; i < map->map_num; i++) { ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map->map_num, maplist[i].name); if (maplist[i].m >= 0) - map_foreachinmap(map->cleanup_sub, i, BL_ALL); + map->foreachinmap(map->cleanup_sub, i, BL_ALL); } ShowStatus("Cleaned up %d maps."CL_CLL"\n", map->map_num); @@ -5479,21 +5742,36 @@ void map_defaults(void) { map->charid2nick = map_charid2nick; map->charid2sd = map_charid2sd; + map->vmap_foreachpc = map_vmap_foreachpc; map->map_foreachpc = map_map_foreachpc; + map->vmap_foreachmob = map_vmap_foreachmob; map->map_foreachmob = map_map_foreachmob; + map->vmap_foreachnpc = map_vmap_foreachnpc; map->map_foreachnpc = map_map_foreachnpc; + map->vmap_foreachregen = map_vmap_foreachregen; map->map_foreachregen = map_map_foreachregen; + map->vmap_foreachiddb = map_vmap_foreachiddb; map->map_foreachiddb = map_map_foreachiddb; + map->vforeachinrange = map_vforeachinrange; map->foreachinrange = map_foreachinrange; + map->vforeachinshootrange = map_vforeachinshootrange; map->foreachinshootrange = map_foreachinshootrange; + map->vforeachinarea = map_vforeachinarea; map->foreachinarea = map_foreachinarea; + map->vforcountinrange = map_vforcountinrange; map->forcountinrange = map_forcountinrange; + map->vforcountinarea = map_vforcountinarea; map->forcountinarea = map_forcountinarea; + map->vforeachinmovearea = map_vforeachinmovearea; map->foreachinmovearea = map_foreachinmovearea; + map->vforeachincell = map_vforeachincell; map->foreachincell = map_foreachincell; + map->vforeachinpath = map_vforeachinpath; map->foreachinpath = map_foreachinpath; + map->vforeachinmap = map_vforeachinmap; map->foreachinmap = map_foreachinmap; + map->vforeachininstance = map_vforeachininstance; map->foreachininstance = map_foreachininstance; map->id2sd = map_id2sd; diff --git a/src/map/map.h b/src/map/map.h index f3a74ed2e..69152ec57 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -841,21 +841,36 @@ struct map_interface { const char* (*charid2nick) (int charid); struct map_session_data* (*charid2sd) (int charid); + void (*vmap_foreachpc) (int (*func)(struct map_session_data* sd, va_list args), va_list args); void (*map_foreachpc) (int (*func)(struct map_session_data* sd, va_list args), ...); + void (*vmap_foreachmob) (int (*func)(struct mob_data* md, va_list args), va_list args); void (*map_foreachmob) (int (*func)(struct mob_data* md, va_list args), ...); + void (*vmap_foreachnpc) (int (*func)(struct npc_data* nd, va_list args), va_list args); void (*map_foreachnpc) (int (*func)(struct npc_data* nd, va_list args), ...); + void (*vmap_foreachregen) (int (*func)(struct block_list* bl, va_list args), va_list args); void (*map_foreachregen) (int (*func)(struct block_list* bl, va_list args), ...); + void (*vmap_foreachiddb) (int (*func)(struct block_list* bl, va_list args), va_list args); void (*map_foreachiddb) (int (*func)(struct block_list* bl, va_list args), ...); + int (*vforeachinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, va_list ap); int (*foreachinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...); + int (*vforeachinshootrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, va_list ap); int (*foreachinshootrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int type, ...); + int (*vforeachinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, va_list ap); int (*foreachinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...); + int (*vforcountinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int count, int type, va_list ap); int (*forcountinrange) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int count, int type, ...); + int (*vforcountinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, va_list ap); int (*forcountinarea) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...); + int (*vforeachinmovearea) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, va_list ap); int (*foreachinmovearea) (int (*func)(struct block_list*,va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...); + int (*vforeachincell) (int (*func)(struct block_list*,va_list), int16 m, int16 x, int16 y, int type, va_list ap); int (*foreachincell) (int (*func)(struct block_list*,va_list), int16 m, int16 x, int16 y, int type, ...); + int (*vforeachinpath) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, va_list ap); int (*foreachinpath) (int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...); + int (*vforeachinmap) (int (*func)(struct block_list*,va_list), int16 m, int type, va_list args); int (*foreachinmap) (int (*func)(struct block_list*,va_list), int16 m, int type, ...); + int (*vforeachininstance)(int (*func)(struct block_list*,va_list), int16 instance_id, int type, va_list ap); int (*foreachininstance)(int (*func)(struct block_list*,va_list), int16 instance_id, int type,...); struct map_session_data * (*id2sd) (int id); diff --git a/src/map/party.c b/src/map/party.c index 29ab5044c..a3fd5019f 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -1031,9 +1031,11 @@ int party_sub_count(struct block_list *bl, va_list ap) return 1; } -/// Executes 'func' for each party member on the same map and in range (0:whole map) -int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_session_data *sd,int range,...) -{ +/** + * Arglist-based version of party_foreachsamemap + * @see party_foreachsamemap + */ +int party_vforeachsamemap(int (*func)(struct block_list*,va_list), struct map_session_data *sd, int range, va_list ap) { struct party_data *p; int i; int x0,y0,x1,y1; @@ -1067,10 +1069,10 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess map->freeblock_lock(); for(i=0;ifreeblock_unlock(); @@ -1078,6 +1080,23 @@ int party_foreachsamemap(int (*func)(struct block_list*,va_list),struct map_sess return total; } +/** + * Executes 'func' for each party member on the same map and within a 'range' cells area + * @param func Function to execute + * @param sd Reference character for party, map, area center + * @param range Area size (0 = whole map) + * @param ... Adidtional parameters to pass to func() + * @return Sum of the return values from func() + */ +int party_foreachsamemap(int (*func)(struct block_list*,va_list), struct map_session_data *sd, int range, ...) { + va_list ap; + int ret; + va_start(ap, range); + ret = party->vforeachsamemap(func, sd, range, ap); + va_end(ap); + return ret; +} + /*========================================== * Party Booking in KRO [Spiria] *------------------------------------------*/ @@ -1291,6 +1310,7 @@ void party_defaults(void) { party->booking_update = party_booking_update; party->booking_search = party_booking_search; party->booking_delete = party_booking_delete; + party->vforeachsamemap = party_vforeachsamemap; party->foreachsamemap = party_foreachsamemap; party->send_xy_timer = party_send_xy_timer; party->fill_member = party_fill_member; diff --git a/src/map/party.h b/src/map/party.h index c2c13cc4f..570c7bd11 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -122,6 +122,7 @@ struct party_interface { #endif bool (*booking_delete) (struct map_session_data *sd); /* */ + int (*vforeachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range, va_list ap); int (*foreachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...); int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data); void (*fill_member) (struct party_member* member, struct map_session_data* sd, unsigned int leader); -- cgit v1.2.3-70-g09d2