Browse Source

- Fixed floating shops being accessible from any location through 3rd party programs
- TODO: needs amending for the walking glitch (bugreport:5016)

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

epoque11 13 years ago
parent
commit
18a6fb23bf
4 changed files with 15 additions and 1 deletions
  1. 3 0
      src/map/clif.c
  2. 8 1
      src/map/npc.c
  3. 1 0
      src/map/pc.h
  4. 3 0
      src/map/script.c

+ 3 - 0
src/map/clif.c

@@ -8671,6 +8671,9 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 		instance_check_idle(map[sd->bl.m].instance_id);
 	}
 	sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
+	
+	// reset the callshop flag if the player changes map
+	sd->state.callshop = 0;
 
 	map_addblock(&sd->bl);
 	clif_spawn(&sd->bl);

+ 8 - 1
src/map/npc.c

@@ -1174,8 +1174,15 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type)
 	}
 	if (nd->sc.option&OPTION_INVISIBLE)	// –³Œø‰»‚³‚ê‚Ä‚¢‚é
 		return 1;
+	if( nd->class_ < 0 && !sd->state.callshop )
+	{// not called through a script and is not a visible NPC so an invalid call
+		return 1;
+	}
+
+	// reset the callshop state for future calls
+	sd->state.callshop = 0;
+	sd->npc_shopid = id;
 
-	sd->npc_shopid=id;
 	if (type==0) {
 		clif_buylist(sd,nd);
 	} else {

+ 1 - 0
src/map/pc.h

@@ -135,6 +135,7 @@ struct map_session_data {
 		unsigned int vending : 1;
 		unsigned int noks : 3; // [Zeph Kill Steal Protection]
 		unsigned int changemap : 1;
+		unsigned int callshop : 1; // flag to indicate that a script used callshop; on a shop
 		short pmap; // Previous map on Map Change
 		unsigned short autoloot;
 		unsigned short autolootid; // [Zephyrus]

+ 3 - 0
src/map/script.c

@@ -13816,6 +13816,9 @@ BUILDIN_FUNC(callshop)
 	
 	if( nd->subtype == SHOP )
 	{
+		// flag the user as using a valid script call for opening the shop (for floating NPCs)
+		sd->state.callshop = 1;
+
 		switch( flag )
 		{
 			case 1: npc_buysellsel(sd,nd->bl.id,0); break; //Buy window