diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.c | 82 | ||||
-rw-r--r-- | src/char_sql/char.c | 49 | ||||
-rw-r--r-- | src/common/mmo.h | 16 | ||||
-rw-r--r-- | src/map/atcommand.h | 2 | ||||
-rw-r--r-- | src/map/clif.c | 37 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/party.c | 2 |
7 files changed, 183 insertions, 6 deletions
diff --git a/src/char/char.c b/src/char/char.c index 7d39e6d92..2ae559f20 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -46,6 +46,7 @@ char char_txt[1024] = "save/athena.txt"; char friends_txt[1024] = "save/friends.txt"; +char hotkeys_txt[1024] = "save/hotkeys.txt"; char char_log_filename[1024] = "log/char.log"; int save_log = 1; // show loading/saving messages @@ -445,6 +446,22 @@ int mmo_friends_list_data_str(char *str, struct mmo_charstatus *p) return 0; } +/*--------------------------------------------------- + Make a data line for hotkeys list + --------------------------------------------------*/ +int mmo_hotkeys_tostr(char *str, struct mmo_charstatus *p) +{ + int i; + char *str_p = str; + str_p += sprintf(str_p, "%d", p->char_id); +#ifdef HOTKEY_SAVING + for (i=0;i<HOTKEY_SAVING;i++) + str_p += sprintf(str_p, ",%d,%d,%d", p->hotkeys[i].type, p->hotkeys[i].id, p->hotkeys[i].lv); +#endif + str_p += '\0'; + + return 0; +} //------------------------------------------------- // Function to create the character line (for save) //------------------------------------------------- @@ -891,6 +908,53 @@ int parse_friend_txt(struct mmo_charstatus *p) return count; } +//--------------------------------- +// Function to read hotkey list +//--------------------------------- +int parse_hotkey_txt(struct mmo_charstatus *p) +{ +#ifdef HOTKEY_SAVING + char line[1024]; + int pos = 0, count = 0, next; + int i,len; + int type, id, lv; + FILE *fp; + + // Open the file and look for the ID + fp = fopen(hotkeys_txt, "r"); + if(fp == NULL) + return -1; + + while(fgets(line, sizeof(line), fp)) + { + if(line[0] == '/' && line[1] == '/') + continue; + if (sscanf(line, "%d%n",&i, &pos) < 1 || i != p->char_id) + continue; //Not this line... + //Read hotkeys + len = strlen(line); + next = pos; + for (count = 0; next < len && count < HOTKEY_SAVING; count++) + { + if (sscanf(line+next, ",%d,%d,%d%n",&type,&id,&lv, &pos) < 3) + //Invalid entry? + break; + p->hotkeys[count].type = type; + p->hotkeys[count].id = id; + p->hotkeys[count].lv = lv; + next+=pos; + } + break; //Found hotkeys. + } + fclose(fp); + return count; +#else + return 0; +#endif +} + + + #ifndef TXT_SQL_CONVERT //--------------------------------- // Function to read characters file @@ -944,7 +1008,9 @@ int mmo_char_init(void) // Initialize friends list parse_friend_txt(&char_dat[char_num].status); // Grab friends for the character - + // Initialize hotkey list + parse_hotkey_txt(&char_dat[char_num].status); // Grab hotkeys for the character + if (ret > 0) { // negative value or zero for errors if (char_dat[char_num].status.char_id >= char_id_count) char_id_count = char_dat[char_num].status.char_id + 1; @@ -1049,7 +1115,17 @@ void mmo_char_sync(void) lock_fclose(f_fp, friends_txt, &lock); - //aFree(id); +#ifdef HOTKEY_SAVING + // Hotkey List data save (Skotlex) + f_fp = lock_fopen(hotkeys_txt, &lock); + for(i = 0; i < char_num; i++) { + mmo_hotkeys_tostr(f_line, &char_dat[id[i]].status); + fprintf(f_fp, "%s" RETCODE, f_line); + } + + lock_fclose(f_fp, hotkeys_txt, &lock); +#endif + DELETE_BUFFER(id); return; @@ -4059,6 +4135,8 @@ int char_config_read(const char *cfgName) strcpy(char_txt, w2); } else if (strcmpi(w1, "friends_txt") == 0) { //By davidsiaw strcpy(friends_txt, w2); + } else if (strcmpi(w1, "hotkeys_txt") == 0) { //By davidsiaw + strcpy(hotkeys_txt, w2); #ifndef TXT_SQL_CONVERT } else if (strcmpi(w1, "max_connect_user") == 0) { max_connect_user = atoi(w2); diff --git a/src/char_sql/char.c b/src/char_sql/char.c index d3081df57..5ff26c0aa 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -57,6 +57,7 @@ char guild_storage_db[256] = "guild_storage"; char party_db[256] = "party"; char pet_db[256] = "pet"; char friend_db[256] = "friends"; +char hotkey_db[256] = "hotkey"; #ifndef TXT_SQL_CONVERT static struct dbt *char_db_; @@ -731,7 +732,28 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus *p){ strcat(save_status, " friends"); } - +#ifdef HOTKEY_SAVING + // hotkeys + tmp_ptr = tmp_sql; + tmp_ptr += sprintf(tmp_ptr, "REPLACE INTO `%s` (`char_id`, `hotkey`, `type`, `itemskill_id`, `skill_lvl`) VALUES ", hotkey_db); + diff = 0; + for(i = 0; i < ARRAYLENGTH(p->hotkeys); i++){ + if(memcmp(&p->hotkeys[i], &cp->hotkeys[i], sizeof(struct hotkey))) + { + tmp_ptr += sprintf(tmp_ptr, "('%d','%d','%d','%d','%d'),", char_id, i, p->hotkeys[i].type, p->hotkeys[i].id , p->hotkeys[i].lv); + diff = 1; + } + } + if(diff) { + tmp_ptr[-1] = 0; + if(mysql_query(&mysql_handle, tmp_sql)){ + ShowSQL("DB error - %s\n",mysql_error(&mysql_handle)); + ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql); + } else { + strcat(save_status, " hotkeys"); + } + } +#endif if (save_status[0]!='\0' && save_log) ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status); #ifndef TXT_SQL_CONVERT @@ -1083,6 +1105,29 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything strcat (t_msg, " friends"); } +#ifdef HOTKEY_SAVING + //Hotkeys + sprintf(tmp_sql, "SELECT `hotkey`, `type`, `itemskill_id`, `skill_lvl` FROM `%s` WHERE `char_id`=%d ORDER BY `hotkey` LIMIT %d;", hotkey_db, char_id, HOTKEY_SAVING); + if(mysql_query(&mysql_handle, tmp_sql)){ + ShowSQL("DB error - %s\n", mysql_error(&mysql_handle)); + ShowDebug("at %s:%d - %s\n", __FILE__, __LINE__, tmp_sql); + } + sql_res = mysql_store_result(&mysql_handle); + + if (sql_res) { + while ((sql_row = mysql_fetch_row(sql_res))) { + n = atoi(sql_row[0]); + if( n < 0 || n >= HOTKEY_SAVING) + continue; + p->hotkeys[n].type = atoi(sql_row[1]); + p->hotkeys[n].id = atoi(sql_row[2]); + p->hotkeys[n].lv = atoi(sql_row[3]); + } + mysql_free_result(sql_res); + 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! cp = idb_ensure(char_db_, char_id, create_charstatus); @@ -3765,6 +3810,8 @@ void sql_config_read(const char* cfgName) strcpy(pet_db,w2); else if(!strcmpi(w1,"friend_db")) strcpy(friend_db,w2); + else if(!strcmpi(w1,"hotkey_db")) + strcpy(hotkey_db,w2); #ifndef TXT_SQL_CONVERT else if(!strcmpi(w1,"db_path")) strcpy(db_path,w2); diff --git a/src/common/mmo.h b/src/common/mmo.h index 2a42c017c..0fcfff137 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -13,6 +13,11 @@ //Remove/Comment this line to disable sc_data saving. [Skotlex] #define ENABLE_SC_SAVING +//Remove/Comment this line to disable server-side hot-key saving support [Skotlex] +//Note that newer clients no longer save hotkeys in the registry! +//The number is the max number of hotkeys to save (27 = 9 skills x 3 bars) +#define HOTKEY_SAVING 27 + #define MAX_MAP_PER_SERVER 1024 #define MAX_INVENTORY 100 //Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well. @@ -180,6 +185,14 @@ struct friend { char name[NAME_LENGTH]; }; +#ifdef HOTKEY_SAVING +struct hotkey { + unsigned int id; + unsigned short lv; + unsigned char type; // 0: item, 1: skill +}; +#endif + struct mmo_charstatus { int char_id; int account_id; @@ -217,6 +230,9 @@ struct mmo_charstatus { struct skill skill[MAX_SKILL]; struct friend friends[MAX_FRIENDS]; //New friend system [Skotlex] +#ifdef HOTKEY_SAVING + struct hotkey hotkeys[HOTKEY_SAVING]; +#endif }; struct registry { diff --git a/src/map/atcommand.h b/src/map/atcommand.h index 7f76dbf30..a4fd609d2 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -10,6 +10,8 @@ //Note: The range is unlimited unless this define is set. //#define AUTOLOOT_DISTANCE AREA_SIZE +#include "map.h" + enum AtCommandType { AtCommand_None = -1, AtCommand_Broadcast = 0, diff --git a/src/map/clif.c b/src/map/clif.c index 30646a5b3..335d94ccf 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8083,6 +8083,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_updatestatus(sd,SP_NEXTJOBEXP); clif_updatestatus(sd,SP_SKILLPOINT); clif_initialstatus(sd); + clif_hotkeys_send(sd); if (sd->sc.option&OPTION_FALCON) clif_status_load(&sd->bl, SI_FALCON, 1); @@ -8193,6 +8194,38 @@ void clif_parse_TickSend(int fd, struct map_session_data *sd) return; } +void clif_hotkeys_send(struct map_session_data *sd) { +#ifdef HOTKEY_SAVING + const int fd = sd->fd; + int i; + if (!fd) return; + WFIFOHEAD(fd, 2+HOTKEY_SAVING*7); + WFIFOW(fd, 0) = 0x02b9; + for(i = 0; i < HOTKEY_SAVING; i++) { + WFIFOB(fd, 2 + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill + WFIFOL(fd, 2 + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID + WFIFOW(fd, 2 + 5 + i * 7) = sd->status.hotkeys[i].lv; // skill level + } + WFIFOSET(fd, packet_len(0x02b9)); +#endif +} + +void clif_parse_Hotkey(int fd, struct map_session_data *sd) { +#ifdef HOTKEY_SAVING + unsigned short idx; + int cmd; + + cmd = RFIFOW(fd, 0); + idx = RFIFOW(fd, packet_db[sd->packet_ver][cmd].pos[0]); + if (idx >= HOTKEY_SAVING) return; + + sd->status.hotkeys[idx].type = RFIFOB(fd, packet_db[sd->packet_ver][cmd].pos[1]); + sd->status.hotkeys[idx].id = RFIFOL(fd, packet_db[sd->packet_ver][cmd].pos[2]); + sd->status.hotkeys[idx].lv = RFIFOW(fd, packet_db[sd->packet_ver][cmd].pos[3]); + return; +#endif +} + /*========================================== * *------------------------------------------*/ @@ -11705,7 +11738,7 @@ static int packetdb_readdb(void) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 0, 0, 0, 0, //#0x02C0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -11843,13 +11876,13 @@ static int packetdb_readdb(void) {clif_parse_FeelSaveOk,"feelsaveok"}, {clif_parse_AdoptRequest,"adopt"}, {clif_parse_debug,"debug"}, - //[blackhole89] //[orn] {clif_parse_ChangeHomunculusName,"changehomunculusname"}, {clif_parse_HomMoveToMaster,"hommovetomaster"}, {clif_parse_HomMoveTo,"hommoveto"}, {clif_parse_HomAttack,"homattack"}, {clif_parse_HomMenu,"hommenu"}, {clif_parse_StoragePassword,"storagepassword"}, + {clif_parse_Hotkey,"hotkey"}, {NULL,NULL} }; diff --git a/src/map/clif.h b/src/map/clif.h index 458dfd281..bb510b94a 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -144,6 +144,7 @@ void clif_soundeffect(struct map_session_data* sd, struct block_list* bl, const int clif_soundeffectall(struct block_list* bl, const char *name, int type, enum send_target coverage); void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick); void clif_parse_LoadEndAck(int fd,struct map_session_data *sd); +void clif_hotkeys_send(struct map_session_data *sd); // trade int clif_traderequest(struct map_session_data* sd, const char* name); diff --git a/src/map/party.c b/src/map/party.c index 2427dab98..195e844cb 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -712,7 +712,7 @@ int party_exp_share(struct party_data* p, struct block_list* src, unsigned int b // count the number of players eligible for exp sharing for (i = c = 0; i < MAX_PARTY; i++) { if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || - battle_config.idle_no_share && (sd[c]->chatID || sd[c]->vender_id || sd[c]->idletime < last_tick - battle_config.idle_no_share) ) + (battle_config.idle_no_share && (sd[c]->chatID || sd[c]->vender_id || sd[c]->idletime < last_tick - battle_config.idle_no_share)) ) continue; c++; } |