diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp new file mode 100644 index 00000000..2b04fd05 --- /dev/null +++ b/src/client/component/console.cpp @@ -0,0 +1,66 @@ +#include + +#include "loader/component_loader.hpp" + +#include +#include + +#include "game/game.hpp" + +#include "console.hpp" + +#include "version.hpp" + +namespace console +{ + static std::atomic_bool ingame = false; + static std::atomic_bool exit = false; + + DWORD WINAPI console_thread(LPVOID) + { + ShowWindow(GetConsoleWindow(), SW_SHOW); + SetConsoleTitleA("S2-Mod: " VERSION); + + std::string cmd; + exit = false; + + while (!exit) + { + std::getline(std::cin, cmd); + if (ingame) + { + game::Cbuf_AddText(0, utils::string::va("%s \n", cmd.data())); + } + } + + return 0; + } + + class component final : public component_interface + { + public: + component() + { + ShowWindow(GetConsoleWindow(), SW_SHOW); + } + + void post_start() override + { + const auto handle = CreateThread(0, 0, console::console_thread, 0, 0, 0); + utils::thread::set_name(handle, "Console"); + } + + void post_unpack() override + { + console::ingame = true; + } + + void pre_destroy() override + { + console::ingame = false; + console::exit = true; + } + }; +} + +REGISTER_COMPONENT(console::component) \ No newline at end of file diff --git a/src/client/component/console.hpp b/src/client/component/console.hpp new file mode 100644 index 00000000..0b703b24 --- /dev/null +++ b/src/client/component/console.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace console +{ + +} \ No newline at end of file diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 5f166785..571f43a4 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -10,6 +10,45 @@ namespace game { uint64_t base_address; + cmd_text* cmd_textArray = (cmd_text*)0x14BD83728; + + void Cbuf_AddText(int localClientNum, const char* text) + { + Sys_EnterCriticalSection(193); + + cmd_text* cmd_text_array = &cmd_textArray[localClientNum]; + + int v4 = strlen(text); + int v5 = cmd_text_array->cmdsize; + if ((int)v5 + v4 < cmd_text_array->maxsize) + { + memcpy(&cmd_text_array->data[v5], text, v4 + 1); + cmd_text_array->cmdsize += v4; + } + + Sys_LeaveCriticalSection(193); + } + + int Cmd_Argc() + { + return cmd_args->argc[cmd_args->nesting]; + } + + const char* Cmd_Argv(const int index) + { + return cmd_args->argv[cmd_args->nesting][index]; + } + + int SV_Cmd_Argc() + { + return sv_cmd_args->argc[sv_cmd_args->nesting]; + } + + const char* SV_Cmd_Argv(const int index) + { + return sv_cmd_args->argv[sv_cmd_args->nesting][index]; + } + namespace environment { launcher::mode mode = launcher::mode::none; @@ -72,6 +111,9 @@ namespace game case launcher::mode::multiplayer: return "Multiplayer"; + case launcher::mode::zombies: + return "Zombies"; + case launcher::mode::singleplayer: return "Singleplayer"; diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 4ba5d2cb..771dbdca 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -9,6 +9,8 @@ namespace game { extern uint64_t base_address; + void Cbuf_AddText(int localClientNum, const char* text); + namespace environment { launcher::mode get_mode(); @@ -51,10 +53,11 @@ namespace game T* address_; }; - namespace environment - { - bool is_dedi(); - } + int Cmd_Argc(); + const char* Cmd_Argv(int index); + + int SV_Cmd_Argc(); + const char* SV_Cmd_Argv(int index); } size_t reverse_b(const size_t ptr); diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index c36c2560..46a4e0e9 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -31,4 +31,11 @@ namespace game E_GAMEUSER_MAX_USERS_ADDED = 0x89245100, E_GAMEUSER_SIGNED_OUT = 0x89245101, }; + + struct cmd_text + { + byte* data; + int maxsize; + int cmdsize; + }; }