Skip to content

Commit

Permalink
feat: console in launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMcAvoy committed Jan 3, 2025
1 parent 0e390b0 commit f239632
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 31 deletions.
15 changes: 12 additions & 3 deletions CarbonLauncher/include/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@
#include "repomanager.h"

namespace Carbon {
struct LogMessage {
std::string message;
std::string time;
};

// The main state of the Carbon Launcher
// Contains all the managers and the process target
class CarbonState_t {
public:
CarbonState_t() {
//#ifndef NDEBUG
// Tell winapi to show a console window
//#ifndef NDEBUG
// Tell winapi to show a console window
AllocConsole();
FILE* file;
freopen_s(&file, "CONOUT$", "w", stdout);
Expand All @@ -25,7 +30,7 @@ namespace Carbon {
spdlog::set_default_logger(console); // Set the default logger to the console logger
console->set_level(spdlog::level::trace); // Set the log level to info
spdlog::set_pattern("%^[ %H:%M:%S | %-8l] %n: %v%$"); // Nice log format
//#endif
//#endif
}

Carbon::GUIManager guiManager;
Expand All @@ -34,6 +39,10 @@ namespace Carbon {
Carbon::PipeManager pipeManager;
Carbon::RepoManager repoManager;

//std::vector<std::string> logMessages;

std::vector<LogMessage> logMessages;

// The target process to manage (e.g. ScrapMechanic.exe)
// This should never be a process that does not have a Contraption
// located in the same place as ScrapMechanic.exe
Expand Down
22 changes: 21 additions & 1 deletion CarbonLauncher/src/guimanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,25 @@ void _GUI() {
}
};

auto renderConsole = [&]() -> void {
ImGui::BeginChild("Console", ImVec2(0, 0), true);
auto begin = C.logMessages.begin();
auto end = C.logMessages.end();
for (auto it = begin; it != end; it++) {
auto& message = *it;
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.8f, 1.0f), message.time.c_str());
ImGui::SameLine();
ImGui::TextWrapped(message.message.c_str());
}

// If we were scrolled to the bottom, scroll down
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
ImGui::SetScrollHereY(1.0f);
}

ImGui::EndChild();
};

switch (C.guiManager.tab) {
case GUIManager::Tab::MyMods:
ImGui::SeparatorText("My Mods");
Expand All @@ -413,7 +432,8 @@ void _GUI() {
break;
case GUIManager::Tab::Console:
ImGui::SeparatorText("Console");
ImGui::TextWrapped("This is where the console will be");
renderConsole();

break;
case GUIManager::Tab::Settings:
ImGui::SeparatorText("Settings");
Expand Down
55 changes: 45 additions & 10 deletions CarbonLauncher/src/pipemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <spdlog/spdlog.h>

#include <ctime>

using namespace Carbon;

PipeManager::PipeManager() {
Expand All @@ -13,8 +15,8 @@ PipeManager::PipeManager() {
PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
1024 * 128,
1024 * 128,
0,
NULL
);
Expand All @@ -36,8 +38,15 @@ PipeManager::PipeManager() {
while (true) {
char buffer[1024]{};
DWORD bytesRead = 0;
if (!ReadFile(pipe, buffer, sizeof(buffer), &bytesRead, NULL)) {
spdlog::error("Failed to read from pipe");
auto res = ReadFile(pipe, buffer, sizeof(buffer), &bytesRead, NULL);
if (!res) {
//spdlog::error("Failed to read from pipe");
int code = GetLastError();
const char* error = nullptr;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&error, 0, nullptr);
spdlog::error("Failed to read from pipe: {}", error);
LocalFree((HLOCAL)error);

C.discordManager.UpdateState("In the launcher!");

Expand All @@ -53,9 +62,9 @@ PipeManager::PipeManager() {
PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
0,
1024 * 1024,
1024 * 1024,
PIPE_WAIT,
NULL
);

Expand All @@ -78,7 +87,7 @@ PipeManager::PipeManager() {
std::string packet(buffer, bytesRead);
auto delimiter = packet.find("-:-");
if (delimiter == std::string::npos) {
spdlog::error("Invalid packet received");
spdlog::error("Invalid packet received, data: `{}`", packet);
continue;
}
auto type = packet.substr(0, delimiter);
Expand All @@ -92,9 +101,35 @@ PipeManager::PipeManager() {
}
else if (type == "LOG") {
packetType = PacketType::LOG;

// just use libs to get timestamp, technically we could use the game's time
// but that would require the game to send the time and this doesn't feel important enough

// h, m, s
std::time_t currentTime = std::time(nullptr);
std::tm timeInfo;

localtime_s(&timeInfo, &currentTime);

std::string time = fmt::format("{:02}:{:02}:{:02}", timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec);

LogMessage logMessage;
logMessage.message = data;
logMessage.time = time;
C.logMessages.emplace_back(logMessage);

// If we have more than 200 messages, remove the oldest one
if (C.logMessages.size() > 200) {
C.logMessages.erase(C.logMessages.begin());
}

spdlog::trace("G-L : `{}` @ {}", !data.empty() ? data : "null", type);
// Early return here, we don't want to add the log packet to the queue
continue;
}
else {
spdlog::error("Unknown packet type received");
spdlog::error("Unknown packet type received, data: `{}`", packet);
spdlog::trace("G-L : `{}` @ {}", !data.empty() ? data : "null", type);
continue;
}

Expand All @@ -116,7 +151,7 @@ PipeManager::PipeManager() {
// Allow the thread some breathing room
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
});
});
this->pipeReader.detach();
}

Expand Down
Loading

0 comments on commit f239632

Please sign in to comment.