console: migrate to iw6x code

This commit is contained in:
Diavolo 2022-12-30 12:06:32 +01:00
parent ce8f397686
commit 24823da340
No known key found for this signature in database
GPG Key ID: FA77F074E98D98A5
6 changed files with 185 additions and 101 deletions

View File

@ -6,6 +6,7 @@
#include <utils/hook.hpp> #include <utils/hook.hpp>
#include "command.hpp" #include "command.hpp"
#include "console.hpp"
static utils::memory::allocator allocator; static utils::memory::allocator allocator;
@ -231,7 +232,7 @@ void command::add_sp_commands()
ent->client->flags ^= 1; ent->client->flags ^= 1;
const auto* msg = (ent->client->flags & 1) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"; const auto* msg = (ent->client->flags & 1) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF";
printf("%s\n", game::native::SEH_LocalizeTextMessage(msg, "noclip print", game::native::LOCMSG_SAFE)); console::info("%s\n", game::native::SEH_LocalizeTextMessage(msg, "noclip print", game::native::LOCMSG_SAFE));
}); });
add("ufo", [] add("ufo", []
@ -248,7 +249,7 @@ void command::add_sp_commands()
ent->client->flags ^= 2; ent->client->flags ^= 2;
const auto* msg = (ent->client->flags & 2) ? "GAME_UFOON" : "GAME_UFOOFF"; const auto* msg = (ent->client->flags & 2) ? "GAME_UFOON" : "GAME_UFOOFF";
printf("%s\n", game::native::SEH_LocalizeTextMessage(msg, "ufo print", game::native::LOCMSG_SAFE)); console::info("%s\n", game::native::SEH_LocalizeTextMessage(msg, "ufo print", game::native::LOCMSG_SAFE));
}); });
add("god", [] add("god", []
@ -265,7 +266,7 @@ void command::add_sp_commands()
ent->flags ^= game::native::FL_GODMODE; ent->flags ^= game::native::FL_GODMODE;
const auto* msg = (ent->flags & game::native::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF"; const auto* msg = (ent->flags & game::native::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF";
printf("%s\n", game::native::SEH_LocalizeTextMessage(msg, "god print", game::native::LOCMSG_SAFE)); console::info("%s\n", game::native::SEH_LocalizeTextMessage(msg, "god print", game::native::LOCMSG_SAFE));
}); });
add("demigod", [] add("demigod", []
@ -282,7 +283,7 @@ void command::add_sp_commands()
ent->flags ^= game::native::FL_DEMI_GODMODE; ent->flags ^= game::native::FL_DEMI_GODMODE;
const auto* msg = (ent->flags & game::native::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF"; const auto* msg = (ent->flags & game::native::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF";
printf("%s\n", game::native::SEH_LocalizeTextMessage(msg, "demigod print", game::native::LOCMSG_SAFE)); console::info("%s\n", game::native::SEH_LocalizeTextMessage(msg, "demigod print", game::native::LOCMSG_SAFE));
}); });
add("notarget", [] add("notarget", []
@ -299,7 +300,7 @@ void command::add_sp_commands()
ent->flags ^= game::native::FL_NOTARGET; ent->flags ^= game::native::FL_NOTARGET;
const auto* msg = (ent->flags & game::native::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF"; const auto* msg = (ent->flags & game::native::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF";
printf("%s\n", game::native::SEH_LocalizeTextMessage(msg, "notarget print", game::native::LOCMSG_SAFE)); console::info("%s\n", game::native::SEH_LocalizeTextMessage(msg, "notarget print", game::native::LOCMSG_SAFE));
}); });
add("setviewpos", [](const params& params) add("setviewpos", [](const params& params)
@ -318,7 +319,7 @@ void command::add_sp_commands()
if (params.size() < 4 || params.size() > 6) if (params.size() < 4 || params.size() > 6)
{ {
printf("setviewpos x y z [yaw] [pitch]\n"); console::info("setviewpos x y z [yaw] [pitch]\n");
return; return;
} }

View File

@ -2,111 +2,137 @@
#include <loader/module_loader.hpp> #include <loader/module_loader.hpp>
#include "game/game.hpp" #include "game/game.hpp"
#include <utils/concurrency.hpp>
#include "console.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
class console final : public module namespace
{ {
public: using message_queue = std::queue<std::string>;
console() utils::concurrency::container<message_queue> message_queue_;
}
console::console()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
(void)_pipe(this->handles_, 1024, _O_TEXT);
(void)_dup2(this->handles_[1], 1);
(void)_dup2(this->handles_[1], 2);
}
void console::post_start()
{
scheduler::loop(std::bind(&console::log_messages, this), scheduler::pipeline::main);
this->console_runner_ = std::thread(std::bind(&console::runner, this));
}
void console::post_load()
{
game::native::Sys_ShowConsole();
message_queue_.access([this]([[maybe_unused]] message_queue& queue)
{ {
ShowWindow(GetConsoleWindow(), SW_HIDE);
(void)_pipe(this->handles_, 1024, _O_TEXT);
(void)_dup2(this->handles_[1], 1);
(void)_dup2(this->handles_[1], 2);
}
void post_start() override
{
scheduler::loop(std::bind(&console::log_messages, this), scheduler::pipeline::main);
this->console_runner_ = std::thread(std::bind(&console::runner, this));
}
void pre_destroy() override
{
this->terminate_runner_ = true;
printf("\r\n");
_flushall();
_close(this->handles_[0]);
_close(this->handles_[1]);
if (this->console_runner_.joinable())
{
this->console_runner_.join();
}
}
void post_load() override
{
game::native::Sys_ShowConsole();
std::lock_guard _(this->mutex_);
this->console_initialized_ = true; this->console_initialized_ = true;
} });
}
private: void console::pre_destroy()
bool console_initialized_ = false; {
bool terminate_runner_ = false; this->terminate_runner_ = true;
std::mutex mutex_; printf("\r\n");
std::thread console_runner_; _flushall();
std::queue<std::string> message_queue_;
int handles_[2]{}; _close(this->handles_[0]);
_close(this->handles_[1]);
void log_messages() if (this->console_runner_.joinable())
{ {
while (this->console_initialized_ && !this->message_queue_.empty()) this->console_runner_.join();
}
}
void console::print(const int type, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
const auto result = format(&ap, fmt);
va_end(ap);
dispatch_message(type, result);
}
void console::log_messages() const
{
while (this->console_initialized_ && !message_queue_.get_raw().empty())
{
std::queue<std::string> message_queue_copy;
{ {
std::queue<std::string> message_queue_copy; message_queue_.access([&](message_queue& queue)
{ {
std::lock_guard _(this->mutex_); message_queue_copy = std::move(queue);
message_queue_copy = this->message_queue_; queue = std::queue<std::string>();
this->message_queue_ = {}; });
}
while (!message_queue_copy.empty())
{
log_message(message_queue_copy.front());
message_queue_copy.pop();
}
} }
fflush(stdout); while (!message_queue_copy.empty())
fflush(stderr); {
log_message(message_queue_copy.front());
message_queue_copy.pop();
}
} }
static void log_message(const std::string& message) fflush(stdout);
{ fflush(stderr);
}
void console::log_message(const std::string& message)
{
#ifdef _DEBUG #ifdef _DEBUG
OutputDebugStringA(message.data()); OutputDebugStringA(message.data());
#endif #endif
game::native::Conbuf_AppendText(message.data()); game::native::Conbuf_AppendText(message.data());
} }
void runner() void console::dispatch_message([[maybe_unused]] const int type, const std::string& message)
{
message_queue_.access([&message](message_queue& queue)
{ {
while (!this->terminate_runner_ && this->handles_[0]) queue.emplace(message);
{ });
char buffer[1024]; }
const auto len = _read(this->handles_[0], buffer, sizeof(buffer));
if (len > 0)
{
std::lock_guard _(this->mutex_);
this->message_queue_.push(std::string(buffer, len));
}
else
{
std::this_thread::sleep_for(10ms);
}
}
std::this_thread::yield(); void console::runner() const
{
while (!this->terminate_runner_ && this->handles_[0])
{
char buffer[1024];
const auto len = _read(this->handles_[0], buffer, sizeof(buffer));
if (len > 0)
{
dispatch_message(con_type_info, std::string(buffer, len));
}
else
{
std::this_thread::sleep_for(10ms);
}
} }
};
std::this_thread::yield();
}
std::string console::format(va_list* ap, const char* message)
{
static thread_local char buffer[0x1000];
const auto count = vsnprintf_s(buffer, _TRUNCATE, message, *ap);
if (count < 0) return {};
return {buffer, static_cast<size_t>(count)};
}
REGISTER_MODULE(console) REGISTER_MODULE(console)

54
src/module/console.hpp Normal file
View File

@ -0,0 +1,54 @@
#pragma once
class console final : public module
{
public:
enum
{
con_type_error = 1,
con_type_warning = 3,
con_type_info = 7,
};
console();
void post_start() override;
void post_load() override;
void pre_destroy() override;
static void print(int type, const char* fmt, ...);
template <typename... Args>
static void error(const char* fmt, Args&&... args)
{
print(con_type_error, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
static void warn(const char* fmt, Args&&... args)
{
print(con_type_warning, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
static void info(const char* fmt, Args&&... args)
{
print(con_type_info, fmt, std::forward<Args>(args)...);
}
private:
bool console_initialized_ = false;
bool terminate_runner_ = false;
std::thread console_runner_;
int handles_[2]{};
void log_messages() const;
static void log_message(const std::string& message);
static void dispatch_message(const int type, const std::string& message);
void runner() const;
static std::string format(va_list* ap, const char* message);
};

View File

@ -2,6 +2,8 @@
#include <loader/module_loader.hpp> #include <loader/module_loader.hpp>
#include "game/game.hpp" #include "game/game.hpp"
#include "console.hpp"
#include <utils/hook.hpp> #include <utils/hook.hpp>
static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsigned int, int) static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsigned int, int)
@ -14,7 +16,7 @@ static __declspec(naked) void db_load_stub_client(game::native::XZoneInfo*, unsi
mov ecx, game::native::DB_LoadXAssets mov ecx, game::native::DB_LoadXAssets
add ecx, 7h add ecx, 7h
push ecx push ecx
retn ret
} }
} }
@ -33,7 +35,7 @@ private:
{ {
if (zone_info[i].name) if (zone_info[i].name)
{ {
printf("Loading FastFile: %s (0x%X | 0x%X)\n", zone_info[i].name, zone_info[i].allocFlags, zone_info[i].freeFlags); console::info("Loading FastFile: %s (0x%X | 0x%X)\n", zone_info[i].name, zone_info[i].allocFlags, zone_info[i].freeFlags);
} }
} }

