Update Client

Hello,

i have found a old patch form the dev Schlumpf for trinitycore.

The code emulation the Blizzard Update Method, but the code is for a older trinitycore version.

Patch File: [Diff] TrinityCore client patcher - Pastebin.com

CGlueMgr__PatchDownloadApply.cpp:

[/URL][URL=“http://pastebin.de/27792”][C++] void CGlueMgr::PatchDownloadApply(){ int reason_for_failure = 5; char | Pastebin.de

SFileAuthenticateArchiveEx.asm:

[/URL][URL=“http://pastebin.de/27793”][ASM (NASM based)] _SFileAuthenticateArchiveEx proc near authresult = Blizzard__Mopaq__Auth | Pastebin.de

SFileAuthenticateArchiveEx.cpp:

[/URL][URL=“http://pastebin.de/27794”][C++] bool SFileAuthenticateArchiveEx ( Blizzard::Mopaq::HSARCHIVE__ *archive | Pastebin.de

SFileAuthenticateArchiveEx_fixed.asm:

[/URL][URL=“http://pastebin.de/27795”][ASM (NASM based)] _SFileAuthenticateArchiveEx proc near authresult = Blizzard__Mopaq__Auth | Pastebin.de

SFileAuthenticateArchiveEx_fixed.cpp:

[/URL][URL=“http://pastebin.de/27796”][C++] bool SFileAuthenticateArchiveEx ( Blizzard::Mopaq::HSARCHIVE__ *archive | Pastebin.de

Can you help me, and update the Patch file for the new Trinity Core version ?

I Attach the PDF file with a tutorial for old cores. The Trinitycore text start by 3.2.

Implementing in-client patching for World of Warcraft.pdf

unless you are using this just for updating older clients to 12340 (3.3.5a) you have to do some client editing/injecting, and I can tell you that part is not an acceptable topic here. Just keep this in mind while discussing this. Personally, I have always wanted the update process to work properly, and, even tried working on it myself a while back, but, it seems a bit pointless now that TC is no longer chasing the latest patch from Blizzard…

i will update with this the clients form 3.0.1 to 3.3.5a. A lot of players have problems with Patching wow, and i will help the player with this script.

thanks Blackplayer Good job

The scripts dont work, the scripts was old =/

Most people don’t actually read the posts I’ve noticed. I bet you’ll get a response that the script didn’t work…

Reading you say? What kind of sorcery is this? /emoticons/default_wink.png

I now the script was old and he don’t work with the new Trinitycore Version. I Need your help to update the script for new Trinitycore Version.

yes guys i Need It too

if possible some one update this script /emoticons/default_sad.png

TnQ

hello ?

It is possible to get this to work with a few minor changes however the client will not run the patch unless your mpq patch file is signed with Blizzard’s key or your client (wow.exe) has been modified in a way that it skips the key validation.

hmm…okeay but can you help we update the script for the current Trinity Version ?

Isnt there such function already in trinty? As I went thru authserver code I seen some code pertaining to updating client.

There are chunks of code already present but these don’t handle everything that should be handled by the patching proces. I’m pretty sure the logonserver crashes when you have patch files present in the folder specified in the code.

Edit:

I’m currently not at home and posting from my phone. I’ll post the code when I get home.

The only issue will be that even with this modified code that will allow the wow client to download patches they cannot be executed. The client will give an error when trying to execute the patch file because your custom patch file isn’t signed with Blizzard’s strong key.

Thank you Vexxer /emoticons/default_biggrin.png

I’ve attached my .diff file with the changes for the patching process to this post, take note that you have to create a “patches” folder in your server root and place your custom patches in that folder. The patches also need a specific name, if for example you want people to patch to build 12345 (3.3.5a is build 12340) you have to add 12345 to the list of allowed builds in AuthCodes.h and name the patch file 12345-enGB.mpq.

If you’re unable to apply the changes from the .diff file let me know and I’ll post the parts to edit in full when I have the time to do that.

patcher.diff

Thank you very very very mutch /emoticons/default_biggrin.png i like you soooooooooooo /emoticons/default_biggrin.png^^

i get an error when applying


patcher.diff:49: trailing whitespace.

#ifndef _PATCHMGR_H

patcher.diff:140: tab in indent.

PATCH_INFO* patch = NULL;

patcher.diff:141: tab in indent.

int locale = *((int*)(_locale.c_str()));

patcher.diff:145: tab in indent.

sLog->outString("Client with version %i and locale %s (xx) is looking for a patch.", _build, _locale.c_str(), _locale);

patcher.diff:147: tab in indent.

for (Patches::iterator itr = _patches.begin(); itr != _patches.end(); ++itr)

error: patch failed: src/server/authserver/Authentication/AuthCodes.h:65

error: src/server/authserver/Authentication/AuthCodes.h: patch does not apply

error: patch failed: src/server/authserver/Main.cpp:33

error: src/server/authserver/Main.cpp: patch does not apply

error: patch failed: src/server/authserver/Server/AuthSocket.cpp:17

error: src/server/authserver/Server/AuthSocket.cpp: patch does not apply

error: patch failed: src/server/authserver/Server/AuthSocket.h:23

error: src/server/authserver/Server/AuthSocket.h: patch does not apply

Edit: fixed it Filebeam - Beam up that File Scottie! - changed the enGB to enUS also


diff -r 73624ee6170e src/server/authserver/Authentication/AuthCodes.h

--- a/src/server/authserver/Authentication/AuthCodes.h Fri Jun 29 23:37:08 2012 +0200

+++ b/src/server/authserver/Authentication/AuthCodes.h Wed Jul 04 22:57:39 2012 +0200

@@ -65,8 +65,8 @@

	 LOGIN_LOCKED_ENFORCED					    = 0x10,

};

-#define POST_BC_ACCEPTED_CLIENT_BUILD		    {12340, 11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0}

-#define PRE_BC_ACCEPTED_CLIENT_BUILD			 {5875, 6005, 0}

+#define POST_BC_ACCEPTED_CLIENT_BUILD		    {12340, 12300, 0}

+#define PRE_BC_ACCEPTED_CLIENT_BUILD			 {0}


enum ExpansionFlags

{

	 POST_BC_EXP_FLAG						    = 0x2,

	 PRE_BC_EXP_FLAG							 = 0x1,

	 NO_VALID_EXP_FLAG						   = 0x0

};

diff -r 73624ee6170e src/server/authserver/Main.cpp

--- a/src/server/authserver/Main.cpp Fri Jun 29 23:37:08 2012 +0200

+++ b/src/server/authserver/Main.cpp Wed Jul 04 22:57:39 2012 +0200

@@ -33,6 +33,8 @@

#include "RealmList.h"

#include "RealmAcceptor.h"

+#include "Patcher.h"

+

#ifndef _TRINITY_REALM_CONFIG

# define _TRINITY_REALM_CONFIG  "authserver.conf"

#endif

@@ -44,6 +46,8 @@


LoginDatabaseWorkerPool LoginDatabase;					  // Accessor to the auth server database


+extern Patcher patcher;

+

// Handle authserver's termination signals

class AuthServerSignalHandler : public Trinity::SignalHandler

{

@@ -103,6 +107,8 @@

	 sLog->outString("<Ctrl-C> to stop.\n");

	 sLog->outString("Using configuration file %s.", cfg_file);


+    patcher.Initialize();

+

	 sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));


#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)

diff -r 73624ee6170e src/server/authserver/Patcher.h

--- /dev/null Thu Jan 01 00:00:00 1970 +0000

+++ b/src/server/authserver/Patcher.h Wed Jul 04 22:57:39 2012 +0200

@@ -0,0 +1,53 @@

+#ifndef _PATCHMGR_H

+#define _PATCHMGR_H

+

+#include "Common.h"

+#include "BigNumber.h"

+#include "RealmSocket.h"

+#include <openssl/md5.h>

+

+class AuthSocket;

+

+typedef struct PATCH_INFO

+{

+    int build;

+    int locale;

+    uint64 filesize;

+    uint8 md5[MD5_DIGEST_LENGTH];

+} PATCH_INFO;

+

+class Patcher

+{

+    typedef std::vector<PATCH_INFO> Patches;

+

+public:

+    void Initialize();

+

+    void LoadPatchMD5(const char*, char*);

+

+    bool InitPatching(int _build, std::string _locale, AuthSocket* _authsocket);

+    bool PossiblePatching(int _build, std::string _locale);

+

+private:

+    PATCH_INFO* getPatchInfo(int _build, std::string _locale, bool* fallback);

+

+    void LoadPatchesInfo();

+    Patches _patches;

+};

+

+// Launch a thread to transfer a patch to the client

+class PatcherRunnable: public ACE_Based::Runnable

+{

+public:

+    PatcherRunnable(class AuthSocket *, uint64 start, uint64 size);

+    void run();

+    void stop();

+

+private:

+    AuthSocket * mySocket;

+    uint64 pos;

+    uint64 size;

+    bool stopped;

+};

+

+#endif

\ No newline at end of file

diff -r 73624ee6170e src/server/authserver/Server/AuthSocket.cpp

--- a/src/server/authserver/Server/AuthSocket.cpp Fri Jun 29 23:37:08 2012 +0200

+++ b/src/server/authserver/Server/AuthSocket.cpp Wed Jul 04 22:57:39 2012 +0200

@@ -17,7 +17,6 @@

  */


#include <algorithm>

-#include <openssl/md5.h>


#include "Common.h"

#include "Database/DatabaseEnv.h"

@@ -29,9 +28,13 @@

#include "AuthCodes.h"

#include "SHA1.h"

#include "openssl/crypto.h"

+#include "../Patcher.h"


#define ChunkSize 2048


+// This needs to become a config variable at some point:

+#define PatchLocation "./patches/"

+

enum eAuthCmd

{

	 AUTH_LOGON_CHALLENGE						 = 0x00,

@@ -145,38 +148,370 @@

#pragma pack(pop)

#endif


-// Launch a thread to transfer a patch to the client

-class PatcherRunnable: public ACE_Based::Runnable

+Patcher patcher;

+

+PATCH_INFO* Patcher::getPatchInfo(int _build, std::string _locale, bool* fallback)

{

-public:

-    PatcherRunnable(class AuthSocket*);

-    void run();

+ PATCH_INFO* patch = NULL;

+ int locale = *((int*)(_locale.c_str()));


-private:

-    AuthSocket* mySocket;

+ sLog->outString("Client with version %i and locale %s (%x) is looking for a patch.", _build, _locale.c_str(), _locale);

+

+ for (Patches::iterator itr = _patches.begin(); itr != _patches.end(); ++itr)

+ {

+  if (itr->build == _build && itr->locale == 'BGne')

+  {

+   patch	 = &(*itr);

+   *fallback = true;

+  }

+ }

+

+ for (Patches::iterator itr = _patches.begin(); itr != _patches.end(); ++itr)

+ {

+  if (itr->build == _build && itr->locale == locale)

+  {

+   patch   = &(*itr);

+   *fallback = false;

+  }

+ }

+

+ return patch;

+}

+

+bool Patcher::PossiblePatching(int _build, std::string _locale)

+{

+ bool temp;

+

+ return getPatchInfo(_build, _locale, &temp) != NULL;

+}

+

+bool Patcher::InitPatching(int _build, std::string _locale, AuthSocket* _authsocket)

+{

+ bool fallback;

+    PATCH_INFO* patch = getPatchInfo(_build, _locale, &fallback);

+   

+    // Start patching if one of them is different of zero.

+    if (patch)

+    {

+	    // Authenticated, patch incoming

+	    uint8 bytes[2] = {0x01, 0x0a};

+	    _authsocket->socket().send((char *)&bytes, sizeof(bytes));

+

+	    std::stringstream path;

+

+	    if (fallback)

+	    {

+		    path << PatchLocation << _build << "-enUS.MPQ";

+	    }

+	    else

+	    {

+		    path << PatchLocation << _build << "-" << _locale << ".MPQ";

+	    }

+

+	    _authsocket->pPatch = fopen(path.str().c_str(), "rb");

+	   

+	    XFER_INIT packet;

+	    packet.cmd		 = XFER_INITIATE;

+	    packet.fileNameLen = 5;

+	    packet.fileName[0] = 'P';

+	    packet.fileName[1] = 'a';

+	    packet.fileName[2] = 't';

+	    packet.fileName[3] = 'c';

+	    packet.fileName[4] = 'h';

+	    packet.file_size = patch->filesize;

+

+	    memcpy(packet.md5, patch->md5, MD5_DIGEST_LENGTH);

+

+	    _authsocket->socket().send((char *)&packet, sizeof(packet));

+

+	    return true;

+    }

+    else

+    {

+	    sLog->outError("Client with version %i and locale %s did not get a patch.", _build, _locale.c_str());

+	    return false;

+    }

+}

+

+// Preload the MD5 hashes of existing patch files on the server

+#ifndef _WIN32

+#include <dirent.h>

+#include <errno.h>

+

+void Patcher::LoadPatchesInfo()

+{

+    DIR *dirp

+    struct dirent *dp;

+    dirp = opendir(PatchLocation);

+

+    if (!dirp)

+	    return;

+

+    while (dirp)

+    {

+	    errno = 0;

+

+	    if ((dip = readdir(dirp)) != NULL)

+	    {

+		    int len = strlen(dp->d_name);

+

+		    if (len < 8)

+			    continue;

+

+		    if (!memcmp(&dp->d_name[1-4], ".MPQ", 4))

+		    {

+			    LoadPatchMD5(PatchLocation, dp->d_name);

+		    }

+	    }

+	    else

+	    {

+		    if (errno != 0)

+		    {

+			    closedir(dirp);

+

+			    return;

+		    }

+

+		    break;

+	    }

+    }

+

+    if (dirp)

+	    closedir(dirp);

+}

+

+#else

+

+void Patcher::LoadPatchesInfo()

+{

+    WIN32_FIND_DATA fil;

+    HANDLE hFil = FindFirstFile(PatchLocation "*.MPQ", &fil);

+

+    if (hFil == INVALID_HANDLE_VALUE) {

+	    // Couldn't find any patches

+	    sLog->outString("  No patches were found.");

+	    return;

+    }

+

+    do

+    {

+	    LoadPatchMD5(PatchLocation, fil.cFileName);

+    }

+    while (FindNextFile(hFil, &fil));

+}

+

+#endif

+

+// Caculate and store MD5 hash for a given patch file

+void Patcher::LoadPatchMD5(const char* szPath, char *szFileName)

+{

+    int build;

+	   

+    union

+    {

+	    int  i;

+	    char c[4];

+    } locale;

+

+    if (sscanf(szFileName, "%i-%c%c%c%c.MPQ", &build, &locale.c[0], &locale.c[1], &locale.c[2], &locale.c[3]) != 5)

+	    return;

+

+    // Try to open the patch file

+    std::string path = szPath;

+    path += szFileName;

+

+    FILE *pPatch = fopen(path.c_str(), "rb");

+

+    if (!pPatch)

+    {

+	    sLog->outError("Error loading patch %s\n", path.c_str());

+	    return;

+    }

+

+    // Calculate the MD5 hash

+    MD5_CTX ctx;

+    MD5_Init(&ctx);

+    uint8* buffer = new uint8[512 * 1024];

+

+    while (!feof(pPatch))

+    {

+	    size_t read = fread(buffer, 1, 512 * 1024, pPatch);

+	    MD5_Update(&ctx, buffer, read);

+    }

+

+    delete [] buffer;

+    fseek(pPatch, 0, SEEK_END);

+    size_t size = ftell(pPatch);

+

+    // Store the result in the internal patch hash map

+    PATCH_INFO pi;

+    pi.build = build;

+    pi.locale = locale.i;

+    pi.filesize = uint64(size);

+    MD5_Final((uint8 *)&pi.md5, &ctx);

+    _patches.push_back(pi);

+   

+    sLog->outString("Added patch for %i %c%c%c%c.", build, locale.c[0], locale.c[1], locale.c[2], locale.c[3]);

+}

+

+// Resume patch transfer

+bool AuthSocket::_HandleXferResume()

+{

+    // Check packet length and patch existence

+    if (socket().recv_len() <  9 || !pPatch)

+    {

+	    sLog->outError("Error while resuming patch transfer (wrong packet)");

+	    return false;

+    }

+

+    // Launch a PatcherRunnable thread starting at a given patch file offset.

+    uint64 start;

+    socket().recv_skip(1);

+    socket().recv((char*)&start, sizeof(start));

+   

+    fseek(pPatch, 0, SEEK_END);

+    size_t size = ftell(pPatch);

+

+    fseek(pPatch, long(start), 0);

+

+    if (_patcher)

+    {

+	    _patcher->stop();

+	    delete _patcher;

+    }

+

+    _patcher = new PatcherRunnable(this, start, size);

+    ACE_Based::Thread u(_patcher);

+

+    return true;

+}

+

+// cancel patch transfer

+bool AuthSocket::_HandleXferCancel()

+{

+    sLog->outStaticDebug("Entering _HandleXferCancel");

+

+    // Close and delete the socket

+    socket().recv_skip(1);

+    socket().shutdown();

+

+    return true;

+}

+

+// Accept patch transfer

+bool AuthSocket::_HandleXferAccept()

+{

+    // Check packet length and patch existence

+    if (!pPatch)

+    {

+	    sLog->outError("Error while accepting patch transfer (wrong packet)");

+	    return false;

+    }

+

+    // Launch a PatcherRunnable thread, starting at the beginning of the patch file.

+    socket().recv_skip(1);

+    fseek(pPatch, 0, SEEK_END);

+    size_t size = ftell(pPatch);

+    fseek(pPatch, 0, 0);

+

+    if (_patcher)

+    {

+	    _patcher->stop();

+	    delete _patcher;

+    }

+

+    _patcher = new PatcherRunnable(this, 0, size);

+    ACE_Based::Thread u(_patcher);

+

+    return true;

+}

+

+

+PatcherRunnable::PatcherRunnable(class AuthSocket * as, uint64 _pos, uint64 _size)

+{

+    mySocket = as;

+    pos	  = _pos;

+    size	 = _size;

+    stopped  = false;

+}

+

+void PatcherRunnable::stop()

+{

+    stopped = true;

+}

+

+#if defined(__GNUC__)

+#pragma pack(1)

+#else

+#pragma pack(push, 1)

+#endif

+

+struct TransferDataPacket

+{

+    uint8  cmd;

+    uint16 chunk_size;

};


-typedef struct PATCH_INFO

+#if defined(__GNUC__)

+#pragma pack(1)

+#else

+#pragma pack(pop)

+#endif

+

+void PatcherRunnable::run()

{

-    uint8 md5[MD5_DIGEST_LENGTH];

-} PATCH_INFO;

+    while (pos < size && !stopped)

+    {

+	    uint64 left = size - pos;

+	    uint16 send = (left > 1500) ?  1500 : left;


-// Caches MD5 hash of client patches present on the server

-class Patcher

+	    char* tosend = new char[sizeof(TransferDataPacket) + send];

+	    TransferDataPacket* hdr = (TransferDataPacket*)tosend;

+

+	    hdr->cmd = XFER_DATA;

+	    hdr->chunk_size = send;

+	    fread(tosend + sizeof(TransferDataPacket), 1, send, mySocket->pPatch);

+	    mySocket->socket().send(tosend, sizeof(TransferDataPacket) + send);

+

+	    delete[] tosend;

+	    pos += send;

+

+	    ACE_OS::sleep(0.8);

+    }

+

+    if (!stopped)

+    {

+	    fclose(mySocket->pPatch);

+	    mySocket->pPatch   = NULL;

+	    mySocket->_patcher = NULL;

+    }

+}

+

+// Launch the patch hashing mechanism on object creation

+void Patcher::Initialize()

{

-public:

-    typedef std::map<std::string, PATCH_INFO*> Patches;

-    ~Patcher();

-    Patcher();

-    Patches::const_iterator begin() const { return _patches.begin(); }

-    Patches::const_iterator end() const { return _patches.end(); }

-    void LoadPatchMD5(char*);

-    bool GetHash(char * pat, uint8 mymd5[16]);

+    sLog->outString("\nSearching for available patches...\n");

+    LoadPatchesInfo();

+}


-private:

-    void LoadPatchesInfo();

-    Patches _patches;

-};

+// Close patch file descriptor before leaving

+AuthSocket::~AuthSocket(void)

+{

+    if (pPatch)

+    {

+	    sLog->outString("AuthSocket::~AuthSocket(void) - pPatch check");

+	    fclose(pPatch);

+	    pPatch = NULL;

+    }

+

+    if (_patcher)

+    {

+	    sLog->outString("AuthSocket::~AuthSocket(void) - _patcher check");

+	    _patcher->stop();

+	    delete _patcher;

+	    _patcher = NULL;

+    }

+}


const AuthHandler table[] =

{

@@ -190,23 +525,19 @@

	 { XFER_CANCEL,			  STATUS_CONNECTED, &AuthSocket::_HandleXferCancel	    }

};


-#define AUTH_TOTAL_COMMANDS 8

-

-// Holds the MD5 hash of client patches present on the server

-Patcher PatchesCache;

+#define AUTH_TOTAL_COMMANDS 9


// Constructor - set the N and g values for SRP6

AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket)

{

	 N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");

	 g.SetDword(7);

-    _authed = false;

+    _authed			   = false;

	 _accountSecurityLevel = SEC_PLAYER;

+    pPatch			    = NULL;

+    _patcher			  = NULL;

}


-// Close patch file descriptor before leaving

-AuthSocket::~AuthSocket(void) {}

-

// Accept the connection and set the s random value for SRP6

void AuthSocket::OnAccept(void)

{

@@ -222,6 +553,7 @@

void AuthSocket::OnRead()

{

	 uint8 _cmd;

+   

	 while (1)

	 {

		 if (!socket().recv_soft((char *)&_cmd, 1))

@@ -352,9 +684,21 @@

	 // Restore string order as its byte order is reversed

	 std::reverse(_os.begin(), _os.end());


+    _localizationName.resize(4);

+    for (int i = 0; i < 4; i++)

+	    _localizationName[i] = ch->country[4-i-1];

+

	 pkt << (uint8)AUTH_LOGON_CHALLENGE;

	 pkt << (uint8)0x00;


+    if (_expversion == NO_VALID_EXP_FLAG && !patcher.PossiblePatching(_build, _localizationName))

+    {

+	    pkt << (uint8) WOW_FAIL_VERSION_INVALID;

+	    socket().send((char const*)pkt.contents(), pkt.size());

+

+	    return true;

+    }

+

	 // Verify that this IP is not in the ip_banned table

	 LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));


@@ -484,10 +828,6 @@

					 uint8 secLevel = fields[4].GetUInt8();

					 _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;


-				    _localizationName.resize(4);

-				    for (int i = 0; i < 4; ++i)

-					    _localizationName[i] = ch->country[4-i-1];

-

					 sLog->outBasic("'%s:%d' [AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", socket().getRemoteAddress().c_str(), socket().getRemotePort(),

							 _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)

						 );

@@ -515,9 +855,11 @@

	 // If the client has no valid version

	 if (_expversion == NO_VALID_EXP_FLAG)

	 {

-	    // Check if we have the appropriate patch on the disk

-	    sLog->outDebug(LOG_FILTER_NETWORKIO, "Client with invalid version, patching is not implemented");

-	    socket().shutdown();

+	    if (!patcher.InitPatching(_build, _localizationName, this))

+	    {

+		    socket().shutdown();

+	    }

+

		 return true;

	 }


@@ -922,179 +1264,4 @@

	 socket().send((char const*)hdr.contents(), hdr.size());

	 return true;

-}

-

-// Resume patch transfer

-bool AuthSocket::_HandleXferResume()

-{

-    sLog->outStaticDebug("Entering _HandleXferResume");

-    // Check packet length and patch existence

-    if (socket().recv_len() < 9 || !pPatch)

-    {

-	    sLog->outError("Error while resuming patch transfer (wrong packet)");

-	    return false;

-    }

-

-    // Launch a PatcherRunnable thread starting at given patch file offset

-    uint64 start;

-    socket().recv_skip(1);

-    socket().recv((char*)&start, sizeof(start));

-    fseek(pPatch, long(start), 0);

-

-    ACE_Based::Thread u(new PatcherRunnable(this));

-    return true;

-}

-

-// Cancel patch transfer

-bool AuthSocket::_HandleXferCancel()

-{

-    sLog->outStaticDebug("Entering _HandleXferCancel");

-

-    // Close and delete the socket

-    socket().recv_skip(1);										 //clear input buffer

-    socket().shutdown();

-

-    return true;

-}

-

-// Accept patch transfer

-bool AuthSocket::_HandleXferAccept()

-{

-    sLog->outStaticDebug("Entering _HandleXferAccept");

-

-    // Check packet length and patch existence

-    if (!pPatch)

-    {

-	    sLog->outError("Error while accepting patch transfer (wrong packet)");

-	    return false;

-    }

-

-    // Launch a PatcherRunnable thread, starting at the beginning of the patch file

-    socket().recv_skip(1);										 // clear input buffer

-    fseek(pPatch, 0, 0);

-

-    ACE_Based::Thread u(new PatcherRunnable(this));

-    return true;

-}

-

-PatcherRunnable::PatcherRunnable(class AuthSocket* as)

-{

-    mySocket = as;

-}

-

-// Send content of patch file to the client

-void PatcherRunnable::run() {}

-

-// Preload MD5 hashes of existing patch files on server

-#ifndef _WIN32

-#include <dirent.h>

-#include <errno.h>

-void Patcher::LoadPatchesInfo()

-{

-    DIR *dirp;

-    struct dirent *dp;

-    dirp = opendir("./patches/");

-

-    if (!dirp)

-	    return;

-

-    while (dirp)

-    {

-	    errno = 0;

-	    if ((dp = readdir(dirp)) != NULL)

-	    {

-		    int l = strlen(dp->d_name);

-

-		    if (l < 8)

-			    continue;

-

-		    if (!memcmp(&dp->d_name[l - 4], ".mpq", 4))

-			    LoadPatchMD5(dp->d_name);

-	    }

-	    else

-	    {

-		    if (errno != 0)

-		    {

-			    closedir(dirp);

-			    return;

-		    }

-		    break;

-	    }

-    }

-

-    if (dirp)

-	    closedir(dirp);

-}

-#else

-void Patcher::LoadPatchesInfo()

-{

-    WIN32_FIND_DATA fil;

-    HANDLE hFil = FindFirstFile("./patches/*.mpq", &fil);

-    if (hFil == INVALID_HANDLE_VALUE)

-	    return;											 // no patches were found

-

-    do

-	    LoadPatchMD5(fil.cFileName);

-    while (FindNextFile(hFil, &fil));

-}

-#endif

-

-// Calculate and store MD5 hash for a given patch file

-void Patcher::LoadPatchMD5(char *szFileName)

-{

-    // Try to open the patch file

-    std::string path = "./patches/";

-    path += szFileName;

-    FILE* pPatch = fopen(path.c_str(), "rb");

-    sLog->outDebug(LOG_FILTER_NETWORKIO, "Loading patch info from %s\n", path.c_str());

-

-    if (!pPatch)

-    {

-	    sLog->outError("Error loading patch %s\n", path.c_str());

-	    return;

-    }

-

-    // Calculate the MD5 hash

-    MD5_CTX ctx;

-    MD5_Init(&ctx);

-    uint8* buf = new uint8[512 * 1024];

-

-    while (!feof(pPatch))

-    {

-	    size_t read = fread(buf, 1, 512 * 1024, pPatch);

-	    MD5_Update(&ctx, buf, read);

-    }

-

-    delete [] buf;

-    fclose(pPatch);

-

-    // Store the result in the internal patch hash map

-    _patches[path] = new PATCH_INFO;

-    MD5_Final((uint8 *)&_patches[path]->md5, &ctx);

-}

-

-// Get cached MD5 hash for a given patch file

-bool Patcher::GetHash(char * pat, uint8 mymd5[16])

