Hehe, well, let me see.. where to start.
First of all, i have no clue how lookup into a hashtable became about
saving information about objects persistently. That's nonsense really, in this
context.
The original post was to point out, that there is a short-cut to looking objects
up inside the hashtables, and gave an algorithm to do so. Simple.
The implementation was done in ~30 mins, so bear with me if it was not
very effective, it was not meant to be, it was meant to be illustrative.
Second, wether the object Ids change from server instance to instance is
irrelevant to this topic. Given an objects id, it is a matter of doing the hash
calculation and asking the list to present the reference it has to the object
with that particular hash.
@Shareen
No, you misread. I stated that there is a way to always have an objects Id,
and that is by hooking the InsertFunction in the client. Interest07 pointed
out that an even better source would be the RecieveMessage function.
There are magnitudes more data to sift through there, but he's absolutely
right.
The main point was, that there is a way to obtain the object Id without
looping the entire list, and that given an objects Id, you can always find
it in the hashtable via a quick calculation, also without looping.
regarding the hashing function:
There is not alot of "science" involved in the hash calculation. It's pure
mathematics.
Code:
objectOffset = listBase + (objectId % listHashSeed) * 4
this calculation is present in the client too, as i stated in the original post.
The listHashSeed is a variable obtained from inside the list class structure.
There is no way to go back, if you have the hash for a particular object,
you cannot obtain the Id. When you compute an objectId's hash, you loose
information about the Id in the process. This is the whole point of doing
it. You compress the data into something useful, like using it for indexing
a list, hence the word HashTable.
I won't go further into the reasons for choosing a hashtable, but if you're
interested i recommend MSDN's guide on data structures.
about object Id's
An objects Id is not assigned at random, you will always be able to get
an objects type from its Id. Like so:
Code:
public static WorldObjectType ResolveId(uint id)
{
WorldObjectType type;
if ((id & 0x80000000) == 0x80000000)
{
type = WorldObjectType.Monster;
}
else if ((id & 0x40000000) == 0x40000000)
{
type = WorldObjectType.Item;
}
else type = WorldObjectType.Player;
return type;
}
This is analogous to the code in the client, which tests wether an objects
Id contains a monster or item flag. This code is repeated inside the client
ad nauseum.
Code:
mov edx, dword ptr [esp+dwId] ; edx = objectId
mov esi, edx
and esi, 0x80000000
jz @objectIsTypeMonster
test edx, 0x40000000
jz @objectIsTypeItem
I would say that, that is quite a bit more than "absolutely nothing".
I havn't researched if the Ids contain other flag bits, since i havn't found
a use for it yet
Anyways, if done right, there are only a few times where you would need to
loop over the entire hashtable:
1) at startup of the bot
2) enter/exit instance