Page 1 of 2

Optional change to CharInfo routine...

Posted: Wed Apr 16, 2003 10:49 pm
by NealThorpayt
Greetings Constructs,

As there has been issues with the CharInfo routine, I thought I would post my current code. My code has removed the item database updating functionality from /charinfo. I have added a new command /udpateitems.

Replace CharInfo function in EQLib.cpp as follows:

Code: Select all

VOID CharInfo(PSPAWNINFO pChar, PCHAR szLine)
{
	CHAR szBuffer[MAX_STRING] = {0};
	bRunNextCommand = TRUE;

	if (gFilterMacro == FILTERMACRO_NONE) cmdCharInfo(pChar, szLine);
	PCHARINFO pCharInfo = NULL;
	if (NULL == (pCharInfo = GetCharInfo())) return;		
	sprintf(szBuffer,"You are bound in %s at %1.2f, %1.2f, %1.2f", GetFullZone(pCharInfo->ZoneBoundId), pCharInfo->ZoneBoundX, pCharInfo->ZoneBoundY, pCharInfo->ZoneBoundZ);
	WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
	sprintf(szBuffer,"You were born in %s at %1.2f, %1.2f, %1.2f", GetFullZone(pCharInfo->ZoneBirthId), pCharInfo->ZoneBirthX, pCharInfo->ZoneBirthY, pCharInfo->ZoneBirthZ);
	WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
}
Add the following to TakeControlOfCommandList in EQLib.cpp:

Code: Select all

		{"/updateitems", "UpdateItemInfo"},
before the line

Code: Select all

		{NULL,			NULL}
Add the following as a new function to EQLib.cpp:

Code: Select all

VOID UpdateItemInfo(PSPAWNINFO pChar, PCHAR szLine) {
	CHAR szBuffer[MAX_STRING] = {0};

	PCHARINFO pCharInfo = NULL;
	if (NULL == (pCharInfo = GetCharInfo())) return;		

	for (int nInvIdx=0; nInvIdx < 30; nInvIdx++) {
		if (pCharInfo->Inventory[nInvIdx] != NULL) {
			BOOL Found = FALSE;
			PITEMDB ItemDB = gItemDB;
			while (ItemDB) {
				if (ItemDB->ID == pCharInfo->Inventory[nInvIdx]->ItemNumber) {
					Found = TRUE;
				}
				ItemDB = ItemDB->pNext;
			}
			if (!Found) {
				PITEMDB Item = (PITEMDB)malloc(sizeof(ITEMDB));
				Item->pNext = gItemDB;
				Item->ID = pCharInfo->Inventory[nInvIdx]->ItemNumber;
				strcpy(Item->szName, pCharInfo->Inventory[nInvIdx]->Name);
				DebugSpew("   New Item found - %d: %s", Item->ID, Item->szName);
				gItemDB = Item;
			}
			if (pCharInfo->Inventory[nInvIdx]->Type == ITEMTYPE_PACK) {
				DebugSpew("   Opening Pack");
				for (int nPackIdx = 0; nPackIdx < pCharInfo->Inventory[nInvIdx]->Container.Slots; nPackIdx++) {
					if (pCharInfo->Inventory[nInvIdx]->Container.Contents[nPackIdx] != NULL) {
						Found = FALSE;
						PITEMDB ItemDB = gItemDB;
						while (ItemDB) {
							if (ItemDB->ID == pCharInfo->Inventory[nInvIdx]->Container.Contents[nPackIdx]->ItemNumber) {
								Found = TRUE;
							}
							ItemDB = ItemDB->pNext;
						}
						if (!Found) {
							PITEMDB Item = (PITEMDB)malloc(sizeof(ITEMDB));
							Item->pNext = gItemDB;
							Item->ID = pCharInfo->Inventory[nInvIdx]->Container.Contents[nPackIdx]->ItemNumber;
							strcpy(Item->szName, pCharInfo->Inventory[nInvIdx]->Container.Contents[nPackIdx]->Name);
							DebugSpew("      New Item found - %d: %s", Item->ID, Item->szName);
							gItemDB = Item;
						}
					}
				}
			}
		}
	}

	for (nInvIdx=0; nInvIdx < NUM_BANK_SLOTS; nInvIdx++) {
		if (pCharInfo->Bank[nInvIdx] != NULL) {
			BOOL Found = FALSE;
			PITEMDB ItemDB = gItemDB;
			while (ItemDB) {
				if (ItemDB->ID == pCharInfo->Bank[nInvIdx]->ItemNumber) {
					Found = TRUE;
				}
				ItemDB = ItemDB->pNext;
			}
			if (!Found) {
				PITEMDB Item = (PITEMDB)malloc(sizeof(ITEMDB));
				Item->pNext = gItemDB;
				Item->ID = pCharInfo->Bank[nInvIdx]->ItemNumber;
				strcpy(Item->szName, pCharInfo->Bank[nInvIdx]->Name);
				DebugSpew("   New Item found - %d: %s", Item->ID, Item->szName);
				gItemDB = Item;
			}
			if (pCharInfo->Bank[nInvIdx]->Type == ITEMTYPE_PACK) {
				LONG nPackIdx;
				for (nPackIdx = 0; nPackIdx < pCharInfo->Bank[nInvIdx]->Container.Slots; nPackIdx++) {
					if (pCharInfo->Bank[nInvIdx]->Container.Contents[nPackIdx] != NULL) {
						PITEMDB ItemDB = gItemDB;
						Found = FALSE;
						while (ItemDB) {
							if (ItemDB->ID == pCharInfo->Bank[nInvIdx]->Container.Contents[nPackIdx]->ItemNumber) {
								Found = TRUE;
							}
							ItemDB = ItemDB->pNext;
						}
						if (!Found) {
							PITEMDB Item = (PITEMDB)malloc(sizeof(ITEMDB));
							Item->pNext = gItemDB;
							Item->ID = pCharInfo->Bank[nInvIdx]->Container.Contents[nPackIdx]->ItemNumber;
							strcpy(Item->szName, pCharInfo->Bank[nInvIdx]->Container.Contents[nPackIdx]->Name);
							DebugSpew("      New Item found - %d: %s", Item->ID, Item->szName);
							gItemDB = Item;
						}
					}
				}
			}
		}
	}

	PITEMDB ItemDB = gItemDB;
	if (ItemDB) {
		FILE *fDB = fopen(gszItemDB, "wt");
		while (ItemDB) {
			sprintf(szBuffer, "%d\t%s\n", ItemDB->ID, ItemDB->szName);
			fputs(szBuffer, fDB);
			ItemDB = ItemDB->pNext;
		}
		fclose(fDB);
	}
}
And finally, add the following to MQ.h:

Code: Select all

extern "C" EQLIB_API VOID	UpdateItemInfo	(PSPAWNINFO, PCHAR);
End of line...

Posted: Wed Apr 16, 2003 11:53 pm
by L124RD
Salutations,
NT, we love you...
DKAA: Make sure this goes to CVS (provided when you install it it works, no offense to your skills NT)

Posted: Thu Apr 17, 2003 3:08 am
by Amadeus
hmm...don't you also have to add

Code: Select all

		{ "/updateitems", CMD_MQ },
to DetermineWhoFirst()?

Posted: Thu Apr 17, 2003 3:27 am
by Clawed
hmm...don't you also have to add

Code: Select all

{ "/updateitems", CMD_MQ },


You didn't used to, as far as I know. But you do now. Otherwise MQ defaults it to the EQ parser... which yields "Not a command"

Posted: Thu Apr 17, 2003 4:40 am
by dont_know_at_all
Verified and checked in with one change:

Code: Select all

   for (nInvIdx=0; nInvIdx < NUM_BANK_SLOTS; nInvIdx++) {
      if ((pCharInfo->Bank[nInvIdx] != NULL) &&
          [b](pCharInfo->Bank[nInvIdx] != (PITEMINFO)1)) {[/b]
         BOOL Found = FALSE;
         PITEMDB ItemDB = gItemDB;
I have a class-specific, newbie armor quest assembly kit in the bank (10 huge slots). It shows up in the bank inventory for my character as the value 0x1.

So, I suppose there can be other flags in bank slots -- a potential crash to desktop.

To answer the question about the CMD_MQ entry: if you are filtering macros, like you should be, then the regular command processor is called first. The macro output is then funneled to the telnet server output. If the regular command process is called, you get the "not a command message" if the command has not been injected in the parser list.

Posted: Thu Apr 17, 2003 9:17 am
by Clawed
Not filtering macros. Some commands still get filtered to EQ client first instead of to MQ. I'm probably just missing something, I'll try to test it more.

Posted: Thu Apr 17, 2003 3:37 pm
by NealThorpayt
Greetings Constructs,

DKAA, can you post the specific newbie class specific container you were talking about, and where to get it. I would like to do some more investigation into that item.

End of line...

Posted: Thu Apr 17, 2003 4:35 pm
by dont_know_at_all
Songweavers Assembly Kit:
http://everquest.allakhazam.com/db/ques ... quest=1831

There are lots of other armor kits that I assume do the same thing.

Magical Mail Assembly Kit
http://everquest.allakhazam.com/db/ques ... quest=1694

Posted: Thu Apr 17, 2003 9:31 pm
by NealThorpayt
Greetings Constructs,

I am completely baffled by this. After DKAA posted his find that his assembly kit had an address of 1 in his bank slots, I began to wonder if this had something to do with mckorr's similar problems with the old /charinfo routine. Unfortunately I can not confirm DKAA's finding. I have created 4 new characters and gotten the newbie assembly kits for them (including both posted by DKAA). In all cases the address in either my inventory slots or bank slots were valid DWORD PTRs. It does not make sense that the code would have an indexed value such as 1 for an address pointer.

For further clarification--
* my base install of EQ came from the Everquest Gold package.
* I have all expansions including LoY.
* I am running a PIV with 512MB and WindowsXP Pro.

It would be helpfull if others would attempt to either confirm or deny these findings.

End of line...

Posted: Thu Apr 17, 2003 10:07 pm
by dont_know_at_all
One other tidbit of information: I completed all the armor quests.

I have the Vel, Kur, Luc, and LoY but not PoP.
PIV, 256, W2k.

I believe I have another char, a cleric, that completed all the armor quests but I don't think I still have the kit.

Posted: Thu Apr 17, 2003 10:13 pm
by NealThorpayt
Greetings Constructs,

I checked with one of my main characters who completed a set of armor quests and still had his assembly kit. The kit shows as a valid pointer in both bank and inventory.

I wonder if PoP is the issue. Hopefully mckorr will chime in with more information.

End of line...

Posted: Thu Apr 17, 2003 10:28 pm
by dont_know_at_all
The only other data point is that it was the last bank slot in memory but the first (top left) in my bank. Three bank slot were empty.

Tonight will dump more data.

Posted: Fri Apr 18, 2003 3:43 am
by dont_know_at_all
The bank slot offset is four bytes too high.

The first slot, where the kit is, is offset -1.

The 0x1 is one DWORD past the last bank slot.

I can't imagine you missed this -- does charinfo vary with the PoP expansion?

Posted: Fri Apr 18, 2003 4:09 am
by NealThorpayt
Greetings Constructs,

Well, I was wondering that myself. If mckorr logs on and checks this thread, maybe we will be able to confirm or deny that assumption.

One thought that I had, that I have yet been able to confirm, is that the bank information is not really at the end of the _CHARINFO struct. And, is in fact a seperate and individual structure pointed to by some other address. This would be the most plausible explanation for any discrepenies in our addressess.

I will look into this further, now that you have confirmed that the offset is different for you.

Thanks for the good work.

End of line...

Posted: Fri Apr 18, 2003 4:14 am
by NealThorpayt
Greetings Constructs,

DKAA, did you get a chance to check your _ZONELIST structure again. This might be a related issue (to PoP). Mine is definetly 129 characters for SmallName.

End of line...