Преглед на файлове

Fixed mapserver crash on script command warp (#2766)

Fixes #2765

Thanks to @LunarSHINING
Lemongrass3110 преди 7 години
родител
ревизия
bb0dd7b8dc
променени са 3 файла, в които са добавени 17 реда и са изтрити 5 реда
  1. 2 2
      src/map/npc.cpp
  2. 1 1
      src/map/npc.hpp
  3. 14 2
      src/map/pc.cpp

+ 2 - 2
src/map/npc.cpp

@@ -304,7 +304,7 @@ int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat
 /*==========================================
  * Dequeue event and add timer for execution (100ms)
  *------------------------------------------*/
-int npc_event_dequeue(struct map_session_data* sd)
+int npc_event_dequeue(struct map_session_data* sd,bool free_script_stack)
 {
 	nullpo_ret(sd);
 
@@ -314,7 +314,7 @@ int npc_event_dequeue(struct map_session_data* sd)
 			clif_clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
 			sd->state.using_fake_npc = 0;
 		}
-		if (sd->st) {
+		if (free_script_stack&&sd->st) {
 			script_free_state(sd->st);
 			sd->st = NULL;
 		}

+ 1 - 1
src/map/npc.hpp

@@ -1123,7 +1123,7 @@ enum npce_event : uint8 {
 };
 struct view_data* npc_get_viewdata(int class_);
 int npc_chat_sub(struct block_list* bl, va_list ap);
-int npc_event_dequeue(struct map_session_data* sd);
+int npc_event_dequeue(struct map_session_data* sd,bool free_script_stack=true);
 int npc_event(struct map_session_data* sd, const char* eventname, int ontouch);
 int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y);
 int npc_touch_areanpc2(struct mob_data *md); // [Skotlex]

+ 14 - 2
src/map/pc.cpp

@@ -5524,12 +5524,19 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
 	{
 		uint32 ip;
 		uint16 port;
+		struct script_state *st;
+
 		//if can't find any map-servers, just abort setting position.
 		if(!sd->mapindex || map_mapname2ipport(mapindex,&ip,&port))
 			return SETPOS_NO_MAPSERVER;
 
-		if (sd->npc_id)
-			npc_event_dequeue(sd);
+		if (sd->npc_id){
+			npc_event_dequeue(sd,false);
+			st = sd->st;
+		}else{
+			st = nullptr;
+		}
+
 		npc_script_event(sd, NPCE_LOGOUT);
 		//remove from map, THEN change x/y coordinates
 		unit_remove_map_pc(sd,clrtype);
@@ -5543,6 +5550,11 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in
 		//Free session data from this map server [Kevin]
 		unit_free_pc(sd);
 
+		if( st ){
+			// Has to be done here, because otherwise unit_free_pc will free the stack already
+			st->state = END;
+		}
+
 		return SETPOS_OK;
 	}