-{

-    for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)

-	    if (!stricmp(pat, i->first.c_str()))

-	    {

-		    memcpy(mymd5, i->second->md5, 16);

-		    return true;

-	    }

-

-    return false;

-}

-

-// Launch the patch hashing mechanism on object creation

-Patcher::Patcher()

-{

-    LoadPatchesInfo();

-}

-

-// Empty and delete the patch map on termination

-Patcher::~Patcher()

-{

-    for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)

-	    delete i->second;

-}

+}

\ No newline at end of file

diff -r 73624ee6170e src/server/authserver/Server/AuthSocket.h

--- a/src/server/authserver/Server/AuthSocket.h Fri Jun 29 23:37:08 2012 +0200

+++ b/src/server/authserver/Server/AuthSocket.h Wed Jul 04 22:57:39 2012 +0200

@@ -23,6 +23,9 @@

#include "BigNumber.h"

#include "RealmSocket.h"


+#include "../Patcher.h"

+#include <openssl/md5.h>

+

// Handle login commands

class AuthSocket: public RealmSocket::Session

{

@@ -52,9 +55,11 @@

	 FILE* pPatch;

	 ACE_Thread_Mutex patcherLock;


+    PatcherRunnable *_patcher;

+    RealmSocket& socket(void) { return socket_; }

+

private:

	 RealmSocket& socket_;

-    RealmSocket& socket(void) { return socket_; }


	 BigNumber N, s, g, v;

	 BigNumber b, B;

any way to get WoTLK patches in .mpq instead of .exe?

Finally found .mpq patches (3.0.1 (stock) to 3.0.2) and renamed it “buildnumber”-enUS.mpq and loaded authserver… seen it got detected there but when I try to login to my server using stock client it just dont patch.I even tested patch by manually applying it on client and it worked :confused: