Jump to content

Possible To Make A Client?


Guest count0

Recommended Posts

  • Replies 162
  • Created
  • Last Reply

Top Posters In This Topic

  • 3 months later...

Are people still actively working on this project? I checked it out recently and fixed some issues with it: like the CRC calculation code needed during AUTH_LOGON_PROOF packet generation, plus updated some of the RealmD packet structs so they match what is received in 2.4.3.

Having said that I can actually get to the Character Selection screen on a real WoW server. With that said, that is when you start getting Warden messages & ping messages. Ping is way easier to handle then Warden biggrin.gif

Link to comment
Share on other sites

<div class='quotetop'>QUOTE </div>

Are people still actively working on this project? I checked it out recently and fixed some issues with it: like the CRC calculation code needed during AUTH_LOGON_PROOF packet generation, plus updated some of the RealmD packet structs so they match what is received in 2.4.3.

Having said that I can actually get to the Character Selection screen on a real WoW server. With that said, that is when you start getting Warden messages & ping messages. Ping is way easier to handle then Warden biggrin.gif[/b]

Yes, the project is still active. If you have written any Patches please consider posting them in the patch section of the forum at http://www.mangosclient.org for review.

About connecting to a "real" WoW server using PseuWoW please consider the LICENSE of PseuWoW. The following sentence may be of special interest in this case:

<div class='quotetop'>QUOTE </div>

* It is NOT intended to be used as a replacement of ANY commercial game client, and it is NOT allowed and NOT possible to connect to ANY commercial game server.[/b]

shlainn

Link to comment
Share on other sites

Well, in that case there isn't any point in posting the patch... since PseuWoW doesn't need to calculate a valid CRC hash to connect to a private server. But glad to see people are still working on this project as it is an interesting concept. As I develop my own code I will periodically compare it to PseuWoW and let you guys know if there is any changes that are needed.

Link to comment
Share on other sites

anyway, the fact that the licence says that its not ALLOWED to connect doesnt mean that it shouldnt be POSSIBLE to connect wink.gif

would be nice if you can post your patch, especially the CRC hash stuff. thx wink.gif

all in all this is just educative; but its your sanity what you do with it.

btw, pseuwow needs devs wink.gif

Link to comment
Share on other sites

<div class='quotetop'>QUOTE (ProjectEden @ Aug 1 2008, 01:29 PM) <{POST_SNAPBACK}></div>

anyway, the fact that the licence says that its not ALLOWED to connect doesnt mean that it shouldnt be POSSIBLE to connect wink.gif

would be nice if you can post your patch, especially the CRC hash stuff. thx wink.gif

all in all this is just educative; but its your sanity what you do with it.

btw, pseuwow needs devs wink.gif[/b]

Stuff to Add to RealmSession.cpp

#include <windows.h>
#include <fstream>

struct sAuthLogonChallenge_S
{
       uint8     cmd;
       uint8     unk2;
       uint8     error;
       uint8     B[32];
       uint8     g_len;
       uint8     g[1];
       uint8     N_len;
       uint8     N[32];
       uint8     salt[32];
       uint8     seed[16]; // <-- I modified this from unk3
       uint8     unk4; // <-- I added this (version 2.4.3)
};

// 2 Static funcs you will need (put them towards the top of the file)
static int GenerateMemoryHash(char* fn, Sha1Hash* Sha1)
{
       HANDLE hFile = CreateFileA(fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

       if (hFile == INVALID_HANDLE_VALUE)
               return 0;

       int len = 0;
       uint32 dwRead;
       uint32 dwLen = -1;
       while (dwLen != 0)
       {
               if (!ReadFile(hFile, &dwLen, 4, &dwRead, NULL))
                       break;

               if (dwRead == 0)
                       break;

               if (dwLen > 0)
               {
                       uint8 *mem = new uint8[dwLen];
                       if (!ReadFile(hFile, mem, dwLen, &dwRead, NULL))
                       {
                               CloseHandle(hFile);
                               return 0;
                       }

                       len += (int)dwRead;

                       Sha1->UpdateData(mem, dwLen);

                       delete[] mem;
               }
       }
       CloseHandle(hFile);

       return len;
}

static void CalcCRC(uint8* crc_hash, uint8* seed, uint8* A) 
{
       char szFileName[128] = {0};
       GetModuleFileName(NULL, szFileName, 128);
       uint32 iPathLen = strlen(szFileName);

       for(iPathLen; iPathLen > 0; iPathLen--)
       {
               if (szFileName[iPathLen] == '\\\\')
               {
                       szFileName[iPathLen+1] = '\\0';
                       strcat(szFileName, "crc.bin");
                       break;
               }
       }

       uint8 szBuf1[64];
       uint8 szBuf2[64];

       memset(szBuf1, 0x36, 64);
       memset(szBuf2, 0x5C, 64);

       for (uint8 i = 0; i < 16; i++)
       {
               szBuf1[i] ^= seed[i];
               szBuf2[i] ^= seed[i];
       }

       Sha1Hash    Sha1;
       Sha1.UpdateData(szBuf1, 64);
       GenerateMemoryHash(szFileName, &Sha1);
       Sha1.Finalize();        

       uint8 H1[64];

       memcpy(H1, Sha1.GetDigest(), Sha1.GetLength());

       Sha1.Initialize();
       Sha1.UpdateData(szBuf2, 64);
       Sha1.UpdateData(H1, 20);
       Sha1.Finalize();

       uint8 H2[64];
       memcpy(H2, Sha1.GetDigest(), Sha1.GetLength());

       Sha1.Initialize();
       Sha1.UpdateData(A, 32);
       Sha1.UpdateData(H2, 20);
       Sha1.Finalize();

       memcpy(crc_hash, Sha1.GetDigest(), Sha1.GetLength());
}

// THEN REPLACE CASE 0 WITH THIS:
       case 0:
               {
                       pkt.read((uint8*)&lc, sizeof(sAuthLogonChallenge_S));
                       logdetail("Login successful, now calculating proof packet...");

                       // now lets start calculating
                       BigNumber N,A,B,a,u,x,v,S,salt,seed,g,k(3); // init BNs, default k to 3
                       std::string user=stringToUpper( _accname );
                       std::string _authstr=stringToUpper( user +":"+_accpass );

                       B.SetBinary(lc.B,32);
                       g.SetBinary(lc.g,lc.g_len);
                       N.SetBinary(lc.N,lc.N_len);
                       salt.SetBinary(lc.salt,32);
                       seed.SetBinary(lc.seed,16);

                       //logdebug("== Server Bignums ==");
                       //logdebug("--> B=%s",B.AsHexStr());
                       //logdebug("--> g=%s",g.AsHexStr());
                       //logdebug("--> N=%s",N.AsHexStr());
                       //logdebug("--> salt=%s",salt.AsHexStr());
                       //logdebug("--> seed=%s",seed.AsHexStr());

                       //logdebug("== My Bignums ==");
                       // Probably should use seed here instead of 19*8
                       a.SetRand(19*8);
                       ASSERT(a.AsDword() > 0);
                       logdebug("--> a=%s",a.AsHexStr());

                       // GetLogonHash
                       Sha1Hash userhash,xhash,uhash;
                       userhash.UpdateData(_authstr);
                       userhash.Finalize();

                       // Getx
                       xhash.UpdateData(salt.AsByteArray(),salt.GetNumBytes());
                       xhash.UpdateData(userhash.GetDigest(),userhash.GetLength());
                       xhash.Finalize();
                       x.SetBinary(xhash.GetDigest(),xhash.GetLength());
                       logdebug("--> x=%s",x.AsHexStr());

                       // GetA
                       A=g.ModExp(a,N);
                       logdebug("--> A=%s",A.AsHexStr());

                       // GetU
                       uhash.UpdateBigNumbers(&A, &B, NULL);
                       uhash.Finalize();
                       u.SetBinary(uhash.GetDigest(), uhash.GetLength());
                       logdebug("--> u=%s",u.AsHexStr());

                       // ClientGetS
                       S=(B - k*g.ModExp(x,N) ).ModExp((a + u * x),N);
                       logdebug("--> S=%s",S.AsHexStr());

                       ASSERT(S.AsDword() > 0);

                       // WHY IS THIS CALCULATED??? IT'S NEVER USED
                       //v=g.ModExp(x,N);
                       //logdebug("--> v=%s",v.AsHexStr());

                       // Get M1 & M2
                       unsigned int i=0;
                       char S1[16+1],S2[16+1]; // 32/2=16  +1 for \\0
                       // split it into 2 seperate strings, interleaved
                       for(i=0;i<16;i++){
                               S1[i]=S.AsByteArray()[i*2];
                               S2[i]=S.AsByteArray()[i*2+1];
                       }

                       // hash each one:
                       Sha1Hash S1hash,S2hash;
                       S1hash.UpdateData((const uint8*)S1,16);
                       S1hash.Finalize();
                       S2hash.UpdateData((const uint8*)S2,16);
                       S2hash.Finalize();
                       // Re-combine them
                       char S_hash[40];
                       for(i=0;i<20;i++){
                               S_hash[i*2]=S1hash.GetDigest()[i];
                               S_hash[i*2+1]=S2hash.GetDigest()[i];
                       }
                       _key.SetBinary((uint8*)S_hash,40); // used later when authing to world
                       logdebug("--> SessionKey=%s",_key.AsHexStr());

                       char Ng_hash[20];
                       Sha1Hash userhash2,Nhash,ghash;
                       userhash2.UpdateData((const uint8*)user.c_str(),user.length());
                       userhash2.Finalize();
                       //printchex((char*)userhash2.GetDigest(),userhash2.GetLength(),true);
                       Nhash.UpdateBigNumbers(&N,NULL);
                       Nhash.Finalize();
                       ghash.UpdateBigNumbers(&g,NULL);
                       ghash.Finalize();
                       for(i=0;i<20;i++)Ng_hash[i] = Nhash.GetDigest()[i]^ghash.GetDigest()[i];
                       //printchex(Ng_hash,20,true);

                       BigNumber t_acc,t_Ng_hash;
                       t_acc.SetBinary((const uint8*)userhash2.GetDigest(),userhash2.GetLength());
                       t_Ng_hash.SetBinary((const uint8*)Ng_hash,20);

                       Sha1Hash M1hash,M2hash;

                       M1hash.UpdateBigNumbers(&t_Ng_hash,&t_acc,&salt,&A,&B,NULL);
                       M1hash.UpdateData((const uint8*)S_hash,40);
                       M1hash.Finalize();

                       M2hash.UpdateBigNumbers(&A,NULL);
                       M2hash.UpdateData((const uint8*)M1hash.GetDigest(),M1hash.GetLength());
                       M2hash.UpdateData((const uint8*)S_hash,40);
                       M2hash.Finalize();

                       //logdebug("== Common Hashes ==");
                       //logdebug("--> M1=%s",toHexDump(M1hash.GetDigest(),M1hash.GetLength(),false).c_str());
                       //logdebug("--> M2=%s",toHexDump(M2hash.GetDigest(),M2hash.GetLength(),false).c_str());
                       // End of GetM1M2

                       // Calc CRC & CRC_hash
                       uint8 crc_hash[20] = {0};
                       CalcCRC(crc_hash, lc.seed, A.AsByteArray());

                       //logdebug("--> CRC=%s",toHexDump((uint8*)crc_hash,20,false).c_str());

                       // now lets prepare the packet
                       ByteBuffer packet;
                       packet << (uint8)AUTH_LOGON_PROOF;
                       packet.append(A.AsByteArray(),A.GetNumBytes());
                       packet.append(M1hash.GetDigest(),M1hash.GetLength());
                       packet.append(crc_hash,20);
                       packet << (uint8)0; // number of keys = 0

                       if(GetInstance()->GetConf()->clientbuild > 5302)
                               packet << (uint8)0; // 1.11.x compatibility (needs one more 0)

                       GetInstance()->SetSessionKey(_key);
                       memcpy(this->_m2,M2hash.GetDigest(),M2hash.GetLength()); // save M2 to an extern var to check it later

                       SendRealmPacket(packet);
                       packet.print();
               }
}

