Skip to content

Commit

Permalink
Endian fixes for all FileSrv messages
Browse files Browse the repository at this point in the history
These don't go through the normal pnNetCli stuff for some reason, which
means we need to handle endian encoding/decoding when they are
constructed rather than when they are sent :(
  • Loading branch information
dpogue committed Sep 4, 2023
1 parent 29c4630 commit 7900279
Showing 1 changed file with 94 additions and 55 deletions.
149 changes: 94 additions & 55 deletions Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ You can contact Cyan Worlds, Inc. by email [email protected]
// It changes the logic by which the decision to attempt a reconnect is made.
#define LOAD_BALANCER_HARDWARE

static void StrCopyLE16(char16_t* dest, const char16_t source[], size_t chars) {
while ((chars > 1) && ((*dest = hsToLE16(*source++)) != 0)) {
--chars;
++dest;
}
if (chars)
*dest = 0;
}


namespace Ngl { namespace File {
/*****************************************************************************
Expand Down Expand Up @@ -107,12 +116,12 @@ struct CliFileConn : hsRefCnt {

void Destroy(); // cleans up the socket and buffer

void Dispatch (const Cli2File_MsgHeader * msg);
bool Recv_PingReply (const File2Cli_PingReply * msg);
bool Recv_BuildIdReply (const File2Cli_BuildIdReply * msg);
bool Recv_BuildIdUpdate (const File2Cli_BuildIdUpdate * msg);
bool Recv_ManifestReply (const File2Cli_ManifestReply * msg);
bool Recv_FileDownloadReply (const File2Cli_FileDownloadReply * msg);
void Dispatch(const Cli2File_MsgHeader * msg);
bool Recv_PingReply(const File2Cli_PingReply* recv);
bool Recv_BuildIdReply(const File2Cli_BuildIdReply* recv);
bool Recv_BuildIdUpdate(const File2Cli_BuildIdUpdate* recv);
bool Recv_ManifestReply(const File2Cli_ManifestReply* recv);
bool Recv_FileDownloadReply(const File2Cli_FileDownloadReply* recv);
};


Expand Down Expand Up @@ -419,7 +428,7 @@ static bool NotifyConnSocketRead (CliFileConn * conn, AsyncNotifySocketRead * re
if (conn->recvBuffer.size() < sizeof(uint32_t))
return true;

uint32_t msgSize = *(uint32_t *)conn->recvBuffer.data();
uint32_t msgSize = hsToLE32(*(uint32_t *)conn->recvBuffer.data());
if (conn->recvBuffer.size() < msgSize)
return true;

Expand Down Expand Up @@ -702,12 +711,12 @@ void CliFileConn::TimerPing () {
pingSendTimeMs = GetNonZeroTimeMs();

Cli2File_PingRequest msg;
msg.messageId = kCli2File_PingRequest;
msg.messageBytes = sizeof(msg);
msg.pingTimeMs = pingSendTimeMs;
msg.messageId = hsToLE32(kCli2File_PingRequest);
msg.messageBytes = hsToLE32(sizeof(msg));
msg.pingTimeMs = hsToLE32(pingSendTimeMs);

// read locks are reentrant, so calling Send is ok here within the read lock
Send(&msg, msg.messageBytes);
Send(&msg, sizeof(msg));
}
break;
}
Expand Down Expand Up @@ -740,7 +749,7 @@ void CliFileConn::Send (const void * data, unsigned bytes) {
void CliFileConn::Dispatch (const Cli2File_MsgHeader * msg) {

#define DISPATCH(a) case kFile2Cli_##a: Recv_##a((const File2Cli_##a *) msg); break
switch (msg->messageId) {
switch (hsToLE32(msg->messageId)) {
DISPATCH(PingReply);
DISPATCH(BuildIdReply);
DISPATCH(BuildIdUpdate);
Expand All @@ -752,43 +761,73 @@ void CliFileConn::Dispatch (const Cli2File_MsgHeader * msg) {
}

//============================================================================
bool CliFileConn::Recv_PingReply (
const File2Cli_PingReply * msg
) {
bool CliFileConn::Recv_PingReply(const File2Cli_PingReply* recv)
{
return true;
}

//============================================================================
bool CliFileConn::Recv_BuildIdReply (
const File2Cli_BuildIdReply * msg
) {
NetTransRecv(msg->transId, (const uint8_t *)msg, msg->messageBytes);
bool CliFileConn::Recv_BuildIdReply(const File2Cli_BuildIdReply* recv)
{
File2Cli_BuildIdReply msg;
msg.messageId = hsToLE32(recv->messageId);
msg.messageBytes = hsToLE32(recv->messageBytes);
msg.transId = hsToLE32(recv->transId);
msg.result = (ENetError)hsToLE32(recv->result);
msg.buildId = hsToLE32(recv->buildId);

NetTransRecv(msg.transId, (const uint8_t *)&msg, msg.messageBytes);

return true;
}

//============================================================================
bool CliFileConn::Recv_BuildIdUpdate (
const File2Cli_BuildIdUpdate * msg
) {
bool CliFileConn::Recv_BuildIdUpdate(const File2Cli_BuildIdUpdate* recv)
{
if (s_buildIdCallback)
s_buildIdCallback(msg->buildId);
s_buildIdCallback(hsToLE32(recv->buildId));
return true;
}

//============================================================================
bool CliFileConn::Recv_ManifestReply (
const File2Cli_ManifestReply * msg
) {
bool CliFileConn::Recv_ManifestReply(const File2Cli_ManifestReply* recv)
{
auto temp = std::make_unique<uint8_t[]>(hsToLE32(recv->messageBytes));

File2Cli_ManifestReply* msg = (File2Cli_ManifestReply*)temp.get();
msg->messageId = hsToLE32(recv->messageId);
msg->messageBytes = hsToLE32(recv->messageBytes);
msg->transId = hsToLE32(recv->transId);
msg->result = (ENetError)hsToLE32(recv->result);
msg->readerId = hsToLE32(recv->readerId);
msg->numFiles = hsToLE32(recv->numFiles);
msg->wcharCount = hsToLE32(recv->wcharCount);

// The manifest format includes \0 characters, so we can't just StrCopy
for (size_t i = 0; i < msg->wcharCount; i++) {
msg->manifestData[i] = hsToLE16(recv->manifestData[i]);
}

NetTransRecv(msg->transId, (const uint8_t *)msg, msg->messageBytes);

return true;
}

//============================================================================
bool CliFileConn::Recv_FileDownloadReply (
const File2Cli_FileDownloadReply * msg
) {
bool CliFileConn::Recv_FileDownloadReply(const File2Cli_FileDownloadReply* recv)
{
auto temp = std::make_unique<uint8_t[]>(hsToLE32(recv->messageBytes));

File2Cli_FileDownloadReply* msg = (File2Cli_FileDownloadReply*)temp.get();
msg->messageId = hsToLE32(recv->messageId);
msg->messageBytes = hsToLE32(recv->messageBytes);
msg->transId = hsToLE32(recv->transId);
msg->result = (ENetError)hsToLE32(recv->result);
msg->readerId = hsToLE32(recv->readerId);
msg->totalFileSize = hsToLE32(recv->totalFileSize);
msg->byteCount = hsToLE32(recv->byteCount);
std::memcpy(msg->fileData, recv->fileData, msg->byteCount);

NetTransRecv(msg->transId, (const uint8_t *)msg, msg->messageBytes);

return true;
Expand All @@ -814,12 +853,12 @@ bool BuildIdRequestTrans::Send () {
return false;

Cli2File_BuildIdRequest buildIdReq;
buildIdReq.messageId = kCli2File_BuildIdRequest;
buildIdReq.transId = m_transId;
buildIdReq.messageBytes = sizeof(buildIdReq);
buildIdReq.messageId = hsToLE32(kCli2File_BuildIdRequest);
buildIdReq.transId = hsToLE32(m_transId);
buildIdReq.messageBytes = hsToLE32(sizeof(buildIdReq));

m_conn->Send(&buildIdReq, sizeof(buildIdReq));

m_conn->Send(&buildIdReq, buildIdReq.messageBytes);

return true;
}

Expand Down Expand Up @@ -882,13 +921,13 @@ bool ManifestRequestTrans::Send () {
return false;

Cli2File_ManifestRequest manifestReq;
StrCopy(manifestReq.group, m_group, std::size(manifestReq.group));
manifestReq.messageId = kCli2File_ManifestRequest;
manifestReq.transId = m_transId;
manifestReq.messageBytes = sizeof(manifestReq);
manifestReq.buildId = m_buildId;
StrCopyLE16(manifestReq.group, m_group, std::size(manifestReq.group));
manifestReq.messageId = hsToLE32(kCli2File_ManifestRequest);
manifestReq.transId = hsToLE32(m_transId);
manifestReq.messageBytes = hsToLE32(sizeof(manifestReq));
manifestReq.buildId = hsToLE32(m_buildId);

m_conn->Send(&manifestReq, manifestReq.messageBytes);
m_conn->Send(&manifestReq, sizeof(manifestReq));

return true;
}
Expand Down Expand Up @@ -936,12 +975,12 @@ bool ManifestRequestTrans::Recv (

// tell the server we got the data
Cli2File_ManifestEntryAck manifestAck;
manifestAck.messageId = kCli2File_ManifestEntryAck;
manifestAck.transId = reply.transId;
manifestAck.messageBytes = sizeof(manifestAck);
manifestAck.readerId = reply.readerId;
manifestAck.messageId = hsToLE32(kCli2File_ManifestEntryAck);
manifestAck.transId = hsToLE32(reply.transId);
manifestAck.messageBytes = hsToLE32(sizeof(manifestAck));
manifestAck.readerId = hsToLE32(reply.readerId);

m_conn->Send(&manifestAck, manifestAck.messageBytes);
m_conn->Send(&manifestAck, sizeof(manifestAck));

// if wcharCount is 2 or less, the data only contains the terminator "\0\0" and we
// don't need to convert anything (and we are done)
Expand Down Expand Up @@ -1121,11 +1160,11 @@ bool DownloadRequestTrans::Send () {

Cli2File_FileDownloadRequest filedownloadReq;
const ST::utf16_buffer buffer = m_filename.AsString().to_utf16();
StrCopy(filedownloadReq.filename, buffer.data(), std::size(filedownloadReq.filename));
filedownloadReq.messageId = kCli2File_FileDownloadRequest;
filedownloadReq.transId = m_transId;
filedownloadReq.messageBytes = sizeof(filedownloadReq);
filedownloadReq.buildId = m_buildId;
StrCopyLE16(filedownloadReq.filename, buffer.data(), std::size(filedownloadReq.filename));
filedownloadReq.messageId = hsToLE32(kCli2File_FileDownloadRequest);
filedownloadReq.transId = hsToLE32(m_transId);
filedownloadReq.messageBytes = hsToLE32(sizeof(filedownloadReq));
filedownloadReq.buildId = hsToLE32(m_buildId);

m_conn->Send(&filedownloadReq, sizeof(filedownloadReq));

Expand All @@ -1151,12 +1190,12 @@ bool DownloadRequestTrans::Recv (

// tell the server we got the data
Cli2File_FileDownloadChunkAck fileAck;
fileAck.messageId = kCli2File_FileDownloadChunkAck;
fileAck.transId = reply.transId;
fileAck.messageBytes = sizeof(fileAck);
fileAck.readerId = reply.readerId;
fileAck.messageId = hsToLE32(kCli2File_FileDownloadChunkAck);
fileAck.transId = hsToLE32(reply.transId);
fileAck.messageBytes = hsToLE32(sizeof(fileAck));
fileAck.readerId = hsToLE32(reply.readerId);

m_conn->Send(&fileAck, fileAck.messageBytes);
m_conn->Send(&fileAck, sizeof(fileAck));

if (IS_NET_ERROR(reply.result)) {
// we have a problem... indicate we are done and abort
Expand Down

0 comments on commit 7900279

Please sign in to comment.