From 036bbfd9ae5a4a77031fb33a87264e58214c2ba0 Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 27 Jun 2006 14:54:01 +0000 Subject: - Fixed indentation on int_pet.c (how did it got messed up?) - Added mapflag "loadevent", now load-map script events will ONLY trigger on maps with this mapflag on, rather than every map. - High Jump can now be used in all versus maps. - Added Kaite's opt3 value, taken from jA - Added state dirty == 2 to storages. Signals when a storage was sent for final saving. Said storage is removed from memory after the ack from the char-server, and they are sent to save if the map/char servers reconnect before the act arrives. In short: they are guaranteed to be saved after a char logs out. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7358 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 9 ++ conf-tmpl/script_athena.conf | 1 + db/const.txt | 1 + src/char/int_pet.c | 192 +++++++++++++++++++++---------------------- src/map/chrif.c | 6 +- src/map/clif.c | 16 ++-- src/map/map.h | 1 + src/map/npc.c | 4 + src/map/script.c | 8 +- src/map/skill.c | 4 +- src/map/status.c | 9 +- src/map/storage.c | 35 ++++++-- src/map/storage.h | 2 +- 13 files changed, 168 insertions(+), 120 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index ea413e0a0..7dd377acb 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,15 @@ 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. 2006/05/27 + * Added mapflag "loadevent", now load-map script events will ONLY trigger + on maps with this mapflag on, rather than every map. [Skotlex] + * High Jump can now be used in all versus maps. [Skotlex] + * Added Kaite's opt3 value, taken from jA [Skotlex] + * Added state dirty == 2 to storages. Signals when a storage was sent for + final saving. Said storage is removed from memory after the ack from the + char-server, and they are sent to save if the map/char servers reconnect + before the ack arrives. In short: they are guaranteed to be saved after a + char logs out. [Skotlex] * Put pay_arche.gat in the "no experience lost" mapflag file. [MasterOfMuppets] 2006/06/26 * Corrected the element of hunter traps. [Skotlex] diff --git a/conf-tmpl/script_athena.conf b/conf-tmpl/script_athena.conf index bb06371ee..e4bb846e5 100644 --- a/conf-tmpl/script_athena.conf +++ b/conf-tmpl/script_athena.conf @@ -62,6 +62,7 @@ logout_event_name: PCLogoutEvent login_event_name: PCLoginEvent // Name of event when a player changes map +// NOTE: This event will only trigger on maps with the "loadmap" flag active. loadmap_event_name: PCLoadMapEvent // Name of event when a player levels up (base lv) diff --git a/db/const.txt b/db/const.txt index 9987e4836..7d5458156 100644 --- a/db/const.txt +++ b/db/const.txt @@ -131,6 +131,7 @@ mf_nodrop 38 mf_jexp 39 mf_bexp 40 mf_novending 41 +mf_loadevent 42 cell_wall 1 cell_water 3 diff --git a/src/char/int_pet.c b/src/char/int_pet.c index d787b9821..67f3fb697 100644 --- a/src/char/int_pet.c +++ b/src/char/int_pet.c @@ -217,8 +217,8 @@ int mapif_delete_pet_ack(int fd,int flag) WFIFOB(fd,2)=flag; WFIFOSET(fd,3); - return 0; - } + return 0; +} int mapif_rename_pet_ack(int fd, int account_id, int char_id, int flag, char *name){ WFIFOW(fd, 0) =0x3884; @@ -231,112 +231,112 @@ int mapif_rename_pet_ack(int fd, int account_id, int char_id, int flag, char *na return 0; } - int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id, - short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name) - { - struct s_pet *p; - p= (struct s_pet *) aCalloc(sizeof(struct s_pet), 1); - if(p==NULL){ - ShowFatalError("int_pet: out of memory !\n"); - mapif_pet_created(fd,account_id,NULL); - return 0; - } - // memset(p,0,sizeof(struct s_pet)); unnecessary after aCalloc [Skotlex] - p->pet_id = pet_newid++; - memcpy(p->name,pet_name,NAME_LENGTH-1); - if(incuvate == 1) - p->account_id = p->char_id = 0; - else { - p->account_id = account_id; - p->char_id = char_id; - } - p->class_ = pet_class; - p->level = pet_lv; - p->egg_id = pet_egg_id; - p->equip = pet_equip; - p->intimate = intimate; - p->hungry = hungry; - p->rename_flag = rename_flag; - p->incuvate = incuvate; - - if(p->hungry < 0) - p->hungry = 0; - else if(p->hungry > 100) - p->hungry = 100; - if(p->intimate < 0) - p->intimate = 0; - else if(p->intimate > 1000) - p->intimate = 1000; - - idb_put(pet_db,p->pet_id,p); - - mapif_pet_created(fd,account_id,p); - +int mapif_create_pet(int fd,int account_id,int char_id,short pet_class,short pet_lv,short pet_egg_id, + short pet_equip,short intimate,short hungry,char rename_flag,char incuvate,char *pet_name) +{ + struct s_pet *p; + p= (struct s_pet *) aCalloc(sizeof(struct s_pet), 1); + if(p==NULL){ + ShowFatalError("int_pet: out of memory !\n"); + mapif_pet_created(fd,account_id,NULL); return 0; } +// memset(p,0,sizeof(struct s_pet)); unnecessary after aCalloc [Skotlex] + p->pet_id = pet_newid++; + memcpy(p->name,pet_name,NAME_LENGTH-1); + if(incuvate == 1) + p->account_id = p->char_id = 0; + else { + p->account_id = account_id; + p->char_id = char_id; + } + p->class_ = pet_class; + p->level = pet_lv; + p->egg_id = pet_egg_id; + p->equip = pet_equip; + p->intimate = intimate; + p->hungry = hungry; + p->rename_flag = rename_flag; + p->incuvate = incuvate; + + if(p->hungry < 0) + p->hungry = 0; + else if(p->hungry > 100) + p->hungry = 100; + if(p->intimate < 0) + p->intimate = 0; + else if(p->intimate > 1000) + p->intimate = 1000; + + idb_put(pet_db,p->pet_id,p); + + mapif_pet_created(fd,account_id,p); - int mapif_load_pet(int fd,int account_id,int char_id,int pet_id) - { - struct s_pet *p; - p= idb_get(pet_db,pet_id); - if(p!=NULL) { - if(p->incuvate == 1) { - p->account_id = p->char_id = 0; - mapif_pet_info(fd,account_id,p); - } - else if(account_id == p->account_id && char_id == p->char_id) - mapif_pet_info(fd,account_id,p); - else - mapif_pet_noinfo(fd,account_id); + return 0; +} + +int mapif_load_pet(int fd,int account_id,int char_id,int pet_id) +{ + struct s_pet *p; + p= idb_get(pet_db,pet_id); + if(p!=NULL) { + if(p->incuvate == 1) { + p->account_id = p->char_id = 0; + mapif_pet_info(fd,account_id,p); } + else if(account_id == p->account_id && char_id == p->char_id) + mapif_pet_info(fd,account_id,p); else mapif_pet_noinfo(fd,account_id); - - return 0; } + else + mapif_pet_noinfo(fd,account_id); + + return 0; +} - static void* create_pet(DBKey key, va_list args) { - struct s_pet *p; - p=(struct s_pet *)aCalloc(sizeof(struct s_pet),1); - p->pet_id = key.i; - return p; +static void* create_pet(DBKey key, va_list args) { + struct s_pet *p; + p=(struct s_pet *)aCalloc(sizeof(struct s_pet),1); + p->pet_id = key.i; + return p; +} +int mapif_save_pet(int fd,int account_id,struct s_pet *data) +{ + struct s_pet *p; + int pet_id, len; + RFIFOHEAD(fd); + len=RFIFOW(fd,2); + + if(sizeof(struct s_pet)!=len-8) { + ShowError("inter pet: data size error %d %d\n",sizeof(struct s_pet),len-8); } - int mapif_save_pet(int fd,int account_id,struct s_pet *data) - { - struct s_pet *p; - int pet_id, len; - RFIFOHEAD(fd); - len=RFIFOW(fd,2); - - if(sizeof(struct s_pet)!=len-8) { - ShowError("inter pet: data size error %d %d\n",sizeof(struct s_pet),len-8); - } - else{ - pet_id = data->pet_id; - if (pet_id == 0) - pet_id = data->pet_id = pet_newid++; - p= idb_ensure(pet_db,pet_id,create_pet); - if(data->hungry < 0) - data->hungry = 0; - else if(data->hungry > 100) - data->hungry = 100; - if(data->intimate < 0) - data->intimate = 0; - else if(data->intimate > 1000) - data->intimate = 1000; - memcpy(p,data,sizeof(struct s_pet)); - if(p->incuvate == 1) - p->account_id = p->char_id = 0; - - mapif_save_pet_ack(fd,account_id,0); - } + else{ + pet_id = data->pet_id; + if (pet_id == 0) + pet_id = data->pet_id = pet_newid++; + p= idb_ensure(pet_db,pet_id,create_pet); + if(data->hungry < 0) + data->hungry = 0; + else if(data->hungry > 100) + data->hungry = 100; + if(data->intimate < 0) + data->intimate = 0; + else if(data->intimate > 1000) + data->intimate = 1000; + memcpy(p,data,sizeof(struct s_pet)); + if(p->incuvate == 1) + p->account_id = p->char_id = 0; - return 0; + mapif_save_pet_ack(fd,account_id,0); } - int mapif_delete_pet(int fd,int pet_id) - { - mapif_delete_pet_ack(fd,inter_pet_delete(pet_id)); + return 0; +} + +int mapif_delete_pet(int fd,int pet_id) +{ + mapif_delete_pet_ack(fd,inter_pet_delete(pet_id)); return 0; } diff --git a/src/map/chrif.c b/src/map/chrif.c index 5b7dee2de..be0b2a25f 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -189,7 +189,7 @@ int chrif_save(struct map_session_data *sd, int flag) return -1; //Refuse to save a char already tagged for final saving. [Skotlex] //For data sync if (sd->state.storage_flag == 1) - storage_storage_save(sd->status.account_id); + storage_storage_save(sd->status.account_id, flag); else if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id); @@ -218,10 +218,8 @@ int chrif_save(struct map_session_data *sd, int flag) #ifndef TXT_ONLY } #endif - if (flag) {//Remove the storage from memory. - storage_delete(sd->status.account_id); + if (flag) sd->state.finalsave = 1; //Mark the last save as done. - } return 0; } diff --git a/src/map/clif.c b/src/map/clif.c index e25b89a8f..1698045e2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -8207,7 +8207,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) sc_start(&sd->bl,SC_NOCHAT,100,0,0); // Lance - if(sd->state.event_loadmap){ + if(sd->state.event_loadmap && map[sd->bl.m].flag.loadevent){ pc_setregstr(sd, add_str("@maploaded$"), map[sd->bl.m].name); npc_script_event(sd, NPCE_LOADMAP); } @@ -9848,8 +9848,6 @@ void clif_parse_NpcStringInput(int fd,struct map_session_data *sd) if(message_len >= sizeof(sd->npc_str)){ ShowWarning("clif: input string too long !\n"); message_len = sizeof(sd->npc_str); - } else { - message_len += 1; // Null character } // Exploit prevention if crafted packets (without null) is being sent. [Lance] @@ -9972,12 +9970,18 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd) { */ void clif_parse_LGMmessage(int fd, struct map_session_data *sd) { unsigned char buf[512]; - int len = RFIFOREST(fd); +// int len = RFIFOREST(fd); int plen = RFIFOW(fd,2); RFIFOHEAD(fd); - if(plen <= 0 || plen > len) // Possible hack! [Lance] - plen = len; + //This shouldn't be needed.... because the parsing code makes sure + //this function is not invoked until enough bytes have been received. + //So if the client "hacks" the packet, all that will happen is that + //it will not be parsed until enough data is received, on which point + //the following packets will be offset, causing them to fail to parse, + //which leads to disconnecting them :3 [Skotlex] +// if(plen <= 0 || plen > len) // Possible hack! [Lance] +// plen = len; if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level(AtCommand_LocalBroadcast))) { diff --git a/src/map/map.h b/src/map/map.h index 94415fcf5..116ff25fd 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1045,6 +1045,7 @@ struct map_data { unsigned nocommand : 1; //Blocks @/# commands for non-gms. [Skotlex] unsigned nodrop : 1; unsigned novending : 1; + unsigned loadevent : 1; } flag; struct point save; struct npc_data *npc[MAX_NPC_PER_MAP]; diff --git a/src/map/npc.c b/src/map/npc.c index 26ab060a7..6f3fe5f00 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2514,6 +2514,10 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4) if( map[m].bexp < 0 ) map[m].bexp = 100; map[m].flag.nobaseexp = (map[m].bexp==0)?1:0; } + else if (strcmpi(w3,"loadevent")==0) { // Skotlex + map[m].flag.loadevent=state; + } + return 0; } diff --git a/src/map/script.c b/src/map/script.c index 02acd4ee5..692b985b4 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6869,7 +6869,7 @@ enum { MF_NOMEMO,MF_NOTELEPORT,MF_NOSAVE,MF_NOBRANCH,MF_NOPENALTY,MF_NOZENYPENA MF_NOWARP,MF_FREE,MF_NOICEWALL,MF_SNOW,MF_FOG,MF_SAKURA,MF_LEAVES,MF_RAIN, MF_INDOORS,MF_NOGO,MF_CLOUDS,MF_CLOUDS2,MF_FIREWORKS,MF_GVG_CASTLE,MF_GVG_DUNGEON,MF_NIGHTENABLED, MF_NOBASEEXP, MF_NOJOBEXP, MF_NOMOBLOOT, MF_NOMVPLOOT, MF_NORETURN, MF_NOWARPTO, MF_NIGHTMAREDROP, - MF_RESTRICTED, MF_NOCOMMAND, MF_NODROP, MF_JEXP, MF_BEXP, MF_NOVENDING }; + MF_RESTRICTED, MF_NOCOMMAND, MF_NODROP, MF_JEXP, MF_BEXP, MF_NOVENDING, MF_LOADEVENT }; int buildin_setmapflagnosave(struct script_state *st) { @@ -7028,6 +7028,9 @@ int buildin_setmapflag(struct script_state *st) case MF_NOVENDING: map[m].flag.novending=1; break; + case MF_LOADEVENT: + map[m].flag.loadevent=1; + break; } } @@ -7167,6 +7170,9 @@ int buildin_removemapflag(struct script_state *st) case MF_NOVENDING: map[m].flag.novending=0; break; + case MF_LOADEVENT: + map[m].flag.loadevent=0; + break; } } diff --git a/src/map/skill.c b/src/map/skill.c index aa55ea971..a07db8ba0 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -883,8 +883,8 @@ int skillnotok (int skillid, struct map_session_data *sd) } return 0; case TK_HIGHJUMP: - if(map[sd->bl.m].flag.noteleport && !map_flag_gvg(sd->bl.m)) - { //Can't be used on noteleport maps, except for gvg maps [Skotlex] + if(map[sd->bl.m].flag.noteleport && !map_flag_vs(sd->bl.m)) + { //Can't be used on noteleport maps, except for vs maps [Skotlex] clif_skill_fail(sd,skillid,0,0); return 1; } diff --git a/src/map/status.c b/src/map/status.c index 08aeb291a..1654d5dc6 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -5278,7 +5278,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val sc->opt3 |= 4096; opt_flag = 0; break; - + case SC_KAITE: + sc->opt3 |= 8192; + opt_flag = 0; + break; //OPTION case SC_HIDING: sc->option |= OPTION_HIDE; @@ -5764,6 +5767,10 @@ int status_change_end( struct block_list* bl , int type,int tid ) sc->opt3 &= ~4096; opt_flag = 0; break; + case SC_KAITE: + sc->opt3 &= ~8192; + opt_flag = 0; + break; default: opt_flag = 0; } diff --git a/src/map/storage.c b/src/map/storage.c index c420795a1..211bdb9ec 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -82,7 +82,7 @@ static int storage_reconnect_sub(DBKey key,void *data,va_list ap) { //Account Storage struct storage* stor = (struct storage*) data; if (stor->dirty && stor->storage_status == 0) //Save closed storages. - storage_storage_save(stor->account_id); + storage_storage_save(stor->account_id, stor->dirty==2?1:0); } return 0; } @@ -390,16 +390,27 @@ void storage_storage_dirty(struct map_session_data *sd) stor->dirty = 1; } -int storage_storage_save(int account_id) +int storage_storage_save(int account_id, int final) { struct storage *stor; stor=account2storage2(account_id); - if(stor && stor->dirty) + if(!stor) return 0; + + if(stor->dirty) { + if (final) { + stor->dirty = 2; + stor->storage_status = 0; //To prevent further manipulation of it. + } intif_send_storage(stor); return 1; } + if (final) + { //Clear storage from memory. Nothing to save. + storage_delete(account_id); + return 1; + } return 0; } @@ -409,13 +420,19 @@ int storage_storage_saved(int account_id) { struct storage *stor; - if((stor=account2storage2(account_id)) != NULL) + if((stor=account2storage2(account_id)) == NULL) + return 0; + + if (stor->dirty == 2) + { //Final save of storage. Remove from memory. + storage_delete(account_id); + return 1; + } + + if (stor->dirty && stor->storage_status == 0) { //Only mark it clean if it's not in use. [Skotlex] - if (stor->dirty && stor->storage_status == 0) - { - stor->dirty = 0; - sortage_sortitem(stor); - } + stor->dirty = 0; + sortage_sortitem(stor); return 1; } return 0; diff --git a/src/map/storage.h b/src/map/storage.h index 40e11331b..e33505062 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -19,7 +19,7 @@ struct storage *account2storage(int account_id); struct storage *account2storage2(int account_id); int storage_delete(int account_id); int storage_storage_quit(struct map_session_data *sd, int flag); -int storage_storage_save(int account_id); +int storage_storage_save(int account_id, int final); int storage_storage_saved(int account_id); //Ack from char server that guild store was saved. void storage_storage_dirty(struct map_session_data *sd); -- cgit v1.2.3-60-g2f50