PenUltima Online Forum Index Official Core: 096.7
Official Core: 097 2008-02-26
Donate towards the POL web hosting bill!
 POL Home   FAQ   Search    Memberlist   Usergroups    Register    Profile   Log in to check your private messages   Log in
Party System
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    PenUltima Online Forum Index -> Custom Script Releases
Display posts from previous:   

Author Message
OldnGrey



Joined: 04 Feb 2006
Posts: 517

PostPosted: Wed Jan 23, 2008 9:06 am    Post subject: Reply with quote

There is one bug in this that annoyed me until I finally did something about it.
It was when a shard initiated a shutdown and forced the players to logoff.
The shard would save and then start a shutdown. It would then bring up an exception if there was someone in a party.

I think the exception is caused by the PartySystem\logoff.src trying to Start_Script during a shutdown.

The fix is easy enough though:
Add 3 lines to the start of PartySystem\logoff.src
Code:
if ( GetGlobalProperty("#restartingserver") )
   return 0;
endif


In your shard restart or shutdown timer script, simply set the #restartingserver global property. I do it 5 minutes before the actual shutdown. I also use the gprop to stop decay of items and corpses.

Author Message
OldnGrey



Joined: 04 Feb 2006
Posts: 517

PostPosted: Tue Jan 29, 2008 10:14 pm    Post subject: Reply with quote

There is still one other bug that spams the console from the party system.

doPlayerStatus.ecl exceeded maximum call depth.
Return path PCs: 12 12 12 12 ......etc

Since the party is only 3 people I doubt it's anything to do with overload. It still seems to work fine in the game though.

Anyone any ideas?

This is the entire packethook. It's very simple and isn't recursive.
Code:
const DEBUG := 0;
const OFFSET_UPDATE_STAT_PLAYERID := 1;
const PARTY_PROP := "#Party";
const PARTY_STATUS_UPDATE_DISTANCE := 19;

exported function handleUpdateStat(character, byref packet)
   // Sending the stat packet will cause the core to want to handle THAT packet as well
   // So if we are sending stat packets out, ignore the packet as it is probably being
   // sent by this script.
   if ( sending_stat )
      sending_stat := 0;
      return 0;
   endif
   
   var id := packet.GetInt32(OFFSET_UPDATE_STAT_PLAYERID);
   var party := GetObjProperty(character, PARTY_PROP);

   if ( DEBUG )
      Print("handleUpdateStat - character: "+character.name+"   packet: "+packet);
   endif

   // Is the character in a party?
   if ( Lower(TypeOf(party)) == "array" )
      var member;

      foreach member_id in (party)         
         // Do not send modified packet to character since they are already getting one
         if ( member_id != id )
            member := SystemFindObjectBySerial(member_id);
            
            // Only send this packet if the party member is close enough to the character
            if ( member && Distance(member, character) <= PARTY_STATUS_UPDATE_DISTANCE )
               sending_stat := 1;
               packet.SendPacket(member);
            endif
         endif
         SleepMS(2);
      endforeach
   endif

   return 0;
endfunction

Author Message
Xpatriat



Joined: 04 Aug 2007
Posts: 7

PostPosted: Wed Jan 30, 2008 1:08 pm    Post subject: Reply with quote

You should do some simple packet capturing, because this looks recursive to me. This is the reason:
Code:

sending_stat :=1;
packet.SendPacket(member);


You're sending the same packet back out, which causes the same packet hook to again be called - and they work critical. If it weren't for the maximum call depth thing, this packet hook would freeze your shard.

With a party of two, you won't get your error because of the code at the top that checks for the sending_stat global var:

Code:

   // sent by this script.
   if ( sending_stat )
      sending_stat := 0;
      return 0;
   endif


But look closer: That code also sets sending_stat back to 0. So with the third and subsequent player, the packet hook WILL run again, causing recursion that only ends when the maximum call depth is exceeded.

Packet hooks run critical, in a single 'process'. Check the script profiles some time and you'll see that only one copy of doPlayerStatus.ecl is ever executed.

Author Message
OldnGrey



Joined: 04 Feb 2006
Posts: 517

PostPosted: Wed Jan 30, 2008 7:49 pm    Post subject: Reply with quote

What you say makes a lot of sense, but I must admit I still don't quite get it. Does packet.SendpPacket go through the packet hook all over again or just get sent out?

If what I read is correct, a sendpacket packethook should simply return 0 if the core is allowed to send it and not have it's own sendpacket. But I guess what the hook is trying to do is create an extra packet to ensure that all the party status bars are onscreen.

Now to solutions:
It occurs to me that the v5 and above client automatically keep a status bar open but greys it out while you are out of range of the player. Therefore the only reason to want this packethook at all is to initiate a status bar for all party members. So maybe we can simply create a single packet when you join a guild. TekProxy wrote this and would have a better idea about how it all hangs together.

However, not all shards use the v5 client, so that may not be enough as older clients drop the status gump when you are out of range.

Post new topic   Reply to topic    PenUltima Online Forum Index -> Custom Script Releases All times are GMT - 4 Hours
Goto page Previous  1, 2, 3
Page 3 of 3

 




Powered by phpBB © 2001, 2005 phpBB Group :: Theme & Graphics by GHS & Scott E. Royalty