Analysis of the "create ghost" command, aka Spawn

EQ2Emulator Development forum.

Moderator: Team Members

Post Reply
skandragon
Posts: 27
Joined: Tue Jan 15, 2008 11:24 pm
Location: Oklahoma
Contact:

Analysis of the "create ghost" command, aka Spawn

Post by skandragon » Fri Jan 18, 2008 10:25 pm

After a bit of digging, I've found what the world structure file calls "unknown4", which is an 8-bit quantity does. It is the number of commands which will appear in the pop-up window, it seems.
Currently, here is the spawn header structure from the WorldStructs.xml file:

Code: Select all

  <Struct Name="WS_SpawnStruct_Header" ClientVersion="1">
    <Data ElementName="index" Type="int8" Size="1"/>
    <Data ElementName="spawn_id" Type="int32" Size="1"/>
    <Data ElementName="unknown" Type="int16" Size="1"/>
    <Data ElementName="unknown2" Type="int32" Size="1"/>
    <Data ElementName="unknown3" Type="float" Size="1"/>
    <Data ElementName="unknown4" Type="int8" Size="1"/>
    <Data ElementName="default_command" Type="EQ2_16Bit_String" Size="1"/>
    <Data ElementName="max_distance" Type="float" Size="1"/>
    <Data ElementName="group_size" Type="int8" Size="1"/>
    <Data ElementName="group_array" Type="Array" ArraySizeVariable="group_size">
      <Data ElementName="group_spawn_id" Type="int32"/>
    </Data>
    <Data ElementName="unknown6" Type="int32" Size="1"/>
  </Struct>
I am not certain unknown3 is a float because of its sometimes out of bound values.
Unknown4 is a "command count", which indicates the number of commands a ghost has. Each command has a max_distance, and is stored as two strings. I suspect this is where the language translation comes into play -- I am betting one of the strings is "send this to the server" and the other is "display this to the user."
Here is an example:

Code: Select all

2b Index
9c ef 3e 00 spawn_id
ff ff Unknown<16>
00 00 00 00 Unknown<32>
d7 b7 c8 a1 Unknown<16>
04 num_cmds
0e 00 62 75 72 6e 69 6e 67 20 65 6d 62 65 72 73 <15>burning embers
00 00 a0 40 max_distance
00 00 Unknown<16>
0e 00 62 75 72 6e 69 6e 67 20 65 6d 62 65 72 73 <15>burning embers
07 00 70 75 74 20 6f 75 74 <7>put out
00 00 a0 40 max_distance
00 00 Unknown<16>
07 00 70 75 74 20 6f 75 74 <7>put out
0c 00 72 6f 61 72 69 6e 67 20 66 69 72 65 <12>roaring fire
00 00 a0 40 max_distance
00 00 Unknown<16>
0c 00 72 6f 61 72 69 6e 67 20 66 69 72 65 <12>roaring fire
09 00 77 61 72 6d 20 66 69 72 65 <9>warm fire
00 00 a0 40 max_distance
00 00 Unknown<16>
09 00 77 61 72 6d 20 66 69 72 65 <9>warm fire
09 00 77 61 72 6d 20 66 69 72 65 <9>warm fire
00 00 a0 40 max_distance
00 1b 09 4d 90
46 00 00 00 (70 bytes of zero-suppressed data follow)
ff 3e 5a 9c ... 7f 7f 7f 13 (zero-suppressed data)
14 00 4e 61 74 75 72 61 ... 65 61 72 74 68 <20>Natural Stone Hearth
00 00 00 00 00 00 00 00 Unknown<32*2>
00 Unknown<8>
00 00 <0>
00 Unknown<8>
I don't know what the 00 00 bytes are after each distance. They might have something to do with the individual objects in a spawn. I will have to analyze this further.
After the commands comes the default command's length<16> and string, its max_distance, and then 5 unknown values.
Next is a zero-suppressed "Substruct_SpawnVisualizationInfoStruct" structure. I've not started looking into this just yet.
Then follows the "footer" portion, as far as I can tell exactly as it should be.
Interesting to note is that some of the ghosts have a default command but no command list. This seems normal. Some have a default command and a list of 2 or more commands. Once again, normal. However, some have only one command listed, which is identical to the default command. I wonder why...

Diamente
Retired
Posts: 45
Joined: Mon Jul 30, 2007 7:49 am
Location: Oklahoma

Post by Diamente » Fri Jan 18, 2008 10:29 pm

Hmm...I wonder if the default command would be a Hail? That's the only thing that pops into my very tired mind at the moment as a universal verb for any spawn.

skandragon
Posts: 27
Joined: Tue Jan 15, 2008 11:24 pm
Location: Oklahoma
Contact:

