Index: source/network/NetFileTransfer.h =================================================================== --- source/network/NetFileTransfer.h +++ source/network/NetFileTransfer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -86,6 +86,10 @@ */ Status HandleMessageReceive(const CNetMessage* message); + Status OnFileTransferResponse(const CNetMessage* message); + Status OnFileTransferData(const CNetMessage* message); + Status OnFileTransferAck(const CNetMessage* message); + /** * Registers a file-receiving task. */ Index: source/network/NetFileTransfer.cpp =================================================================== --- source/network/NetFileTransfer.cpp +++ source/network/NetFileTransfer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -27,104 +27,115 @@ Status CNetFileTransferer::HandleMessageReceive(const CNetMessage* message) { if (message->GetType() == NMT_FILE_TRANSFER_RESPONSE) - { - CFileTransferResponseMessage* respMessage = (CFileTransferResponseMessage*)message; - - if (m_FileReceiveTasks.find(respMessage->m_RequestID) == m_FileReceiveTasks.end()) - { - LOGERROR("Net transfer: Unsolicited file transfer response (id=%d)", (int)respMessage->m_RequestID); - return ERR::FAIL; - } + return OnFileTransferResponse(message); - if (respMessage->m_Length == 0 || respMessage->m_Length > MAX_FILE_TRANSFER_SIZE) - { - LOGERROR("Net transfer: Invalid size for file transfer response (length=%d)", (int)respMessage->m_Length); - return ERR::FAIL; - } + if (message->GetType() == NMT_FILE_TRANSFER_DATA) + return OnFileTransferData(message); - shared_ptr task = m_FileReceiveTasks[respMessage->m_RequestID]; + if (message->GetType() == NMT_FILE_TRANSFER_ACK) + return OnFileTransferAck(message); - task->m_Length = respMessage->m_Length; - task->m_Buffer.reserve(respMessage->m_Length); + return INFO::SKIPPED; +} - LOGMESSAGERENDER("Downloading data over network (%d KB) - please wait...", (int)(task->m_Length/1024)); - m_LastProgressReportTime = timer_Time(); +Status CNetFileTransferer::OnFileTransferResponse(const CNetMessage* message) +{ + CFileTransferResponseMessage* respMessage = (CFileTransferResponseMessage*)message; - return INFO::OK; + if (m_FileReceiveTasks.find(respMessage->m_RequestID) == m_FileReceiveTasks.end()) + { + LOGERROR("Net transfer: Unsolicited file transfer response (id=%d)", (int)respMessage->m_RequestID); + return ERR::FAIL; } - else if (message->GetType() == NMT_FILE_TRANSFER_DATA) + + if (respMessage->m_Length == 0 || respMessage->m_Length > MAX_FILE_TRANSFER_SIZE) { - CFileTransferDataMessage* dataMessage = (CFileTransferDataMessage*)message; + LOGERROR("Net transfer: Invalid size for file transfer response (length=%d)", (int)respMessage->m_Length); + return ERR::FAIL; + } - if (m_FileReceiveTasks.find(dataMessage->m_RequestID) == m_FileReceiveTasks.end()) - { - LOGERROR("Net transfer: Unsolicited file transfer data (id=%d)", (int)dataMessage->m_RequestID); - return ERR::FAIL; - } + shared_ptr task = m_FileReceiveTasks[respMessage->m_RequestID]; - shared_ptr task = m_FileReceiveTasks[dataMessage->m_RequestID]; + task->m_Length = respMessage->m_Length; + task->m_Buffer.reserve(respMessage->m_Length); - task->m_Buffer += dataMessage->m_Data; + LOGMESSAGERENDER("Downloading data over network (%d KB) - please wait...", (int)(task->m_Length/1024)); + m_LastProgressReportTime = timer_Time(); - if (task->m_Buffer.size() > task->m_Length) - { - LOGERROR("Net transfer: Invalid size for file transfer data (length=%d actual=%d)", (int)task->m_Length, (int)task->m_Buffer.size()); - return ERR::FAIL; - } + return INFO::OK; +} - CFileTransferAckMessage ackMessage; - ackMessage.m_RequestID = task->m_RequestID; - ackMessage.m_NumPackets = 1; // TODO: would be nice to send a single ack for multiple packets at once - m_Session->SendMessage(&ackMessage); +Status CNetFileTransferer::OnFileTransferData(const CNetMessage* message) +{ + CFileTransferDataMessage* dataMessage = (CFileTransferDataMessage*)message; - if (task->m_Buffer.size() == task->m_Length) - { - LOGMESSAGERENDER("Download completed"); + if (m_FileReceiveTasks.find(dataMessage->m_RequestID) == m_FileReceiveTasks.end()) + { + LOGERROR("Net transfer: Unsolicited file transfer data (id=%d)", (int)dataMessage->m_RequestID); + return ERR::FAIL; + } - task->OnComplete(); - m_FileReceiveTasks.erase(dataMessage->m_RequestID); - return INFO::OK; - } + shared_ptr task = m_FileReceiveTasks[dataMessage->m_RequestID]; - // TODO: should report progress using proper GUI + task->m_Buffer += dataMessage->m_Data; - // Report the download status occassionally - double t = timer_Time(); - if (t > m_LastProgressReportTime + 0.5) - { - LOGMESSAGERENDER("Downloading data: %.1f%% of %d KB", 100.f*task->m_Buffer.size()/task->m_Length, (int)(task->m_Length/1024)); - m_LastProgressReportTime = t; - } + if (task->m_Buffer.size() > task->m_Length) + { + LOGERROR("Net transfer: Invalid size for file transfer data (length=%d actual=%d)", (int)task->m_Length, (int)task->m_Buffer.size()); + return ERR::FAIL; + } + + CFileTransferAckMessage ackMessage; + ackMessage.m_RequestID = task->m_RequestID; + ackMessage.m_NumPackets = 1; // TODO: would be nice to send a single ack for multiple packets at once + m_Session->SendMessage(&ackMessage); + + if (task->m_Buffer.size() == task->m_Length) + { + LOGMESSAGERENDER("Download completed"); + task->OnComplete(); + m_FileReceiveTasks.erase(dataMessage->m_RequestID); return INFO::OK; } - else if (message->GetType() == NMT_FILE_TRANSFER_ACK) + + // TODO: should report progress using proper GUI + + // Report the download status occassionally + double t = timer_Time(); + if (t > m_LastProgressReportTime + 0.5) { - CFileTransferAckMessage* ackMessage = (CFileTransferAckMessage*)message; + LOGMESSAGERENDER("Downloading data: %.1f%% of %d KB", 100.f*task->m_Buffer.size()/task->m_Length, (int)(task->m_Length/1024)); + m_LastProgressReportTime = t; + } - if (m_FileSendTasks.find(ackMessage->m_RequestID) == m_FileSendTasks.end()) - { - LOGERROR("Net transfer: Unsolicited file transfer ack (id=%d)", (int)ackMessage->m_RequestID); - return ERR::FAIL; - } + return INFO::OK; +} - CNetFileSendTask& task = m_FileSendTasks[ackMessage->m_RequestID]; +Status CNetFileTransferer::OnFileTransferAck(const CNetMessage* message) +{ + CFileTransferAckMessage* ackMessage = (CFileTransferAckMessage*)message; - if (ackMessage->m_NumPackets > task.packetsInFlight) - { - LOGERROR("Net transfer: Invalid num packets for file transfer ack (num=%d inflight=%d)", - (int)ackMessage->m_NumPackets, (int)task.packetsInFlight); - return ERR::FAIL; - } + if (m_FileSendTasks.find(ackMessage->m_RequestID) == m_FileSendTasks.end()) + { + LOGERROR("Net transfer: Unsolicited file transfer ack (id=%d)", (int)ackMessage->m_RequestID); + return ERR::FAIL; + } - task.packetsInFlight -= ackMessage->m_NumPackets; + CNetFileSendTask& task = m_FileSendTasks[ackMessage->m_RequestID]; - return INFO::OK; + if (ackMessage->m_NumPackets > task.packetsInFlight) + { + LOGERROR("Net transfer: Invalid num packets for file transfer ack (num=%d inflight=%d)", + (int)ackMessage->m_NumPackets, (int)task.packetsInFlight); + return ERR::FAIL; } - return INFO::SKIPPED; -} + task.packetsInFlight -= ackMessage->m_NumPackets; + return INFO::OK; + +} void CNetFileTransferer::StartTask(const shared_ptr& task) {