Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 61 additions & 3 deletions src/TConsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <lua.hpp>
#include <mutex>
#include <openssl/opensslv.h>
#include <regex>
#include <sstream>
#include <stdexcept>
#include <unordered_map>
Expand Down Expand Up @@ -75,6 +76,62 @@ TEST_CASE("TrimString") {
CHECK(TrimString("") == "");
}

static std::string ConvertColorCodes(const std::string& input) {
static const std::unordered_map<char, std::string> ColorMap = {
{ 'r', "\x1b[0m" }, // reset
{ 'p', "\n" }, // newline
{ 'n', "\x1b[4m" }, // underline
{ 'l', "\x1b[1m" }, // bold
{ 'm', "\x1b[9m" }, // strike-through
{ 'o', "\x1b[3m" }, // italic
{ '0', "\x1b[30m" }, // black
{ '1', "\x1b[34m" }, // blue
{ '2', "\x1b[32m" }, // green
{ '3', "\x1b[36m" }, // cyan
{ '4', "\x1b[31m" }, // red
{ '5', "\x1b[35m" }, // magenta
{ '6', "\x1b[33m" }, // yellow/orange
{ '7', "\x1b[37m" }, // white
{ '8', "\x1b[90m" }, // dark gray
{ '9', "\x1b[94m" }, // light blue
{ 'a', "\x1b[92m" }, // light green
{ 'b', "\x1b[96m" }, // light cyan
{ 'c', "\x1b[91m" }, // light red
{ 'd', "\x1b[95m" }, // light magenta
{ 'e', "\x1b[93m" }, // light yellow
{ 'f', "\x1b[97m" }, // bright white
};

std::string result;
result.reserve(input.size());

for (size_t i = 0; i < input.size(); ++i) {
if (input[i] == '^' && i + 1 < input.size()) {
char code = static_cast<char>(std::tolower(static_cast<unsigned char>(input[i + 1])));
auto it = ColorMap.find(code);
if (it != ColorMap.end()) {
result += it->second;
++i;
continue;
}
}
result += input[i];
}

return result;
}

TEST_CASE("ConvertColorCodes") {
CHECK(ConvertColorCodes("^rHello") == "\x1b[0mHello");
CHECK(ConvertColorCodes("^4Red^r") == "\x1b[31mRed\x1b[0m");
CHECK(ConvertColorCodes("^lBold^r") == "\x1b[1mBold\x1b[0m");
CHECK(ConvertColorCodes("No codes") == "No codes");
CHECK(ConvertColorCodes("^") == "^");
CHECK(ConvertColorCodes("^^") == "^^");
CHECK(ConvertColorCodes("^z") == "^z");
CHECK(ConvertColorCodes("^2Green ^4Red^r") == "\x1b[32mGreen \x1b[31mRed\x1b[0m");
}

static std::string GetDate() {
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
time_t tt = std::chrono::system_clock::to_time_t(now);
Expand Down Expand Up @@ -896,7 +953,7 @@ void TConsole::InitializeCommandline() {
}

void TConsole::Write(const std::string& str) {
auto ToWrite = GetDate() + str;
auto ToWrite = GetDate() + ConvertColorCodes(str);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be moved to a higher level function? I'd prefer this to be part of a printColored function (in-line with print and printRaw in lua, c++ code can just call this helper) instead of applying to everything going to the console.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my opinion, but I don't necessarily see the point of having several print functions. You might as well have one that handles most things. That's how it works right now: print(“\x1b[31mError: \x1b[0mSomething went wrong”). I just simplified it by doing this: print("^4Error: ^rSomething went wrong"). I think it would be overkill to have fun creating new print functions.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want server scripts to suddenly output unexpected text, however I suppose the original will still be present in the server log.
Either way, this should be something applied in the lua api handler, not for everything going to the terminal.

// allows writing to stdout without an initialized console
if (mCommandline) {
mCommandline->write(ToWrite);
Expand All @@ -906,11 +963,12 @@ void TConsole::Write(const std::string& str) {
}

void TConsole::WriteRaw(const std::string& str) {
auto ToWrite = ConvertColorCodes(str);
// allows writing to stdout without an initialized console
if (mCommandline) {
mCommandline->write(str);
mCommandline->write(ToWrite);
} else {
std::cout << str << std::endl;
std::cout << ToWrite << std::endl;
}
}

Expand Down