//Load entire questlog for a character int mapif_quests_fromsql(int char_id, struct quest questlog[]) { int i; struct quest tmp_quest; SqlStmt * stmt; stmt = SqlStmt_Malloc(sql_handle); if( stmt == NULL ) { SqlStmt_ShowDebug(stmt); return 0; } memset(&tmp_quest, 0, sizeof(struct quest)); if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", quest_db, MAX_QUEST_DB) || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SqlStmt_Execute(stmt) || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_INT, &tmp_quest.count[0], 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_INT, &tmp_quest.count[1], 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_INT, &tmp_quest.count[2], 0, NULL, NULL) ) SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_QUEST_DB && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) memcpy(&questlog[i], &tmp_quest, sizeof(tmp_quest)); SqlStmt_Free(stmt); return i; }
//Load achievements for a character int mapif_achievement_fromsql(int char_id, struct s_achievement ad[]) { int i; struct s_achievement tmp_ad; SqlStmt * stmt; stmt = SqlStmt_Malloc(sql_handle); if( stmt == NULL ) { SqlStmt_ShowDebug(stmt); return 0; } memset(&tmp_ad,0,sizeof(tmp_ad)); if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `completed`, `count1`, `count2`, `count3`, `count4`, `count5` FROM `%s` WHERE `char_id` = ? LIMIT %d", achievement_db, ACHIEVEMENT_MAX) || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SqlStmt_Execute(stmt) || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_ad.id, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_CHAR, &tmp_ad.completed, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_INT, &tmp_ad.count[0], 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_INT, &tmp_ad.count[1], 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_INT, &tmp_ad.count[2], 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_INT, &tmp_ad.count[3], 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_INT, &tmp_ad.count[4], 0, NULL, NULL) ) SqlStmt_ShowDebug(stmt); for( i = 0; i < ACHIEVEMENT_MAX && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i ) memcpy(&ad[i], &tmp_ad, sizeof(tmp_ad)); SqlStmt_Free(stmt); return i; }
//-------------------------------------------------------- // Save registry to sql int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type) { struct global_reg* r; SqlStmt* stmt; int i; if( account_id <= 0 ) return 0; reg->account_id = account_id; reg->char_id = char_id; //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) switch( type ) { case 3: //Char Reg if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) ) Sql_ShowDebug(sql_handle); account_id = 0; break; case 2: //Account Reg if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) ) Sql_ShowDebug(sql_handle); char_id = 0; break; case 1: //Account2 Reg ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); return 0; default: ShowError("inter_accreg_tosql: Invalid type %d\n", type); return 0; } if( reg->reg_num <= 0 ) return 0; stmt = SqlStmt_Malloc(sql_handle); if( SQL_ERROR == SqlStmt_Prepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `char_id`, `str`, `value`) VALUES ('%d','%d','%d',?,?)", reg_db, type, account_id, char_id) ) SqlStmt_ShowDebug(stmt); for( i = 0; i < reg->reg_num; ++i ) { r = ®->reg[i]; if( r->str[0] != '\0' && r->value != '\0' ) { // str SqlStmt_BindParam(stmt, 0, SQLDT_STRING, r->str, strnlen(r->str, sizeof(r->str))); // value SqlStmt_BindParam(stmt, 1, SQLDT_STRING, r->value, strnlen(r->value, sizeof(r->value))); if( SQL_ERROR == SqlStmt_Execute(stmt) ) SqlStmt_ShowDebug(stmt); } } SqlStmt_Free(stmt); return 1; }
/** * Loads the entire questlog for a character. * * @param char_id Character ID * @param count Pointer to return the number of found entries. * @return Array of found entries. It has *count entries, and it is care of the * caller to aFree() it afterwards. */ struct quest *mapif_quests_fromsql(int char_id, int *count) { struct quest *questlog = NULL; struct quest tmp_quest; SqlStmt *stmt; if (!count) return NULL; stmt = SQL->StmtMalloc(sql_handle); if (stmt == NULL) { SqlStmt_ShowDebug(stmt); *count = 0; return NULL; } memset(&tmp_quest, 0, sizeof(struct quest)); if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=?", quest_db) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_INT, &tmp_quest.count[0], 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_INT, &tmp_quest.count[1], 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_INT, &tmp_quest.count[2], 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); *count = 0; return NULL; } *count = (int)SQL->StmtNumRows(stmt); if (*count > 0) { int i = 0; questlog = (struct quest *)aCalloc(*count, sizeof(struct quest)); while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) { if (i >= *count) // Sanity check, should never happen break; memcpy(&questlog[i++], &tmp_quest, sizeof(tmp_quest)); } if (i < *count) { // Should never happen. Compact array *count = i; questlog = aRealloc(questlog, sizeof(struct quest)*i); } } SQL->StmtFree(stmt); return questlog; }
bool mapif_homunculus_save(struct s_homunculus *hd) { bool flag = true; char esc_name[NAME_LENGTH*2+1]; Sql_EscapeStringLen(sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH)); if(hd->hom_id == 0) { // new homunculus if(SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` " "(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) " "VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')", homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize)) { Sql_ShowDebug(sql_handle); flag = false; } else { hd->hom_id = (int)Sql_LastInsertId(sql_handle); } } else { if(SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'", homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id)) { Sql_ShowDebug(sql_handle); flag = false; } else { SqlStmt *stmt; int i; stmt = SqlStmt_Malloc(sql_handle); if (SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", skill_homunculus_db, hd->hom_id)) SqlStmt_ShowDebug(stmt); for(i = 0; i < MAX_HOMUNSKILL; ++i) { if(hd->hskill[i].id > 0 && hd->hskill[i].lv != 0) { SqlStmt_BindParam(stmt, 0, SQLDT_USHORT, &hd->hskill[i].id, 0); SqlStmt_BindParam(stmt, 1, SQLDT_USHORT, &hd->hskill[i].lv, 0); if(SQL_ERROR == SqlStmt_Execute(stmt)) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); flag = false; break; } } } SqlStmt_Free(stmt); } } return flag; }
void auction_save(struct auction_data *auction) { int j; StringBuf buf; SqlStmt* stmt; if( !auction ) return; StringBuf_Init(&buf); StringBuf_Printf(&buf, "UPDATE `%s` SET `seller_id` = '%d', `seller_name` = ?, `buyer_id` = '%d', `buyer_name` = ?, `price` = '%d', `buynow` = '%d', `hours` = '%d', `timestamp` = '%lu', `nameid` = '%hu', `item_name` = ?, `type` = '%d', `refine` = '%d', `attribute` = '%d'", auction_db, auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute); for( j = 0; j < MAX_SLOTS; j++ ) StringBuf_Printf(&buf, ", `card%d` = '%hu'", j, auction->item.card[j]); StringBuf_Printf(&buf, " WHERE `auction_id` = '%d'", auction->auction_id); stmt = SqlStmt_Malloc(sql_handle); if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); } SqlStmt_Free(stmt); StringBuf_Destroy(&buf); }
int log_branch(struct map_session_data *sd) { if(!log_config.enable_logs) return 0; nullpo_ret(sd); if( log_config.sql_logs ) { SqlStmt* stmt; stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', ?, '%s')", log_config.log_branch_db, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return 0; } SqlStmt_Free(stmt); } else { FILE* logfp; if((logfp = fopen(log_config.log_branch, "a+")) == NULL) return 0; time(&curtime); strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp,"%s - %s[%d:%d]\t%s\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex)); fclose(logfp); } return 1; }
/** * Load achievements for a character. * @param char_id: Character ID * @param count: Pointer to return the number of found entries. * @return Array of found entries. It has *count entries, and it is care of the caller to aFree() it afterwards. */ struct achievement *mapif_achievements_fromsql(uint32 char_id, int *count) { struct achievement *achievelog = NULL; struct achievement tmp_achieve; SqlStmt *stmt; StringBuf buf; int i; if (!count) return NULL; memset(&tmp_achieve, 0, sizeof(tmp_achieve)); StringBuf_Init(&buf); StringBuf_AppendStr(&buf, "SELECT `id`, COALESCE(UNIX_TIMESTAMP(`completed`),0), COALESCE(UNIX_TIMESTAMP(`rewarded`),0)"); for (i = 0; i < MAX_ACHIEVEMENT_OBJECTIVES; ++i) StringBuf_Printf(&buf, ", `count%d`", i + 1); StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id` = '%u'", schema_config.achievement_table, char_id); stmt = SqlStmt_Malloc(sql_handle); if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); *count = 0; return NULL; } SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &tmp_achieve.achievement_id, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_achieve.completed, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_INT, &tmp_achieve.rewarded, 0, NULL, NULL); for (i = 0; i < MAX_ACHIEVEMENT_OBJECTIVES; ++i) SqlStmt_BindColumn(stmt, 3 + i, SQLDT_INT, &tmp_achieve.count[i], 0, NULL, NULL); *count = (int)SqlStmt_NumRows(stmt); if (*count > 0) { i = 0; achievelog = (struct achievement *)aCalloc(*count, sizeof(struct achievement)); while (SQL_SUCCESS == SqlStmt_NextRow(stmt)) { if (i >= *count) // Sanity check, should never happen break; memcpy(&achievelog[i++], &tmp_achieve, sizeof(tmp_achieve)); } if (i < *count) { // Should never happen. Compact array *count = i; achievelog = (struct achievement *)aRealloc(achievelog, sizeof(struct achievement) * i); } } SqlStmt_Free(stmt); StringBuf_Destroy(&buf); ShowInfo("achievement load complete from DB - id: %d (total: %d)\n", char_id, *count); return achievelog; }
/// Stores a single message in the database. /// Returns the message's ID if successful (or 0 if it fails). int mail_savemessage(struct mail_message *msg) { StringBuf buf; SqlStmt *stmt; int j; // build message save query StrBuf->Init(&buf); StrBuf->Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`, `unique_id`", mail_db); for(j = 0; j < MAX_SLOTS; j++) StrBuf->Printf(&buf, ", `card%d`", j); StrBuf->Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%lu', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%"PRIu64"'", msg->send_id, msg->dest_id, (unsigned long)msg->timestamp, msg->status, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify, msg->item.unique_id); for(j = 0; j < MAX_SLOTS; j++) StrBuf->Printf(&buf, ", '%d'", msg->item.card[j]); StrBuf->AppendStr(&buf, ")"); // prepare and execute query stmt = SqlStmt_Malloc(sql_handle); if (SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StrBuf->Value(&buf)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, msg->send_name, strnlen(msg->send_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, msg->title, strnlen(msg->title, MAIL_TITLE_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, msg->body, strnlen(msg->body, MAIL_BODY_LENGTH)) || SQL_SUCCESS != SqlStmt_Execute(stmt)) { SqlStmt_ShowDebug(stmt); msg->id = 0; } else msg->id = (int)SqlStmt_LastInsertId(stmt); SqlStmt_Free(stmt); StrBuf->Destroy(&buf); return msg->id; }
unsigned int auction_create(struct auction_data *auction) { int j; StringBuf buf; SqlStmt* stmt; if( !auction ) return false; auction->timestamp = time(NULL) + (auction->hours * 3600); StringBuf_Init(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s` (`seller_id`,`seller_name`,`buyer_id`,`buyer_name`,`price`,`buynow`,`hours`,`timestamp`,`nameid`,`item_name`,`type`,`refine`,`attribute`,`unique_id`", auction_db); for( j = 0; j < MAX_SLOTS; j++ ) StringBuf_Printf(&buf, ",`card%d`", j); StringBuf_Printf(&buf, ") VALUES ('%d',?,'%d',?,'%d','%d','%d','%lu','%d',?,'%d','%d','%d','%"PRIu64"'", auction->seller_id, auction->buyer_id, auction->price, auction->buynow, auction->hours, (unsigned long)auction->timestamp, auction->item.nameid, auction->type, auction->item.refine, auction->item.attribute, auction->item.unique_id); for( j = 0; j < MAX_SLOTS; j++ ) StringBuf_Printf(&buf, ",'%d'", auction->item.card[j]); StringBuf_AppendStr(&buf, ")"); //Unique Non Stackable Item ID updateLastUid(auction->item.unique_id); dbUpdateUid(sql_handle); stmt = SqlStmt_Malloc(sql_handle); if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, auction->seller_name, strnlen(auction->seller_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, auction->buyer_name, strnlen(auction->buyer_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, auction->item_name, strnlen(auction->item_name, ITEM_NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); auction->auction_id = 0; } else { struct auction_data *auction_; unsigned int tick = auction->hours * 3600000; auction->item.amount = 1; auction->item.identify = 1; auction->item.expire_time = 0; auction->auction_id = (unsigned int)SqlStmt_LastInsertId(stmt); auction->auction_end_timer = add_timer( gettick() + tick , auction_end_timer, auction->auction_id, 0); ShowInfo("New Auction %u | time left %u ms | By %s.\n", auction->auction_id, tick, auction->seller_name); CREATE(auction_, struct auction_data, 1); memcpy(auction_, auction, sizeof(struct auction_data)); idb_put(auction_db_, auction_->auction_id, auction_); } SqlStmt_Free(stmt); StringBuf_Destroy(&buf); return auction->auction_id; }
int log_chat(const char* type, int type_id, int src_charid, int src_accid, const char* map, int x, int y, const char* dst_charname, const char* message) { // Log CHAT (Global, Whisper, Party, Guild, Main chat) // LOGGING FILTERS [Lupus] // ============================================================= // 0 = Don't log at all // 1 = Log EVERYTHING! // Advanced Filter Bits: || // 02 - Log Global messages // 04 - Log Whisper messages // 08 - Log Party messages // 16 - Log Guild messages // 32 - Log Main chat messages // 64 - Don't log anything when WOE is on //Check ON/OFF if(log_config.chat <= 0) return 0; //Deactivated #ifndef TXT_ONLY if(log_config.sql_logs > 0) { SqlStmt* stmt; if (strlen(message) > CHAT_SIZE) { if (battle_config.error_log) ShowError("log chat: Received message too long from type %d (%d:%d)!\n", type_id, src_accid, src_charid); return 0; } stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%s', '%d', '%d', '%d', '%s', '%d', '%d', ?, ?)", log_config.log_chat_db, type, type_id, src_charid, src_accid, map, x, y) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (char*)dst_charname, safestrnlen(dst_charname, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, CHAT_SIZE)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return 0; } SqlStmt_Free(stmt); } else #endif { FILE* logfp; if((logfp = fopen(log_config.log_chat, "a+")) == NULL) return 0; time(&curtime); strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp, "%s - %s,%d,%d,%d,%s,%d,%d,%s,%s\n", timestring, type, type_id, src_charid, src_accid, map, x, y, dst_charname, message); fclose(logfp); } return 1; }
/** * Saves an existing homunculus. * * @param hd The homunculus' data. * @retval false in case of errors. */ bool mapif_homunculus_save(const struct s_homunculus *hd) { bool flag = true; char esc_name[NAME_LENGTH*2+1]; nullpo_retr(false, hd); Assert_retr(false, hd->hom_id > 0); SQL->EscapeStringLen(inter->sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH)); if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'", homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id)) { Sql_ShowDebug(inter->sql_handle); flag = false; } else { int i; SqlStmt *stmt = SQL->StmtMalloc(inter->sql_handle); if (SQL_ERROR == SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", skill_homunculus_db, hd->hom_id)) { SqlStmt_ShowDebug(stmt); flag = false; } else { for (i = 0; i < MAX_HOMUNSKILL; ++i) { if (hd->hskill[i].id > 0 && hd->hskill[i].lv != 0) { SQL->StmtBindParam(stmt, 0, SQLDT_USHORT, (void*)&hd->hskill[i].id, 0); // FIXME: StmtBindParam should take const void SQL->StmtBindParam(stmt, 1, SQLDT_USHORT, (void*)&hd->hskill[i].lv, 0); // FIXME: StmtBindParam should take const void if (SQL_ERROR == SQL->StmtExecute(stmt)) { SqlStmt_ShowDebug(stmt); flag = false; break; } } } } SQL->StmtFree(stmt); } return flag; }
void log_branch_sub_sql(struct map_session_data* sd) { SqlStmt* stmt; stmt = SQL->StmtMalloc(logs->mysql_handle); if( SQL_SUCCESS != SQL->StmtPrepare(stmt, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', ?, '%s')", logs->config.log_branch, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SQL->StmtExecute(stmt) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return; } SQL->StmtFree(stmt); }
void log_npc_sub_sql(struct map_session_data *sd, const char *message) { SqlStmt* stmt; stmt = SqlStmt_Malloc(logs->mysql_handle); if (SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`npc_date`, `account_id`, `char_id`, `char_name`, `map`, `mes`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", logs->config.log_npc, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255)) || SQL_SUCCESS != SqlStmt_Execute(stmt)) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return; } SqlStmt_Free(stmt); }
void log_chat_sub_sql(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char *mapname, int x, int y, const char* dst_charname, const char* message) { SqlStmt* stmt; stmt = SQL->StmtMalloc(logs->mysql_handle); if( SQL_SUCCESS != SQL->StmtPrepare(stmt, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', ?, ?)", logs->config.log_chat, logs->chattype2char(type), type_id, src_charid, src_accid, mapname, x, y) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, (char*)dst_charname, safestrnlen(dst_charname, NAME_LENGTH)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, CHAT_SIZE_MAX)) || SQL_SUCCESS != SQL->StmtExecute(stmt) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return; } SQL->StmtFree(stmt); }
/// logs chat void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char* mapname, int x, int y, const char* dst_charname, const char* message) { if( ( log_config.chat&type ) == 0 ) {// disabled return; } if( log_config.log_chat_woe_disable && ( agit_flag || agit2_flag ) ) {// no chat logging during woe return; } if( log_config.sql_logs ) { #ifdef BETA_THREAD_TEST char entry[512]; int e_length = 0; e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', '%s', '%s')", log_config.log_chat, log_chattype2char(type), type_id, src_charid, src_accid, mapname, x, y, dst_charname, message ); queryThread_log(entry,e_length); #else SqlStmt* stmt; stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`time`, `type`, `type_id`, `src_charid`, `src_accountid`, `src_map`, `src_map_x`, `src_map_y`, `dst_charname`, `message`) VALUES (NOW(), '%c', '%d', '%d', '%d', '%s', '%d', '%d', ?, ?)", log_config.log_chat, log_chattype2char(type), type_id, src_charid, src_accid, mapname, x, y) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (char*)dst_charname, safestrnlen(dst_charname, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, CHAT_SIZE_MAX)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return; } SqlStmt_Free(stmt); #endif } else { char timestring[255]; time_t curtime; FILE* logfp; if( ( logfp = fopen(log_config.log_chat, "a") ) == NULL ) return; time(&curtime); strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp, "%s - %c,%d,%d,%d,%s,%d,%d,%s,%s\n", timestring, log_chattype2char(type), type_id, src_charid, src_accid, mapname, x, y, dst_charname, message); fclose(logfp); } }
int db2sql(char** str, const char* source, int line, int scriptopt) { struct item_data *it = NULL; unsigned char offset = 0; #ifdef RENEWAL if( iMap->db_use_sql_item_db ) offset = 1; #endif if( (it = itemdb->exists(parse_dbrow(str,source,line,scriptopt))) ) { /* renewal has the 'matk' and 'equip_level' is now 'equip_level_min', and there is a new 'equip_level_max' field */ #ifdef RENEWAL if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`matk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level_min`,`equip_level_max`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_re_db, it->nameid,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11+offset],NULL,0),atoi(str[12+offset]),atoi(str[13+offset]),atoi(str[14+offset]),it->wlv,it->elv,it->elvmax,atoi(str[17+offset]),it->look) ) #else if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",iMap->item_db_db, it->nameid,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11],NULL,0),atoi(str[12]),atoi(str[13]),atoi(str[14]),it->wlv,it->elv,atoi(str[17]),it->look) ) #endif SqlStmt_ShowDebug(stmt); else { if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, it->name, strlen(it->name)) ) SqlStmt_ShowDebug(stmt); else { if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, it->jname, strlen(it->jname)) ) SqlStmt_ShowDebug(stmt); else { #ifdef RENEWAL if( iMap->db_use_sql_item_db ) offset += 1; #endif if( it->script ) trimbraces(str[19+offset]); if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, it->script?str[19+offset]:"", it->script?strlen(str[19+offset]):0) ) SqlStmt_ShowDebug(stmt); else { if( it->equip_script ) trimbraces(str[20+offset]); if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, it->equip_script?str[20+offset]:"", it->equip_script?strlen(str[20+offset]):0) ) SqlStmt_ShowDebug(stmt); else { if( it->unequip_script ) trimbraces(str[21+offset]); if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_STRING, it->unequip_script?str[21+offset]:"", it->unequip_script?strlen(str[21+offset]):0) ) SqlStmt_ShowDebug(stmt); else { if( SQL_SUCCESS != SQL->StmtExecute(stmt) ) SqlStmt_ShowDebug(stmt); } } } } } } return it->nameid; } return 0; }
/// Loads permanent variables from database static void script_load_mapreg(void) { /* 0 1 2 +-------------------------+ | varname | index | value | +-------------------------+ */ SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle); char varname[32+1]; int index; char value[255+1]; uint32 length; if ( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg_table) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return; } SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL); SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL); while ( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) { int s = add_str(varname); int i = index; if( varname[length-1] == '$' ) idb_put(mapregstr_db, (i<<24)|s, aStrdup(value)); else { idb_put(mapreg_db, (i<<24)|s, (void *)atoi(value)); if( !strcmp(varname, "$Region") && i > 0 && i < MAX_REGIONS ) region[i].guild_id = atoi(value); // Regional Control } } SqlStmt_Free(stmt); mapreg_dirty = false; }
/// logs used atcommands void log_atcommand(struct map_session_data* sd, const char* message) { nullpo_retv(sd); if( !log_config.commands || !pc_should_log_commands(sd) ) return; if( log_config.sql_logs ) { #ifdef BETA_THREAD_TEST char entry[512]; int e_length = 0; e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', '%s', '%s', '%s')", log_config.log_gm, sd->status.account_id, sd->status.char_id, sd->status.name ,mapindex_id2name(sd->mapindex), message); queryThread_log(entry,e_length); #else SqlStmt* stmt; stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return; } SqlStmt_Free(stmt); #endif } else { char timestring[255]; time_t curtime; FILE* logfp; if( ( logfp = fopen(log_config.log_gm, "a") ) == NULL ) return; time(&curtime); strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message); fclose(logfp); } }
int chlogif_parse_ackchangesex(int fd, struct char_session_data* sd) { if (RFIFOREST(fd) < 7) return 0; else { unsigned char buf[7]; int acc = RFIFOL(fd,2); int sex = RFIFOB(fd,6); RFIFOSKIP(fd,7); if (acc > 0) { // TODO: Is this even possible? unsigned char i; int char_id = 0, class_ = 0, guild_id = 0; DBMap* auth_db = char_get_authdb(); struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); SqlStmt *stmt; if (node != NULL) node->sex = sex; // get characters stmt = SqlStmt_Malloc(sql_handle); if (SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `char_id`, `class`, `guild_id` FROM `%s` WHERE `account_id` = '%d'", schema_config.char_db, acc) || SqlStmt_Execute(stmt)) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); } SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &char_id, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &class_, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_INT, &guild_id, 0, NULL, NULL); for (i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i) { chlogif_parse_change_sex_sub(sex, acc, char_id, class_, guild_id); } SqlStmt_Free(stmt); } // notify all mapservers about this change WBUFW(buf,0) = 0x2b0d; WBUFL(buf,2) = acc; WBUFB(buf,6) = sex; chmapif_sendall(buf, 7); } return 1; }
int log_atcommand(struct map_session_data* sd, const char* message) { if(!log_config.enable_logs) return 0; nullpo_retr(0, sd); #ifndef TXT_ONLY if(log_config.sql_logs > 0) { SqlStmt* stmt; if (strlen(message) > CHAT_SIZE) { if (battle_config.error_log) ShowError("log atcommand: Received message too long from player %s (%d:%d)!\n", sd->status.name, sd->status.account_id, sd->status.char_id); return 0; } stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm_db, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return 0; } SqlStmt_Free(stmt); } else #endif { FILE* logfp; if((logfp = fopen(log_config.log_gm, "a+")) == NULL) return 0; time(&curtime); strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message); fclose(logfp); } return 1; }
/// logs items, that summon monsters void log_branch(struct map_session_data* sd) { nullpo_retv(sd); if( !log_config.branch ) return; if( log_config.sql_logs ) { #ifdef BETA_THREAD_TEST char entry[512]; int e_length = 0; e_length = sprintf(entry, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', '%s', '%s')", log_config.log_branch, sd->status.account_id, sd->status.char_id, sd->status.name, mapindex_id2name(sd->mapindex)); queryThread_log(entry,e_length); #else SqlStmt* stmt; stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, LOG_QUERY " INTO `%s` (`branch_date`, `account_id`, `char_id`, `char_name`, `map`) VALUES (NOW(), '%d', '%d', ?, '%s')", log_config.log_branch, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return; } SqlStmt_Free(stmt); #endif } else { char timestring[255]; time_t curtime; FILE* logfp; if( ( logfp = fopen(log_config.log_branch, "a") ) == NULL ) return; time(&curtime); strftime(timestring, sizeof(timestring), log_timestamp_format, localtime(&curtime)); fprintf(logfp,"%s - %s[%d:%d]\t%s\n", timestring, sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex)); fclose(logfp); } }
/// logs used GM commands void log_atcommand(struct map_session_data* sd, int cmdlvl, const char* message) { nullpo_retv(sd); if( cmdlvl < log_config.gm ) return; #ifndef TXT_ONLY if( log_config.sql_logs ) { SqlStmt* stmt; stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return; } SqlStmt_Free(stmt); } else #endif { char timestring[255]; time_t curtime; FILE* logfp; if( ( logfp = fopen(log_config.log_gm, "a") ) == NULL ) return; time(&curtime); strftime(timestring, sizeof(timestring), "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message); fclose(logfp); } }
static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new) { Sql* sql_handle = db->accounts; SqlStmt* stmt = SQL->StmtMalloc(sql_handle); bool result = false; // try do { if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION") ) { Sql_ShowDebug(sql_handle); break; } if( is_new ) {// insert into account table if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `last_mac`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", db->account_db) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_STRING, (void*)&acc->email, strlen(acc->email)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 5, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 6, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 7, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 8, SQLDT_INT, (void*)&acc->expiration_time, sizeof(acc->expiration_time)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 9, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 13, SQLDT_UCHAR, (void*)&acc->char_slots, sizeof(acc->char_slots)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 14, SQLDT_STRING, (void*)&acc->pincode, strlen(acc->pincode)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 15, SQLDT_LONG, (void*)&acc->pincode_change, sizeof(acc->pincode_change)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 16, SQLDT_STRING, (void*)acc->mac_address, strlen(acc->mac_address)) || SQL_SUCCESS != SQL->StmtExecute(stmt) ) { SqlStmt_ShowDebug(stmt); break; } } else {// update account table if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?,`pincode_change`=?, `last_mac`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, (void*)acc->email, strlen(acc->email)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 5, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 6, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 7, SQLDT_LONG, (void*)&acc->expiration_time, sizeof(acc->expiration_time)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 8, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 9, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 12, SQLDT_UCHAR, (void*)&acc->char_slots, sizeof(acc->char_slots)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 13, SQLDT_STRING, (void*)&acc->pincode, strlen(acc->pincode)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 14, SQLDT_LONG, (void*)&acc->pincode_change, sizeof(acc->pincode_change)) || SQL_SUCCESS != SQL->StmtBindParam(stmt, 15, SQLDT_STRING, (void*)acc->mac_address, strlen(acc->mac_address)) || SQL_SUCCESS != SQL->StmtExecute(stmt) ) { SqlStmt_ShowDebug(stmt); break; } } // if we got this far, everything was successful result = true; } while(0); // finally result &= ( SQL_SUCCESS == SQL->QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") ); SQL->StmtFree(stmt); return result; }
/** * Save a struct mmo_account in sql. * @param db: pointer to db * @param acc: pointer of mmo_account to save * @param is_new: if it's a new entry or should we update * @return true if successful, false if something has failed */ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, bool is_new) { Sql* sql_handle = db->accounts; SqlStmt* stmt = SqlStmt_Malloc(sql_handle); bool result = false; int i; // try do { if( SQL_SUCCESS != Sql_QueryStr(sql_handle, "START TRANSACTION") ) { Sql_ShowDebug(sql_handle); break; } if( is_new ) {// insert into account table if( SQL_SUCCESS != SqlStmt_Prepare(stmt, #ifdef VIP_ENABLE "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `vip_time`, `old_group` ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", #else "INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", #endif db->account_db) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_STRING, (void*)&acc->email, strlen(acc->email)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_INT, (void*)&acc->expiration_time, sizeof(acc->expiration_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_UCHAR, (void*)&acc->char_slots, sizeof(acc->char_slots)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_STRING, (void*)&acc->pincode, strlen(acc->pincode)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG, (void*)&acc->pincode_change, sizeof(acc->pincode_change)) #ifdef VIP_ENABLE || SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_LONG, (void*)&acc->vip_time, sizeof(acc->vip_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 17, SQLDT_INT, (void*)&acc->old_group, sizeof(acc->old_group)) #endif || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); break; } } else {// update account table if( SQL_SUCCESS != SqlStmt_Prepare(stmt, #ifdef VIP_ENABLE "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=?, `vip_time`=?, `old_group`=? WHERE `account_id` = '%d'", #else "UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=? WHERE `account_id` = '%d'", #endif db->account_db, acc->account_id) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, (void*)acc->email, strlen(acc->email)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->expiration_time, sizeof(acc->expiration_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_UCHAR, (void*)&acc->char_slots, sizeof(acc->char_slots)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_STRING, (void*)&acc->pincode, strlen(acc->pincode)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_LONG, (void*)&acc->pincode_change, sizeof(acc->pincode_change)) #ifdef VIP_ENABLE || SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG, (void*)&acc->vip_time, sizeof(acc->vip_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_INT, (void*)&acc->old_group, sizeof(acc->old_group)) #endif || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); break; } } // remove old account regs if( SQL_SUCCESS != Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) ) { Sql_ShowDebug(sql_handle); break; } // insert new account regs if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );", db->accreg_db, acc->account_id) ) { SqlStmt_ShowDebug(stmt); break; } for( i = 0; i < acc->account_reg2_num; ++i ) { if( SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); break; } } if( i < acc->account_reg2_num ) { result = false; break; } // if we got this far, everything was successful result = true; } while(0); // finally result &= ( SQL_SUCCESS == Sql_QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") ); SqlStmt_Free(stmt); return result; }
/** * Loads the entire questlog for a character. * * @param char_id Character ID * @param count Pointer to return the number of found entries. * @return Array of found entries. It has *count entries, and it is care of the * caller to aFree() it afterwards. */ struct quest *mapif_quests_fromsql(int char_id, int *count) { struct quest *questlog = NULL; struct quest tmp_quest; SqlStmt *stmt; StringBuf buf; int i; int sqlerror = SQL_SUCCESS; if (!count) return NULL; stmt = SQL->StmtMalloc(sql_handle); if (stmt == NULL) { SqlStmt_ShowDebug(stmt); *count = 0; return NULL; } StrBuf->Init(&buf); StrBuf->AppendStr(&buf, "SELECT `quest_id`, `state`, `time`"); for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) { StrBuf->Printf(&buf, ", `count%d`", i+1); } StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=?", quest_db); memset(&tmp_quest, 0, sizeof(struct quest)); if (SQL_ERROR == SQL->StmtPrepare(stmt, StrBuf->Value(&buf)) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL) ) sqlerror = SQL_ERROR; StrBuf->Destroy(&buf); for (i = 0; sqlerror != SQL_ERROR && i < MAX_QUEST_OBJECTIVES; i++) { // Stop on the first error sqlerror = SQL->StmtBindColumn(stmt, 3+i, SQLDT_INT, &tmp_quest.count[i], 0, NULL, NULL); } if (sqlerror == SQL_ERROR) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); *count = 0; return NULL; } *count = (int)SQL->StmtNumRows(stmt); if (*count > 0) { i = 0; questlog = (struct quest *)aCalloc(*count, sizeof(struct quest)); while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) { if (i >= *count) // Sanity check, should never happen break; memcpy(&questlog[i++], &tmp_quest, sizeof(tmp_quest)); } if (i < *count) { // Should never happen. Compact array *count = i; questlog = aRealloc(questlog, sizeof(struct quest)*i); } } SQL->StmtFree(stmt); return questlog; }
//------------------------------------------------ //Guild bound items pull for offline characters [Akinari] //------------------------------------------------ int mapif_parse_itembound_retrieve(int fd) { StringBuf buf; SqlStmt* stmt; struct item item; int j, i=0, s; bool found=false; struct item items[MAX_INVENTORY]; int char_id = RFIFOL(fd,2); int aid = RFIFOL(fd,6); int guild_id = RFIFOW(fd,10); StringBuf_Init(&buf); StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`"); for( j = 0; j < MAX_SLOTS; ++j ) StringBuf_Printf(&buf, ", `card%d`", j); StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'",inventory_db,char_id); stmt = SqlStmt_Malloc(sql_handle); if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd,aid,guild_id); return 1; } SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 8, SQLDT_UINT, &item.bound, 0, NULL, NULL); for( j = 0; j < MAX_SLOTS; ++j ) SqlStmt_BindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) { if(item.bound == 2) { memcpy(&items[i],&item,sizeof(struct item)); i++; } } Sql_FreeResult(sql_handle); if(!i) { //No items found - No need to continue StringBuf_Destroy(&buf); SqlStmt_Free(stmt); mapif_itembound_ack(fd,aid,guild_id); return 0; } //First we delete the character's items StringBuf_Clear(&buf); StringBuf_Printf(&buf, "DELETE FROM `%s` WHERE",inventory_db); for(j=0; j<i; j++) { if( found ) StringBuf_AppendStr(&buf, " OR"); else found = true; StringBuf_Printf(&buf, " `id`=%d",items[j].id); } if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd,aid,guild_id); return 1; } //Now let's update the guild storage with those deleted items found = false; StringBuf_Clear(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`", guild_storage_db); for( j = 0; j < MAX_SLOTS; ++j ) StringBuf_Printf(&buf, ", `card%d`", j); StringBuf_AppendStr(&buf, ") VALUES "); for( j = 0; j < i; ++j ) { if( found ) StringBuf_AppendStr(&buf, ","); else found = true; StringBuf_Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'", guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound); for( s = 0; s < MAX_SLOTS; ++s ) StringBuf_Printf(&buf, ", '%d'", items[j].card[s]); StringBuf_AppendStr(&buf, ")"); } if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd,aid,guild_id); return 1; } StringBuf_Destroy(&buf); SqlStmt_Free(stmt); //Finally reload storage and tell map we're done mapif_load_guild_storage(fd,aid,guild_id,0); mapif_itembound_ack(fd,aid,guild_id); return 0; }
/** * ZI 0x3056 <char_id>.L <account_id>.L <guild_id>.W * Pulls guild bound items for offline characters * @author [Akinari] */ int mapif_parse_itembound_retrieve(int fd) { StringBuf buf; SqlStmt *stmt; unsigned short i = 0, count = 0; struct item item, items[MAX_INVENTORY]; int j, guild_id = RFIFOW(fd,10); uint32 char_id = RFIFOL(fd,2), account_id = RFIFOL(fd,6); StringBuf_Init(&buf); //Get bound items from player's inventory StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`"); for( j = 0; j < MAX_SLOTS; ++j ) StringBuf_Printf(&buf, ", `card%d`", j); StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d' AND `bound` = %d", inventory_db, char_id, BOUND_GUILD); stmt = SqlStmt_Malloc(sql_handle); if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd, account_id, guild_id); return 1; } SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &item.nameid, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL); SqlStmt_BindColumn(stmt, 8, SQLDT_UINT, &item.bound, 0, NULL, NULL); for( j = 0; j < MAX_SLOTS; ++j ) SqlStmt_BindColumn(stmt, 9 + j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); memset(&items, 0, sizeof(items)); while( SQL_SUCCESS == SqlStmt_NextRow(stmt) ) memcpy(&items[count++], &item, sizeof(struct item)); Sql_FreeResult(sql_handle); ShowInfo("Found '"CL_WHITE"%d"CL_RESET"' guild bound item(s) from CID = "CL_WHITE"%d"CL_RESET", AID = %d, Guild ID = "CL_WHITE"%d"CL_RESET".\n", count, char_id, account_id, guild_id); if( !count ) { //No items found - No need to continue StringBuf_Destroy(&buf); SqlStmt_Free(stmt); mapif_itembound_ack(fd, account_id, guild_id); return 1; } set_session_flag(account_id, 1); //Delete bound items from player's inventory StringBuf_Clear(&buf); StringBuf_Printf(&buf, "DELETE FROM `%s` WHERE `bound` = %d", inventory_db, BOUND_GUILD); if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); mapif_itembound_ack(fd, account_id, guild_id); return 1; } //Send the deleted items to map-server to store them in guild storage [Cydh] mapif_itembound_store2gstorage(fd, guild_id, items, count); //Verifies equip bitmasks (see item.equip) and handles the sql statement #define CHECK_REMOVE(var, mask, token, num) {\ if( (var)&(mask) && !(j&(num)) ) {\ if( j )\ StringBuf_AppendStr(&buf, ",");\ StringBuf_AppendStr(&buf, "`"#token"`='0'");\ j |= (1<<num);\ }\ } StringBuf_Clear(&buf); j = 0; for( i = 0; i < count && i < MAX_INVENTORY; i++ ) { if( !&items[i] || !items[i].equip ) continue; //Equips can be at more than one slot at the same time CHECK_REMOVE(items[i].equip, EQP_HAND_R, weapon, 0); CHECK_REMOVE(items[i].equip, EQP_HAND_L, shield, 1); CHECK_REMOVE(items[i].equip, EQP_HEAD_TOP|EQP_COSTUME_HEAD_TOP, head_top, 2); CHECK_REMOVE(items[i].equip, EQP_HEAD_MID|EQP_COSTUME_HEAD_MID, head_mid, 3); CHECK_REMOVE(items[i].equip, EQP_HEAD_LOW|EQP_COSTUME_HEAD_LOW, head_bottom, 4); CHECK_REMOVE(items[i].equip, EQP_GARMENT|EQP_COSTUME_GARMENT, robe, 5); } #undef CHECK_REMOVE //Update player's view if( j ) { StringBuf buf2; StringBuf_Init(&buf2); StringBuf_Printf(&buf2, "UPDATE `%s` SET %s WHERE `char_id`='%d'", char_db, StringBuf_Value(&buf), char_id); if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_ERROR == SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); StringBuf_Destroy(&buf); StringBuf_Destroy(&buf2); mapif_itembound_ack(fd, account_id, guild_id); return 1; } StringBuf_Destroy(&buf2); } StringBuf_Destroy(&buf); SqlStmt_Free(stmt); unset_session_flag(account_id, 1); return 0; }
/// Stores a single message in the database. /// Returns the message's ID if successful (or 0 if it fails). int mail_savemessage(struct mail_message* msg) { StringBuf buf; SqlStmt* stmt; int i, j; bool found = false; // build message save query StringBuf_Init(&buf); StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`,`type`", schema_config.mail_db); StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%lu', '%d', '%d', '%d'", msg->send_id, msg->dest_id, (unsigned long)msg->timestamp, msg->status, msg->zeny, msg->type); StringBuf_AppendStr(&buf, ")"); // prepare and execute query stmt = SqlStmt_Malloc(sql_handle); if( SQL_SUCCESS != SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, msg->send_name, strnlen(msg->send_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, msg->dest_name, strnlen(msg->dest_name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, msg->title, strnlen(msg->title, MAIL_TITLE_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, msg->body, strnlen(msg->body, MAIL_BODY_LENGTH)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); StringBuf_Destroy(&buf); return msg->id = 0; } else msg->id = (int)SqlStmt_LastInsertId(stmt); SqlStmt_Free(stmt); StringBuf_Clear(&buf); StringBuf_Printf(&buf,"INSERT INTO `%s` (`id`, `index`, `amount`, `nameid`, `refine`, `attribute`, `identify`, `unique_id`, `bound`", schema_config.mail_attachment_db); for (j = 0; j < MAX_SLOTS; j++) StringBuf_Printf(&buf, ", `card%d`", j); for (j = 0; j < MAX_ITEM_RDM_OPT; ++j) { StringBuf_Printf(&buf, ", `option_id%d`", j); StringBuf_Printf(&buf, ", `option_val%d`", j); StringBuf_Printf(&buf, ", `option_parm%d`", j); } StringBuf_AppendStr(&buf, ") VALUES "); for( i = 0; i < MAIL_MAX_ITEM; i++ ){ // skip empty and already matched entries if( msg->item[i].nameid == 0 ) continue; if( found ){ StringBuf_AppendStr(&buf, ","); }else{ found = true; } StringBuf_Printf(&buf, "('%" PRIu64 "', '%hu', '%d', '%hu', '%d', '%d', '%d', '%" PRIu64 "', '%d'", (uint64)msg->id, i, msg->item[i].amount, msg->item[i].nameid, msg->item[i].refine, msg->item[i].attribute, msg->item[i].identify, msg->item[i].unique_id, msg->item[i].bound); for (j = 0; j < MAX_SLOTS; j++) StringBuf_Printf(&buf, ", '%hu'", msg->item[i].card[j]); for (j = 0; j < MAX_ITEM_RDM_OPT; ++j) { StringBuf_Printf(&buf, ", '%d'", msg->item[i].option[j].id); StringBuf_Printf(&buf, ", '%d'", msg->item[i].option[j].value); StringBuf_Printf(&buf, ", '%d'", msg->item[i].option[j].param); } StringBuf_AppendStr(&buf, ")"); } if( found && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) ){ Sql_ShowDebug(sql_handle); } StringBuf_Destroy(&buf); return msg->id; }
// Loads new mails of this char_id/account_id static int inter_rodex_fromsql(int char_id, int account_id, int8 opentype, int64 mail_id, struct rodex_maillist *mails) { int count = 0; struct rodex_message msg = { 0 }; struct SqlStmt *stmt; nullpo_retr(-1, mails); stmt = SQL->StmtMalloc(inter->sql_handle); switch (opentype) { case RODEX_OPENTYPE_MAIL: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE `expire_date` > '%d' AND `receiver_id` = '%d' AND `mail_id` > '%"PRId64"'" "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; case RODEX_OPENTYPE_ACCOUNT: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE " "`expire_date` > '%d' AND `receiver_accountid` = '%d' AND `mail_id` > '%"PRId64"'" "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), account_id, mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; case RODEX_OPENTYPE_RETURN: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `expire_date` + '%d' > '%d' AND `mail_id` > '%"PRId64"')" "ORDER BY `mail_id` ASC", rodex_db, char_id, (int)time(NULL), RODEX_EXPIRE, (int)time(NULL), mail_id) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; case RODEX_OPENTYPE_UNSET: if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `mail_id`, `sender_name`, `sender_id`, `receiver_name`, `receiver_id`, `receiver_accountid`," "`title`, `body`, `zeny`, `type`, `is_read`, `sender_read`, `send_date`, `expire_date`, `weight`" "FROM `%s` WHERE " "((`expire_date` > '%d' AND (`receiver_id` = '%d' OR `receiver_accountid` = '%d'))" "OR (`is_read` = 0 AND `sender_id` = '%d' AND `expire_date` <= '%d' AND `expire_date` + '%d' > '%d'))" "ORDER BY `mail_id` ASC", rodex_db, (int)time(NULL), char_id, account_id, char_id, (int)time(NULL), RODEX_EXPIRE, (int)time(NULL)) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } break; } if (SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT64, &msg.id, sizeof msg.id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_STRING, &msg.sender_name, sizeof msg.sender_name, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &msg.sender_id, sizeof msg.sender_id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_STRING, &msg.receiver_name, sizeof msg.receiver_name, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_INT, &msg.receiver_id, sizeof msg.receiver_id, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_INT, &msg.receiver_accountid, sizeof msg.receiver_accountid, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_STRING, &msg.title, sizeof msg.title, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_STRING, &msg.body, sizeof msg.body, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_INT64, &msg.zeny, sizeof msg.zeny, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_UINT8, &msg.type, sizeof msg.type, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_BOOL, &msg.is_read, sizeof msg.is_read, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 11, SQLDT_BOOL, &msg.sender_read, sizeof msg.sender_read, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 12, SQLDT_INT, &msg.send_date, sizeof msg.send_date, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 13, SQLDT_INT, &msg.expire_date, sizeof msg.expire_date, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 14, SQLDT_INT, &msg.weight, sizeof msg.weight, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); SQL->StmtFree(stmt); return -1; } { struct item it = { 0 }; StringBuf buf; struct SqlStmt *stmt_items = SQL->StmtMalloc(inter->sql_handle); int i; if (stmt_items == NULL) { SQL->StmtFreeResult(stmt); SQL->StmtFree(stmt); return -1; } StrBuf->Init(&buf); StrBuf->AppendStr(&buf, "SELECT `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); for (i = 0; i < MAX_SLOTS; i++) { StrBuf->Printf(&buf, ", `card%d`", i); } for (i = 0; i < MAX_ITEM_OPTIONS; i++) { StrBuf->Printf(&buf, ", `opt_idx%d`, `opt_val%d`", i, i); } StrBuf->Printf(&buf, "FROM `%s` WHERE mail_id = ? ORDER BY `mail_id` ASC", rodex_item_db); if (SQL_ERROR == SQL->StmtPrepareStr(stmt_items, StrBuf->Value(&buf)) || SQL_ERROR == SQL->StmtBindParam(stmt_items, 0, SQLDT_INT64, &msg.id, sizeof msg.id) ) { SqlStmt_ShowDebug(stmt_items); } // Read mails while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) { if (msg.type & MAIL_TYPE_ITEM) { if (SQL_ERROR == SQL->StmtExecute(stmt_items) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 0, SQLDT_INT, &it.nameid, sizeof it.nameid, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 1, SQLDT_SHORT, &it.amount, sizeof it.amount, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 2, SQLDT_UINT, &it.equip, sizeof it.equip, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 3, SQLDT_CHAR, &it.identify, sizeof it.identify, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 4, SQLDT_CHAR, &it.refine, sizeof it.refine, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 5, SQLDT_CHAR, &it.attribute, sizeof it.attribute, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 6, SQLDT_UINT, &it.expire_time, sizeof it.expire_time, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 7, SQLDT_UCHAR, &it.bound, sizeof it.bound, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 8, SQLDT_UINT64, &it.unique_id, sizeof it.unique_id, NULL, NULL) ) { SqlStmt_ShowDebug(stmt_items); } for (i = 0; i < MAX_SLOTS; i++) { if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + i, SQLDT_INT, &it.card[i], sizeof it.card[i], NULL, NULL)) SqlStmt_ShowDebug(stmt_items); } for (i = 0; i < MAX_ITEM_OPTIONS; i++) { if (SQL_ERROR == SQL->StmtBindColumn(stmt_items, 9 + MAX_SLOTS + i * 2, SQLDT_INT16, &it.option[i].index, sizeof it.option[i].index, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt_items, 10 + MAX_SLOTS + i * 2, SQLDT_INT16, &it.option[i].value, sizeof it.option[i].value, NULL, NULL) ) { SqlStmt_ShowDebug(stmt_items); } } for (i = 0; i < RODEX_MAX_ITEM && SQL_SUCCESS == SQL->StmtNextRow(stmt_items); ++i) { msg.items[i].item = it; msg.items_count++; } } if (msg.items_count == 0) { msg.type &= ~MAIL_TYPE_ITEM; } if (msg.zeny == 0) { msg.type &= ~MAIL_TYPE_ZENY; } #if PACKETVER >= 20170419 if (opentype == RODEX_OPENTYPE_UNSET) { if (msg.receiver_id == 0) msg.opentype = RODEX_OPENTYPE_ACCOUNT; else if (msg.expire_date < time(NULL)) msg.opentype = RODEX_OPENTYPE_RETURN; else msg.opentype = RODEX_OPENTYPE_MAIL; } else { msg.opentype = opentype; } #else msg.opentype = opentype; #endif #if PACKETVER < 20160601 // NPC Message Type isn't supported in old clients msg.type &= ~MAIL_TYPE_NPC; #endif ++count; VECTOR_ENSURE(*mails, 1, 1); VECTOR_PUSH(*mails, msg); memset(&msg, 0, sizeof(struct rodex_message)); SQL->StmtFreeResult(stmt_items); } StrBuf->Destroy(&buf); SQL->StmtFree(stmt_items); } SQL->StmtFreeResult(stmt); SQL->StmtFree(stmt); ShowInfo("rodex load complete from DB - id: %d (total: %d)\n", char_id, count); return count; }