Now to get that to compile you will also need to add the print() to ByteBuffer.h which I wrote (and ksniffer people will find familiar)

which is way nicer then the hexlike or textlike (and combines both into one)

                void print() 
               {
                       uint32 line = 1;
                       uint32 countpos = 0;
                       printf("Packet Size: %u\\r\\n", size());
                       printf("|------------------------------------------------|----------------|\\r\\n");
                       printf("|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|\\r\\n");
                       printf("|------------------------------------------------|----------------|\\r\\n");
                       if (size() > 0)
                       {
                               printf("|");
                               for (uint32 count = 0; count < size(); count++) 
                               {
                                       if (countpos == 16)
                                       {
                                               countpos = 0;
                                               printf("|");
                                               for (uint32 a = count-16; a < count; a++)
                                               {
                                                       if ((read<uint8>(a) < 32) || (read<uint8>(a) > 126))
                                                               printf(".");
                                                       else
                                                               printf("%c", read<uint8>(a));
                                               }
                                               printf("|\\r\\n");
                                               line++;
                                               printf("|");
                                       }
                                       printf("%02x ", read<uint8>(count));

                                       // Fix to parse packets with length < OR = to 16 bytes.
                                       if (count+1 == size() && size() <= 16)
                                       {
                                               for (uint32 b = countpos+1; b < 16; b++)
                                                       printf("     ");

                                               printf("|");

                                               for (uint32 a = 0; a < size(); a++) 
                                               {
                                                       if ((read<uint8>(a) < 32) || (read<uint8>(a) > 126))
                                                               printf(".");
                                                       else
                                                               printf("%c", read<uint8>(a));
                                               }

                                               for (uint32 c = count; c < 15; c++)
                                                       printf(" ");

                                               printf("|\\r\\n");
                                       }

                                       // Fix to parse the last line of the packets when the length is > 16 and its in the last line
                                       if (count+1 == size() && size() > 16) 
                                       {
                                               for (uint32 b = countpos+1; b < 16; b++)
                                                       printf("     ");

                                               printf("|");
                                               uint16 print = 0;

                                               for (uint32 a = line*16 - 16; a < size(); a++)
                                               {
                                                       if ((read<uint8>(a) < 32) || (read<uint8>(a) > 126))
                                                               printf(".");
                                                       else
                                                               printf("%c", read<uint8>(a));
                                                       print++;
                                               }

                                               for (uint32 c = print; c < 16; c++)
                                                       printf(" ");

                                               printf("|\\r\\n");
                                       }
                                       countpos++;
                               }
                       }
                       printf("-------------------------------------------------------------------\\r\\n\\r\\n");
               }

