View Single Post
  #101  
Old 02-03-2009, 06:31 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

I was able to get Targeting working finally and also able to get names to show up now too. The only other major thing to get working from the spawn structure is size. Most of the rest isn't really required and could be done later at any point. These are a couple of major things that were holding me back from making much more progress, so having those working will help alot to getting the game playable.

The actual process I used to find those settings is a bit of a pain, but seems to actually work fairly well. Basically, I took all of the unknowns in the spawn structure and have been setting each one to send 1s for all fields in them. So, by doing this for each section of unknowns 1 at a time, I can compile the changes and then start the server and log in to observe if there were any differences and what they are.

Here is the actual spawn encoding that I am using to test:

Code:
ENCODE(OP_NewSpawn) {  ENCODE_FORWARD(OP_ZoneSpawns); }
ENCODE(OP_ZoneEntry){  ENCODE_FORWARD(OP_ZoneSpawns); }
ENCODE(OP_ZoneSpawns) {
	//consume the packet
	EQApplicationPacket *in = *p;
	*p = NULL;
	
	//store away the emu struct
	unsigned char *__emu_buffer = in->pBuffer;
	Spawn_Struct *emu = (Spawn_Struct *) __emu_buffer;
	
	//determine and verify length
	int entrycount = in->size / sizeof(Spawn_Struct);
	if(entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
		_log(NET__STRUCTS, "Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
		delete in;
		return;
	}
	
	//make the EQ struct.
	in->size = sizeof(structs::Spawn_Struct)*entrycount;
	in->pBuffer = new unsigned char[in->size];
	structs::Spawn_Struct *eq = (structs::Spawn_Struct *) in->pBuffer;
	
	//zero out the packet. We could avoid this memset by setting all fields (including unknowns)
	//in the loop.
	memset(in->pBuffer, 0, in->size);
	
	//do the transform...
	int r;
	int k;
	for(r = 0; r < entrycount; r++, eq++, emu++) {

		eq->deity = emu->deity;
		eq->gender = emu->gender;
		for(k = 0; k < 9; k++) {
			eq->equipment[k].equip0 = emu->equipment[k];
			eq->equipment[k].equip1 = 0;
			eq->equipment[k].itemId = 0;
			eq->colors[k].color = emu->colors[k].color;
		}
		eq->guildID = emu->guildID;
		eq->class_ = emu->class_;
		eq->gm = emu->gm;
		eq->runspeed = emu->runspeed;
		eq->light = emu->light;
		eq->level = emu->level;
		eq->race = emu->race;
		strcpy(eq->suffix, emu->suffix);
		eq->bodytype = emu->bodytype;
		eq->curHp = emu->curHp;
		strcpy(eq->lastName, emu->lastName);
		strcpy(eq->title, emu->title);
		eq->NPC = emu->NPC;
		eq->x = emu->x;
		eq->deltaX = emu->deltaX;
		eq->deltaY = emu->deltaY;
		eq->z = emu->z;
		eq->deltaHeading = emu->deltaHeading;
		eq->y = emu->y;
		eq->deltaZ = emu->deltaZ;
		eq->animation = emu->animation;
		eq->heading = emu->heading;
		eq->spawnId = emu->spawnId;
		strcpy(eq->name, emu->name);
		eq->petOwnerId = emu->petOwnerId;
		eq->anon = emu->anon;
		eq->walkspeed = emu->walkspeed;

		eq->targetable = 1; //New Field - Force NPCs to Targetable for now
		eq->showname = 1; //New Field - Toggles Name Display on or off - 0 = off, 1 = on
		eq->linkdead = 0; //New Field - Toggles LD on or off after name - 0 = off, 1 = on

		//Hack Test for finding more fields in the Struct:
		memset(eq->unknown0001, 0x01, sizeof(eq->unknown0001));
		memset(eq->unknown0005, 0x01, sizeof(eq->unknown0005)); // 15
		//memset(eq->unknown0008, 0x01, sizeof(eq->unknown0008)); // 13
		//memset(eq->unknown0048, 0x01, sizeof(eq->unknown0048)); // 12 - No Visible Change?
		//eq->unknown0820 = 1;	//Stand State - Stand/Sit/Crouch
		//eq->unknown0059 = 1; // 1 Turned off on 6 - west bug?
		//memset(eq->unknown0074, 0x01, sizeof(eq->unknown0074)); // 16 - No Visible Change?
		//memset(eq->unknown0077, 0x01, sizeof(eq->unknown0077));
		//memset(eq->unknown0079, 0x01, sizeof(eq->unknown0079));
		//memset(eq->unknown0106, 0x01, sizeof(eq->unknown0106)); // 11 - No Visible Change?
		//memset(eq->unknown0107, 0x01, sizeof(eq->unknown0107));
		//memset(eq->unknown0110, 0x01, sizeof(eq->unknown0110));
		//eq->unknown0111 = 1; // 1 - No Visible Change?
		//eq->unknown0613 = 0; //was bodytype
		//memset(eq->unknown0154, 0x01, sizeof(eq->unknown0154)); // 2 - freeze in place?
		//memset(eq->unknown0263, 0x01, sizeof(eq->unknown0263)); // 1 - no player character visible?
		//memset(eq->unknown0281, 0x01, sizeof(eq->unknown0281)); // 2 3
		//eq->unknown0307 = 1; // 9 10 11 - No Visible Change?
		//memset(eq->unknown0308, 0x01, sizeof(eq->unknown0308)); //
		//memset(eq->unknown0309, 0x01, sizeof(eq->unknown0309)); // 8 - No Visible Change?
		//memset(eq->unknown442, 0x01, sizeof(eq->unknown442)); // 6 - crash?
		//eq->unknown443 = 1; // 1 turned off on 9 - No Visible Change?
		//memset(eq->unknown0760, 0x01, sizeof(eq->unknown0760)); // 4 avatar height?
		//eq->unknown0779 = 0; // 1 - int32 avatar height?
		//memset(eq->unknown0496, 0x01, sizeof(eq->unknown0496)); // 4 5

		// 1 all set to one shows you at floor level
		// 2 seems to cause invis and freeze in place and west bug
		// 3 causes no player character, but spawns work and has west bug
		// 4 looks just like 2 accept you can move and are at floor level
		// 5 Looks like 3
		// 6 Caused a crash
		// 7 west bug gone 
		// 8 Looks normal accept no player character
		// 9 Targetable mobs!!! Still no player character...
		// 10 Narrowing down bodytype
		// 11 Non-targetable again and narrowing down bodytype
		// 12 Bodytype location identified!!!  Targeting works...  Nother other visible changes
		// 13 Can target self but not spawns.  West bug again
		// 14 Names showing and also LD showing!!!  Still West Bug though...
		// 15 Show Names field now identified.  

	}
	
	
	//kill off the emu structure and send the eq packet.
	delete[] __emu_buffer;
	
	_log(NET__ERROR, "Sending zone spawns");
	_hex(NET__ERROR, in->pBuffer, in->size);
	
	dest->FastQueuePacket(&in, ack_req);
}
The section noted in blue are the new fields I found and am forcing them to send all spawns with a certain setting in that field. The section noted in green are the actual settings to test the unknown fields. I just uncomment the line of the unknown section I want to test. There are some notes next to some of them as to what I noticed when testing them. There are also numbers next to some as well, which correspond to the section in orange below that. Basically, I tried picking the unknowns that were smallest first. I was doing more than 1 at a time to reduce the number of times I would have to recompile. The numbers tell which ones I turned on for each test number I ran. So, the ones that have 1 next to them were the first ones I tried and the notes in orange below are what I saw as a result from that first test. The notes could have been done better, but at least it was something to reference to help keep track of what was being done and being seen.

The reason I am doing a little write-up on how I did this is so others may be able to use the same technique in the future to help refine the structures even further. Other than being able to figure out the structure from reading the IDA output, which is well above my skill level, this guess and test technique is the only other way I could think of to figure out these needed structure fields.

The same technique should be able to work fine for figuring out the rest of the fields. I think it should be fairly easy to figure out stuff like beard and beard color, face, etc with this technique. So, almost anyone could help refine this list of field positions in the structure.

I will most likely be doing a write-up wiki page on what I know about working with packet structures. It really isn't all too complex, but it is important to understand a few key things that took me a while to figure out on my own.

I will probably do an SVN update with the new targeting and name stuff tonight, or very soon. It is finally getting to the point where it is almost playable. I think getting items working is probably one of the biggest things left to do. I have the item structure worked out, but may need help in finding the best way to implement it.

I was finally able to try attacking a mob for the first time in SoF, and of course it caused EQ to crash :P I am pretty sure the crash was due to the fact that items hadn't been loaded though.

For a while, I was a bit concerned that we would never be able to get SoF functioning well enough to actually use as an upgrade to Titanium. Now, I am fairly confident that all possible issues can be resolved and that it will almost certainly be completed and at least as functional as Titanium is now. It is all really just a matter of time and work. I am really hoping that once I have the game somewhat playable and most systems functioning, that others will start assisting in the project. I know most people think this stuff is well beyond their skill level, but if I can learn it, most people with technical skill can as well. And, I think that if I write a couple of wiki pages to help people understand what to do, it will make a huge difference in who can start helping.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote