Sfoglia il codice sorgente

-Fix bugrepot:7609 fix picklog enum (add cashshop type)
-Fix bugreport:7615 freeze after closse by Secure timer, also fix "Unable to restore stack! Double continuation!" case (when dead by mob talking to npc)
-Upd secure timer, now stop timer when we already in close/end state.
-Fix st_>mes_active case where var wasn't refresh but dialogue was ended
-Add packet support for ZC_ITEM_PICKUP_ACK_V5 (0x990), (0x0897,0x093F,0x0886,0x035f) (Hercule/Shaktoh)
-Cleanup too duplicate, too wide comment

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17303 54d463be-8e91-2dee-dedb-b68131a5f0ec

glighta 12 anni fa
parent
commit
eb013a6d5e

+ 5 - 4
db/packet_db.txt

@@ -1802,7 +1802,7 @@ packet_ver: 33
 packet_ver: 34
 0x01FD,15,repairitem,2
 0x086D,26,friendslistadd,2
-0x0897,5,hommenu,2:4
+0x0897,5,changedir,2:4
 0x0947,36,storagepassword,0
 0x086F,26,partyinvite2,2
 0x0888,19,wanttoconnection,2:6:10:14:18
@@ -1810,7 +1810,7 @@ packet_ver: 34
 0x089B,10,useskilltoid,2:4:6
 0x0881,5,walktoxy,2
 0x0363,6,ticksend,2
-0x093F,5,changedir,2:4
+0x093F,5,hommenu,2:4
 0x0933,6,takeitem,2
 0x0438,6,dropitem,2:4
 0x08AC,8,movetokafra,2:4
@@ -1827,13 +1827,14 @@ packet_ver: 34
 0x0998,8,equipitem,2:4
 //0x0281,-1,itemlistwindowselected,2:4:8
 0x0938,-1,reqopenbuyingstore,2:4:8:9:89
-//0x0817,2,reqclosebuyingstore,0
-//0x0360,6,reqclickbuyingstore,2
+0x0886,2,reqclosebuyingstore,0
+0x035f,6,reqclickbuyingstore,2
 0x0922,-1,reqtradebuyingstore,2:4:8:12
 0x094E,-1,searchstoreinfo,2:4:5:9:13:14:15
 //0x0835,2,searchstoreinfonextpage,0
 //0x0838,12,searchstoreinfolistitemclick,2:6:10
 0x0447,2
+0x990,31 //additem
 0x99b,8 //maptypeproperty2
 0x84b,19 //fallitem4
 

+ 1 - 1
npc/re/scripts_athena.conf

@@ -1,7 +1,7 @@
 // --------------------------------------------------------------
 // -                    Renewal Core Scripts                    -
 // --------------------------------------------------------------
-
+npc: npc/re/tester.txt
 // -------------------------- Airport ---------------------------
 npc: npc/re/airports/izlude.txt
 

+ 2 - 2
sql-files/logs.sql

@@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS `picklog` (
   `id` int(11) NOT NULL auto_increment,
   `time` datetime NOT NULL default '0000-00-00 00:00:00',
   `char_id` int(11) NOT NULL default '0',
-  `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U') NOT NULL default 'P',
+  `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$') NOT NULL default 'P',
   `nameid` int(11) NOT NULL default '0',
   `amount` int(11) NOT NULL default '1',
   `refine` tinyint(3) unsigned NOT NULL default '0',
@@ -139,4 +139,4 @@ CREATE TABLE IF NOT EXISTS `cashlog` (
   `map` varchar(11) NOT NULL DEFAULT '',
   PRIMARY KEY (`id`),
   INDEX `type` (`type`)
-) ENGINE=MyISAM AUTO_INCREMENT=1;
+) ENGINE=MyISAM AUTO_INCREMENT=1;

+ 1 - 0
sql-files/upgrades/upgrade_svn17303_log.sql

@@ -0,0 +1 @@
+ALTER TABLE `picklog` CHANGE `type` `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$') NOT NULL default 'P';

+ 14 - 19
src/map/clif.c

@@ -1271,11 +1271,6 @@ static void clif_weather_check(struct map_session_data *sd)
 			clif_specialeffect_single(&sd->bl, 163, fd);
 		if (map[m].flag.leaves)
 			clif_specialeffect_single(&sd->bl, 333, fd);
-		/**
-		 * No longer available, keeping here just in case it's back someday. [Ind]
-		 **/
-		//if (map[m].flag.rain)
-		//	clif_specialeffect_single(&sd->bl, 161, fd);
 	}
 }
 /**
@@ -1714,8 +1709,7 @@ void clif_fixpos(struct block_list *bl)
 	WBUFW(buf,8) = bl->y;
 	clif_send(buf, packet_len(0x88), bl, AREA);
 
-	if( disguised(bl) )
-	{
+	if( disguised(bl) ) {
 		WBUFL(buf,2) = -bl->id;
 		clif_send(buf, packet_len(0x88), bl, SELF);
 	}
@@ -1882,8 +1876,7 @@ void clif_scriptclose(struct map_session_data *sd, int npcid)
 /*==========================================
  *
  *------------------------------------------*/
-void clif_sendfakenpc(struct map_session_data *sd, int npcid)
-{
+void clif_sendfakenpc(struct map_session_data *sd, int npcid) {
 	unsigned char *buf;
 	int fd = sd->fd;
 	sd->state.using_fake_npc = 1;
@@ -2117,6 +2110,7 @@ static void clif_addcards(unsigned char* buf, struct item* item)
 /// 00a0 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B (ZC_ITEM_PICKUP_ACK)
 /// 029a <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L (ZC_ITEM_PICKUP_ACK2)
 /// 02d4 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W (ZC_ITEM_PICKUP_ACK3)
+/// 0990 <index>.W <amount>.W <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B <result>.B <expire time>.L <bindOnEquipType>.W <unknow>.W (ZC_ITEM_PICKUP_ACK_V5)
 void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
 {
 	int fd;
@@ -2124,8 +2118,10 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
 	const int cmd = 0xa0;
 #elif PACKETVER < 20071002
 	const int cmd = 0x29a;
-#else
+#elif PACKETVER < 20120925
 	const int cmd = 0x2d4;
+#else
+	const int cmd = 0x990;
 #endif
 	nullpo_retv(sd);
 
@@ -2181,6 +2177,9 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail)
 #endif
 #if PACKETVER >= 20071002
 		WFIFOW(fd,27)=0;  // unknown
+#endif
+#if PACKETVER >= 20120925
+		WFIFOW(fd,29)=0;  // unknown
 #endif
 	}
 
@@ -2240,8 +2239,7 @@ void clif_delitem(struct map_session_data *sd,int n,int amount, short reason)
 // Simplifies inventory/cart/storage packets by handling the packet section relevant to items. [Skotlex]
 // Equip is >= 0 for equippable items (holds the equip-point, is 0 for pet
 // armor/egg) -1 for stackable items, -2 for stackable items where arrows must send in the equip-point.
-void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *id, int equip)
-{
+void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *id, int equip) {
 	if (id->view_id > 0)
 		WBUFW(buf,n)=id->view_id;
 	else
@@ -2264,8 +2262,7 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
 }
 void clif_favorite_item(struct map_session_data* sd, unsigned short index);
 //Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
-void clif_inventorylist(struct map_session_data *sd)
-{
+void clif_inventorylist(struct map_session_data *sd) {
 	int i,n,ne,arrow=-1;
 	unsigned char *buf;
 	unsigned char *bufe;
@@ -2340,8 +2337,7 @@ void clif_inventorylist(struct map_session_data *sd)
 	if( arrow >= 0 )
 		clif_arrowequip(sd,arrow);
 
-	if( ne )
-	{
+	if( ne ) {
 #if PACKETVER < 20071002
 		WBUFW(bufe,0)=0xa4;
 #else
@@ -3111,8 +3107,7 @@ void clif_refreshlook(struct block_list *bl,int id,int type,int val,enum send_ta
 ///     <int>.B <need int>.B <dex>.B <need dex>.B <luk>.B <need luk>.B <atk>.W <atk2>.W
 ///     <matk min>.W <matk max>.W <def>.W <def2>.W <mdef>.W <mdef2>.W <hit>.W
 ///     <flee>.W <flee2>.W <crit>.W <aspd>.W <aspd2>.W
-void clif_initialstatus(struct map_session_data *sd)
-{
+void clif_initialstatus(struct map_session_data *sd) {
 	int fd, mdef2;
 	unsigned char *buf;
 
@@ -16747,7 +16742,7 @@ static int packetdb_readdb(void)
 		0,  0,  0,  0,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0,  0,
 	//#0x0980
 		0,  0,  0, 29,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-		0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0,  0,
+		31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  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, 14,  0,  0,  0,  0,  0,  0,  0,  0,
 

+ 4 - 4
src/map/mob.c

@@ -159,9 +159,9 @@ void mvptomb_create(struct mob_data *md, char *killer, time_t time)
 	map_addnpc(nd->bl.m, nd);
 	map_addblock(&nd->bl);
 	status_set_viewdata(&nd->bl, nd->class_);
-    status_change_init(&nd->bl);
-    unit_dataset(&nd->bl);
-    clif_spawn(&nd->bl);
+	status_change_init(&nd->bl);
+	unit_dataset(&nd->bl);
+	clif_spawn(&nd->bl);
 
 }
 
@@ -2491,7 +2491,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 			for(i = 0; i < MAX_MVP_DROP; i++) {
 				while( 1 ) {
-					int va = rand()%MAX_MVP_DROP;
+					int va = rnd()%MAX_MVP_DROP;
 					if( !mdrop_id[va] || !md->db->mvpitem[i].nameid ) {
 						mdrop_id[va] = md->db->mvpitem[i].nameid;
 						mdrop_p[va]  = md->db->mvpitem[i].p;

+ 11 - 25
src/map/npc.c

@@ -246,6 +246,7 @@ struct npc_data* npc_name2id(const char* name)
 int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) {
 	struct map_session_data* sd = NULL;
 	unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
+	int cur_tick = gettick(); //ensure we are on last tick
 	if( (sd = map_id2sd(id)) == NULL || !sd->npc_id ) {
 		if( sd ) sd->npc_idle_timer = INVALID_TIMER;
 		return 0;//Not logged in anymore OR no longer attached to a npc
@@ -261,22 +262,13 @@ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat
 		//case NPCT_WAIT: var starts with this value
 	}
 
-	if( DIFF_TICK(tick,sd->npc_idle_tick) > (timeout*1000) ) {
-		/**
-		 * If we still have the NPC script attached, tell it to stop.
-		 **/
-		if( sd->st )
-			sd->st->state = END;
-		sd->state.menu_or_input = 0;
-		sd->npc_menu = 0;
-
-		/**
-		 * This guy's been idle for longer than allowed, close him.
-		 **/
-		clif_scriptclose(sd,sd->npc_id);
-		sd->npc_idle_timer = INVALID_TIMER;
-	} else //Create a new instance of ourselves to continue
-		sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+	if( DIFF_TICK(cur_tick,sd->npc_idle_tick) > (timeout*1000) ) {
+		pc_close_npc(sd,1);
+	} else if(sd->st && (sd->st->state == END || sd->st->state == CLOSE)){
+		sd->npc_idle_timer = INVALID_TIMER; //stop timer the script is already ending
+	} else { //Create a new instance of ourselves to continue
+		sd->npc_idle_timer = add_timer(cur_tick + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
+	}
 	return 0;
 }
 #endif
@@ -1248,14 +1240,8 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
 			return 1;
 		}
 	}
-	/**
-	 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
-	 **/
 #ifdef SECURE_NPCTIMEOUT
-	/**
-	 * Update the last NPC iteration
-	 **/
-	sd->npc_idle_tick = gettick();
+	sd->npc_idle_tick = gettick(); //Update the last NPC iteration
 #endif
 
 	/**
@@ -1264,7 +1250,7 @@ int npc_scriptcont(struct map_session_data* sd, int id, bool closing)
 	if( sd->progressbar.npc_id && DIFF_TICK(sd->progressbar.timeout,gettick()) > 0 )
 		return 1;
 
-	if( closing && sd->st->state == CLOSE )
+	if( closing && sd->st && sd->st->state == CLOSE )
 		sd->st->state = END;
 
 	run_script_main(sd->st);
@@ -1290,7 +1276,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
 			sd->npc_id=0;
 		return 1;
 	}
-    if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
+	if (nd->sc.option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?)
 		return 1;
 	if( nd->class_ < 0 && !sd->state.callshop )
 	{// not called through a script and is not a visible NPC so an invalid call

+ 0 - 3
src/map/npc.h

@@ -175,9 +175,6 @@ extern struct npc_data* fake_nd;
 
 int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list);
 
-/**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
 #ifdef SECURE_NPCTIMEOUT
 	int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data);
 #endif

+ 34 - 21
src/map/pc.c

@@ -965,13 +965,9 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
 	sd->invincible_timer = INVALID_TIMER;
 	sd->npc_timer_id = INVALID_TIMER;
 	sd->pvp_timer = INVALID_TIMER;
-	/**
-	 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
-	 **/
+
 #ifdef SECURE_NPCTIMEOUT
-	/**
-	 * Initialize to defaults/expected
-	 **/
+	// Initialize to defaults/expected
 	sd->npc_idle_timer = INVALID_TIMER;
 	sd->npc_idle_tick = tick;
 	sd->npc_idle_type = NPCT_INPUT;
@@ -6569,6 +6565,37 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
 	sd->canlog_tick = gettick();
 }
 
+/*
+ *  Method to properly close npc for player and clear anything related
+ * @flag == 1 : produce close button
+ * @flag == 2 : directly close it
+ */
+void pc_close_npc(struct map_session_data *sd,int flag) {
+	nullpo_retv(sd);
+
+	if (sd->npc_id) {
+		if (sd->state.using_fake_npc) {
+			clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
+			sd->state.using_fake_npc = 0;
+		}
+		if (sd->st) {
+			sd->st->state = (flag==1)?CLOSE:END;
+			sd->st->mes_active = 0;
+		}
+		sd->state.menu_or_input = 0;
+		sd->npc_menu = 0;
+		sd->npc_idle_timer = INVALID_TIMER;
+		clif_scriptclose(sd,sd->npc_id);
+		if(flag==2 && sd->st) {
+			if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
+				script_free_state(sd->st);
+				sd->st = NULL;
+				sd->npc_id = 0;
+			}
+		}
+	}
+}
+
 /*==========================================
  * Invoked when a player has negative current hp
  *------------------------------------------*/
@@ -6620,21 +6647,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 			duel_reject(sd->duel_invite, sd);
 	}
 
-	// Clear anything NPC-related when you die and was interacting with one.
-	if (sd->npc_id) {
-		if (sd->state.using_fake_npc) {
-			clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
-			sd->state.using_fake_npc = 0;
-		}
-		if (sd->state.menu_or_input)
-			sd->state.menu_or_input = 0;
-		if (sd->npc_menu)
-			sd->npc_menu = 0;
-
-		sd->npc_id = 0;
-		if (sd->st && sd->st->state != END)
-			sd->st->state = END;
-	}
+	pc_close_npc(sd,2); //close npc if we were using one
 
 	/* e.g. not killed thru pc_damage */
 	if( pc_issit(sd) ) {

+ 1 - 3
src/map/pc.h

@@ -472,9 +472,6 @@ struct map_session_data {
 	unsigned int bg_id;
 	unsigned short user_font;
 
-	/**
-	 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
-	 **/
 #ifdef SECURE_NPCTIMEOUT
 	/**
 	 * ID of the timer
@@ -720,6 +717,7 @@ int pc_setnewpc(struct map_session_data*,int,int,int,unsigned int,int,int);
 bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers);
 void pc_authfail(struct map_session_data *);
 int pc_reg_received(struct map_session_data *sd);
+void pc_close_npc(struct map_session_data *sd,int flag);
 
 int pc_isequip(struct map_session_data *sd,int n);
 int pc_equippoint(struct map_session_data *sd,int n);

+ 3 - 6
src/map/script.c

@@ -3606,9 +3606,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event)
 			st->bk_st = NULL;
 			st->bk_npcid = 0;
 		} else if(dequeue_event) {
-			/**
-			 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
-			 **/
+
 #ifdef SECURE_NPCTIMEOUT
 			/**
 			 * We're done with this NPC session, so we cancel the timer (if existent) and move on
@@ -3652,9 +3650,6 @@ static void script_attach_state(struct script_state* st)
 		sd->st = st;
 		sd->npc_id = st->oid;
 		sd->npc_item_flag = st->npc_item_flag; // load default.
-/**
- * For the Secure NPC Timeout option (check config/Secure.h) [RR]
- **/
 #ifdef SECURE_NPCTIMEOUT
 		if( sd->npc_idle_timer == INVALID_TIMER )
 			sd->npc_idle_timer = add_timer(gettick() + (SECURE_NPCTIMEOUT_INTERVAL*1000),npc_rr_secure_timeout_timer,sd->bl.id,0);
@@ -6916,6 +6911,7 @@ BUILDIN_FUNC(delitem)
 
 	ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
 	st->state = END;
+	st->mes_active = 0;
 	clif_scriptclose(sd, st->oid);
 	return 1;
 }
@@ -6992,6 +6988,7 @@ BUILDIN_FUNC(delitem2)
 
 	ShowError("script:delitem2: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid);
 	st->state = END;
+	st->mes_active = 0;
 	clif_scriptclose(sd, st->oid);
 	return 1;
 }