Post by skandragon » Fri Jan 18, 2008 10:53 pm

Some have "hail" as the only command (that is, the default.) Some have "attack" as a rather common one.
Oddly enough, bankers show up with NO commands. I suspect there is a flag that says "use this command group" or "is a banker" and the client just knows how to make a banker work.

LethalEncounter
Team: Zombie
Posts: 2717
Joined: Wed Jul 25, 2007 10:10 pm

Post by LethalEncounter » Sat Jan 19, 2008 8:18 am

You must have an old version of WorldStructs.xml, the current WS_SpawnStruct_Header is:

Code: Select all

<Struct Name="WS_SpawnStruct_Header" ClientVersion="1">
<Data ElementName="index" Type="int16" Size="1" OversizedValue="255" />
<Data ElementName="spawn_id" Type="int32" Size="1" />
<Data ElementName="unknown" Type="int16" Size="1" />
<Data ElementName="unknown2" Type="int32" Size="1" />
<Data ElementName="unknown3" Type="float" Size="1" />
<Data ElementName="command_list" Type="int8" Size="1" />
<Data ElementName="command_list_array" Type="Array" ArraySizeVariable="command_list">
	<Data ElementName="command_list_name" Type="EQ2_16Bit_String" />
	<Data ElementName="command_list_max_distance" Type="float" Size="1" />
	<Data ElementName="command_list_unknown1" Type="int8" Size="1" />
	<Data ElementName="command_list_unknown2" Type="int8" Size="1" />
	<Data ElementName="command_list_command" Type="EQ2_16Bit_String" />
</Data>
<Data ElementName="default_command" Type="EQ2_16Bit_String" Size="1" />
<Data ElementName="max_distance" Type="float" Size="1" />
<Data ElementName="group_size" Type="int8" Size="1" />
<Data ElementName="group_array" Type="Array" ArraySizeVariable="group_size">
	<Data ElementName="group_spawn_id" Type="int32" />
</Data>
<Data ElementName="unknown6" Type="int32" Size="1" />
</Struct>
Also, all bankers I have seen have "bank" in their default_command.

skandragon
Posts: 27
Joined: Tue Jan 15, 2008 11:24 pm
Location: Oklahoma
Contact:

Post by skandragon » Sat Jan 19, 2008 9:11 am

Aye, that I did. I used the release version, not the cvs version, of that file.
Here's the documented structure I'm using in my protocol analyzer:

Code: Select all

All data elements are little-endian unless specified.
Data types:
  uint8
    An unsigned 8-bit value.
  uint16
    An unsigned 16-bit value.
  uint32
    An unsigned 32-bit value.
  eq2int
    A somewhat strange way to encode integers.  8-bit values less than 0xff are encoded directly.
    16-bit values are encoded by prefixing with "0xff uint16", and 32-bit values are encoded by prefixing
    with 0xff 0xff 0xff "uint32".
  eq2string
    A uint16 length field, followed by that many characters consisting of the string data.
    
  zero_suppressed
    A uint32 length, followed by "packed" zero-suppressed structure.  When expanded, this
    field will likely have many, many 0x00 values.
Substructures:
  ghost_command:
    eq2string command_name
      The command name.  This might be the displayed, or transmitted version.
    float max_distance
      The maximum distance from which this command can be issued.
    uint16 unknown
      Seems to almost always be 0x00 0x00
    eq2string command_name2
      The command name, repeated.  This might be the displayed, or transmitted version.
"create ghost" client command:
  eq2int index
    A client-specific ID for this spawn.  These are reused as older ones should have been
    forgotten by the client.  This is what is used for various interactions with the spawn.
  uint32 spawn_id
    A 32-bit opaque value indicating the spawn ID.  This is a server-global one -- all clients
    see the same ID.
  uint16 unknown
    Seems to nearly always be FF FF
  uint32 unknown
    Unknown.
  uint32 unknown
    Unknown.
  eq2int num_commands
    Indicates a number of "command structures" which follow.
  Zero-or-more ghost_commands structures
  eq2string default_command
    This is what happens when you just click on the ghost.
  float max_distance
    Max distance from which the default command works.
  eq2int spawn_group_size
    The number of other IDs in this group.
  Zero-or-more uint32 spawn_group_member_id
    The other IDs in this group.
  uint32 unknown
    Unknown.
  zero_suppressed spawn_info
    This is the zero-suppressed data block.  Unpacking it provides data about the object.
    This is not yet fully analyzed (by me) but some data exists in 
  uint32 unknown
    Unknown.
  eq2string spawn_name
    The name, possibily displayed to the client.
  uint8 unknown
    Unknown.
  eq2string guild_name
    The "guild" name.
  uint8 unknown
    Unknown.

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests