mirror of
https://github.com/HerculesWS/Hercules
synced 2026-08-15 12:23:13 -04:00
Rewritten NSI_UNIQUE_ID system to get rid of the cross-database interreg dependency
- Removes the need for map-server to access the interreg table to store the last used ID. - Login, char and map databases can now be hosted separately. - Note: the unique_id structure has changed, and it now contains the generator character ID in its upper 32 bits. - Now NSI_UNIQUE_ID System is enabled always Special thanks to Haruna.
This commit is contained in:
parent
4768082904
commit
dd49dbc3e8
13 changed files with 21 additions and 101 deletions
|
|
@ -111,6 +111,7 @@ CREATE TABLE IF NOT EXISTS `char` (
|
|||
`char_opt` INT( 11 ) unsigned NOT NULL default '0',
|
||||
`font` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`unban_time` int(11) unsigned NOT NULL default '0',
|
||||
`uniqueitem_counter` bigint(20) NOT NULL,
|
||||
PRIMARY KEY (`char_id`),
|
||||
UNIQUE KEY `name_key` (`name`),
|
||||
KEY `account_id` (`account_id`),
|
||||
|
|
@ -709,8 +710,6 @@ CREATE TABLE IF NOT EXISTS `interreg` (
|
|||
`value` varchar(20) NOT NULL,
|
||||
PRIMARY KEY (`varname`)
|
||||
) ENGINE=InnoDB;
|
||||
INSERT INTO `interreg` (`varname`, `value`) VALUES
|
||||
('unique_id', '0');
|
||||
|
||||
--
|
||||
-- Table structure for table `account_data`
|
||||
|
|
|
|||
3
sql-files/upgrades/2014-04-07--22-04.sql
Normal file
3
sql-files/upgrades/2014-04-07--22-04.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#1396893866
|
||||
ALTER TABLE `char` ADD COLUMN `uniqueitem_counter` bigint(20) NOT NULL AFTER `unban_time`;
|
||||
INSERT INTO `sql_updates` (`timestamp`) VALUES (1396893866);
|
||||
|
|
@ -19,4 +19,5 @@
|
|||
2014-01-04--16-47.sql
|
||||
2014-01-06--17-22.sql
|
||||
2014-02-19--17-57.sql
|
||||
2014-03-25--23-57.sql
|
||||
2014-03-25--23-57.sql
|
||||
2014-04-07--22-04.sql
|
||||
|
|
@ -469,7 +469,8 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
|
|||
(p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
|
||||
(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
|
||||
(p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->robe != cp->robe) ||
|
||||
(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font)
|
||||
(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) ||
|
||||
(p->uniqueitem_counter != cp->uniqueitem_counter )
|
||||
) { //Save status
|
||||
unsigned int opt = 0;
|
||||
|
||||
|
|
@ -485,7 +486,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
|
|||
"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d',"
|
||||
"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
|
||||
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
|
||||
"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u'"
|
||||
"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'"
|
||||
" WHERE `account_id`='%d' AND `char_id` = '%d'",
|
||||
char_db, p->base_level, p->job_level,
|
||||
p->base_exp, p->job_exp, p->zeny,
|
||||
|
|
@ -496,7 +497,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
|
|||
mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
|
||||
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
|
||||
(unsigned long)p->delete_date, // FIXME: platform-dependent size
|
||||
p->robe,p->slotchange,opt,p->font,
|
||||
p->robe,p->slotchange,opt,p->font,p->uniqueitem_counter,
|
||||
p->account_id, p->char_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
|
|
@ -841,10 +842,7 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit
|
|||
for( j = 0; j < MAX_SLOTS; ++j )
|
||||
StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
|
||||
StrBuf->AppendStr(&buf, ")");
|
||||
|
||||
updateLastUid(items[i].unique_id); // Unique Non Stackable Item ID
|
||||
}
|
||||
dbUpdateUid(sql_handle); // Unique Non Stackable Item ID
|
||||
|
||||
if( found && SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) )
|
||||
{
|
||||
|
|
@ -982,10 +980,7 @@ int inventory_to_sql(const struct item items[], int max, int id) {
|
|||
for( j = 0; j < MAX_SLOTS; ++j )
|
||||
StrBuf->Printf(&buf, ", '%d'", items[i].card[j]);
|
||||
StrBuf->AppendStr(&buf, ")");
|
||||
|
||||
updateLastUid(items[i].unique_id);// Unique Non Stackable Item ID
|
||||
}
|
||||
dbUpdateUid(sql_handle);
|
||||
|
||||
if( found && SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) {
|
||||
Sql_ShowDebug(sql_handle);
|
||||
|
|
@ -1130,7 +1125,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
|
|||
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_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`,`rename`,`delete_date`,`robe`,`slotchange`,"
|
||||
"`char_opt`,`font`"
|
||||
"`char_opt`,`font`,`uniqueitem_counter`"
|
||||
" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
|
||||
|| SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|
||||
|| SQL_ERROR == SQL->StmtExecute(stmt)
|
||||
|
|
@ -1189,6 +1184,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
|
|||
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_USHORT, &p->slotchange, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT, &opt, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UCHAR, &p->font, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 55, SQLDT_UINT, &p->uniqueitem_counter, 0, NULL, NULL)
|
||||
)
|
||||
{
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
|
|
|
|||
|
|
@ -90,10 +90,6 @@ unsigned int auction_create(struct auction_data *auction)
|
|||
for( j = 0; j < MAX_SLOTS; j++ )
|
||||
StrBuf->Printf(&buf, ",'%d'", auction->item.card[j]);
|
||||
StrBuf->AppendStr(&buf, ")");
|
||||
|
||||
//Unique Non Stackable Item ID
|
||||
updateLastUid(auction->item.unique_id);
|
||||
dbUpdateUid(sql_handle);
|
||||
|
||||
stmt = SQL->StmtMalloc(sql_handle);
|
||||
if( SQL_SUCCESS != SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
|
||||
|
|
|
|||
|
|
@ -117,10 +117,6 @@ int mail_savemessage(struct mail_message* msg)
|
|||
for (j = 0; j < MAX_SLOTS; j++)
|
||||
StrBuf->Printf(&buf, ", '%d'", msg->item.card[j]);
|
||||
StrBuf->AppendStr(&buf, ")");
|
||||
|
||||
//Unique Non Stackable Item ID
|
||||
updateLastUid(msg->item.unique_id);
|
||||
dbUpdateUid(sql_handle);
|
||||
|
||||
// prepare and execute query
|
||||
stmt = SQL->StmtMalloc(sql_handle);
|
||||
|
|
|
|||
|
|
@ -1372,23 +1372,4 @@ int inter_parse_frommap(int fd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
uint64 inter_chk_lastuid(int8 flag, uint64 value){
|
||||
static uint64 last_updt_uid = 0;
|
||||
static int8 update = 0;
|
||||
if(flag)
|
||||
{
|
||||
if(last_updt_uid < value){
|
||||
last_updt_uid = value;
|
||||
update = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}else if(update)
|
||||
{
|
||||
update = 0;
|
||||
return last_updt_uid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,17 +29,4 @@ extern Sql* lsql_handle;
|
|||
|
||||
int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type);
|
||||
|
||||
uint64 inter_chk_lastuid(int8 flag, uint64 value);
|
||||
#ifdef NSI_UNIQUE_ID
|
||||
#define updateLastUid(val_) inter_chk_lastuid(1, (val_))
|
||||
#define dbUpdateUid(handler_) do { \
|
||||
uint64 unique_id_ = inter_chk_lastuid(0, 0); \
|
||||
if (unique_id_ && SQL_ERROR == SQL->Query((handler_), "UPDATE `%s` SET `value`='%"PRIu64"' WHERE `varname`='unique_id'", interreg_db, unique_id_)) \
|
||||
Sql_ShowDebug(handler_);\
|
||||
} while(0)
|
||||
#else
|
||||
#define dbUpdateUid(handler_)
|
||||
#define updateLastUid(val_)
|
||||
#endif
|
||||
|
||||
#endif /* _CHAR_INTER_H_ */
|
||||
|
|
|
|||
|
|
@ -435,6 +435,8 @@ struct mmo_charstatus {
|
|||
unsigned short mod_exp,mod_drop,mod_death;
|
||||
|
||||
unsigned char font;
|
||||
|
||||
uint32 uniqueitem_counter;
|
||||
};
|
||||
|
||||
typedef enum mail_status {
|
||||
|
|
|
|||
|
|
@ -57,10 +57,6 @@
|
|||
/// When uncommented the cap takes place after modifiers.
|
||||
//#define HMAP_ZONE_DAMAGE_CAP_TYPE
|
||||
|
||||
/// Uncomment to enable Non Stackable items unique ID
|
||||
/// By enabling it, the system will create an unique id for each new non stackable item created
|
||||
//#define NSI_UNIQUE_ID
|
||||
|
||||
/// Comment to disable Guild/Party Bound item system
|
||||
#define GP_BOUND_ITEMS
|
||||
|
||||
|
|
|
|||
|
|
@ -1966,44 +1966,10 @@ int itemdb_readdb_sql(const char *tablename) {
|
|||
/*==========================================
|
||||
* Unique item ID function
|
||||
* Only one operation by once
|
||||
* Flag:
|
||||
* 0 return new id
|
||||
* 1 set new value, checked with current value
|
||||
* 2 set new value bypassing anything
|
||||
* 3/other return last value
|
||||
*------------------------------------------*/
|
||||
uint64 itemdb_unique_id(int8 flag, int64 value) {
|
||||
static uint64 item_uid = 0;
|
||||
|
||||
if(flag)
|
||||
{
|
||||
if(flag == 1)
|
||||
{ if(item_uid < value)
|
||||
return (item_uid = value);
|
||||
}else if(flag == 2)
|
||||
return (item_uid = value);
|
||||
|
||||
return item_uid;
|
||||
}
|
||||
uint64 itemdb_unique_id(struct map_session_data *sd) {
|
||||
|
||||
return ++item_uid;
|
||||
}
|
||||
int itemdb_uid_load() {
|
||||
char * uid;
|
||||
if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `value` FROM `%s` WHERE `varname`='unique_id'",map->interreg_db))
|
||||
Sql_ShowDebug(map->mysql_handle);
|
||||
|
||||
if( SQL_SUCCESS != SQL->NextRow(map->mysql_handle) ) {
|
||||
ShowError("itemdb_uid_load: Unable to fetch unique_id data\n");
|
||||
SQL->FreeResult(map->mysql_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SQL->GetData(map->mysql_handle, 0, &uid, NULL);
|
||||
itemdb->unique_id(1, (uint64)strtoull(uid, NULL, 10));
|
||||
SQL->FreeResult(map->mysql_handle);
|
||||
|
||||
return 0;
|
||||
return ((uint64)sd->status.char_id << 32) | sd->status.uniqueitem_counter++;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2057,8 +2023,7 @@ void itemdb_read(bool minimal) {
|
|||
sv->readdb(map->db_path, "item_stack.txt", ',', 3, 3, -1, itemdb->read_stack);
|
||||
sv->readdb(map->db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, itemdb->read_buyingstore);
|
||||
sv->readdb(map->db_path, "item_nouse.txt", ',', 3, 3, -1, itemdb->read_nouse);
|
||||
|
||||
itemdb->uid_load();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2348,7 +2313,6 @@ void itemdb_defaults(void) {
|
|||
itemdb->readdb_libconfig = itemdb_readdb_libconfig;
|
||||
itemdb->readdb_sql = itemdb_readdb_sql;
|
||||
itemdb->unique_id = itemdb_unique_id;
|
||||
itemdb->uid_load = itemdb_uid_load;
|
||||
itemdb->read = itemdb_read;
|
||||
itemdb->destroy_item_data = destroy_item_data;
|
||||
itemdb->final_sub = itemdb_final_sub;
|
||||
|
|
|
|||
|
|
@ -576,8 +576,7 @@ struct itemdb_interface {
|
|||
int (*readdb_libconfig_sub) (config_setting_t *it, int n, const char *source);
|
||||
int (*readdb_libconfig) (const char *filename);
|
||||
int (*readdb_sql) (const char *tablename);
|
||||
uint64 (*unique_id) (int8 flag, int64 value);
|
||||
int (*uid_load) ();
|
||||
uint64 (*unique_id) (struct map_session_data *sd);
|
||||
void (*read) (bool minimal);
|
||||
void (*destroy_item_data) (struct item_data *self, int free_self);
|
||||
int (*final_sub) (DBKey key, DBData *data, va_list ap);
|
||||
|
|
|
|||
|
|
@ -3991,10 +3991,10 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
|
|||
sd->inventory_data[i] = data;
|
||||
clif->additem(sd,i,amount,0);
|
||||
}
|
||||
#ifdef NSI_UNIQUE_ID
|
||||
|
||||
if( !itemdb->isstackable2(data) && !item_data->unique_id )
|
||||
sd->status.inventory[i].unique_id = itemdb->unique_id(0,0);
|
||||
#endif
|
||||
sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
|
||||
|
||||
logs->pick_pc(sd, log_type, amount, &sd->status.inventory[i],sd->inventory_data[i]);
|
||||
|
||||
sd->weight += w;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue