Advertisement
Guest User

TrinityCore client patcher

a guest
Apr 28th, 2012
1,244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 20.52 KB | None | 0 0
  1. --- a/src/server/authserver/Main.cpp    Sun Jan 09 13:02:12 2011 +0100
  2. +++ b/src/server/authserver/Main.cpp    Mon Jan 10 19:25:05 2011 +0100
  3. @@ -43,6 +43,8 @@
  4.  
  5.  LoginDatabaseWorkerPool LoginDatabase;                      // Accessor to the realm server database
  6.  
  7. +extern Patcher patcher;
  8. +
  9.  // Handle realmd's termination signals
  10.  class RealmdSignalHandler : public Trinity::SignalHandler
  11.  {
  12. @@ -101,6 +103,8 @@
  13.      sLog->outString("%s (realm-daemon)", _FULLVERSION);
  14.      sLog->outString("<Ctrl-C> to stop.\n");
  15.      sLog->outString("Using configuration file %s.", cfg_file);
  16. +    
  17. +    patcher.Initialize();
  18.  
  19.      sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
  20.  
  21. --- a/src/server/authserver/Server/AuthSocket.cpp   Sun Jan 09 13:02:12 2011 +0100
  22. +++ b/src/server/authserver/Server/AuthSocket.cpp   Mon Jan 10 19:25:05 2011 +0100
  23. @@ -16,8 +16,6 @@
  24.   * with this program. If not, see <http://www.gnu.org/licenses/>.
  25.   */
  26.  
  27. -#include <openssl/md5.h>
  28. -
  29.  #include "Common.h"
  30.  #include "Database/DatabaseEnv.h"
  31.  #include "ByteBuffer.h"
  32. @@ -50,6 +48,13 @@
  33.      STATUS_AUTHED
  34.  };
  35.  
  36. +// TODO: Add as config variable.
  37. +#ifndef _WIN32
  38. +#define PATCH_PATH "../var/patches/"
  39. +#else
  40. +#define PATCH_PATH "./patches/"
  41. +#endif
  42. +
  43.  // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some paltform
  44.  #if defined(__GNUC__)
  45.  #pragma pack(1)
  46. @@ -143,38 +148,360 @@
  47.  #pragma pack(pop)
  48.  #endif
  49.  
  50. -// Launch a thread to transfer a patch to the client
  51. -class PatcherRunnable: public ACE_Based::Runnable
  52. +Patcher patcher;
  53. +
  54. +
  55. +PATCH_INFO* Patcher::getPatchInfo(int _build, std::string _locale, bool* fallback)
  56.  {
  57. -public:
  58. -    PatcherRunnable(class AuthSocket *);
  59. -    void run();
  60. +    PATCH_INFO* patch = NULL;
  61. +    int locale = *((int*)(_locale.c_str()));
  62. +    
  63. +    sLog->outDebug("Client with version %i and locale %s (%x) looking for patch.", _build, _locale.c_str(), locale);
  64. +    
  65. +    for(Patches::iterator it = _patches.begin(); it != _patches.end(); ++it)
  66. +        if(it->build == _build && it->locale == 'BGne')
  67. +        {
  68. +            patch = &(*it);
  69. +            *fallback = true;
  70. +        }
  71. +            
  72. +    for(Patches::iterator it = _patches.begin(); it != _patches.end(); ++it)
  73. +        if(it->build == _build && it->locale == locale)
  74. +        {
  75. +            patch = &(*it);
  76. +            *fallback = false;
  77. +        }
  78. +            
  79. +    return patch;
  80. +}
  81.  
  82. -private:
  83. -    AuthSocket * mySocket;
  84. +bool Patcher::PossiblePatching(int _build, std::string _locale)
  85. +{
  86. +    bool temp;
  87. +    return getPatchInfo(_build, _locale, &temp) != NULL;
  88. +}
  89. +
  90. +bool Patcher::InitPatching(int _build, std::string _locale, AuthSocket* _authsocket)
  91. +{
  92. +    bool fallback;
  93. +    PATCH_INFO* patch = getPatchInfo(_build, _locale,&fallback);
  94. +    
  95. +    // one of them nonzero, start patching.
  96. +    if(patch)
  97. +    {
  98. +           uint8 bytes[2] = {0x01,0x0a}; // authed, patch inc!
  99. +        _authsocket->socket().send((char *)&bytes, sizeof(bytes));
  100. +        
  101. +        std::stringstream path;
  102. +        if(fallback)
  103. +        {
  104. +            path << PATCH_PATH << _build << "-enGB.mpq";
  105. +        }
  106. +        else
  107. +        {
  108. +            path << PATCH_PATH << _build << "-" << _locale << ".mpq";
  109. +        }
  110. +        _authsocket->pPatch = fopen(path.str().c_str(),"rb");
  111. +        sLog->outError("Patch: %s", path.str().c_str());
  112. +        XFER_INIT packet;
  113. +        packet.cmd = XFER_INITIATE;
  114. +        packet.fileNameLen = 5;
  115. +        packet.fileName[0] = 'P';
  116. +        packet.fileName[1] = 'a';
  117. +        packet.fileName[2] = 't';
  118. +        packet.fileName[3] = 'c';
  119. +        packet.fileName[4] = 'h';
  120. +        packet.file_size = patch->filesize;
  121. +        memcpy(packet.md5,patch->md5,MD5_DIGEST_LENGTH);
  122. +        _authsocket->socket().send((char *)&packet, sizeof(packet));
  123. +        return true;
  124. +    }
  125. +    else
  126. +    {
  127. +        sLog->outError("Client with version %i and locale %s did not get a patch.", _build, _locale.c_str());
  128. +        return false;
  129. +    }
  130. +}
  131. +
  132. +// Preload MD5 hashes of existing patch files on server
  133. +#ifndef _WIN32
  134. +#include <dirent.h>
  135. +#include <errno.h>
  136. +void Patcher::LoadPatchesInfo()
  137. +{
  138. +    DIR *dirp;
  139. +    struct dirent *dp;
  140. +    dirp = opendir(PATCH_PATH);
  141. +
  142. +    if (!dirp)
  143. +        return;
  144. +
  145. +    while (dirp)
  146. +    {
  147. +        errno = 0;
  148. +        if ((dp = readdir(dirp)) != NULL)
  149. +        {
  150. +            int l = strlen(dp->d_name);
  151. +
  152. +            if (l < 8)
  153. +                continue;
  154. +
  155. +            if (!memcmp(&dp->d_name[l - 4], ".mpq", 4))
  156. +            {
  157. +                LoadPatchMD5(PATCH_PATH, dp->d_name);
  158. +            }
  159. +        }
  160. +        else
  161. +        {
  162. +            if (errno != 0)
  163. +            {
  164. +                closedir(dirp);
  165. +                return;
  166. +            }
  167. +            break;
  168. +        }
  169. +    }
  170. +
  171. +    if (dirp)
  172. +        closedir(dirp);
  173. +}
  174. +#else
  175. +void Patcher::LoadPatchesInfo()
  176. +{
  177. +    WIN32_FIND_DATA fil;
  178. +    HANDLE hFil = FindFirstFile(PATCH_PATH "*.mpq", &fil);
  179. +    if (hFil == INVALID_HANDLE_VALUE)
  180. +        return;                                             // no patches were found
  181. +
  182. +    do
  183. +    {
  184. +        LoadPatchMD5(PATCH_PATH, fil.cFileName);
  185. +    }
  186. +    while (FindNextFile(hFil, &fil));
  187. +}
  188. +#endif
  189. +
  190. +// Calculate and store MD5 hash for a given patch file
  191. +void Patcher::LoadPatchMD5(const char* szPath,char *szFileName)
  192. +{
  193. +    int build;
  194. +    union
  195. +    {
  196. +        int i;
  197. +        char c[4];
  198. +    } locale;
  199. +    
  200. +    if(sscanf(szFileName,"%i-%c%c%c%c.mpq",&build,&locale.c[0],&locale.c[1],&locale.c[2],&locale.c[3]) != 5)
  201. +        return;
  202. +        
  203. +    // Try to open the patch file
  204. +    std::string path = szPath;
  205. +    path += szFileName;
  206. +    FILE *pPatch = fopen(path.c_str(), "rb");
  207. +
  208. +    if (!pPatch)
  209. +    {
  210. +        sLog->outError("Error loading patch %s\n", path.c_str());
  211. +        return;
  212. +    }
  213. +
  214. +    // Calculate the MD5 hash
  215. +    MD5_CTX ctx;
  216. +    MD5_Init(&ctx);
  217. +    uint8* buf = new uint8[512 * 1024];
  218. +
  219. +    while (!feof(pPatch))
  220. +    {
  221. +        size_t read = fread(buf, 1, 512 * 1024, pPatch);
  222. +        MD5_Update(&ctx, buf, read);
  223. +    }
  224. +
  225. +    delete [] buf;
  226. +    fseek(pPatch,0,SEEK_END);
  227. +    size_t size = ftell(pPatch);
  228. +    fclose(pPatch);
  229. +
  230. +    // Store the result in the internal patch hash map
  231. +    PATCH_INFO pi;
  232. +    pi.build = build;
  233. +    pi.locale = locale.i;
  234. +    pi.filesize = uint64(size);
  235. +    MD5_Final((uint8 *)&pi.md5, &ctx);
  236. +    _patches.push_back(pi);
  237. +    sLog->outDebug("Added patch for %i %c%c%c%c.",build,locale.c[0],locale.c[1],locale.c[2],locale.c[3]);
  238. +}
  239. +
  240. +// Resume patch transfer
  241. +bool AuthSocket::_HandleXferResume()
  242. +{
  243. +    // Check packet length and patch existence
  244. +    if (socket().recv_len() < 9 || !pPatch)
  245. +    {
  246. +        sLog->outError("Error while resuming patch transfer (wrong packet)");
  247. +        return false;
  248. +    }
  249. +
  250. +    // Launch a PatcherRunnable thread starting at given patch file offset
  251. +    uint64 start;
  252. +    socket().recv_skip(1);
  253. +    socket().recv((char*)&start,sizeof(start));
  254. +    
  255. +    fseek(pPatch,0,SEEK_END);
  256. +    size_t size = ftell(pPatch);
  257. +    
  258. +    fseek(pPatch, long(start), 0);
  259. +
  260. +    if(_patcher)
  261. +    {
  262. +        _patcher->stop();
  263. +        delete _patcher;
  264. +    }
  265. +    _patcher = new PatcherRunnable(this,start,size);
  266. +    ACE_Based::Thread u(_patcher);
  267. +    return true;
  268. +}
  269. +
  270. +// Cancel patch transfer
  271. +bool AuthSocket::_HandleXferCancel()
  272. +{
  273. +    sLog->outStaticDebug("Entering _HandleXferCancel");
  274. +
  275. +    // Close and delete the socket
  276. +    socket().recv_skip(1);                                         //clear input buffer
  277. +    socket().shutdown();
  278. +
  279. +    return true;
  280. +}
  281. +
  282. +// Accept patch transfer
  283. +bool AuthSocket::_HandleXferAccept()
  284. +{
  285. +    // Check packet length and patch existence
  286. +    if (!pPatch)
  287. +    {
  288. +        sLog->outError("Error while accepting patch transfer (wrong packet)");
  289. +        return false;
  290. +    }
  291. +
  292. +    // Launch a PatcherRunnable thread, starting at the beginning of the patch file
  293. +    socket().recv_skip(1);                                         // clear input buffer
  294. +    fseek(pPatch,0,SEEK_END);
  295. +    size_t size = ftell(pPatch);
  296. +    fseek(pPatch, 0, 0);
  297. +
  298. +    if(_patcher)
  299. +    {
  300. +        _patcher->stop();
  301. +        delete _patcher;
  302. +    }
  303. +    _patcher = new PatcherRunnable(this,0,size);
  304. +    ACE_Based::Thread u(_patcher);
  305. +    return true;
  306. +}
  307. +
  308. +PatcherRunnable::PatcherRunnable(class AuthSocket * as,uint64 _pos,uint64 _size)
  309. +{
  310. +    mySocket = as;
  311. +    pos = _pos;
  312. +    size = _size;
  313. +    stopped = false;
  314. +}
  315. +
  316. +void PatcherRunnable::stop()
  317. +{
  318. +    stopped = true;
  319. +}
  320. +
  321. +#if defined(__GNUC__)
  322. +#pragma pack(1)
  323. +#else
  324. +#pragma pack(push,1)
  325. +#endif
  326. +struct TransferDataPacket
  327. +{
  328. +     uint8 cmd;
  329. +     uint16 chunk_size;
  330.  };
  331. +#if defined(__GNUC__)
  332. +#pragma pack()
  333. +#else
  334. +#pragma pack(pop)
  335. +#endif
  336.  
  337. -typedef struct PATCH_INFO
  338. +// Send content of patch file to the client
  339. +void PatcherRunnable::run()
  340.  {
  341. -    uint8 md5[MD5_DIGEST_LENGTH];
  342. -} PATCH_INFO;
  343. +    sLog->outDebug("PatcherRunnable::run(): %ld -> %ld",pos,size);
  344. +    //sleep(1);
  345. +    //sLog->outDebug("PatcherRunnable::run(): go!");
  346. +    
  347. +    while( pos < size && !stopped )
  348. +    {
  349. +        uint64 left = size - pos;
  350. +        uint16 send = (left>4096)?4096:left;
  351. +        
  352. +        char* tosend = new char[sizeof(TransferDataPacket)+send];
  353. +        TransferDataPacket* hdr = (TransferDataPacket*)tosend;
  354. +        hdr->cmd = 0x31;
  355. +        hdr->chunk_size = send;
  356. +        fread(tosend+sizeof(TransferDataPacket),1,send,mySocket->pPatch);
  357. +        mySocket->socket().send(tosend, sizeof(TransferDataPacket)+send);
  358. +    
  359. +        delete[] tosend;
  360. +        
  361. +        pos += send;
  362. +        usleep(1000);
  363. +    }
  364. +    
  365. +    if(!stopped)
  366. +    {
  367. +        fclose(mySocket->pPatch);
  368. +        mySocket->pPatch = NULL;
  369. +        mySocket->_patcher = NULL;
  370. +    }
  371. +    
  372. +    sLog->outDebug("patcher done.");
  373. +}
  374.  
  375. -// Caches MD5 hash of client patches present on the server
  376. -class Patcher
  377. +/*
  378. +// Get cached MD5 hash for a given patch file
  379. +bool Patcher::GetHash(char * pat, uint8 mymd5[16])
  380.  {
  381. -public:
  382. -    typedef std::map<std::string, PATCH_INFO*> Patches;
  383. -    ~Patcher();
  384. -    Patcher();
  385. -    Patches::const_iterator begin() const { return _patches.begin(); }
  386. -    Patches::const_iterator end() const { return _patches.end(); }
  387. -    void LoadPatchMD5(char*);
  388. -    bool GetHash(char * pat,uint8 mymd5[16]);
  389. +    for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)
  390. +        if (!stricmp(pat, i->first.c_str()))
  391. +        {
  392. +            memcpy(mymd5, i->second->md5, 16);
  393. +            return true;
  394. +        }
  395.  
  396. -private:
  397. -    void LoadPatchesInfo();
  398. -    Patches _patches;
  399. -};
  400. +    return false;
  401. +}*/
  402. +
  403. +// Launch the patch hashing mechanism on object creation
  404. +void Patcher::Initialize()
  405. +{
  406. +    sLog->outDebug("Searching for available patches.");
  407. +    LoadPatchesInfo();
  408. +}
  409. +
  410. +
  411. +
  412. +
  413. +// Close patch file descriptor before leaving
  414. +AuthSocket::~AuthSocket(void)
  415. +{
  416. +    if(pPatch)
  417. +    {
  418. +        fclose(pPatch);
  419. +        pPatch = NULL;
  420. +    }
  421. +    if(_patcher)
  422. +    {
  423. +        _patcher->stop();
  424. +        delete _patcher;
  425. +        _patcher = NULL;
  426. +    }
  427. +}
  428.  
  429.  const AuthHandler table[] =
  430.  {
  431. @@ -190,9 +517,6 @@
  432.  
  433.  #define AUTH_TOTAL_COMMANDS 8
  434.  
  435. -// Holds the MD5 hash of client patches present on the server
  436. -Patcher PatchesCache;
  437. -
  438.  // Constructor - set the N and g values for SRP6
  439.  AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket)
  440.  {
  441. @@ -200,11 +524,10 @@
  442.      g.SetDword(7);
  443.      _authed = false;
  444.      _accountSecurityLevel = SEC_PLAYER;
  445. +    pPatch = NULL;
  446. +    _patcher = NULL;
  447.  }
  448.  
  449. -// Close patch file descriptor before leaving
  450. -AuthSocket::~AuthSocket(void) {}
  451. -
  452.  // Accept the connection and set the s random value for SRP6
  453.  void AuthSocket::OnAccept(void)
  454.  {
  455. @@ -342,9 +665,20 @@
  456.      _login = (const char*)ch->I;
  457.      _build = ch->build;
  458.      _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG);
  459. +    
  460. +    _localizationName.resize(4);
  461. +    for (int i = 0; i < 4; ++i)
  462. +        _localizationName[i] = ch->country[4-i-1];
  463.  
  464.      pkt << (uint8)AUTH_LOGON_CHALLENGE;
  465.      pkt << (uint8)0x00;
  466. +    
  467. +    if (_expversion == NO_VALID_EXP_FLAG && !patcher.PossiblePatching(_build, _localizationName))
  468. +    {
  469. +        pkt << (uint8)WOW_FAIL_VERSION_INVALID;            
  470. +        socket().send((char const*)pkt.contents(), pkt.size());
  471. +        return true;
  472. +    }
  473.  
  474.      // Verify that this IP is not in the ip_banned table
  475.      LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDIPBANS));
  476. @@ -475,10 +809,6 @@
  477.                      uint8 secLevel = fields[4].GetUInt8();
  478.                      _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
  479.  
  480. -                    _localizationName.resize(4);
  481. -                    for (int i = 0; i < 4; ++i)
  482. -                        _localizationName[i] = ch->country[4-i-1];
  483. -
  484.                      sLog->outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName));
  485.                  }
  486.              }
  487. @@ -504,9 +834,10 @@
  488.      // If the client has no valid version
  489.      if (_expversion == NO_VALID_EXP_FLAG)
  490.      {
  491. -        // Check if we have the appropriate patch on the disk
  492. -        sLog->outDebug("Client with invalid version, patching is not implemented");
  493. -        socket().shutdown();
  494. +        if( !patcher.InitPatching(_build, _localizationName, this) )
  495. +        {
  496. +            socket().shutdown();
  497. +        }
  498.          return true;
  499.      }
  500.  
  501. @@ -894,178 +1225,3 @@
  502.  
  503.      return true;
  504.  }
  505. -
  506. -// Resume patch transfer
  507. -bool AuthSocket::_HandleXferResume()
  508. -{
  509. -    sLog->outStaticDebug("Entering _HandleXferResume");
  510. -    // Check packet length and patch existence
  511. -    if (socket().recv_len() < 9 || !pPatch)
  512. -    {
  513. -        sLog->outError("Error while resuming patch transfer (wrong packet)");
  514. -        return false;
  515. -    }
  516. -
  517. -    // Launch a PatcherRunnable thread starting at given patch file offset
  518. -    uint64 start;
  519. -    socket().recv_skip(1);
  520. -    socket().recv((char*)&start,sizeof(start));
  521. -    fseek(pPatch, long(start), 0);
  522. -
  523. -    ACE_Based::Thread u(new PatcherRunnable(this));
  524. -    return true;
  525. -}
  526. -
  527. -// Cancel patch transfer
  528. -bool AuthSocket::_HandleXferCancel()
  529. -{
  530. -    sLog->outStaticDebug("Entering _HandleXferCancel");
  531. -
  532. -    // Close and delete the socket
  533. -    socket().recv_skip(1);                                         //clear input buffer
  534. -    socket().shutdown();
  535. -
  536. -    return true;
  537. -}
  538. -
  539. -// Accept patch transfer
  540. -bool AuthSocket::_HandleXferAccept()
  541. -{
  542. -    sLog->outStaticDebug("Entering _HandleXferAccept");
  543. -
  544. -    // Check packet length and patch existence
  545. -    if (!pPatch)
  546. -    {
  547. -        sLog->outError("Error while accepting patch transfer (wrong packet)");
  548. -        return false;
  549. -    }
  550. -
  551. -    // Launch a PatcherRunnable thread, starting at the beginning of the patch file
  552. -    socket().recv_skip(1);                                         // clear input buffer
  553. -    fseek(pPatch, 0, 0);
  554. -
  555. -    ACE_Based::Thread u(new PatcherRunnable(this));
  556. -    return true;
  557. -}
  558. -
  559. -PatcherRunnable::PatcherRunnable(class AuthSocket * as)
  560. -{
  561. -    mySocket = as;
  562. -}
  563. -
  564. -// Send content of patch file to the client
  565. -void PatcherRunnable::run() {}
  566. -
  567. -// Preload MD5 hashes of existing patch files on server
  568. -#ifndef _WIN32
  569. -#include <dirent.h>
  570. -#include <errno.h>
  571. -void Patcher::LoadPatchesInfo()
  572. -{
  573. -    DIR *dirp;
  574. -    struct dirent *dp;
  575. -    dirp = opendir("./patches/");
  576. -
  577. -    if (!dirp)
  578. -        return;
  579. -
  580. -    while (dirp)
  581. -    {
  582. -        errno = 0;
  583. -        if ((dp = readdir(dirp)) != NULL)
  584. -        {
  585. -            int l = strlen(dp->d_name);
  586. -
  587. -            if (l < 8)
  588. -                continue;
  589. -
  590. -            if (!memcmp(&dp->d_name[l - 4], ".mpq", 4))
  591. -                LoadPatchMD5(dp->d_name);
  592. -        }
  593. -        else
  594. -        {
  595. -            if (errno != 0)
  596. -            {
  597. -                closedir(dirp);
  598. -                return;
  599. -            }
  600. -            break;
  601. -        }
  602. -    }
  603. -
  604. -    if (dirp)
  605. -        closedir(dirp);
  606. -}
  607. -#else
  608. -void Patcher::LoadPatchesInfo()
  609. -{
  610. -    WIN32_FIND_DATA fil;
  611. -    HANDLE hFil = FindFirstFile("./patches/*.mpq", &fil);
  612. -    if (hFil == INVALID_HANDLE_VALUE)
  613. -        return;                                             // no patches were found
  614. -
  615. -    do
  616. -        LoadPatchMD5(fil.cFileName);
  617. -    while (FindNextFile(hFil, &fil));
  618. -}
  619. -#endif
  620. -
  621. -// Calculate and store MD5 hash for a given patch file
  622. -void Patcher::LoadPatchMD5(char *szFileName)
  623. -{
  624. -    // Try to open the patch file
  625. -    std::string path = "./patches/";
  626. -    path += szFileName;
  627. -    FILE *pPatch = fopen(path.c_str(), "rb");
  628. -    sLog->outDebug("Loading patch info from %s\n", path.c_str());
  629. -
  630. -    if (!pPatch)
  631. -    {
  632. -        sLog->outError("Error loading patch %s\n", path.c_str());
  633. -        return;
  634. -    }
  635. -
  636. -    // Calculate the MD5 hash
  637. -    MD5_CTX ctx;
  638. -    MD5_Init(&ctx);
  639. -    uint8* buf = new uint8[512 * 1024];
  640. -
  641. -    while (!feof(pPatch))
  642. -    {
  643. -        size_t read = fread(buf, 1, 512 * 1024, pPatch);
  644. -        MD5_Update(&ctx, buf, read);
  645. -    }
  646. -
  647. -    delete [] buf;
  648. -    fclose(pPatch);
  649. -
  650. -    // Store the result in the internal patch hash map
  651. -    _patches[path] = new PATCH_INFO;
  652. -    MD5_Final((uint8 *)&_patches[path]->md5, &ctx);
  653. -}
  654. -
  655. -// Get cached MD5 hash for a given patch file
  656. -bool Patcher::GetHash(char * pat, uint8 mymd5[16])
  657. -{
  658. -    for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)
  659. -        if (!stricmp(pat, i->first.c_str()))
  660. -        {
  661. -            memcpy(mymd5, i->second->md5, 16);
  662. -            return true;
  663. -        }
  664. -
  665. -    return false;
  666. -}
  667. -
  668. -// Launch the patch hashing mechanism on object creation
  669. -Patcher::Patcher()
  670. -{
  671. -    LoadPatchesInfo();
  672. -}
  673. -
  674. -// Empty and delete the patch map on termination
  675. -Patcher::~Patcher()
  676. -{
  677. -    for (Patches::iterator i = _patches.begin(); i != _patches.end(); ++i)
  678. -        delete i->second;
  679. -}
  680.  
  681. --- a/src/server/authserver/Server/AuthSocket.h Sun Jan 09 13:02:12 2011 +0100
  682. +++ b/src/server/authserver/Server/AuthSocket.h Mon Jan 10 19:25:05 2011 +0100
  683. @@ -23,6 +23,8 @@
  684.  #include "BigNumber.h"
  685.  #include "RealmSocket.h"
  686.  
  687. +#include <openssl/md5.h>
  688. +
  689.  enum RealmFlags
  690.  {
  691.      REALM_FLAG_NONE                              = 0x00,
  692. @@ -36,6 +38,53 @@
  693.      REALM_FLAG_FULL                              = 0x80
  694.  };
  695.  
  696. +
  697. +class AuthSocket;
  698. +
  699. +// clientpatching
  700. +
  701. +typedef struct PATCH_INFO
  702. +{
  703. +    int build;
  704. +    int locale;
  705. +    uint64 filesize;
  706. +    uint8 md5[MD5_DIGEST_LENGTH];
  707. +} PATCH_INFO;
  708. +
  709. +class Patcher
  710. +{
  711. +    typedef std::vector<PATCH_INFO> Patches;
  712. +public:
  713. +    void Initialize();
  714. +    
  715. +    void LoadPatchMD5(const char*,char*);
  716. +    bool GetHash(char * pat,uint8 mymd5[16]);
  717. +    
  718. +    bool InitPatching(int _build, std::string _locale, AuthSocket* _authsocket);
  719. +    bool PossiblePatching(int _build, std::string _locale);
  720. +
  721. +private:
  722. +    PATCH_INFO* getPatchInfo(int _build, std::string _locale, bool* fallback);
  723. +
  724. +    void LoadPatchesInfo();
  725. +    Patches _patches;
  726. +};
  727. +
  728. +// Launch a thread to transfer a patch to the client
  729. +class PatcherRunnable: public ACE_Based::Runnable
  730. +{
  731. +public:
  732. +    PatcherRunnable(class AuthSocket *,uint64 start,uint64 size);
  733. +    void run();
  734. +    void stop();
  735. +
  736. +private:
  737. +    AuthSocket * mySocket;
  738. +    uint64 pos;
  739. +    uint64 size;
  740. +    bool stopped;
  741. +};
  742. +
  743.  // Handle login commands
  744.  class AuthSocket: public RealmSocket::Session
  745.  {
  746. @@ -64,10 +113,11 @@
  747.  
  748.      FILE *pPatch;
  749.      ACE_Thread_Mutex patcherLock;
  750. +    PatcherRunnable *_patcher;
  751.  
  752. +    RealmSocket& socket(void) { return socket_; }
  753.  private:
  754.      RealmSocket& socket_;
  755. -    RealmSocket& socket(void) { return socket_; }
  756.  
  757.      BigNumber N, s, g, v;
  758.      BigNumber b, B;
  759.      
  760. --- a/src/server/authserver/Server/RealmSocket.cpp  Sun Jan 09 13:02:12 2011 +0100
  761. +++ b/src/server/authserver/Server/RealmSocket.cpp  Mon Jan 10 19:25:05 2011 +0100
  762. @@ -246,6 +246,7 @@
  763.      if (session_)
  764.          session_->OnClose();
  765.  
  766. +    reactor()->remove_handler(this, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::ALL_EVENTS_MASK);
  767.      return 0;
  768.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement