mirror of
https://github.com/debauchee/barrier.git
synced 2026-07-18 03:51:10 +08:00
Patch by Jerry:
- Fixed line endings - Integ test for file transfer - Fixed crashed problem when log info is larger than 2048 bytes - Fixed compile error caused by std exception (by Feng ye) - Fixed include path on Mac and linux (by Feng ye)
This commit is contained in:
@@ -83,7 +83,7 @@ public:
|
||||
virtual void screensaver(bool activate) = 0;
|
||||
virtual void resetOptions() = 0;
|
||||
virtual void setOptions(const COptionsList& options) = 0;
|
||||
virtual void fileChunkSending(UInt8 mark, const UInt8* data) = 0;
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
|
||||
virtual CString getName() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2) = 0;
|
||||
virtual void gameDeviceTimingReq() = 0;
|
||||
virtual void cryptoIv(const UInt8* iv) = 0;
|
||||
virtual void fileChunkSending(UInt8 mark, const UInt8* data) = 0;
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0;
|
||||
|
||||
private:
|
||||
synergy::IStream* m_stream;
|
||||
|
||||
@@ -394,7 +394,7 @@ CClientProxy1_0::cryptoIv(const UInt8* iv)
|
||||
}
|
||||
|
||||
void
|
||||
CClientProxy1_0::fileChunkSending(UInt8 mark, const UInt8* iv)
|
||||
CClientProxy1_0::fileChunkSending(UInt8 mark, char* data, size_t dataSize)
|
||||
{
|
||||
// ignore -- not supported in protocol 1.0
|
||||
LOG((CLOG_DEBUG "fileChunkSending not supported"));
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
|
||||
virtual void gameDeviceTimingReq();
|
||||
virtual void cryptoIv(const UInt8* iv);
|
||||
virtual void fileChunkSending(UInt8 mark, const UInt8* data);
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
|
||||
|
||||
protected:
|
||||
virtual bool parseHandshakeMessage(const UInt8* code);
|
||||
|
||||
@@ -42,7 +42,6 @@ protected:
|
||||
private:
|
||||
void handleKeepAlive(const CEvent&, void*);
|
||||
|
||||
|
||||
private:
|
||||
double m_keepAliveRate;
|
||||
CEventQueueTimer* m_keepAliveTimer;
|
||||
|
||||
@@ -29,6 +29,14 @@ public:
|
||||
CClientProxy1_4(const CString& name, synergy::IStream* adoptedStream, CServer* server, IEventQueue* events);
|
||||
~CClientProxy1_4();
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! get server pointer
|
||||
CServer* getServer() { return m_server; }
|
||||
|
||||
//@}
|
||||
|
||||
// IClient overrides
|
||||
virtual void gameDeviceButtons(GameDeviceID id, GameDeviceButton buttons);
|
||||
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
#include "CProtocolUtil.h"
|
||||
#include "CLog.h"
|
||||
#include "IStream.h"
|
||||
#include "CServer.h"
|
||||
|
||||
//
|
||||
// CClientProxy1_5
|
||||
//
|
||||
|
||||
CClientProxy1_5::CClientProxy1_5(const CString& name, synergy::IStream* stream, CServer* server, IEventQueue* events) :
|
||||
CClientProxy1_4(name, stream, server, events)
|
||||
CClientProxy1_4(name, stream, server, events),
|
||||
m_events(events)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -34,23 +36,64 @@ CClientProxy1_5::~CClientProxy1_5()
|
||||
}
|
||||
|
||||
void
|
||||
CClientProxy1_5::fileChunkSending(UInt8 mark, const UInt8* data)
|
||||
CClientProxy1_5::fileChunkSending(UInt8 mark, char* data, size_t dataSize)
|
||||
{
|
||||
CString chunk(reinterpret_cast<const char*>(data));
|
||||
CString chunk(data, dataSize);
|
||||
|
||||
switch (mark) {
|
||||
case '0':
|
||||
LOG((CLOG_DEBUG2 "file sending start: file size = %s", data));
|
||||
case kFileStart:
|
||||
LOG((CLOG_DEBUG2 "file sending start: size=%s", data));
|
||||
break;
|
||||
|
||||
case '1':
|
||||
LOG((CLOG_DEBUG2 "file chunk sending: %s", data));
|
||||
case kFileChunk:
|
||||
LOG((CLOG_DEBUG2 "file chunk sending: size=%i", chunk.size()));
|
||||
break;
|
||||
|
||||
case '2':
|
||||
case kFileEnd:
|
||||
LOG((CLOG_DEBUG2 "file sending finished"));
|
||||
break;
|
||||
}
|
||||
|
||||
CProtocolUtil::writef(getStream(), kMsgDFileTransfer, mark, &chunk);
|
||||
}
|
||||
|
||||
bool
|
||||
CClientProxy1_5::parseMessage(const UInt8* code)
|
||||
{
|
||||
if (memcmp(code, kMsgDFileTransfer, 4) == 0) {
|
||||
fileChunkReceived();
|
||||
}
|
||||
else {
|
||||
return CClientProxy1_4::parseMessage(code);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CClientProxy1_5::fileChunkReceived()
|
||||
{
|
||||
// parse
|
||||
UInt8 mark;
|
||||
CString content;
|
||||
CProtocolUtil::readf(getStream(), kMsgDFileTransfer + 4, &mark, &content);
|
||||
|
||||
CServer* server = getServer();
|
||||
switch (mark) {
|
||||
case kFileStart:
|
||||
LOG((CLOG_DEBUG2 "recv file data from client: file size=%s", content.c_str()));
|
||||
server->clearReceivedFileData();
|
||||
server->setExpectedFileSize(content);
|
||||
break;
|
||||
|
||||
case kFileChunk:
|
||||
LOG((CLOG_DEBUG2 "recv file data from client: chunck size=%i", content.size()));
|
||||
server->fileChunkReceived(content);
|
||||
break;
|
||||
|
||||
case kFileEnd:
|
||||
LOG((CLOG_DEBUG2 "file data transfer finished"));
|
||||
m_events->addEvent(CEvent(m_events->forIScreen().fileRecieveComplete(), server));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,5 +28,10 @@ public:
|
||||
CClientProxy1_5(const CString& name, synergy::IStream* adoptedStream, CServer* server, IEventQueue* events);
|
||||
~CClientProxy1_5();
|
||||
|
||||
virtual void fileChunkSending(UInt8 mark, const UInt8* data);
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
|
||||
virtual bool parseMessage(const UInt8* code);
|
||||
void fileChunkReceived();
|
||||
|
||||
private:
|
||||
IEventQueue* m_events;
|
||||
};
|
||||
|
||||
@@ -274,7 +274,7 @@ CPrimaryClient::screensaver(bool)
|
||||
}
|
||||
|
||||
void
|
||||
CPrimaryClient::fileChunkSending(UInt8 mark, const UInt8* data)
|
||||
CPrimaryClient::fileChunkSending(UInt8 mark, char* data, size_t dataSize)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
virtual void screensaver(bool activate);
|
||||
virtual void resetOptions();
|
||||
virtual void setOptions(const COptionsList& options);
|
||||
virtual void fileChunkSending(UInt8 mark, const UInt8* data);
|
||||
virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
|
||||
|
||||
private:
|
||||
CScreen* m_screen;
|
||||
|
||||
@@ -33,14 +33,22 @@
|
||||
#include "TMethodEventJob.h"
|
||||
#include "CArch.h"
|
||||
#include "CKeyState.h"
|
||||
#include "CScreen.h"
|
||||
#include "CThread.h"
|
||||
#include "TMethodJob.h"
|
||||
#include "CFileChunker.h"
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include "CScreen.h"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
//
|
||||
// CServer
|
||||
//
|
||||
|
||||
const size_t CServer::m_chunkSize = 1024 * 512; // 512kb
|
||||
|
||||
CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen, IEventQueue* events) :
|
||||
m_events(events),
|
||||
m_mock(false),
|
||||
@@ -177,6 +185,10 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen
|
||||
this,
|
||||
new TMethodEventJob<CServer>(this,
|
||||
&CServer::handleFileChunkSendingEvent));
|
||||
m_events->adoptHandler(m_events->forIScreen().fileRecieveComplete(),
|
||||
this,
|
||||
new TMethodEventJob<CServer>(this,
|
||||
&CServer::handleFileRecieveCompleteEvent));
|
||||
|
||||
// add connection
|
||||
addClient(m_primaryClient);
|
||||
@@ -1516,8 +1528,13 @@ CServer::handleFakeInputEndEvent(const CEvent&, void*)
|
||||
void
|
||||
CServer::handleFileChunkSendingEvent(const CEvent& event, void*)
|
||||
{
|
||||
UInt8* data = reinterpret_cast<UInt8*>(event.getData());
|
||||
onFileChunkSending(data);
|
||||
onFileChunkSending(event.getData());
|
||||
}
|
||||
|
||||
void
|
||||
CServer::handleFileRecieveCompleteEvent(const CEvent& event, void*)
|
||||
{
|
||||
onFileRecieveComplete();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1981,13 +1998,32 @@ CServer::onGameDeviceTimingReq()
|
||||
}
|
||||
|
||||
void
|
||||
CServer::onFileChunkSending(const UInt8* data)
|
||||
CServer::onFileChunkSending(const void* data)
|
||||
{
|
||||
CFileChunker::CFileChunk* fileChunk = reinterpret_cast<CFileChunker::CFileChunk*>(const_cast<void*>(data));
|
||||
|
||||
LOG((CLOG_DEBUG1 "onFileChunkSending"));
|
||||
assert(m_active != NULL);
|
||||
|
||||
// relay
|
||||
m_active->fileChunkSending(data[0], &data[1]);
|
||||
m_active->fileChunkSending(fileChunk->m_chunk[0], &(fileChunk->m_chunk[1]), fileChunk->m_dataSize);
|
||||
}
|
||||
|
||||
void
|
||||
CServer::onFileRecieveComplete()
|
||||
{
|
||||
if (isReceivedFileSizeValid()) {
|
||||
if (!m_fileTransferDes.empty()) {
|
||||
std::fstream file;
|
||||
file.open(m_fileTransferDes.c_str(), std::ios::out | std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
// TODO: file open failed
|
||||
}
|
||||
|
||||
file.write(m_receivedFileData.c_str(), m_receivedFileData.size());
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2260,3 +2296,49 @@ CServer::CKeyboardBroadcastInfo::alloc(State state, const CString& screens)
|
||||
strcpy(info->m_screens, screens.c_str());
|
||||
return info;
|
||||
}
|
||||
|
||||
void
|
||||
CServer::clearReceivedFileData()
|
||||
{
|
||||
m_receivedFileData.clear();
|
||||
}
|
||||
|
||||
void
|
||||
CServer::setExpectedFileSize(CString data)
|
||||
{
|
||||
std::istringstream iss(data);
|
||||
iss >> m_expectedFileSize;
|
||||
}
|
||||
|
||||
void
|
||||
CServer::fileChunkReceived(CString data)
|
||||
{
|
||||
m_receivedFileData += data;
|
||||
}
|
||||
|
||||
bool
|
||||
CServer::isReceivedFileSizeValid()
|
||||
{
|
||||
return m_expectedFileSize == m_receivedFileData.size();
|
||||
}
|
||||
|
||||
void
|
||||
CServer::sendFileToClient(const char* filename)
|
||||
{
|
||||
CThread* thread = new CThread(
|
||||
new TMethodJob<CServer>(
|
||||
this, &CServer::sendFileThread,
|
||||
reinterpret_cast<void*>(const_cast<char*>(filename))));
|
||||
}
|
||||
|
||||
void
|
||||
CServer::sendFileThread(void* filename)
|
||||
{
|
||||
try {
|
||||
char* name = reinterpret_cast<char*>(filename);
|
||||
CFileChunker::sendFileChunks(name, m_events, this);
|
||||
}
|
||||
catch (std::runtime_error error) {
|
||||
LOG((CLOG_ERR "failed sending file chunks: %s", error.what()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,21 @@ public:
|
||||
//! Notify of game device feedback
|
||||
void gameDeviceFeedback(GameDeviceID id, UInt16 m1, UInt16 m2);
|
||||
|
||||
//! Clears the file buffer
|
||||
void clearReceivedFileData();
|
||||
|
||||
//! Set the expected size of receiving file
|
||||
void setExpectedFileSize(CString data);
|
||||
|
||||
//! Set
|
||||
void setFileTransferDes(CString& des) { m_fileTransferDes = des; }
|
||||
|
||||
//! Received a chunk of file data
|
||||
void fileChunkReceived(CString data);
|
||||
|
||||
//! Create a new thread and use it to send file to client
|
||||
void sendFileToClient(const char* filename);
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
//@{
|
||||
@@ -159,6 +174,9 @@ public:
|
||||
Set the \c list to the names of the currently connected clients.
|
||||
*/
|
||||
void getClients(std::vector<CString>& list) const;
|
||||
|
||||
//! Return true if recieved file size is valid
|
||||
bool isReceivedFileSizeValid();
|
||||
|
||||
//@}
|
||||
|
||||
@@ -299,6 +317,7 @@ private:
|
||||
void handleFakeInputBeginEvent(const CEvent&, void*);
|
||||
void handleFakeInputEndEvent(const CEvent&, void*);
|
||||
void handleFileChunkSendingEvent(const CEvent&, void*);
|
||||
void handleFileRecieveCompleteEvent(const CEvent&, void*);
|
||||
|
||||
// event processing
|
||||
void onClipboardChanged(CBaseClientProxy* sender,
|
||||
@@ -318,7 +337,8 @@ private:
|
||||
void onGameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
|
||||
void onGameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
|
||||
void onGameDeviceTimingReq();
|
||||
void onFileChunkSending(const UInt8* data);
|
||||
void onFileChunkSending(const void* data);
|
||||
void onFileRecieveComplete();
|
||||
|
||||
// add client to list and attach event handlers for client
|
||||
bool addClient(CBaseClientProxy*);
|
||||
@@ -343,6 +363,9 @@ private:
|
||||
// force the cursor off of \p client
|
||||
void forceLeaveClient(CBaseClientProxy* client);
|
||||
|
||||
// thread funciton for sending file
|
||||
void sendFileThread(void*);
|
||||
|
||||
public:
|
||||
bool m_mock;
|
||||
|
||||
@@ -438,6 +461,13 @@ private:
|
||||
CScreen* m_screen;
|
||||
|
||||
IEventQueue* m_events;
|
||||
|
||||
// file transfer
|
||||
size_t m_expectedFileSize;
|
||||
CString m_receivedFileData;
|
||||
static const size_t m_chunkSize;
|
||||
CString m_fileTransferSrc;
|
||||
CString m_fileTransferDes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user