mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 22:37:02 +00:00
[Realmd] Added submodule back in
This commit is contained in:
parent
92fd7b3ca1
commit
11641a8bd7
15 changed files with 3321 additions and 0 deletions
221
src/realmd/PatchHandler.cpp
Normal file
221
src/realmd/PatchHandler.cpp
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/**
|
||||
* MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
||||
*
|
||||
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
\ingroup realmd
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "PatchHandler.h"
|
||||
#include "AuthCodes.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <ace/OS_NS_sys_socket.h>
|
||||
#include <ace/OS_NS_dirent.h>
|
||||
#include <ace/OS_NS_errno.h>
|
||||
#include <ace/OS_NS_unistd.h>
|
||||
|
||||
#include <ace/os_include/netinet/os_tcp.h>
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#pragma pack(push,1)
|
||||
#endif
|
||||
|
||||
struct Chunk
|
||||
{
|
||||
ACE_UINT8 cmd;
|
||||
ACE_UINT16 data_size;
|
||||
ACE_UINT8 data[4096]; // 4096 - page size on most arch
|
||||
};
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#pragma pack()
|
||||
#else
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
PatchHandler::PatchHandler(ACE_HANDLE socket, ACE_HANDLE patch)
|
||||
{
|
||||
reactor(NULL);
|
||||
set_handle(socket);
|
||||
patch_fd_ = patch;
|
||||
}
|
||||
|
||||
PatchHandler::~PatchHandler()
|
||||
{
|
||||
if (patch_fd_ != ACE_INVALID_HANDLE)
|
||||
{ ACE_OS::close(patch_fd_); }
|
||||
}
|
||||
|
||||
int PatchHandler::open(void*)
|
||||
{
|
||||
if (get_handle() == ACE_INVALID_HANDLE || patch_fd_ == ACE_INVALID_HANDLE)
|
||||
{ return -1; }
|
||||
|
||||
int nodelay = 0;
|
||||
if (-1 == peer().set_option(ACE_IPPROTO_TCP,
|
||||
TCP_NODELAY,
|
||||
&nodelay,
|
||||
sizeof(nodelay)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(TCP_CORK)
|
||||
int cork = 1;
|
||||
if (-1 == peer().set_option(ACE_IPPROTO_TCP,
|
||||
TCP_CORK,
|
||||
&cork,
|
||||
sizeof(cork)))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif // TCP_CORK
|
||||
|
||||
(void) peer().disable(ACE_NONBLOCK);
|
||||
|
||||
return activate(THR_NEW_LWP | THR_DETACHED | THR_INHERIT_SCHED);
|
||||
}
|
||||
|
||||
int PatchHandler::svc(void)
|
||||
{
|
||||
// Do 1 second sleep, similar to the one in game/WorldSocket.cpp
|
||||
// Seems client have problems with too fast sends.
|
||||
ACE_OS::sleep(1);
|
||||
|
||||
int flags = MSG_NOSIGNAL;
|
||||
|
||||
Chunk data;
|
||||
data.cmd = CMD_XFER_DATA;
|
||||
|
||||
ssize_t r;
|
||||
|
||||
while ((r = ACE_OS::read(patch_fd_, data.data, sizeof(data.data))) > 0)
|
||||
{
|
||||
data.data_size = (ACE_UINT16)r;
|
||||
|
||||
if (peer().send((const char*)&data,
|
||||
((size_t) r) + sizeof(data) - sizeof(data.data),
|
||||
flags) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (r == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PatchCache::~PatchCache()
|
||||
{
|
||||
for (Patches::iterator i = patches_.begin(); i != patches_.end(); ++i)
|
||||
{ delete i->second; }
|
||||
}
|
||||
|
||||
PatchCache::PatchCache()
|
||||
{
|
||||
LoadPatchesInfo();
|
||||
}
|
||||
|
||||
PatchCache* PatchCache::instance()
|
||||
{
|
||||
return ACE_Singleton<PatchCache, ACE_Thread_Mutex>::instance();
|
||||
}
|
||||
|
||||
void PatchCache::LoadPatchMD5(const char* szFileName)
|
||||
{
|
||||
// Try to open the patch file
|
||||
std::string path = "./patches/";
|
||||
path += szFileName;
|
||||
FILE* pPatch = fopen(path.c_str(), "rb");
|
||||
sLog.outDebug("Loading patch info from %s", path.c_str());
|
||||
|
||||
if (!pPatch)
|
||||
{ return; }
|
||||
|
||||
// Calculate the MD5 hash
|
||||
MD5_CTX ctx;
|
||||
MD5_Init(&ctx);
|
||||
|
||||
const size_t check_chunk_size = 4 * 1024;
|
||||
|
||||
ACE_UINT8 buf[check_chunk_size];
|
||||
|
||||
while (!feof(pPatch))
|
||||
{
|
||||
size_t read = fread(buf, 1, check_chunk_size, pPatch);
|
||||
MD5_Update(&ctx, buf, read);
|
||||
}
|
||||
|
||||
fclose(pPatch);
|
||||
|
||||
// Store the result in the internal patch hash map
|
||||
patches_[path] = new PATCH_INFO;
|
||||
MD5_Final((ACE_UINT8*) & patches_[path]->md5, &ctx);
|
||||
}
|
||||
|
||||
bool PatchCache::GetHash(const char* pat, ACE_UINT8 mymd5[MD5_DIGEST_LENGTH])
|
||||
{
|
||||
for (Patches::iterator i = patches_.begin(); i != patches_.end(); ++i)
|
||||
if (!stricmp(pat, i->first.c_str()))
|
||||
{
|
||||
memcpy(mymd5, i->second->md5, MD5_DIGEST_LENGTH);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PatchCache::LoadPatchesInfo()
|
||||
{
|
||||
ACE_DIR* dirp = ACE_OS::opendir(ACE_TEXT("./patches/"));
|
||||
|
||||
if (!dirp)
|
||||
{ return; }
|
||||
|
||||
ACE_DIRENT* dp;
|
||||
|
||||
while ((dp = ACE_OS::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); }
|
||||
}
|
||||
|
||||
ACE_OS::closedir(dirp);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue