First version of server side avatar upload feature (support for external avatar server). Still hard coded, cannot be configured.
This commit is contained in:
@@ -84,6 +84,10 @@ HEADERS += \
|
|||||||
src/net/ircthread.h \
|
src/net/ircthread.h \
|
||||||
src/net/netexception.h \
|
src/net/netexception.h \
|
||||||
src/net/servermanager.h \
|
src/net/servermanager.h \
|
||||||
|
src/net/transferdata.h \
|
||||||
|
src/net/transferhelper.h \
|
||||||
|
src/net/uploaderthread.h \
|
||||||
|
src/net/uploadhelper.h \
|
||||||
src/third_party/tinyxml/tinystr.h \
|
src/third_party/tinyxml/tinystr.h \
|
||||||
src/third_party/tinyxml/tinyxml.h \
|
src/third_party/tinyxml/tinyxml.h \
|
||||||
src/third_party/libircclient/include/libircclient.h \
|
src/third_party/libircclient/include/libircclient.h \
|
||||||
@@ -179,6 +183,9 @@ SOURCES += \
|
|||||||
src/net/common/irccallback.cpp \
|
src/net/common/irccallback.cpp \
|
||||||
src/net/common/ircthread.cpp \
|
src/net/common/ircthread.cpp \
|
||||||
src/net/common/servermanager.cpp \
|
src/net/common/servermanager.cpp \
|
||||||
|
src/net/common/transferhelper.cpp \
|
||||||
|
src/net/common/uploaderthread.cpp \
|
||||||
|
src/net/common/uploadhelper.cpp \
|
||||||
src/gui/generic/serverguiwrapper.cpp \
|
src/gui/generic/serverguiwrapper.cpp \
|
||||||
src/gui/qttoolsinterface.cpp
|
src/gui/qttoolsinterface.cpp
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#define MAX_AVATAR_FILE_SIZE 30720
|
#define MAX_AVATAR_FILE_SIZE 30720
|
||||||
|
|
||||||
struct AvatarFileState;
|
struct AvatarFileState;
|
||||||
|
class UploaderThread;
|
||||||
|
|
||||||
class AvatarManager
|
class AvatarManager
|
||||||
{
|
{
|
||||||
@@ -77,6 +78,8 @@ private:
|
|||||||
|
|
||||||
mutable boost::mutex m_cacheDirMutex;
|
mutable boost::mutex m_cacheDirMutex;
|
||||||
std::string m_cacheDir;
|
std::string m_cacheDir;
|
||||||
|
|
||||||
|
boost::shared_ptr<UploaderThread> m_uploader;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "avatarmanager.h"
|
#include "avatarmanager.h"
|
||||||
#include <net/net_helper.h>
|
#include <net/net_helper.h>
|
||||||
#include <net/socket_msg.h>
|
#include <net/socket_msg.h>
|
||||||
|
#include <net/uploaderthread.h>
|
||||||
#include <core/loghelper.h>
|
#include <core/loghelper.h>
|
||||||
#include <core/crypthelper.h>
|
#include <core/crypthelper.h>
|
||||||
|
|
||||||
@@ -54,10 +55,13 @@ struct AvatarFileState
|
|||||||
|
|
||||||
AvatarManager::AvatarManager()
|
AvatarManager::AvatarManager()
|
||||||
{
|
{
|
||||||
|
m_uploader.reset(new UploaderThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarManager::~AvatarManager()
|
AvatarManager::~AvatarManager()
|
||||||
{
|
{
|
||||||
|
m_uploader->SignalTermination();
|
||||||
|
m_uploader->Join(UPLOADER_THREAD_TERMINATE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -87,6 +91,7 @@ AvatarManager::Init(const std::string &dataDir, const std::string &cacheDir)
|
|||||||
retVal = retVal && tmpRet;
|
retVal = retVal && tmpRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_uploader->Run();
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +361,7 @@ AvatarManager::StoreAvatarInCache(const MD5Buf &md5buf, AvatarFileType avatarFil
|
|||||||
if (!o.fail())
|
if (!o.fail())
|
||||||
{
|
{
|
||||||
o.write((const char *)data, size);
|
o.write((const char *)data, size);
|
||||||
|
//m_uploader->QueueUpload(fileName, size);
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_cachedAvatarsMutex);
|
boost::mutex::scoped_lock lock(m_cachedAvatarsMutex);
|
||||||
m_cachedAvatars.insert(AvatarMap::value_type(md5buf, fileName));
|
m_cachedAvatars.insert(AvatarMap::value_type(md5buf, fileName));
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ void startWindowImpl::networkError(int errorID, int /*osErrorID*/) {
|
|||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
break;
|
break;
|
||||||
case ERR_SOCK_INVALID_SERVERLIST_URL:
|
case ERR_SOCK_INVALID_SERVERLIST_URL:
|
||||||
case ERR_SOCK_DOWNLOAD_INVALID_URL:
|
case ERR_SOCK_TRANSFER_INVALID_URL:
|
||||||
{ QMessageBox::warning(this, tr("Network Error"),
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
tr("Invalid server list URL.\nPlease correct the address in the settings."),
|
tr("Invalid server list URL.\nPlease correct the address in the settings."),
|
||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
@@ -677,14 +677,14 @@ void startWindowImpl::networkError(int errorID, int /*osErrorID*/) {
|
|||||||
tr("Could not unzip the PokerTH internet server list."),
|
tr("Could not unzip the PokerTH internet server list."),
|
||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
break;
|
break;
|
||||||
case ERR_SOCK_DOWNLOAD_INIT_FAILED:
|
case ERR_SOCK_TRANSFER_INIT_FAILED:
|
||||||
case ERR_SOCK_DOWNLOAD_SELECT_FAILED:
|
case ERR_SOCK_TRANSFER_SELECT_FAILED:
|
||||||
case ERR_SOCK_DOWNLOAD_FAILED:
|
case ERR_SOCK_TRANSFER_FAILED:
|
||||||
{ QMessageBox::warning(this, tr("Network Error"),
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
tr("Could not download the PokerTH internet server list.\nPlease make sure you are directly connected to the internet."),
|
tr("Could not download the PokerTH internet server list.\nPlease make sure you are directly connected to the internet."),
|
||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
break;
|
break;
|
||||||
case ERR_SOCK_DOWNLOAD_OPEN_FAILED:
|
case ERR_SOCK_TRANSFER_OPEN_FAILED:
|
||||||
{ QMessageBox::warning(this, tr("Network Error"),
|
{ QMessageBox::warning(this, tr("Network Error"),
|
||||||
tr("Could not open the target file when downloading the server list."),
|
tr("Could not open the target file when downloading the server list."),
|
||||||
QMessageBox::Close); }
|
QMessageBox::Close); }
|
||||||
|
|||||||
@@ -21,148 +21,31 @@
|
|||||||
#include <net/downloadhelper.h>
|
#include <net/downloadhelper.h>
|
||||||
#include <net/netexception.h>
|
#include <net/netexception.h>
|
||||||
#include <net/socket_msg.h>
|
#include <net/socket_msg.h>
|
||||||
#include <curl/curl.h>
|
#include <net/transferdata.h>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
struct DownloadData
|
|
||||||
{
|
|
||||||
CURL *curlHandle;
|
|
||||||
CURLM *curlMultiHandle;
|
|
||||||
FILE *targetFile;
|
|
||||||
string curlUrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
DownloadHelper::DownloadHelper()
|
DownloadHelper::DownloadHelper()
|
||||||
{
|
{
|
||||||
m_data.reset(new DownloadData);
|
|
||||||
m_data->curlHandle = NULL;
|
|
||||||
m_data->curlMultiHandle = NULL;
|
|
||||||
m_data->targetFile = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadHelper::~DownloadHelper()
|
DownloadHelper::~DownloadHelper()
|
||||||
{
|
{
|
||||||
Cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DownloadHelper::Init(const string &url, const string &targetFileName)
|
DownloadHelper::InternalInit(const string &/*url*/, const string &targetFileName, const string &/*user*/, const string &/*password*/)
|
||||||
{
|
{
|
||||||
// Open target file for writing.
|
// Open target file for writing.
|
||||||
m_data->targetFile = fopen(targetFileName.c_str(), "wb");
|
GetData()->targetFile = fopen(targetFileName.c_str(), "wb");
|
||||||
if (!m_data->targetFile)
|
if (!GetData()->targetFile)
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_OPEN_FAILED, 0);
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_OPEN_FAILED, 0);
|
||||||
|
|
||||||
// Initialise curl.
|
|
||||||
m_data->curlHandle = curl_easy_init();
|
|
||||||
if (!m_data->curlHandle)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_INIT_FAILED, 0);
|
|
||||||
m_data->curlMultiHandle = curl_multi_init();
|
|
||||||
if (!m_data->curlMultiHandle)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_INIT_FAILED, 0);
|
|
||||||
|
|
||||||
// Use a copy of the url string, because some curl versions require a copy.
|
|
||||||
m_data->curlUrl = url;
|
|
||||||
if (curl_easy_setopt(m_data->curlHandle, CURLOPT_URL, m_data->curlUrl.c_str()) != CURLE_OK)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_INVALID_URL, 0);
|
|
||||||
// Assume that the following calls never fail.
|
// Assume that the following calls never fail.
|
||||||
curl_easy_setopt(m_data->curlHandle, CURLOPT_WRITEFUNCTION, NULL);
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_WRITEFUNCTION, NULL);
|
||||||
curl_easy_setopt(m_data->curlHandle, CURLOPT_WRITEDATA, m_data->targetFile);
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_WRITEDATA, GetData()->targetFile);
|
||||||
|
|
||||||
// Use the multi interface for better abort handling.
|
|
||||||
if (curl_multi_add_handle(m_data->curlMultiHandle, m_data->curlHandle) != CURLM_OK)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_INIT_FAILED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
DownloadHelper::Process()
|
|
||||||
{
|
|
||||||
bool retVal = false;
|
|
||||||
int runningHandles = 0;
|
|
||||||
CURLMcode curlResult;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
curlResult = curl_multi_perform(m_data->curlMultiHandle, &runningHandles);
|
|
||||||
} while (curlResult == CURLM_CALL_MULTI_PERFORM);
|
|
||||||
|
|
||||||
if (curlResult != CURLM_OK)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_FAILED, 0);
|
|
||||||
|
|
||||||
if (runningHandles)
|
|
||||||
{
|
|
||||||
struct timeval timeout;
|
|
||||||
fd_set readSet;
|
|
||||||
fd_set writeSet;
|
|
||||||
fd_set exceptSet;
|
|
||||||
int maxfd = -1;
|
|
||||||
|
|
||||||
FD_ZERO(&readSet);
|
|
||||||
FD_ZERO(&writeSet);
|
|
||||||
FD_ZERO(&exceptSet);
|
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000;
|
|
||||||
|
|
||||||
curl_multi_fdset(m_data->curlMultiHandle, &readSet, &writeSet, &exceptSet, &maxfd);
|
|
||||||
|
|
||||||
if (maxfd >= 0)
|
|
||||||
{
|
|
||||||
int selectResult = select(maxfd+1, &readSet, &writeSet, &exceptSet, &timeout);
|
|
||||||
if (!IS_VALID_SELECT(selectResult))
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_SELECT_FAILED, SOCKET_ERRNO());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Retrieve actual error code.
|
|
||||||
int numMsgs;
|
|
||||||
CURLMsg *tmpMsg;
|
|
||||||
CURLcode code = CURLE_FAILED_INIT;
|
|
||||||
do {
|
|
||||||
tmpMsg = curl_multi_info_read(m_data->curlMultiHandle, &numMsgs);
|
|
||||||
if (tmpMsg)
|
|
||||||
code = tmpMsg->data.result;
|
|
||||||
} while (tmpMsg && tmpMsg->msg != CURLMSG_DONE);
|
|
||||||
|
|
||||||
// Clean up the curl handles.
|
|
||||||
Cleanup();
|
|
||||||
|
|
||||||
// Throw exception if an error occured.
|
|
||||||
if (code != CURLE_OK)
|
|
||||||
{
|
|
||||||
if (code == CURLE_URL_MALFORMAT)
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_INVALID_URL, 0);
|
|
||||||
else
|
|
||||||
throw NetException(__FILE__, __LINE__, ERR_SOCK_DOWNLOAD_FAILED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
retVal = true;
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DownloadHelper::Cleanup()
|
|
||||||
{
|
|
||||||
if (m_data->curlMultiHandle)
|
|
||||||
{
|
|
||||||
curl_multi_cleanup(m_data->curlMultiHandle);
|
|
||||||
m_data->curlMultiHandle = NULL;
|
|
||||||
}
|
|
||||||
if (m_data->curlHandle)
|
|
||||||
{
|
|
||||||
curl_easy_cleanup(m_data->curlHandle);
|
|
||||||
m_data->curlHandle = NULL;
|
|
||||||
}
|
|
||||||
if (m_data->targetFile)
|
|
||||||
{
|
|
||||||
fflush(m_data->targetFile);
|
|
||||||
fclose(m_data->targetFile);
|
|
||||||
m_data->targetFile = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/socket_helper.h>
|
||||||
|
#include <net/transferhelper.h>
|
||||||
|
#include <net/netexception.h>
|
||||||
|
#include <net/socket_msg.h>
|
||||||
|
#include <net/transferdata.h>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
TransferHelper::TransferHelper()
|
||||||
|
{
|
||||||
|
m_data.reset(new TransferData);
|
||||||
|
m_data->curlHandle = NULL;
|
||||||
|
m_data->curlMultiHandle = NULL;
|
||||||
|
m_data->targetFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransferHelper::~TransferHelper()
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TransferHelper::Init(const string &url, const string &targetFileName, const string &user, const string &password)
|
||||||
|
{
|
||||||
|
// Initialise curl.
|
||||||
|
m_data->curlHandle = curl_easy_init();
|
||||||
|
if (!m_data->curlHandle)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INIT_FAILED, 0);
|
||||||
|
m_data->curlMultiHandle = curl_multi_init();
|
||||||
|
if (!m_data->curlMultiHandle)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INIT_FAILED, 0);
|
||||||
|
|
||||||
|
// Use a copy of the url string, because some curl versions require a copy.
|
||||||
|
m_data->curlUrl = url;
|
||||||
|
if (curl_easy_setopt(m_data->curlHandle, CURLOPT_URL, m_data->curlUrl.c_str()) != CURLE_OK)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INVALID_URL, 0);
|
||||||
|
|
||||||
|
InternalInit(url, targetFileName, user, password);
|
||||||
|
|
||||||
|
// Use the multi interface for better abort handling.
|
||||||
|
if (curl_multi_add_handle(m_data->curlMultiHandle, m_data->curlHandle) != CURLM_OK)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INIT_FAILED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TransferHelper::Process()
|
||||||
|
{
|
||||||
|
bool retVal = false;
|
||||||
|
int runningHandles = 0;
|
||||||
|
CURLMcode curlResult;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
curlResult = curl_multi_perform(m_data->curlMultiHandle, &runningHandles);
|
||||||
|
} while (curlResult == CURLM_CALL_MULTI_PERFORM);
|
||||||
|
|
||||||
|
if (curlResult != CURLM_OK)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_FAILED, 0);
|
||||||
|
|
||||||
|
if (runningHandles)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
fd_set readSet;
|
||||||
|
fd_set writeSet;
|
||||||
|
fd_set exceptSet;
|
||||||
|
int maxfd = -1;
|
||||||
|
|
||||||
|
FD_ZERO(&readSet);
|
||||||
|
FD_ZERO(&writeSet);
|
||||||
|
FD_ZERO(&exceptSet);
|
||||||
|
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = RECV_TIMEOUT_MSEC * 1000;
|
||||||
|
|
||||||
|
curl_multi_fdset(m_data->curlMultiHandle, &readSet, &writeSet, &exceptSet, &maxfd);
|
||||||
|
|
||||||
|
if (maxfd >= 0)
|
||||||
|
{
|
||||||
|
int selectResult = select(maxfd+1, &readSet, &writeSet, &exceptSet, &timeout);
|
||||||
|
if (!IS_VALID_SELECT(selectResult))
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_SELECT_FAILED, SOCKET_ERRNO());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Retrieve actual error code.
|
||||||
|
int numMsgs;
|
||||||
|
CURLMsg *tmpMsg;
|
||||||
|
CURLcode code = CURLE_FAILED_INIT;
|
||||||
|
do {
|
||||||
|
tmpMsg = curl_multi_info_read(m_data->curlMultiHandle, &numMsgs);
|
||||||
|
if (tmpMsg)
|
||||||
|
code = tmpMsg->data.result;
|
||||||
|
} while (tmpMsg && tmpMsg->msg != CURLMSG_DONE);
|
||||||
|
|
||||||
|
// Clean up the curl handles.
|
||||||
|
Cleanup();
|
||||||
|
|
||||||
|
// Throw exception if an error occured.
|
||||||
|
if (code != CURLE_OK)
|
||||||
|
{
|
||||||
|
if (code == CURLE_URL_MALFORMAT)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_INVALID_URL, 0);
|
||||||
|
else
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_FAILED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal = true;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TransferHelper::Cleanup()
|
||||||
|
{
|
||||||
|
if (m_data->curlMultiHandle)
|
||||||
|
{
|
||||||
|
curl_multi_cleanup(m_data->curlMultiHandle);
|
||||||
|
m_data->curlMultiHandle = NULL;
|
||||||
|
}
|
||||||
|
if (m_data->curlHandle)
|
||||||
|
{
|
||||||
|
curl_easy_cleanup(m_data->curlHandle);
|
||||||
|
m_data->curlHandle = NULL;
|
||||||
|
}
|
||||||
|
if (m_data->targetFile)
|
||||||
|
{
|
||||||
|
fflush(m_data->targetFile);
|
||||||
|
fclose(m_data->targetFile);
|
||||||
|
m_data->targetFile = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<TransferData>
|
||||||
|
TransferHelper::GetData()
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/uploaderthread.h>
|
||||||
|
#include <net/uploadhelper.h>
|
||||||
|
#include <net/netexception.h>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <core/loghelper.h>
|
||||||
|
|
||||||
|
#define UPLOAD_DELAY_MSEC 100
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
|
|
||||||
|
UploaderThread::UploaderThread()
|
||||||
|
: m_uploadInProgress(false)
|
||||||
|
{
|
||||||
|
m_uploadHelper.reset(new UploadHelper());
|
||||||
|
}
|
||||||
|
|
||||||
|
UploaderThread::~UploaderThread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UploaderThread::QueueUpload(const std::string &filename, int filesize)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_uploadQueueMutex);
|
||||||
|
m_uploadQueue.push(UploadData(filename, filesize));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UploaderThread::Main()
|
||||||
|
{
|
||||||
|
while (!ShouldTerminate())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (m_uploadInProgress)
|
||||||
|
{
|
||||||
|
m_uploadInProgress = m_uploadHelper->Process();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_uploadInProgress)
|
||||||
|
{
|
||||||
|
Msleep(UPLOAD_DELAY_MSEC);
|
||||||
|
UploadData data;
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_uploadQueueMutex);
|
||||||
|
if (!m_uploadQueue.empty())
|
||||||
|
{
|
||||||
|
data = m_uploadQueue.front();
|
||||||
|
m_uploadQueue.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!data.filename.empty() && data.filesize > 0)
|
||||||
|
{
|
||||||
|
path filepath(data.filename);
|
||||||
|
m_uploadHelper->Init("url" + filepath.leaf(), filepath.file_string().c_str(), "user", "pwd");
|
||||||
|
m_uploadInProgress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const NetException &e)
|
||||||
|
{
|
||||||
|
LOG_ERROR(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <net/socket_helper.h>
|
||||||
|
#include <net/uploadhelper.h>
|
||||||
|
#include <net/netexception.h>
|
||||||
|
#include <net/socket_msg.h>
|
||||||
|
#include <net/transferdata.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
readFunction(char *bufptr, size_t size, size_t nitems, void *userp)
|
||||||
|
{
|
||||||
|
FILE *tmpFile = (FILE *)userp;
|
||||||
|
int ret = fread(bufptr, size, nitems, tmpFile);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadHelper::UploadHelper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadHelper::~UploadHelper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UploadHelper::InternalInit(const string &/*url*/, const string &targetFileName, const string &user, const string &password)
|
||||||
|
{
|
||||||
|
int filesize = 0;
|
||||||
|
struct stat filestat;
|
||||||
|
|
||||||
|
if (stat(targetFileName.c_str(), &filestat) == 0) /* success */
|
||||||
|
filesize = filestat.st_size;
|
||||||
|
|
||||||
|
// Open target file for writing.
|
||||||
|
// Open target file for writing.
|
||||||
|
GetData()->targetFile = fopen(targetFileName.c_str(), "rb");
|
||||||
|
if (!GetData()->targetFile)
|
||||||
|
throw NetException(__FILE__, __LINE__, ERR_SOCK_TRANSFER_OPEN_FAILED, 0);
|
||||||
|
|
||||||
|
GetData()->userCredentials = user + ":" + password;
|
||||||
|
// Assume that the following calls never fail.
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_READFUNCTION, readFunction);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_READDATA, GetData()->targetFile);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_INFILESIZE_LARGE, filesize);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_USERPWD, GetData()->userCredentials.c_str());
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_UPLOAD, 1L);
|
||||||
|
curl_easy_setopt(GetData()->curlHandle, CURLOPT_PUT, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -21,32 +21,18 @@
|
|||||||
#ifndef _DOWNLOADHELPER_H_
|
#ifndef _DOWNLOADHELPER_H_
|
||||||
#define _DOWNLOADHELPER_H_
|
#define _DOWNLOADHELPER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <net/transferhelper.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
struct DownloadData;
|
|
||||||
|
|
||||||
|
|
||||||
class DownloadHelper
|
class DownloadHelper : public TransferHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DownloadHelper();
|
DownloadHelper();
|
||||||
virtual ~DownloadHelper();
|
virtual ~DownloadHelper();
|
||||||
|
|
||||||
// Set the parameters. Does not do any error checking.
|
protected:
|
||||||
// Throws an exception on failure.
|
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
||||||
void Init(const std::string &url, const std::string &targetFileName);
|
const std::string &user, const std::string &password);
|
||||||
|
|
||||||
// Returns true when done, false should call again.
|
|
||||||
// Throws an exception on error.
|
|
||||||
bool Process();
|
|
||||||
|
|
||||||
// Close all handles.
|
|
||||||
void Cleanup();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::auto_ptr<DownloadData> m_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -46,11 +46,11 @@
|
|||||||
#define ERR_SOCK_INVALID_SERVERLIST_MD5 23
|
#define ERR_SOCK_INVALID_SERVERLIST_MD5 23
|
||||||
#define ERR_SOCK_INVALID_SERVERLIST_XML 24
|
#define ERR_SOCK_INVALID_SERVERLIST_XML 24
|
||||||
#define ERR_SOCK_UNZIP_FAILED 25
|
#define ERR_SOCK_UNZIP_FAILED 25
|
||||||
#define ERR_SOCK_DOWNLOAD_INIT_FAILED 26
|
#define ERR_SOCK_TRANSFER_INIT_FAILED 26
|
||||||
#define ERR_SOCK_DOWNLOAD_OPEN_FAILED 27
|
#define ERR_SOCK_TRANSFER_OPEN_FAILED 27
|
||||||
#define ERR_SOCK_DOWNLOAD_INVALID_URL 28
|
#define ERR_SOCK_TRANSFER_INVALID_URL 28
|
||||||
#define ERR_SOCK_DOWNLOAD_SELECT_FAILED 29
|
#define ERR_SOCK_TRANSFER_SELECT_FAILED 29
|
||||||
#define ERR_SOCK_DOWNLOAD_FAILED 30
|
#define ERR_SOCK_TRANSFER_FAILED 30
|
||||||
// The following errors are game errors.
|
// The following errors are game errors.
|
||||||
#define ERR_NET_VERSION_NOT_SUPPORTED 101
|
#define ERR_NET_VERSION_NOT_SUPPORTED 101
|
||||||
#define ERR_NET_SERVER_MAINTENANCE 102
|
#define ERR_NET_SERVER_MAINTENANCE 102
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* libcurl transfer data struct. */
|
||||||
|
|
||||||
|
#ifndef _TRANSFERDATA_H_
|
||||||
|
#define _TRANSFERDATA_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct TransferData
|
||||||
|
{
|
||||||
|
CURL *curlHandle;
|
||||||
|
CURLM *curlMultiHandle;
|
||||||
|
FILE *targetFile;
|
||||||
|
std::string curlUrl;
|
||||||
|
std::string userCredentials;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* libcurl transfer helper. */
|
||||||
|
|
||||||
|
#ifndef _TRANSFERHELPER_H_
|
||||||
|
#define _TRANSFERHELPER_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
struct TransferData;
|
||||||
|
|
||||||
|
|
||||||
|
class TransferHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransferHelper();
|
||||||
|
virtual ~TransferHelper();
|
||||||
|
|
||||||
|
// Set the parameters. Does not do any error checking.
|
||||||
|
// Throws an exception on failure.
|
||||||
|
void Init(const std::string &url, const std::string &targetFileName,
|
||||||
|
const std::string &user = "", const std::string &password = "");
|
||||||
|
|
||||||
|
// Returns true when done, false should call again.
|
||||||
|
// Throws an exception on error.
|
||||||
|
bool Process();
|
||||||
|
|
||||||
|
// Close all handles.
|
||||||
|
void Cleanup();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
boost::shared_ptr<TransferData> GetData();
|
||||||
|
|
||||||
|
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
||||||
|
const std::string &user, const std::string &password) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
boost::shared_ptr<TransferData> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* Network file upload thread. */
|
||||||
|
|
||||||
|
#ifndef _UPLOADERTHREAD_H_
|
||||||
|
#define _UPLOADERTHREAD_H_
|
||||||
|
|
||||||
|
#include <core/thread.h>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#define UPLOADER_THREAD_TERMINATE_TIMEOUT THREAD_WAIT_INFINITE
|
||||||
|
class UploadHelper;
|
||||||
|
|
||||||
|
class UploaderThread : public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
UploaderThread();
|
||||||
|
virtual ~UploaderThread();
|
||||||
|
|
||||||
|
void QueueUpload(const std::string &filename, int filesize);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct UploadData
|
||||||
|
{
|
||||||
|
UploadData() : filesize(0) {}
|
||||||
|
UploadData(const std::string &f, int s) : filename(f), filesize(s) {}
|
||||||
|
|
||||||
|
std::string filename;
|
||||||
|
int filesize;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::queue<UploadData> UploadDataQueue;
|
||||||
|
|
||||||
|
// Main function of the thread.
|
||||||
|
virtual void Main();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
UploadDataQueue m_uploadQueue;
|
||||||
|
mutable boost::mutex m_uploadQueueMutex;
|
||||||
|
|
||||||
|
boost::shared_ptr<UploadHelper> m_uploadHelper;
|
||||||
|
bool m_uploadInProgress;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2009 by Lothar May *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
/* libcurl upload helper. */
|
||||||
|
|
||||||
|
#ifndef _UPLOADHELPER_H_
|
||||||
|
#define _UPLOADHELPER_H_
|
||||||
|
|
||||||
|
#include <net/transferhelper.h>
|
||||||
|
|
||||||
|
|
||||||
|
class UploadHelper : public TransferHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UploadHelper();
|
||||||
|
virtual ~UploadHelper();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void InternalInit(const std::string &url, const std::string &targetFileName,
|
||||||
|
const std::string &user, const std::string &password);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Reference in New Issue
Block a user