Handle email dumping separately from chat dumping

This makes it actually possible to unambiguously parse the full thing
on the receiving end.
This commit is contained in:
dongresource 2021-12-03 22:23:59 +01:00
parent 9ab998688c
commit 05d6174351
3 changed files with 56 additions and 3 deletions

View File

@ -10,6 +10,8 @@
using namespace Email; using namespace Email;
std::vector<std::string> Email::dump;
// New email notification // New email notification
static void emailUpdateCheck(CNSocket* sock, CNPacketData* data) { static void emailUpdateCheck(CNSocket* sock, CNPacketData* data) {
INITSTRUCT(sP_FE2CL_REP_PC_NEW_EMAIL, resp); INITSTRUCT(sP_FE2CL_REP_PC_NEW_EMAIL, resp);
@ -307,7 +309,7 @@ static void emailSend(CNSocket* sock, CNPacketData* data) {
std::string logEmail = "[Email] " + PlayerManager::getPlayerName(plr, true) + " (to " + PlayerManager::getPlayerName(&otherPlr, true) + "): <" + email.SubjectLine + ">\n" + email.MsgBody; std::string logEmail = "[Email] " + PlayerManager::getPlayerName(plr, true) + " (to " + PlayerManager::getPlayerName(&otherPlr, true) + "): <" + email.SubjectLine + ">\n" + email.MsgBody;
std::cout << logEmail << std::endl; std::cout << logEmail << std::endl;
Chat::dump.push_back(logEmail); dump.push_back(logEmail);
} }
void Email::init() { void Email::init() {

View File

@ -1,5 +1,10 @@
#pragma once #pragma once
#include <vector>
#include <string>
namespace Email { namespace Email {
void init(); extern std::vector<std::string> dump;
void init();
} }

View File

@ -1,6 +1,7 @@
#include "servers/CNShardServer.hpp" #include "servers/CNShardServer.hpp"
#include "PlayerManager.hpp" #include "PlayerManager.hpp"
#include "Chat.hpp" #include "Chat.hpp"
#include "Email.hpp"
#include "servers/Monitor.hpp" #include "servers/Monitor.hpp"
#include "settings.hpp" #include "settings.hpp"
@ -38,9 +39,42 @@ static bool transmit(std::list<SOCKET>::iterator& it, char *buff, int len) {
return true; return true;
} }
/*
* The longest protocol message is for an email.
*
* message type + two formatted character names + the other formatting chars
* + the email title + the email body = ~1154
*
* The body can grow to twice its usual size (512) in the pathological case
* where every character is a newline.
*
* Multi-byte Unicode characters aren't a factor, as they should've been
* stripped out by sanitizeText().
*/
#define BUFSIZE 2048
static int process_email(char *buff, std::string email) {
strncpy(buff, "email ", 6);
int i = 6;
for (char c : email) {
if (i == BUFSIZE-2)
break;
buff[i++] = c;
// indent each line to prevent "endemail" spoofing
if (c == '\n')
buff[i++] = '\t';
}
buff[i++] = '\n';
return i;
}
static void tick(CNServer *serv, time_t delta) { static void tick(CNServer *serv, time_t delta) {
std::lock_guard<std::mutex> lock(sockLock); std::lock_guard<std::mutex> lock(sockLock);
char buff[256]; char buff[BUFSIZE];
int n; int n;
auto it = sockets.begin(); auto it = sockets.begin();
@ -70,6 +104,17 @@ outer:
goto outer; goto outer;
} }
// emails
for (auto& str : Email::dump) {
n = process_email(buff, str);
if (!transmit(it, buff, n))
goto outer;
if (!transmit(it, (char*)"endemail\n", 9))
goto outer;
}
if (!transmit(it, (char*)"end\n", 4)) if (!transmit(it, (char*)"end\n", 4))
continue; continue;
@ -77,6 +122,7 @@ outer:
} }
Chat::dump.clear(); Chat::dump.clear();
Email::dump.clear();
} }
bool Monitor::acceptConnection(SOCKET fd, uint16_t revents) { bool Monitor::acceptConnection(SOCKET fd, uint16_t revents) {