- Merged and completed Latio's work on server-side hot-key saving (http://www.eathena.ws/board/index.php?s=&showtopic=159388&view=findpost&p=884453)
- Now hotkeys are stored server-side (table hotkey in SQL servers, file save/hotkeys.txt for TXT servers). You can disable this behaviour by commenting out the 'HOTKEY_SAVING' define in mmo.h - Fixed a few compilation warnings/errors. - Apply upgrade_svn11018.sql to create the hotkey table. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11019 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
efff167bc0
commit
dff80559d4
@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2007/08/15
|
||||
* Merged and completed Latio's work on server-side hot-key saving
|
||||
(http://www.eathena.ws/board/index.php?s=&showtopic=159388&view=findpost&p=884453):
|
||||
Now hotkeys are stored server-side (table hotkey in SQL servers, file
|
||||
save/hotkeys.txt for TXT servers). You can disable this behaviour by
|
||||
commenting out the 'HOTKEY_SAVING' define in mmo.h
|
||||
* Apply upgrade_svn11018.sql to create the hotkey table. [Skotlex]
|
||||
* Some serious code cleanups
|
||||
- adjusted @reloadbattleconf to not depend on variable ordering
|
||||
- changed all battle vars to 'int' (removes pointless duplicit coding)
|
||||
|
@ -8,6 +8,9 @@ storage_txt: save/storage.txt
|
||||
// Party flatfile database, for party names, members and other party info.
|
||||
party_txt: save/party.txt
|
||||
|
||||
// Hotkeys flatfile database, where character skill shortcuts are stored.
|
||||
hotkeys_txt: save/hotkeys.txt
|
||||
|
||||
// Guild flatfile database, for guild names, members, and other guild info.
|
||||
guild_txt: save/guild.txt
|
||||
|
||||
@ -114,6 +117,7 @@ loginlog_db: loginlog
|
||||
|
||||
// Character Database Tables
|
||||
char_db: char
|
||||
hotkey_db: hotkey
|
||||
scdata_db: sc_data
|
||||
cart_db: cart_inventory
|
||||
inventory_db: inventory
|
||||
|
@ -1014,7 +1014,7 @@ packet_ver: 22
|
||||
0x02b7,10
|
||||
0x02b8,22
|
||||
0x02b9,191
|
||||
0x02ba,11
|
||||
0x02ba,11,hotkey,2:4:5:9
|
||||
0x02bb,8
|
||||
0x02bc,6
|
||||
|
||||
|
@ -116,6 +116,21 @@ CREATE TABLE `friends` (
|
||||
KEY `char_id` (`char_id`)
|
||||
) TYPE=MyISAM;
|
||||
|
||||
--
|
||||
-- Table structure for table `hotkey`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `hotkey`;
|
||||
CREATE TABLE `hotkey` (
|
||||
`char_id` INT(11) NOT NULL,
|
||||
`hotkey` TINYINT(2) unsigned NOT NULL,
|
||||
`type` TINYINT(1) unsigned NOT NULL default '0',
|
||||
`itemskill_id` INT(11) unsigned NOT NULL default '0',
|
||||
`skill_lvl` TINYINT(4) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`char_id`,`hotkey`),
|
||||
INDEX (`char_id`)
|
||||
) TYPE=MYISAM;
|
||||
|
||||
--
|
||||
-- Table structure for table `global_reg_value`
|
||||
--
|
||||
|
10
sql-files/upgrade_svn11018.sql
Normal file
10
sql-files/upgrade_svn11018.sql
Normal file
@ -0,0 +1,10 @@
|
||||
DROP TABLE IF EXISTS `hotkey`;
|
||||
CREATE TABLE `hotkey` (
|
||||
`char_id` INT(11) NOT NULL,
|
||||
`hotkey` TINYINT(2) unsigned NOT NULL,
|
||||
`type` TINYINT(1) unsigned NOT NULL default '0',
|
||||
`itemskill_id` INT(11) unsigned NOT NULL default '0',
|
||||
`skill_lvl` TINYINT(4) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`char_id`,`hotkey`),
|
||||
INDEX (`char_id`)
|
||||
) TYPE=MYISAM;
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user