/*========================================== * Founds up to N matches. Returns number of matches [Skotlex] *------------------------------------------*/ int itemdb_searchname_array(struct item_data** data, int size, const char *str) { struct item_data* item; int i; int count=0; // Search in the array for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i ) { item = itemdb_array[i]; if( item == NULL ) continue; if( stristr(item->jname,str) || stristr(item->name,str) ) { if( count < size ) data[count] = item; ++count; } } // search in the db if( count < size ) { DBData *db_data[MAX_SEARCH]; int db_count = 0; size -= count; db_count = itemdb_other->getall(itemdb_other, (DBData**)&db_data, size, itemdb_searchname_array_sub, str); for (i = 0; i < db_count; i++) data[count++] = db_data2ptr(db_data[i]); count += db_count; } return count; }
/** * @see DBApply */ static int chrif_reconnect(DBKey key, DBData *data, va_list ap) { struct auth_node *node = db_data2ptr(data); switch (node->state) { case ST_LOGIN: if (node->sd && node->char_dat == NULL) { //Since there is no way to request the char auth, make it fail. pc_authfail(node->sd); chrif_char_offline(node->sd); chrif_auth_delete(node->account_id, node->char_id, ST_LOGIN); } break; case ST_LOGOUT: //Re-send final save chrif_save(node->sd, 1); break; case ST_MAPCHANGE: { //Re-send map-change request. struct map_session_data *sd = node->sd; uint32 ip; uint16 port; if(map_mapname2ipport(sd->mapindex,&ip,&port)==0) chrif_changemapserver(sd, ip, port); else //too much lag/timeout is the closest explanation for this error. clif_authfail_fd(sd->fd, 3); break; } } return 0; }
static int channel_db_final(DBKey key, DBData *data, va_list ap) { struct channel_data *cd = (struct channel_data *)db_data2ptr(data); ShowInfo("Channel System : Removing Channel %s from memory.\n", cd->name); db_destroy(cd->users_db); return 0; }
/** * Parses storage and saves 'dirty' ones upon reconnect. [Skotlex] * @see DBApply */ static int storage_reconnect_sub(DBKey key, DBData *data, va_list ap) { struct guild_storage *stor = db_data2ptr(data); if (stor->dirty && stor->storage_status == 0) //Save closed storages. storage_guild_storagesave(0, stor->guild_id,0); return 0; }
/** * @see DBApply */ static int itemdb_final_sub(DBKey key, DBData *data, va_list ap) { struct item_data *id = db_data2ptr(data); if( id != &dummy_item ) destroy_item_data(id, 1); return 0; }
/** * @see DBApply */ int auth_db_final(DBKey key, DBData *data, va_list ap) { struct auth_node *node = db_data2ptr(data); if (node->char_dat) aFree(node->char_dat); if (node->sd) aFree(node->sd); ers_free(auth_db_ers, node); return 0; }
/** * Load this character's account id into the 'online accounts' packet * @see DBApply */ int chlogif_send_acc_tologin_sub(DBKey key, DBData *data, va_list ap) { struct online_char_data* character = (struct online_char_data*)db_data2ptr(data); int* i = va_arg(ap, int*); if(character->server > -1) { WFIFOL(login_fd,8+(*i)*4) = character->account_id; (*i)++; return 1; } return 0; }
/** * Clears the quest database for shutdown or reload. */ static int questdb_free(DBKey key, DBData *data, va_list ap) { struct quest_db *quest = db_data2ptr(data); if( !quest ) return 0; //if( &quest->name ) // StringBuf_Destroy(&quest->name); aFree(quest); return 1; }
/** * Existence check of WISP data * @see DBApply */ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) { unsigned long tick; struct WisData *wd = (struct WisData *)db_data2ptr(data); tick = va_arg(ap, unsigned long); if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX) wis_dellist[wis_delnum++] = wd->id; return 0; }
/*========================================== * Founds up to N matches. Returns number of matches [Skotlex] * @param *data * @param size * @param str * @return Number of matches item *------------------------------------------*/ int itemdb_searchname_array(struct item_data** data, int size, const char *str) { DBData *db_data[MAX_SEARCH]; int i, count = 0, db_count; db_count = itemdb->getall(itemdb, (DBData**)&db_data, size, itemdb_searchname_array_sub, str); for (i = 0; i < db_count && count < size; i++) data[count++] = db_data2ptr(db_data[i]); return count; }
/** * @see DBMatcher */ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap) { struct item_data *item = db_data2ptr(&data); char *str = va_arg(ap,char *); if (stristr(item->jname,str)) return 0; if (stristr(item->name,str)) return 0; return strcmpi(item->jname,str); }
/// Saves permanent variables to database static void script_save_mapreg(void) { DBIterator* iter; DBData *data; DBKey key; iter = db_iterator(mapreg_db); for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) { int num = (key.i & 0x00ffffff); int i = (key.i & 0xff000000) >> 24; const char* name = get_str(num); if( name[1] == '@' ) continue; if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, db_data2i(data), name, i) ) Sql_ShowDebug(mmysql_handle); } dbi_destroy(iter); iter = db_iterator(mapregstr_db); for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) { int num = (key.i & 0x00ffffff); int i = (key.i & 0xff000000) >> 24; const char* name = get_str(num); char tmp_str2[2*255+1]; if( name[1] == '@' ) continue; Sql_EscapeStringLen(mmysql_handle, tmp_str2, db_data2ptr(data), safestrnlen(db_data2ptr(data), 255)); if( SQL_ERROR == Sql_Query(mmysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d'", mapreg_table, tmp_str2, name, i) ) Sql_ShowDebug(mmysql_handle); } dbi_destroy(iter); mapreg_dirty = false; }
/** * Sub function to apply on online_db. * Mark a character as offline. * @param data: 1 entry in the db * @param ap: args * @return : Value to be added up by the function that is applying this * @see DBApply */ int login_online_db_setoffline(DBKey key, DBData *data, va_list ap) { struct online_login_data* p = (struct online_login_data*)db_data2ptr(data); int server = va_arg(ap, int); if( server == -1 ) { p->char_server = -1; if( p->waiting_disconnect != INVALID_TIMER ) { delete_timer(p->waiting_disconnect, login_waiting_disconnect_timer); p->waiting_disconnect = INVALID_TIMER; } } else if( p->char_server == server ) p->char_server = -2; //Char server disconnected. return 0; }
/** * @see DBMatcher */ static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap) { struct item_data *item = (struct item_data *)db_data2ptr(&data); char *str; str = va_arg(ap,char *); if(item == &dummy_item) return 1; //Invalid item. if(stristr(item->jname,str)) return 0; if(stristr(item->name,str)) return 0; return strcmpi(item->jname,str); }
/** * Search for item name * name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) * @see DBApply */ static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap) { struct item_data *item = db_data2ptr(data), **dst, **dst2; char *str; str = va_arg(ap,char *); dst = va_arg(ap,struct item_data **); dst2 = va_arg(ap,struct item_data **); //Absolute priority to Aegis code name. if (strcmpi(item->name,str) == 0) *dst = item; //Second priority to Client displayed name. if (strcmpi(item->jname,str) == 0) *dst2 = item; return 0; }
/** * Attempt to autojoin a player to a channel */ int channel_pcautojoin_sub(DBKey key, DBData *data, va_list ap) { struct Channel *channel = (struct Channel *)db_data2ptr(data); struct map_session_data *sd = NULL; char channame[CHAN_NAME_LENGTH+1]; nullpo_ret(channel); nullpo_ret((sd = va_arg(ap, struct map_session_data *))); if (channel->pass[0]) return 0; if (!(channel->opt&CHAN_OPT_AUTOJOIN)) return 0; if (!pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) && !channel_pccheckgroup(channel, sd->group_id)) return 0; safesnprintf(channame, sizeof(channame), "#%s", channel->name); channel_pcjoin(sd, channame, NULL); return 1; }
/** * @see DBApply */ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { struct battleground_data *bg = db_data2ptr(data); struct map_session_data *sd; int i; nullpo_ret(bg); for( i = 0; i < MAX_BG_MEMBERS; i++ ) { if( (sd = bg->members[i].sd) == NULL ) continue; if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y ) { // xy update bg->members[i].x = sd->bl.x; bg->members[i].y = sd->bl.y; clif_bg_xy(sd); } } return 0; }
/** * This can still happen (client times out while waiting for char to confirm auth data) * @see DBApply */ int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) { struct auth_node *node = db_data2ptr(data); const char* states[] = { "Login", "Logout", "Map change" }; if(DIFF_TICK(gettick(),node->node_created)>60000) { switch (node->state) { case ST_LOGOUT: //Re-save attempt (->sd should never be null here). node->node_created = gettick(); //Refresh tick (avoid char-server load if connection is really bad) chrif_save(node->sd, 1); break; default: //Clear data. any connected players should have timed out by now. ShowInfo("auth_db: Node (state %s) timed out for %d:%d\n", states[node->state], node->account_id, node->char_id); chrif_char_offline_nsd(node->account_id, node->char_id); chrif_auth_delete(node->account_id, node->char_id, node->state); break; } return 1; } return 0; }
/** * Sub function of login_online_data_cleanup. * Checking if all users in db are still connected to a char-server, and remove them if they aren't. * @param data: 1 entry in the db * @param ap: args * @return: Value to be added up by the function that is applying this * @see DBApply */ static int login_online_data_cleanup_sub(DBKey key, DBData *data, va_list ap) { struct online_login_data *character= (struct online_login_data*)db_data2ptr(data); if (character->char_server == -2) //Unknown server.. set them offline login_remove_online_user(character->account_id); return 0; }