View File

@ -8,6 +8,7 @@
#include "scheduler.hpp" #include "scheduler.hpp"
#include "file_system.hpp" #include "file_system.hpp"
#include "scripting.hpp" #include "scripting.hpp"
#include "console.hpp"
const game::native::dvar_t* game_log::g_log; const game::native::dvar_t* game_log::g_log;
const game::native::dvar_t* game_log::g_logSync; const game::native::dvar_t* game_log::g_logSync;
@ -60,15 +61,15 @@ void game_log::gscr_log_print()
void game_log::g_init_game_stub() void game_log::g_init_game_stub()
{ {
printf("------- Game Initialization -------\n"); console::info("------- Game Initialization -------\n");
printf("gamename: %s\n", reinterpret_cast<const char*>(0x7FFC68)); console::info("gamename: %s\n", reinterpret_cast<const char*>(0x7FFC68));
printf("gamedate: %s\n", __DATE__); console::info("gamedate: %s\n", __DATE__);
const auto* log = g_log->current.string; const auto* log = g_log->current.string;
if (*log == '\0') if (*log == '\0')
{ {
printf("Not logging to disk.\n"); console::info("Not logging to disk.\n");
} }
else else
{ {
@ -76,11 +77,11 @@ void game_log::g_init_game_stub()
if (!log_file) if (!log_file)
{ {
printf("WARNING: Couldn't open logfile: %s\n", log); console::info("WARNING: Couldn't open logfile: %s\n", log);
} }
else else
{ {
printf("Logging to disk: '%s'.\n", log); console::info("Logging to disk: '%s'.\n", log);
g_log_printf("------------------------------------------------------------\n"); g_log_printf("------------------------------------------------------------\n");
g_log_printf("InitGame\n"); g_log_printf("InitGame\n");
} }
@ -91,7 +92,7 @@ void game_log::g_init_game_stub()
void game_log::g_shutdown_game_stub(int free_scripts) void game_log::g_shutdown_game_stub(int free_scripts)
{ {
printf("==== ShutdownGame (%d) ====\n", free_scripts); console::info("==== ShutdownGame (%d) ====\n", free_scripts);
if (log_file) if (log_file)
{ {

View File

@ -1,11 +1,11 @@
#include <std_include.hpp> #include <std_include.hpp>
#include <loader/module_loader.hpp> #include <loader/module_loader.hpp>
#include "game/game.hpp" #include "game/game.hpp"
#include "game/engine/scoped_critical_section.hpp" #include "game/engine/scoped_critical_section.hpp"
#include "log_file.hpp" #include "log_file.hpp"
#include "file_system.hpp" #include "file_system.hpp"
#include "console.hpp"
const char* log_file::log_file_name; const char* log_file::log_file_name;
@ -80,7 +80,7 @@ void log_file::info(const char* fmt, ...)
com_log_print_message(msg); com_log_print_message(msg);
} }
printf("%s", msg); console::info("%s", msg);
} }
void log_file::post_load() void log_file::post_load()