summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-09-27 11:18:58 +0000
committerFlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-09-27 11:18:58 +0000
commita46c1fbcb1b7df32c678af8f0bbfda801d6142dc (patch)
tree7911e6f38e2e13b8d1b31b34e61f46ffe35b459c /src
parent7df1201fe4659ecaea754e101ebd5bcd4051e4f2 (diff)
downloadhercules-a46c1fbcb1b7df32c678af8f0bbfda801d6142dc.tar.gz
hercules-a46c1fbcb1b7df32c678af8f0bbfda801d6142dc.tar.bz2
hercules-a46c1fbcb1b7df32c678af8f0bbfda801d6142dc.tar.xz
hercules-a46c1fbcb1b7df32c678af8f0bbfda801d6142dc.zip
* Reimplemented mmo_char_fromsql using sql statements. (fixes bugreport:93)
* Fixed buildin_gethominfo not being included in the script engine. (bugreport:124) * homunculus_evolution -> homevolution in script_commands.txt. * Deleted item DEFAULT from item_db.txt and regenerated item_db.sql. (bugreport:103) * Skip empty lines and give more feedback (for invalid lines) when reading item_db.txt/item_db2.txt. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11311 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/char_sql/char.c310
-rw-r--r--src/map/atcommand.c1
-rw-r--r--src/map/itemdb.c81
-rw-r--r--src/map/script.c2
4 files changed, 224 insertions, 170 deletions
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 5579719c4..fc25afdc3 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -821,100 +821,123 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
char t_msg[128] = "";
struct mmo_charstatus* cp;
StringBuf buf;
- char* data;
- size_t len;
+ SqlStmt* stmt;
+ char last_map[MAP_NAME_LENGTH_EXT];
+ char save_map[MAP_NAME_LENGTH_EXT];
+ char point_map[MAP_NAME_LENGTH_EXT];
+ struct point tmp_point;
+ struct item tmp_item;
+ struct skill tmp_skill;
+ struct s_friend tmp_friend;
+ struct hotkey tmp_hotkey;
+ int hotkey_num;
+
memset(p, 0, sizeof(struct mmo_charstatus));
- p->char_id = char_id;
if (save_log) ShowInfo("Char load request (%d)\n", char_id);
+ stmt = SqlStmt_Malloc(sql_handle);
+ if( stmt == NULL )
+ {
+ SqlStmt_ShowDebug(stmt);
+ return 0;
+ }
+
// read char data
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT "
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT "
"`char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`hair`,"
"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`"
- " FROM `%s` WHERE `char_id` = '%d'", char_db, char_id) )
+ " FROM `%s` WHERE `char_id`=? LIMIT 1", char_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, &p->char_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &p->account_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UCHAR, &p->char_num, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_STRING, &p->name, sizeof(p->name), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_SHORT, &p->class_, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_UINT, &p->base_level, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_UINT, &p->job_level, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 7, SQLDT_UINT, &p->base_exp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 8, SQLDT_UINT, &p->job_exp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 9, SQLDT_INT, &p->zeny, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 10, SQLDT_SHORT, &p->str, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 11, SQLDT_SHORT, &p->agi, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 12, SQLDT_SHORT, &p->vit, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 13, SQLDT_SHORT, &p->int_, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 14, SQLDT_SHORT, &p->dex, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 15, SQLDT_SHORT, &p->luk, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 16, SQLDT_INT, &p->max_hp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 17, SQLDT_INT, &p->hp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 18, SQLDT_INT, &p->max_sp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 19, SQLDT_INT, &p->sp, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 20, SQLDT_USHORT, &p->status_point, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 21, SQLDT_USHORT, &p->skill_point, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 22, SQLDT_UINT, &p->option, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 23, SQLDT_UCHAR, &p->karma, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 24, SQLDT_SHORT, &p->manner, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 25, SQLDT_INT, &p->party_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_INT, &p->guild_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_INT, &p->pet_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_INT, &p->hom_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT, &p->father, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT, &p->mother, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT, &p->child, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->fame, 0, NULL, NULL) )
{
- Sql_ShowDebug(sql_handle);
+ SqlStmt_ShowDebug(stmt);
+ SqlStmt_Free(stmt);
return 0;
}
- if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
+ if( SQL_ERROR == SqlStmt_NextRow(stmt) )
{
ShowError("Requested non-existant character id: %d!\n", char_id);
- Sql_FreeResult(sql_handle);
+ SqlStmt_Free(stmt);
return 0;
}
+ p->last_point.map = mapindex_name2id(last_map);
+ p->save_point.map = mapindex_name2id(save_map);
- p->char_id = char_id;
- //TODO: prepared statement goes here >_> [ultramage]
- Sql_GetData(sql_handle, 1, &data, NULL); p->account_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL); p->char_num = atoi(data);
- Sql_GetData(sql_handle, 3, &data, &len); memcpy(p->name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 4, &data, NULL); p->class_ = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL); p->base_level = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL); p->job_level = atoi(data);
- Sql_GetData(sql_handle, 7, &data, NULL); p->base_exp = (unsigned int)cap_value(strtoul(data,NULL,10), 0, UINT_MAX);
- Sql_GetData(sql_handle, 8, &data, NULL); p->job_exp = (unsigned int)cap_value(strtoul(data,NULL,10), 0, UINT_MAX);
- Sql_GetData(sql_handle, 9, &data, NULL); p->zeny = atoi(data);
- Sql_GetData(sql_handle, 10, &data, NULL); p->str = atoi(data);
- Sql_GetData(sql_handle, 11, &data, NULL); p->agi = atoi(data);
- Sql_GetData(sql_handle, 12, &data, NULL); p->vit = atoi(data);
- Sql_GetData(sql_handle, 13, &data, NULL); p->int_ = atoi(data);
- Sql_GetData(sql_handle, 14, &data, NULL); p->dex = atoi(data);
- Sql_GetData(sql_handle, 15, &data, NULL); p->luk = atoi(data);
- Sql_GetData(sql_handle, 16, &data, NULL); p->max_hp = atoi(data);
- Sql_GetData(sql_handle, 17, &data, NULL); p->hp = atoi(data);
- Sql_GetData(sql_handle, 18, &data, NULL); p->max_sp = atoi(data);
- Sql_GetData(sql_handle, 19, &data, NULL); p->sp = atoi(data);
- Sql_GetData(sql_handle, 20, &data, NULL); p->status_point = (unsigned short)cap_value(atoi(data), 0, USHRT_MAX);
- Sql_GetData(sql_handle, 21, &data, NULL); p->skill_point = (unsigned short)cap_value(atoi(data), 0, USHRT_MAX);
- Sql_GetData(sql_handle, 22, &data, NULL); p->option = atoi(data);
- Sql_GetData(sql_handle, 23, &data, NULL); p->karma = atoi(data);
- Sql_GetData(sql_handle, 24, &data, NULL); p->manner = atoi(data);
- Sql_GetData(sql_handle, 25, &data, NULL); p->party_id = atoi(data);
- Sql_GetData(sql_handle, 26, &data, NULL); p->guild_id = atoi(data);
- Sql_GetData(sql_handle, 27, &data, NULL); p->pet_id = atoi(data);
- Sql_GetData(sql_handle, 28, &data, NULL); p->hom_id = atoi(data);
- Sql_GetData(sql_handle, 29, &data, NULL); p->hair = atoi(data);
- Sql_GetData(sql_handle, 30, &data, NULL); p->hair_color = atoi(data);
- Sql_GetData(sql_handle, 31, &data, NULL); p->clothes_color = atoi(data);
- Sql_GetData(sql_handle, 32, &data, NULL); p->weapon = atoi(data);
- Sql_GetData(sql_handle, 33, &data, NULL); p->shield = atoi(data);
- Sql_GetData(sql_handle, 34, &data, NULL); p->head_top = atoi(data);
- Sql_GetData(sql_handle, 35, &data, NULL); p->head_mid = atoi(data);
- Sql_GetData(sql_handle, 36, &data, NULL); p->head_bottom = atoi(data);
- Sql_GetData(sql_handle, 37, &data, NULL); p->last_point.map = mapindex_name2id(data);
- Sql_GetData(sql_handle, 38, &data, NULL); p->last_point.x = atoi(data);
- Sql_GetData(sql_handle, 39, &data, NULL); p->last_point.y = atoi(data);
- Sql_GetData(sql_handle, 40, &data, NULL); p->save_point.map = mapindex_name2id(data);
- Sql_GetData(sql_handle, 41, &data, NULL); p->save_point.x = atoi(data);
- Sql_GetData(sql_handle, 42, &data, NULL); p->save_point.y = atoi(data);
- Sql_GetData(sql_handle, 43, &data, NULL); p->partner_id = atoi(data);
- Sql_GetData(sql_handle, 44, &data, NULL); p->father = atoi(data);
- Sql_GetData(sql_handle, 45, &data, NULL); p->mother = atoi(data);
- Sql_GetData(sql_handle, 46, &data, NULL); p->child = atoi(data);
- Sql_GetData(sql_handle, 47, &data, NULL); p->fame = atoi(data);
-
- //free mysql result.
- Sql_FreeResult(sql_handle);
- strcat (t_msg, " status");
+ strcat(t_msg, " status");
if (!load_everything) // For quick selection of data when displaying the char menu
+ {
+ SqlStmt_Free(stmt);
return 1;
+ }
//read memo data
//`memo` (`memo_id`,`char_id`,`map`,`x`,`y`)
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`='%d' ORDER by `memo_id`", memo_db, char_id) )
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `map`,`x`,`y` FROM `%s` WHERE `char_id`=? ORDER by `memo_id` LIMIT %d", memo_db, MAX_MEMOPOINTS)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_STRING, &point_map, sizeof(point_map), NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_point.x, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_point.y, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
- for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
{
- Sql_GetData(sql_handle, 0, &data, NULL); p->memo_point[i].map = mapindex_name2id(data);
- Sql_GetData(sql_handle, 1, &data, NULL); p->memo_point[i].x = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL); p->memo_point[i].y = atoi(data);
+ tmp_point.map = mapindex_name2id(point_map);
+ memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point));
}
strcat(t_msg, " memo");
@@ -922,26 +945,27 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
//`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`)
StringBuf_Init(&buf);
StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`");
- 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);
+ for( i = 0; i < MAX_SLOTS; ++i )
+ StringBuf_Printf(&buf, ", `card%d`", i);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY);
- if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
- Sql_ShowDebug(sql_handle);
- for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
- {
- Sql_GetData(sql_handle, 0, &data, NULL); p->inventory[i].id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL); p->inventory[i].nameid = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL); p->inventory[i].amount = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL); p->inventory[i].equip = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL); p->inventory[i].identify = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL); p->inventory[i].refine = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL); p->inventory[i].attribute = atoi(data);
- for( j = 0; j < MAX_SLOTS; ++j )
- {
- Sql_GetData(sql_handle, 7 + j, &data, NULL); p->inventory[i].card[j] = atoi(data);
- }
- }
+ if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || 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_item.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ for( i = 0; i < MAX_SLOTS; ++i )
+ if( SQL_ERROR == SqlStmt_BindColumn(stmt, 7+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&p->inventory[i], &tmp_item, sizeof(tmp_item));
strcat(t_msg, " inventory");
//read cart
@@ -950,80 +974,88 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
StringBuf_AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`");
for( j = 0; j < MAX_SLOTS; ++j )
StringBuf_Printf(&buf, ", `card%d`", j);
- StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", cart_db, char_id);
+ StringBuf_Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", cart_db, MAX_CART);
- if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
- Sql_ShowDebug(sql_handle);
- for( i = 0; i < MAX_CART && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
- {
- Sql_GetData(sql_handle, 0, &data, NULL); p->cart[i].id = atoi(data);
- Sql_GetData(sql_handle, 1, &data, NULL); p->cart[i].nameid = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL); p->cart[i].amount = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL); p->cart[i].equip = atoi(data);
- Sql_GetData(sql_handle, 4, &data, NULL); p->cart[i].identify = atoi(data);
- Sql_GetData(sql_handle, 5, &data, NULL); p->cart[i].refine = atoi(data);
- Sql_GetData(sql_handle, 6, &data, NULL); p->cart[i].attribute = atoi(data);
- for( j = 0; j < MAX_SLOTS; ++j )
- {
- Sql_GetData(sql_handle, 7 + j, &data, NULL); p->cart[i].card[j] = atoi(data);
- }
- }
+ if( SQL_ERROR == SqlStmt_PrepareStr(stmt, StringBuf_Value(&buf))
+ || 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_item.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ for( i = 0; i < MAX_SLOTS; ++i )
+ if( SQL_ERROR == SqlStmt_BindColumn(stmt, 7+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_CART && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&p->cart[i], &tmp_item, sizeof(tmp_item));
strcat(t_msg, " cart");
//read skill
//`skill` (`char_id`, `id`, `lv`)
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`='%d'", skill_db, char_id) )
- Sql_ShowDebug(sql_handle);
- for( i = 0; i < MAX_SKILL && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `id`, `lv` FROM `%s` WHERE `char_id`=? LIMIT %d", skill_db, MAX_SKILL)
+ || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0)
+ || SQL_ERROR == SqlStmt_Execute(stmt)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_USHORT, &tmp_skill.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_USHORT, &tmp_skill.lv, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+ tmp_skill.flag = 0;
+
+ for( i = 0; i < MAX_SKILL && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
{
- int n;
- Sql_GetData(sql_handle, 0, &data, NULL);
- n = atoi(data);
- p->skill[n].id = n; //FIXME: why not use a boolean?
- Sql_GetData(sql_handle, 1, &data, NULL);
- p->skill[n].lv = atoi(data);
+ if( tmp_skill.id < ARRAYLENGTH(p->skill) )
+ memcpy(&p->skill[tmp_skill.id], &tmp_skill, sizeof(tmp_skill));
+ else
+ ShowWarning("mmo_char_fromsql: ignoring invalid skill (id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", tmp_skill.id, tmp_skill.lv, p->name, p->account_id, p->char_id);
}
strcat(t_msg, " skills");
- //Friend list
- //Shamelessly stolen from its_sparky (ie: thanks) and then assimilated by [Skotlex]
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT c.name, f.friend_account, f.friend_id FROM `%s` f LEFT JOIN `%s` c ON f.friend_account=c.account_id AND f.friend_id=c.char_id WHERE f.char_id='%d'", friend_db, char_db, char_id) )
- Sql_ShowDebug(sql_handle);
- for( i = 0; i < MAX_FRIENDS && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
- {
- // name
- Sql_GetData(sql_handle, 0, &data, &len);
- if( *data == '\0' )
- continue;
- memcpy(p->friends[i].name, data, min(len, NAME_LENGTH));
- Sql_GetData(sql_handle, 1, &data, NULL); p->friends[i].account_id = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL); p->friends[i].char_id = atoi(data);
- }
+ //read friends
+ //`friends` (`char_id`, `friend_account`, `friend_id`)
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `account_id`,`char_id`,`name` FROM `%s` WHERE (`account_id`,`char_id`) IN (SELECT DISTINCT `friend_account`,`friend_id` FROM `%s` WHERE `char_id`=?) LIMIT %d", char_db, friend_db, MAX_FRIENDS)
+ || 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_friend.account_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_INT, &tmp_friend.char_id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_STRING, &tmp_friend.name, sizeof(tmp_friend.name), NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ for( i = 0; i < MAX_FRIENDS && SQL_SUCCESS == SqlStmt_NextRow(stmt); ++i )
+ memcpy(&p->friends[i], &tmp_friend, sizeof(tmp_friend));
strcat(t_msg, " friends");
#ifdef HOTKEY_SAVING
- //Hotkeys
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`='%d'", hotkey_db, char_id) )
- Sql_ShowDebug(sql_handle);
- while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
+ //read hotkeys
+ //`hotkey` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`
+ if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`=?", hotkey_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, &hotkey_num, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 1, SQLDT_UCHAR, &tmp_hotkey.type, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 2, SQLDT_UINT, &tmp_hotkey.id, 0, NULL, NULL)
+ || SQL_ERROR == SqlStmt_BindColumn(stmt, 3, SQLDT_USHORT, &tmp_hotkey.lv, 0, NULL, NULL) )
+ SqlStmt_ShowDebug(stmt);
+
+ while( SQL_SUCCESS == SqlStmt_NextRow(stmt) )
{
- int n;
- Sql_GetData(sql_handle, 0, &data, NULL); n = atoi(data);
- if( n < 0 || n >= HOTKEY_SAVING )
- continue;
- Sql_GetData(sql_handle, 1, &data, NULL); p->hotkeys[n].type = atoi(data);
- Sql_GetData(sql_handle, 2, &data, NULL); p->hotkeys[n].id = atoi(data);
- Sql_GetData(sql_handle, 3, &data, NULL); p->hotkeys[n].lv = atoi(data);
+ if( hotkey_num >= 0 && hotkey_num < HOTKEY_SAVING )
+ memcpy(&p->hotkeys[hotkey_num], &tmp_hotkey, sizeof(tmp_hotkey));
+ else
+ ShowWarning("mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
}
strcat(t_msg, " hotkeys");
#endif
if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg); //ok. all data load successfuly!
- Sql_FreeResult(sql_handle);
+ SqlStmt_Free(stmt);
StringBuf_Destroy(&buf);
cp = idb_ensure(char_db_, char_id, create_charstatus);
- memcpy(cp, p, sizeof(struct mmo_charstatus));
+ memcpy(cp, p, sizeof(struct mmo_charstatus));
return 1;
}
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 2124a9181..da70bbd06 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -277,7 +277,6 @@ ACMD_FUNC(readmail); // [Valaris]
ACMD_FUNC(deletemail); // [Valaris]
ACMD_FUNC(sendmail); // [Valaris]
ACMD_FUNC(sendprioritymail); // [Valaris]
-ACMD_FUNC(deletemail); // [Valaris]
ACMD_FUNC(refreshonline); // [Valaris]
#endif
#ifdef DMALLOC
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 101738989..f6cdf6b3f 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -742,10 +742,10 @@ static bool itemdb_parse_dbrow(char** str, char* source, int line)
if (id->slot > MAX_SLOTS)
{
- ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
+ ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
id->slot = MAX_SLOTS;
}
-
+
itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
id->class_upper = atoi(str[12]);
id->sex = atoi(str[13]);
@@ -812,58 +812,79 @@ static int itemdb_readdb(void)
// process rows one by one
while(fgets(line, sizeof(line), fp))
{
- char *str[32], *p, *np;
+ char *str[32], *p;
int i;
lines++;
if(line[0] == '/' && line[1] == '/')
continue;
memset(str, 0, sizeof(str));
- for(i = 0, np = p = line; i < 19 && p; i++)
+
+ p = line;
+ while( ISSPACE(*p) )
+ ++p;
+ if( *p == '\0' )
+ continue;// empty line
+ for( i = 0; i < 19; ++i )
{
str[i] = p;
- if ((p = strchr(p,',')) != NULL) {
- *p++ = '\0'; np = p;
- }
+ p = strchr(p,',');
+ if( p == NULL )
+ break;// comma not found
+ *p = '\0';
+ ++p;
}
- if( i < 19 )
+ if( p == NULL )
{
- ShowWarning("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
continue;
}
- if((p=strchr(np,'{')) == NULL)
+ // Script
+ if( *p != '{' )
+ {
+ ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
continue;
- str[19] = p; //Script
- np = strchr(p,'}');
- while (np && np[1] && np[1] != ',')
- np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
- if (!np || !np[1]) {
- continue; //Couldn't find the end of the script field.
}
- np[1] = '\0'; //Set end of script
- np += 2; //Skip to next field
+ str[19] = p;
+ p = strstr(p+1,"},");
+ if( p == NULL )
+ {
+ ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ p[1] = '\0';
+ p += 2;
- if(!np || (p=strchr(np,'{'))==NULL)
+ // OnEquip_Script
+ if( *p != '{' )
+ {
+ ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
continue;
- str[20] = p; //Equip Script
- np = strchr(p,'}');
- while (np && np[1] && np[1] != ',')
- np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
- if (!np || !np[1]) {
- continue; //Couldn't find the end of the script field.
}
- np[1] = '\0'; //Set end of script
- np += 2; //Skip comma, to next field
+ str[20] = p;
+ p = strstr(p+1,"},");
+ if( p == NULL )
+ {
+ ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
+ continue;
+ }
+ p[1] = '\0';
+ p += 2;
- if(!np || (p=strchr(np,'{'))==NULL)
+ // OnUnequip_Script (last column)
+ if( *p != '{' )
+ {
+ ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
continue;
- str[21] = p; //Unequip script, last column.
+ }
+ str[21] = p;
+
if (!itemdb_parse_dbrow(str, path, lines))
continue;
-
+
count++;
}
diff --git a/src/map/script.c b/src/map/script.c
index 1aeff2e2e..306076fc4 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3954,6 +3954,7 @@ BUILDIN_FUNC(getusersname); //jA commands added [Lupus]
BUILDIN_FUNC(dispbottom);
BUILDIN_FUNC(recovery);
BUILDIN_FUNC(getpetinfo);
+BUILDIN_FUNC(gethominfo);
BUILDIN_FUNC(checkequipedcard);
BUILDIN_FUNC(globalmes);
BUILDIN_FUNC(jump_zero);
@@ -4293,6 +4294,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(getusersname,"*"),
BUILDIN_DEF(recovery,""),
BUILDIN_DEF(getpetinfo,"i"),
+ BUILDIN_DEF(gethominfo,"i"),
BUILDIN_DEF(checkequipedcard,"i"),
BUILDIN_DEF(jump_zero,"ii"), //for future jA script compatibility
BUILDIN_DEF(globalmes,"s*"),