With all that you will calculate the CRC correctly... IF you have the crc.bin file on your system (and this is something I will not provide, mainly cause it's about 11MB in size).

Now, with all that and the crc.bin I can connect to a real wow server with your client. However, there is something messed up with your TcpSocket class as when I get the RealmList packet from the server it doesn't combine all the split packets (WoW servers sends them in 1460 byte increments) back. The packet I get claims a length of 8947 bytes (for 229 servers)... but when I get the packet it is only 4140 bytes and thus crashes the subsequent function. Now the re-joining of packets across TCP protocol should be invisible to the user, but clearly something is messed up. Interestingly, on another side note, if I add a sanity check to the RealmSession handling function to just return if pkt.size() != len the subsequent bytes that arrive on the RealmSocket are prepended to the front of the buffer instead of appended to the back (if you follow what I mean).

Link to comment
Share on other sites

thx a lot for the code biggrin.gif - can you also tell me how to generate a crc.bin file? i'd like to add that feature to stuffextract. afaik it must contain some original client memory region, but not sure.

... i will also try to fix the RealmList packet handling soon.

Link to comment
Share on other sites

I am interested too in the crc.bin generation (or any other way to verify that crc at the server side). I'm interested because I'd like to implement the checking of whatever crc/hash the client sends on the MaNGOS side here. Might keep an idiot away that is screwing with his client somehow. PM is fine if you prefer that. Thanks in advance!

Link to comment
Share on other sites

  • 2 weeks later...

<div class='quotetop'>QUOTE (ProjectEden @ Aug 1 2008, 04:32 PM) <{POST_SNAPBACK}></div>

thx a lot for the code biggrin.gif - can you also tell me how to generate a crc.bin file? i'd like to add that feature to stuffextract. afaik it must contain some original client memory region, but not sure.[/b]

Debating this as it's not my code and I would have to see how the original author feels about this.

<div class='quotetop'>QUOTE (ProjectEden @ Aug 1 2008, 04:32 PM) <{POST_SNAPBACK}></div>

... i will also try to fix the RealmList packet handling soon.[/b]

I fixed it the following way:

void RealmSession::_HandleRealmList(ByteBuffer& pkt)
{
       logdebug("RealmList Packet");

       std::string realmAddr;

       uint32 unk;
       uint16 len,count;
       uint8 cmd;
       pkt >> cmd >> len >> unk >> count;

       while( pkt.size() < len )
       {
               Sleep( 100 ); // wait for the rest of the packet
               _socket->OnRead();

               if ( pktQueue.size() )
                       pkt.append( *pktQueue.next() );
       }
       log( "%i %i", pkt.size(), len );
       pkt.print();

       // no realm?
       if(count==0)
               return;

       // do we have the wrong size?
       // subtract 3 bytes since len provided in packet
       // is from that point on so we miss the opcode (1 byte)
       // and the size (2 bytes)
       if (len != (pkt.size()-3))
       {
               return;
       }

... The rest of the pseuwow code as it is here
}

Link to comment
Share on other sites

Another thing, when interacting with proper server the CMSG_AUTH_SESSION will not work if you pass a "(uin32) 0x00" for the AddOn information list at the end of that packet, b/c it requires that the Blizzard provided Addons be listed, at the minimum. I don't think MaNGOS currently cares about this field so it works with MaNGOS just fine.

For proper server you would need the following bytes at the end of the packet:

        uint8 addon_info[160] = {
               0xd0,0x01,0x00,0x00,0x78,0x9c,0x75,0xcf,
               0x3b,0x0e,0xc2,0x30,0x0c,0x80,0xe1,0x72,
               0x0f,0x2e,0x43,0x18,0x50,0xa5,0x66,0xa1,
               0x65,0x46,0x26,0x71,0x2b,0xab,0x89,0x53,
               0x19,0x87,0x47,0x4f,0x0f,0x0b,0x62,0x71,
               0xbd,0x7e,0xd6,0x6f,0xd9,0x25,0x5a,0x57,
               0x90,0x78,0x3d,0xd4,0xa0,0x54,0xf8,0xd2,
               0x36,0xbb,0xfc,0xdc,0x77,0xcd,0x77,0xdc,
               0xcf,0x1c,0xa8,0x26,0x1c,0x09,0x53,0xf4,
               0xc4,0x94,0x61,0xb1,0x96,0x88,0x23,0xf1,
               0x64,0x06,0x8e,0x25,0xdf,0x40,0xbb,0x32,
               0x6d,0xda,0x80,0x2f,0xb5,0x50,0x60,0x54,
               0x33,0x79,0xf2,0x7d,0x95,0x07,0xbe,0x6d,
               0xac,0x94,0xa2,0x03,0x9e,0x4d,0x6d,0xf9,
               0xbe,0x60,0xb0,0xb3,0xad,0x62,0xee,0x4b,
               0x98,0x51,0xb7,0x7e,0xf1,0x10,0xa4,0x98,
               0x72,0x06,0x8a,0x26,0x0c,0x90,0x90,0xed,
               0x7b,0x83,0x40,0xc4,0x7e,0xa6,0x94,0xb6,
               0x98,0x18,0xc5,0x36,0xca,0xe8,0x81,0x61,
               0x42,0xf9,0xeb,0x07,0x63,0xab,0x8b,0xec};
       for (uint8 i = 0; i < 160; i++) 
       {
               auth << addon_info[i];
       }

Link to comment
Share on other sites

I encountered something new today while logging in to the server so I figured I would provide the info. The SMSG_AUTH_RESPONSE (just prior to when you ask for the enumeration of all your characters on a given realm) can return an errorcode of 0x1B (you expect 0x0C for success). 0x1B is indicative of a Realm Queue present. I haven't reversed all the information in the packet but it includes the # of people ahead of you in the queue. Here is what you should add to your SMSG_AUTH_RESPONSE handler to not be trouble by it. Note, MaNGOS currently does not ever send 0x1B as an error code as Realm Queues are currently not supported (AFAIK).

void WorldSession::_wshandle_SMSG_AUTH_RESPONSE(WorldPacket& pkt)
{
       PrintPacket(stderr, true, pkt, pkt.size());

       uint8 errcode;
       pkt >> errcode;
       if(errcode == 0xC)
       {
               logdetail("World Authentication successful, preparing for char list request...");
               WorldPacket new_pkt(CMSG_CHAR_ENUM, 0);
               SendWorldPacket(new_pkt);
       }
       else if (errcode == 0x1B)
       {
               uint32 unk_count = pkt.size() - 5;
               uint8    *unknown = new uint8[unk_count];
               uint32 number;
               for (size_t i = 0; i < unk_count; i++) 
               {
                       pkt >> unknown[i];
               }
               pkt >> number;
               delete unknown;
               logerror("World Authentication encountered: Login Queue of %d", number);
               Sleep( 100 );
       }
       else
       {
               logerror("World Authentication failed, errcode=0x%02X", (uint8)errcode);
               SetMustDie();
       }
}

HERE is a LOG DUMP of the PACKETS I encountered while logging in... notice that they vary between two sizes:

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 15
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 08 ad 1e ff 42 00 00 00 00 00 1b 00 00 00        |.....B......... |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 15
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 78 1e 1f ff 42 00 00 00 00 00 19 00 00 00        |.x...B......... |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 5
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 1b 00 00 00                                                                    |.....                     |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 15
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 6c 66 1f ff 42 00 00 00 00 00 19 00 00 00        |.lf..B......... |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 5
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 19 00 00 00                                                                    |.....                     |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 5
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 16 00 00 00                                                                    |.....                     |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 5
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 11 00 00 00                                                                    |.....                     |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 5
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|1b 04 00 00 00                                                                    |.....                     |
-------------------------------------------------------------------

{SERVER} Packet: (0x01ee) SMSG_AUTH_RESPONSE - Packet Size = 1
|------------------------------------------------|----------------|
|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
|------------------------------------------------|----------------|
|0c                                                                                            |.                             |
-------------------------------------------------------------------

Link to comment
Share on other sites

<div class='quotetop'>QUOTE (Exoskeleton @ Aug 21 2008, 06:51 PM) <{POST_SNAPBACK}></div>

you better post these things on mangosclient.org because we have to check both forums now xD[/b]

Sorry, don't have an account there and I'm trying to keep the numbers of forums & accounts I have to a minimum, otherwise I forget.

Anyways, here is another update - add this to your MovementInfo structure:

        // spline
       float     u_unk1;
       uint32    spline_flag;
       uint64        s_unkGUID;
       uint32    s_travel_time, s_inflight_time, s_tick_count, s_points_count;
       float        splineX, splineY, splineZ, splineO;
       float     s_tempX, s_tempY, s_tempZ;

Then, you can do this in your _MovementUpdate():

                // TODO: Verify this
               if(mi.flags & MOVEMENTFLAG_SPLINE2)
               {
                       pkt >> mi.spline_flag;
                       if (mi.spline_flag & 0x10000)
                               pkt >> mi.splineX >> mi.splineY >> mi.splineZ;
                       if (mi.spline_flag & 0x20000)
                               pkt >> mi.s_unkGUID;
                       if (mi.spline_flag & 0x40000)
                               pkt >> mi.splineO;

                       pkt >> mi.s_inflight_time >> mi.s_travel_time >> mi.s_tick_count >> mi.s_points_count;
                       for (uint32 i = 0; i < mi.s_points_count; ++i)
                       {
                               // These are X,Y,Z points in a path
                               pkt >> mi.s_tempX >> mi.s_tempY >> mi.s_tempZ;
                       }
                       // Final path point (points_count - 1)
                       pkt >> mi.s_tempX >> mi.s_tempY >> mi.s_tempZ;

                       logdev("MovementUpdate: MOVEMENTFLAG_SPLINE2 is set with %u points", mi.s_points_count);
               }

Turns out that on the real server the Spline2 will happen a lot for units/players.

Link to comment
Share on other sites

  • 1 month later...

<div class='quotetop'>QUOTE (nitrogrlie @ Aug 18 2008, 01:39 PM) <{POST_SNAPBACK}></div>

Debating this as it's not my code and I would have to see how the original author feels about this.[/b]

Since it's been a while and, unless I missed it somewhere, there was no final conclusion posted: can we assume the original author prefers not to share the code? Or is there still a chance it will be shared in the (near) future?

Just asking so I know where we stand, nothing more smile.gif

Link to comment
Share on other sites

  • 3 weeks later...

I thought you might want to know this if you don't check mangosclient.org on a regular basis:

Quote from mangosclient.org

False.Genesis: gone to army >.< i will be away for the next 9 months (only home at weekends), and probably not able to commit any code in the first 3 months. blame the crappy german army for that!

As a little present i have released the 13.52 version and created a package (based on rev 337) that is availible in the downloads section.

For help with setting PseuWoW up, check the wiki.

(There are still a few quirks in this release, especially in the character and realm selection screen, but better then nothing)

if anyone could try to fix the compatibility problems with ascent... would be really cool.

Link to comment
Share on other sites

Its sad to see this cause I really like the project, I tested it myself and can say that it work pretty good. Before I made already a Chatbot with the elder Client (In 2.3.3 times) and it was quite funny.

I hope that the community continue on that project.

We certainly will :D

Link to comment
Share on other sites

  • 6 months later...
  • 4 months later...

You know what I love about open source? I mean aside from the obvious aspect of being free.

It gives power to all of us to make software exactly the way we want it, not being forced to accept whatever features are decided by the forces of economics that determine the destiny of commercial programs.

Sure, an open source project may take forever, due to lack of manpower, time, and resources for development but it gets done the right way.

I fully support the idea of an original MMORPG client for MaNGOS. It's not only very much in the spirit and philosophy at the core of the MaNGOS project, it's also the chance for everyone to contribute in creating a game they've always wanted. Got an idea for a new race, class, spell, profession, or item?

But, remember, we're not limited to simple copy-cat features of existing software. We can have the audacity to make it better!

In fact, the framework of this client, paired with MaNGOS, means you could create any kind of MMORPG you wanted! All you need is the proper scripting, models, textures, and other assets where you could have something like, say, a Halo-style tactical RPG with world-spanning combat.

Hmm...Master Chief as a gnome.:ph34r:

Link to comment
Share on other sites

the project is still up and running, but slow on development at the moment.

I use it as a wow chat client by compiling it without the GUI.

You can also code custom scripts to use it as a BOT to watch over the server and execute custom commands. For private use you can add the fishbot script to make it fish for you. Very nice progress.

check it out: http://www.mangosclient.org/news.php

If anyone wants my sourcecode I have it compiled for wow 2.4.3 with the GUI disabled

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use