EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Bug Reports (https://www.eqemulator.org/forums/forumdisplay.php?f=591)
-   -   Memming Spell Sets: bug and fix (https://www.eqemulator.org/forums/showthread.php?t=21882)

number6 11-12-2006 11:44 PM

Memming Spell Sets: bug and fix
 
At the moment, if you have no memmed spells at all, then loading a spell set from the client UI works. But, it doesn't un-mem spells first. I've added code for OP_LoadSpellSet to simply unmem all spells first, and it works. It seems the client deals with handling the sequential memming of the spells, presumably so the user can interrupt it, so that turned out to be an easy one. It works fine for me with the titanium client, can't test with any other.

** edit: It's been pointed out by one of my players that this still doesn't quite mimic "live" behaviour, which apparently only un-mems spells that are about to change, thus speeding things up. Sorry - but I think this is a reasonable halfway house, I don't know how to parse the contents of the EQApplicationPacket.

Cheers, Paul.

*** ../../EQEmu-0.7.0-903/zone/client_packet.h 2006-08-15 02:18:33.000000000 +0100
--- client_packet.h 2006-11-13 11:17:23.000000000 +0000
***************
*** 207,210 ****
--- 207,211 ----
void Handle_OP_RequestTitles(const EQApplicationPacket *app);
void Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app);
void Handle_OP_Ignore(const EQApplicationPacket *app);
+ void Handle_OP_LoadSpellSet(const EQApplicationPacket *app);

*** ../../EQEmu-0.7.0-903/zone/client_packet.cpp 2006-10-31 03:04:23.000000000 +0000
--- client_packet.cpp 2006-11-13 11:24:08.000000000 +0000
***************
*** 307,312 ****
--- 307,313 ----
ConnectedOpcodes[OP_SenseHeading] = &Client::Handle_OP_Ignore;
ConnectedOpcodes[OP_FloatListThing] = &Client::Handle_OP_Ignore;
ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
+ ConnectedOpcodes[OP_LoadSpellSet] = &Client::Handle_OP_LoadSpellSet;

}

***************
*** 4393,4398 ****
--- 4394,4406 ----
return;
}

+ void Client::Handle_OP_LoadSpellSet(const EQApplicationPacket *app)
+ {
+ Client::UnmemSpellAll(true);
+ return;
+ }
+
+
void Client::Handle_OP_PetitionBug(const EQApplicationPacket *app)
{
if(app->size!=sizeof(PetitionBug_Struct))

number6 11-13-2006 11:03 PM

Did more testing and there's an issue. If you have a spell in, say slot 1 in spellset 1 and spellset 2 has the same spell in the same slot, the client does not attempt to re-mem it when switching. What this means is that I think the client is sending over info about what it meant to be un-memmed in the EQApplicationPacket.

I will work on this and try to decode the packet and make this work properly. Apologies :) Does anyone have any magic ways to decode EQAppicationPacket? If not I'll just dump them out to hex and scratch my head a bit!

Paul.

number6 11-14-2006 05:15 AM

I worked it out. Here's the "real" patch; it deals with only unmemming the spells you need to remove, and everything appears to work perfectly. I will go and have a lie-down now :)

Paul.

Code:

*** ../../EQEmu-0.7.0-903/zone/client_packet.cpp        2006-10-31 03:04:23.000000000 +0000
--- client_packet.cpp  2006-11-14 16:59:45.000000000 +0000
***************
*** 307,312 ****
--- 307,313 ----
        ConnectedOpcodes[OP_SenseHeading] = &Client::Handle_OP_Ignore;
        ConnectedOpcodes[OP_FloatListThing] = &Client::Handle_OP_Ignore;
        ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
+      ConnectedOpcodes[OP_LoadSpellSet] = &Client::Handle_OP_LoadSpellSet;

  }

***************
*** 4393,4398 ****
--- 4394,4414 ----
        return;
  }

