Merge pull request #105 from fedddddd/dev

Dev
This commit is contained in:
fed 2021-12-21 15:44:23 +01:00 committed by GitHub
commit b997e0eb32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 323 additions and 81 deletions

View File

@ -58,7 +58,7 @@ namespace command
const auto current = game::Dvar_ValueToString(dvar, nullptr, &dvar->current);
const auto reset = game::Dvar_ValueToString(dvar, nullptr, &dvar->reset);
game_console::print(game_console::con_type_info, "\"%s\" is: \"%s\" default: \"%s\" hash: %i",
game_console::print(game_console::con_type_info, "\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX",
args[0], current, reset, dvar->name);
game_console::print(game_console::con_type_info, " %s\n",

View File

@ -31,7 +31,7 @@ namespace console
while (true)
{
std::getline(std::cin, cmd);
command::execute(cmd.data(), false);
game_console::add(cmd.data(), false);
}
});
}

View File

@ -69,7 +69,7 @@ namespace game_console
matches.clear();
}
void print(const std::string& data)
void print(const std::string& data, bool print_ = true)
{
if (con.visible_line_count > 0 && con.display_line_offset == (con.output.size() - con.visible_line_count))
{
@ -78,7 +78,10 @@ namespace game_console
con.output.push_back(data);
if (print_)
{
printf("%s\n", data.data());
}
if (con.output.size() > 1024)
{
@ -182,50 +185,6 @@ namespace game_console
return false;
}
void find_matches(std::string input, std::vector<std::string>& suggestions, const bool exact)
{
input = utils::string::to_lower(input);
for (const auto& dvar : dvars::dvar_list)
{
auto name = utils::string::to_lower(dvar);
if (match_compare(input, name, exact))
{
suggestions.push_back(dvar);
}
if (exact && suggestions.size() > 1)
{
return;
}
}
if (suggestions.size() == 0 && game::Dvar_FindVar(input.data()))
{
suggestions.push_back(input.data());
}
game::cmd_function_s* cmd = (*game::cmd_functions);
while (cmd)
{
if (cmd->name)
{
std::string name = utils::string::to_lower(cmd->name);
if (match_compare(input, name, exact))
{
suggestions.push_back(cmd->name);
}
if (exact && suggestions.size() > 1)
{
return;
}
}
cmd = cmd->next;
}
}
void draw_input()
{
con.globals.font_height = static_cast<float>(console_font->pixelHeight);
@ -534,19 +493,20 @@ namespace game_console
void execute(const char* cmd)
{
const auto sv_running = game::Dvar_FindVar("sv_running")->current.enabled;
if (sv_running)
{
std::string command = cmd;
scheduler::once([command]()
{
scripting::notify(*game::levelEntityId, "console_command", {command});
}, scheduler::pipeline::server);
game::Cbuf_AddText(0, utils::string::va("%s \n", cmd));
}
game::Cbuf_AddText(0, utils::string::va("%s \n", cmd));
void add(const std::string& cmd, bool print_)
{
execute(cmd.data());
history.push_front(cmd);
if (history.size() > 10)
{
history.erase(history.begin() + 10);
}
print(cmd, print_);
}
bool console_key_event(const int localClientNum, const int key, const int down)
@ -678,6 +638,69 @@ namespace game_console
return true;
}
void find_matches(std::string input, std::vector<std::string>& suggestions, const bool exact)
{
input = utils::string::to_lower(input);
for (const auto& dvar : dvars::dvar_list)
{
auto name = utils::string::to_lower(dvar);
if (match_compare(input, name, exact))
{
suggestions.push_back(dvar);
}
if (exact && suggestions.size() > 1)
{
return;
}
}
if (suggestions.size() == 0 && game::Dvar_FindVar(input.data()))
{
suggestions.push_back(input.data());
}
game::cmd_function_s* cmd = (*game::cmd_functions);
while (cmd)
{
if (cmd->name)
{
std::string name = utils::string::to_lower(cmd->name);
if (match_compare(input, name, exact))
{
suggestions.push_back(cmd->name);
}
if (exact && suggestions.size() > 1)
{
return;
}
}
cmd = cmd->next;
}
}
std::deque<std::string>& get_output()
{
return con.output;
}
std::deque<std::string>& get_history()
{
return history;
}
void clear_console()
{
clear();
con.line_count = 0;
con.output.clear();
history_index = -1;
history.clear();
}
class component final : public component_interface
{
public:
@ -699,14 +722,7 @@ namespace game_console
strncpy_s(con.globals.auto_complete_choice, "", 64);
// add clear command
command::add("clear", [&]()
{
clear();
con.line_count = 0;
con.output.clear();
history_index = -1;
history.clear();
});
command::add("clear", clear_console);
// add our dvars
dvars::con_inputBoxColor = dvars::register_vec4(

View File

@ -16,5 +16,11 @@ namespace game_console
bool console_char_event(int local_client_num, int key);
bool console_key_event(int local_client_num, int key, int down);
void find_matches(std::string input, std::vector<std::string>& suggestions, const bool exact);
void execute(const char* cmd);
void clear_console();
void add(const std::string& cmd, bool print_ = true);
std::deque<std::string>& get_output();
std::deque<std::string>& get_history();
}

View File

@ -119,6 +119,7 @@ namespace gui
{
ImGui::Checkbox("Asset list", &enabled_menus["asset_list"]);
ImGui::Checkbox("Entity list", &enabled_menus["entity_list"]);
ImGui::Checkbox("Console", &enabled_menus["console"]);
ImGui::EndMenu();
}
@ -239,6 +240,12 @@ namespace gui
});
}
void copy_to_clipboard(const std::string& text)
{
utils::string::set_clipboard_data(text);
gui::notification("Text copied to clipboard", utils::string::va("\"%s\"", text.data()));
}
class component final : public component_interface
{
public:

View File

@ -19,4 +19,5 @@ namespace gui
void on_frame(const std::function<void()>& callback);
bool is_menu_open(const std::string& name);
void notification(const std::string& title, const std::string& text, const std::chrono::milliseconds duration = 3s);
void copy_to_clipboard(const std::string& text);
}

View File

@ -15,6 +15,9 @@ namespace asset_list
{
namespace
{
bool shown_assets[game::XAssetType::ASSET_TYPE_COUNT];
std::string filter_buffer{};
void enum_assets(const game::XAssetType type, const std::function<void(game::XAssetHeader)>& callback, const bool includeOverride)
{
game::DB_EnumXAssets_Internal(type, static_cast<void(*)(game::XAssetHeader, void*)>([](game::XAssetHeader header, void* data)
@ -31,19 +34,16 @@ namespace asset_list
return;
}
static bool shown_assets[game::XAssetType::ASSET_TYPE_COUNT];
{
ImGui::Begin("Asset list", &gui::enabled_menus["asset_list"]);
static char filter[0x200]{};
ImGui::InputText("asset type", filter, IM_ARRAYSIZE(filter));
ImGui::InputText("asset type", &filter_buffer);
for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++)
{
const auto name = game::g_assetNames[i];
const auto type = static_cast<game::XAssetType>(i);
if (strstr(name, filter))
if (utils::string::find_lower(name, filter_buffer))
{
ImGui::Checkbox(name, &shown_assets[type]);
}
@ -73,15 +73,14 @@ namespace asset_list
const auto asset = game::XAsset{type, header};
const auto* const asset_name = game::DB_GetXAssetName(&asset);
if (!strstr(asset_name, filter))
if (!utils::string::find_lower(asset_name, filter))
{
return;
}
if (ImGui::Button(asset_name))
{
utils::string::set_clipboard_data(asset_name);
gui::notification("Text copied to clipboard!", utils::string::va("\"%s\"", asset_name));
gui::copy_to_clipboard(asset_name);
}
}, true);

View File

@ -0,0 +1,206 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include "scheduler.hpp"
#include "command.hpp"
#include "game_console.hpp"
#include "gui.hpp"
#include <utils/string.hpp>
#include <utils/hook.hpp>
#include <utils/concurrency.hpp>
namespace gui_console
{
namespace
{
bool auto_scroll = true;
int history_index = -1;
std::string input{};
std::string filter{};
std::vector<std::string> matches{};
int input_text_edit(ImGuiInputTextCallbackData* data)
{
switch (data->EventFlag)
{
case ImGuiInputTextFlags_CallbackCompletion:
{
matches.clear();
const std::string text = data->Buf;
if (text.find(" ") != std::string::npos)
{
game_console::find_matches(text.substr(0, text.find(" ")), matches, true);
}
else
{
game_console::find_matches(text, matches, false);
}
if (matches.size() < 24)
{
const auto match = matches[0].data();
data->DeleteChars(0, data->BufTextLen);
data->InsertChars(0, match, match + strlen(match));
}
break;
}
case ImGuiInputTextFlags_CallbackHistory:
{
const auto history = game_console::get_history();
if (data->EventKey == ImGuiKey_UpArrow)
{
if (++history_index >= history.size())
{
history_index = static_cast<int>(history.size()) - 1;
}
data->DeleteChars(0, data->BufTextLen);
if (history_index != -1)
{
const auto text = history.at(history_index).data();
data->InsertChars(0, text, text + strlen(text));
}
}
else if (data->EventKey == ImGuiKey_DownArrow)
{
if (--history_index < -1)
{
history_index = -1;
}
data->DeleteChars(0, data->BufTextLen);
if (history_index != -1)
{
const auto text = history.at(history_index).data();
data->InsertChars(0, text, text + strlen(text));
}
}
break;
}
}
return 0;
}
std::string get_filtered_text()
{
std::string text{};
const auto history = game_console::get_output();
for (const auto& line : history)
{
if (utils::string::find_lower(line, filter))
{
text.append(line.data());
text.append("\n");
}
}
if (text[text.size() - 1] == '\n')
{
text.pop_back();
}
return text;
}
void on_frame()
{
auto* open = &gui::enabled_menus["console"];
if (!*open)
{
return;
}
auto filtered_text = get_filtered_text();
static auto input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion |
ImGuiInputTextFlags_CallbackHistory;
ImGui::Begin("Console", open);
if (ImGui::BeginPopup("Options"))
{
ImGui::Checkbox("Auto-scroll", &auto_scroll);
ImGui::EndPopup();
}
if (ImGui::Button("Clear"))
{
game_console::clear_console();
}
ImGui::SameLine();
if (ImGui::Button("Copy"))
{
utils::string::set_clipboard_data(filtered_text);
gui::notification("Console", "Text copied to clipboard");
}
ImGui::Separator();
if (ImGui::Button("Options"))
{
ImGui::OpenPopup("Options");
}
ImGui::SameLine();
ImGui::InputText("Filter", &filter);
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::BeginChild("console_scroll", ImVec2(0, -footer_height_to_reserve), false);
ImGui::Text(filtered_text.data(), ImVec2(-1, -1));
if (auto_scroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
{
ImGui::SetScrollHereY(1.0f);
}
ImGui::EndChild();
if (ImGui::InputText("Input", &input, input_text_flags, input_text_edit))
{
auto history = game_console::get_history();
if (history_index != -1)
{
const auto itr = history.begin() + history_index;
if (*itr == input)
{
history.erase(history.begin() + history_index);
}
}
game_console::add(input.data());
input.clear();
ImGui::SetKeyboardFocusHere(-1);
}
ImGui::End();
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
gui::on_frame(on_frame);
}
};
}
REGISTER_COMPONENT(gui_console::component)

View File

@ -348,7 +348,8 @@ namespace entity_list
const auto classname = classname_value.as<std::string>();
const auto team_ = team_value.as<std::string>();
if (strstr(classname.data(), "actor_") && (team == entity_team::team_any || team_ == team_names[team]))
if (utils::string::find_lower(classname, "actor_") &&
(team == entity_team::team_any || team_ == team_names[team]))
{
result.push(entity);
}
@ -457,8 +458,8 @@ namespace entity_list
for (const auto& filter : data.filters.fields)
{
if (field_value.is<std::string>() &&
strstr(field.first.data(), utils::string::to_lower(filter.first).data()) &&
strstr(value_string.data(), filter.second.data()))
utils::string::find_lower(field.first, filter.first) &&
utils::string::find_lower(value_string, filter.second))
{
match_count++;
}
@ -789,16 +790,14 @@ namespace entity_list
if (ImGui::Button(field.first.data()))
{
utils::string::set_clipboard_data(field.first);
gui::notification("Text copied to clipboard!", utils::string::va("\"%s\"", field.first.data()));
gui::copy_to_clipboard(field.first);
}
ImGui::SameLine();
if (ImGui::Button(field.second.data()))
{
utils::string::set_clipboard_data(field.second);
gui::notification("Text copied to clipboard!", utils::string::va("\"%s\"", field.second.data()));
gui::copy_to_clipboard(field.second);
}
}
@ -815,7 +814,8 @@ namespace entity_list
ImGui::InputText("field name", field_filter, IM_ARRAYSIZE(field_filter));
for (auto& field : data.selected_fields)
{
if (strstr(field.first.data(), field_filter) && ImGui::Checkbox(field.first.data(), &field.second))
if (utils::string::find_lower(field.first, field_filter) &&
ImGui::Checkbox(field.first.data(), &field.second))
{
data.force_update = true;
}

View File

@ -192,4 +192,9 @@ namespace utils::string
return str;
}
bool find_lower(const std::string& a, const std::string& b)
{
return to_lower(a).find(to_lower(b)) != std::string::npos;
}
}

View File

@ -98,4 +98,6 @@ namespace utils::string
std::wstring convert(const std::string& str);
std::string replace(std::string str, const std::string& from, const std::string& to);
bool find_lower(const std::string& a, const std::string& b);
}