+ void Client::Handle_OP_LoadSpellSet(const EQApplicationPacket *app)
+ {
+      if(app->size!=sizeof(LoadSpellSet_Struct))
+              printf("Wrong size of LoadSpellSet_Struct! Expected: %i, Got: %i\n",sizeof(LoadSpellSet_Struct),app->size);
+      else {
+              int i;
+              LoadSpellSet_Struct* set=(LoadSpellSet_Struct*)app->pBuffer;
+              for(i=0;i<MAX_PP_MEMSPELL;i++) {
+                      if (set->spell[i] != 0xFFFFFFFF) UnmemSpell(i,true);
+              }
+      }
+      return;
+ }
+
+
  void Client::Handle_OP_PetitionBug(const EQApplicationPacket *app)
  {
        if(app->size!=sizeof(PetitionBug_Struct))

*** ../../EQEmu-0.7.0-903/zone/client_packet.h  2006-08-15 02:18:33.000000000 +0100
--- client_packet.h    2006-11-13 11:17:23.000000000 +0000
***************
*** 207,210 ****
--- 207,211 ----
        void Handle_OP_RequestTitles(const EQApplicationPacket *app);
        void Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app);
        void Handle_OP_Ignore(const EQApplicationPacket *app);
+      void Handle_OP_LoadSpellSet(const EQApplicationPacket *app);

*** ../../EQEmu-0.7.0-903/common/eq_packet_structs.h    2006-10-22 21:12:38.000000000 +0100
--- eq_packet_structs.h 2006-11-14 16:42:48.000000000 +0000
***************
*** 3178,3183 ****
--- 3178,3187 ----
        uint32  value;          //always 4
  };

+ struct LoadSpellSet_Struct {
+      uint32  spell[10];      // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
+ };
+
  //old structures live here:
  #include "eq_old_structs.h"


John Adams 11-14-2006 11:17 AM

Quote:

Originally Posted by number6
I will go and have a lie-down now :)

lol, knocks the wind out of ya, eh?

Thanks for your diligence!

fathernitwit 11-24-2006 05:59 AM

good work. I'll get this put in.

number6 11-29-2006 04:16 AM

There's a mistake in the current CVS code related to my spell set patch which I guess has crept in when you tidied things up. I originally had, in common/eq_packet_structs.h, this:

Code:

struct LoadSpellSet_Struct {
      uint32  spell[10];      // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
};

but you have it as
Code:

struct LoadSpellSet_Struct {
      uint32  spell[MAX_PP_MEMSPELL];      // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
};

The client actually sends back 10 spell entries to the server, even though the client actually crashes if it is asked by the server to manipulate the 10th slot. In the current source you've changed MAX_PP_MEMSPELL to 10. I've fixed it on my server by having the for loop run through to MAX_PP_MEMSPELL-1. I originally tried setting MAX_PP_MEMSPELL back to 9 but this had strange effects (the client was not seeing my characters at login).

Paul.

John Adams 11-29-2006 07:18 AM

Is he using MAX_PP_MEMSPELL because you normally only get 8 slots unless you spend the AA to get 9?

Therefore, it cannot be hardcoded to 0-9 (or 10)? Or does the client get them all regardless of what you can use?

number6 11-29-2006 08:42 PM

MAX_PP_MEMSPELL is a constant in the server code and reflects the number of spell slots the server is prepared to support. It's separate to the question of whether the character currently in use has 8 or 9 active slots.

The issue is that when the client does a LoadSpellSet, it sends across a data packet containing information for 10 spells. But, if the server sends back a SpellUnmem request for the 10th slot, the client crashes out. It seems to me that whoever programmed the client decided to put a hard max of 10 on the packet structure for LoadSpellSet but didn't manage to code it to ignore any requests for spell un-memming in slots that the client doesn't actually handle. If the client receives requests for the 9th slot and that isn't enabled, then it just ignores the request - this is sensible, but sadly not done for the 10th slot :)

So, in a nutshell, we have to forcibly prevent LoadSpellSet from sending back data out of range of slots 0-8 otherwise the titanium client crashes. Do other versions of the client act differently? I don't know. Perhaps the "correct" solution is to allow configuring of the maximum number of spell slots in the patch file for each client version.

Paul.

bufferofnewbies 11-29-2006 08:46 PM

Ahh, I was wondering why I was crashing to desktop everytime I tried to load a spell set that worked yesterday. I really need to read all the forums more often...

fathernitwit 11-30-2006 04:33 PM

MAX_PP_MEMSPELLS was changed to 10. Further, its unlikely that a packet which is only sent TO the server with no reply would cause the client to crash.

number6 11-30-2006 10:08 PM

I assure you that if you do an "UnmemSpell(9, true);" the client crashes.


All times are GMT -4. The time now is 05:48 AM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.