mirror of
https://github.com/XLabsProject/s1x-client.git
synced 2023-08-02 15:02:12 +02:00
Bunch of new stuff
This commit is contained in:
parent
c6bbca328a
commit
7d559d5a31
@ -13,15 +13,11 @@ namespace bots
|
||||
{
|
||||
bool can_spawn()
|
||||
{
|
||||
// disable spawning for now, causes a crash if more than svs_numclients.
|
||||
|
||||
//const auto index = *game::mp::svs_numclients - 1;
|
||||
//const auto cant = game::mp::svs_clients[index].header.state;
|
||||
//if (cant)
|
||||
//{
|
||||
return false;
|
||||
//}
|
||||
//return true;
|
||||
if (party::get_client_count() < *game::mp::svs_numclients)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_bot()
|
||||
|
@ -295,12 +295,92 @@ namespace command
|
||||
|
||||
static void add_commands_sp()
|
||||
{
|
||||
add("give", [](const params& params)
|
||||
{
|
||||
if (!game::SV_Loaded())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.size() < 2)
|
||||
{
|
||||
game::CG_GameMessage(0, "You did not specify a weapon name");
|
||||
return;
|
||||
}
|
||||
|
||||
auto ps = game::SV_GetPlayerstateForClientNum(0);
|
||||
auto wp = game::G_GetWeaponForName(params.get(1));
|
||||
if (game::G_GivePlayerWeapon(ps, wp, 0, 0, 0, 0, 0, 0))
|
||||
{
|
||||
game::G_InitializeAmmo(ps, wp, 0);
|
||||
game::G_SelectWeapon(0, wp);
|
||||
}
|
||||
});
|
||||
|
||||
add("take", [](const params& params)
|
||||
{
|
||||
if (!game::SV_Loaded())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.size() < 2)
|
||||
{
|
||||
game::CG_GameMessage(0, "You did not specify a weapon name");
|
||||
return;
|
||||
}
|
||||
|
||||
auto ps = game::SV_GetPlayerstateForClientNum(0);
|
||||
auto wp = game::G_GetWeaponForName(params.get(1));
|
||||
game::G_TakePlayerWeapon(ps, wp);
|
||||
});
|
||||
}
|
||||
|
||||
static void add_commands_mp()
|
||||
{
|
||||
client_command_hook.create(0x1402E98F0, &client_command);
|
||||
|
||||
add_sv("give", [](const int client_num, const params_sv& params)
|
||||
{
|
||||
if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
|
||||
{
|
||||
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.size() < 2)
|
||||
{
|
||||
game::SV_GameSendServerCommand(client_num, 1, "f \"You did not specify a weapon name\"");
|
||||
return;
|
||||
}
|
||||
|
||||
auto ps = game::SV_GetPlayerstateForClientNum(client_num);
|
||||
auto wp = game::G_GetWeaponForName(params.get(1));
|
||||
if (game::G_GivePlayerWeapon(ps, wp, 0, 0, 0, 0, 0, 0))
|
||||
{
|
||||
game::G_InitializeAmmo(ps, wp, 0);
|
||||
game::G_SelectWeapon(client_num, wp);
|
||||
}
|
||||
});
|
||||
|
||||
add_sv("take", [](const int client_num, const params_sv& params)
|
||||
{
|
||||
if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
|
||||
{
|
||||
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.size() < 2)
|
||||
{
|
||||
game::SV_GameSendServerCommand(client_num, 1, "f \"You did not specify a weapon name\"");
|
||||
return;
|
||||
}
|
||||
|
||||
auto ps = game::SV_GetPlayerstateForClientNum(client_num);
|
||||
auto wp = game::G_GetWeaponForName(params.get(1));
|
||||
game::G_TakePlayerWeapon(ps, wp);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
52
src/client/component/filesystem.cpp
Normal file
52
src/client/component/filesystem.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "filesystem.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "dvars.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
namespace filesystem
|
||||
{
|
||||
file::file(std::string name)
|
||||
: name_(std::move(name))
|
||||
{
|
||||
char* buffer{};
|
||||
const auto size = game::FS_ReadFile(this->name_.data(), &buffer);
|
||||
|
||||
if (size >= 0 && buffer)
|
||||
{
|
||||
this->valid_ = true;
|
||||
this->buffer_.append(buffer, size);
|
||||
game::FS_FreeFile(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool file::exists() const
|
||||
{
|
||||
return this->valid_;
|
||||
}
|
||||
|
||||
const std::string& file::get_buffer() const
|
||||
{
|
||||
return this->buffer_;
|
||||
}
|
||||
|
||||
const std::string& file::get_name() const
|
||||
{
|
||||
return this->name_;
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
// Set fs_basegame
|
||||
dvars::override::Dvar_RegisterString("fs_basegame", "s1-mod", 2048);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(filesystem::component)
|
19
src/client/component/filesystem.hpp
Normal file
19
src/client/component/filesystem.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace filesystem
|
||||
{
|
||||
class file
|
||||
{
|
||||
public:
|
||||
file(std::string name);
|
||||
|
||||
bool exists() const;
|
||||
const std::string& get_buffer() const;
|
||||
const std::string& get_name() const;
|
||||
|
||||
private:
|
||||
bool valid_ = false;
|
||||
std::string name_;
|
||||
std::string buffer_;
|
||||
};
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "party.hpp"
|
||||
|
||||
#include "dvars.hpp"
|
||||
#include "command.hpp"
|
||||
#include "network.hpp"
|
||||
#include "scheduler.hpp"
|
||||
@ -70,6 +71,40 @@ namespace party
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
int get_dvar_int(const std::string& dvar)
|
||||
{
|
||||
auto* dvar_value = game::Dvar_FindVar(dvar.data());
|
||||
if (dvar_value && dvar_value->current.integer)
|
||||
{
|
||||
return dvar_value->current.integer;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool get_dvar_bool(const std::string& dvar)
|
||||
{
|
||||
auto* dvar_value = game::Dvar_FindVar(dvar.data());
|
||||
if (dvar_value && dvar_value->current.enabled)
|
||||
{
|
||||
return dvar_value->current.enabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void didyouknow_stub(const char* dvar_name, const char* string)
|
||||
{
|
||||
if (!party::sv_motd.empty())
|
||||
{
|
||||
string = party::sv_motd.data();
|
||||
}
|
||||
|
||||
// This function either does Dvar_SetString or Dvar_RegisterString for the given dvar
|
||||
reinterpret_cast<void(*)(const char*, const char*)>(0x1404C39B0)(dvar_name, string);
|
||||
party::sv_motd.clear();
|
||||
}
|
||||
}
|
||||
|
||||
int get_client_count()
|
||||
@ -77,10 +112,10 @@ namespace party
|
||||
auto count = 0;
|
||||
for (auto i = 0; i < *game::mp::svs_numclients; ++i)
|
||||
{
|
||||
//if (game::mp::svs_clients[i].header.state >= 3)
|
||||
//{
|
||||
// ++count;
|
||||
//}
|
||||
if (game::mp::svs_clients[i].header.state >= 3)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
@ -91,11 +126,11 @@ namespace party
|
||||
auto count = 0;
|
||||
for (auto i = 0; i < *game::mp::svs_numclients; ++i)
|
||||
{
|
||||
//if (game::mp::svs_clients[i].header.state >= 3 &&
|
||||
// game::mp::svs_clients[i].testClient != game::TC_NONE)
|
||||
//{
|
||||
// ++count;
|
||||
//}
|
||||
if (game::mp::svs_clients[i].header.state >= 3 &&
|
||||
game::SV_BotIsBot(i))
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
@ -146,10 +181,9 @@ namespace party
|
||||
return;
|
||||
}
|
||||
|
||||
// starting map doesn't work, only private match -> start
|
||||
// starting map like this crashes the game.
|
||||
printf("Starting map: %s\n", mapname.data());
|
||||
game::SV_StartMapForParty(0, mapname.data(), true);
|
||||
//game::SV_StartMap(0, mapname.data());
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,6 +344,8 @@ namespace party
|
||||
printf("%s\n", message.data());
|
||||
});
|
||||
|
||||
utils::hook::call(0x14048811C, didyouknow_stub); // allow custom didyouknow based on sv_motd
|
||||
|
||||
network::on("getInfo", [](const game::netadr_s& target, const std::string_view& data)
|
||||
{
|
||||
utils::info_string info{};
|
||||
@ -326,8 +362,6 @@ namespace party
|
||||
info.set("sv_maxclients", utils::string::va("%i", *game::mp::svs_numclients));
|
||||
info.set("protocol", utils::string::va("%i", PROTOCOL));
|
||||
info.set("playmode", utils::string::va("%i", game::Com_GetCurrentCoDPlayMode()));
|
||||
//info.set("shortversion", SHORTVERSION);
|
||||
//info.set("hc", (Dvar::Var("g_hardcore").get<bool>() ? "1" : "0"));
|
||||
|
||||
network::send(target, "infoResponse", info.build(), '\n');
|
||||
});
|
||||
@ -350,8 +384,17 @@ namespace party
|
||||
return;
|
||||
}
|
||||
|
||||
const auto gamename = info.get("gamename");
|
||||
if (gamename != "S1"s)
|
||||
{
|
||||
const auto str = "Invalid gamename.";
|
||||
printf("%s\n", str);
|
||||
game::Com_Error(game::ERR_DROP, str);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto playmode = info.get("playmode");
|
||||
if (playmode.empty())
|
||||
if (game::CodPlayMode(std::atoi(playmode.data())) != game::Com_GetCurrentCoDPlayMode())
|
||||
{
|
||||
const auto str = "Invalid playmode.";
|
||||
printf("%s\n", str);
|
||||
@ -377,15 +420,6 @@ namespace party
|
||||
return;
|
||||
}
|
||||
|
||||
const auto gamename = info.get("gamename");
|
||||
if (gamename != "S1"s)
|
||||
{
|
||||
const auto str = "Invalid gamename.";
|
||||
printf("%s\n", str);
|
||||
game::Com_Error(game::ERR_DROP, str);
|
||||
return;
|
||||
}
|
||||
|
||||
party::sv_motd = info.get("sv_motd");
|
||||
|
||||
connect_to_party(target, mapname, gametype);
|
||||
|
@ -5,8 +5,9 @@
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
#include "scheduler.hpp"
|
||||
#include "dvars.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "fastfiles.hpp"
|
||||
#include "dvars.hpp"
|
||||
|
||||
#include <utils/string.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
@ -41,7 +42,7 @@ namespace patches
|
||||
if (game::environment::is_mp())
|
||||
{
|
||||
// Make name save
|
||||
game::Dvar_RegisterString("name", "Unknown Soldier", 0x1, "Player name.");
|
||||
game::Dvar_RegisterString("name", "Unknown Soldier", game::DVAR_FLAG_SAVED, "Player name.");
|
||||
|
||||
// Disable data validation error popup
|
||||
game::Dvar_RegisterInt("data_validation_allow_drop", 0, 0, 0, 0, "");
|
||||
@ -54,14 +55,14 @@ namespace patches
|
||||
const unsigned int /*flags*/,
|
||||
const char* description)
|
||||
{
|
||||
return game::Dvar_RegisterInt(name, 0, 0, 1000, 0x1, description);
|
||||
return game::Dvar_RegisterInt(name, 0, 0, 1000, game::DVAR_FLAG_SAVED, description);
|
||||
}
|
||||
|
||||
game::dvar_t* register_cg_fov_stub(const char* name, float value, float min, float /*max*/,
|
||||
const unsigned int flags,
|
||||
const char* description)
|
||||
{
|
||||
return game::Dvar_RegisterFloat(name, value, min, 160, flags | 0x1, description);
|
||||
return game::Dvar_RegisterFloat(name, value, min, 160, game::DVAR_FLAG_SAVED, description);
|
||||
}
|
||||
|
||||
game::dvar_t* register_fovscale_stub(const char* name, float /*value*/, float /*min*/, float /*max*/,
|
||||
@ -69,7 +70,7 @@ namespace patches
|
||||
const char* desc)
|
||||
{
|
||||
// changed max value from 2.0f -> 5.0f and min value from 0.5f -> 0.1f
|
||||
return game::Dvar_RegisterFloat(name, 1.0f, 0.1f, 5.0f, 0x1, desc);
|
||||
return game::Dvar_RegisterFloat(name, 1.0f, 0.1f, 5.0f, game::DVAR_FLAG_SAVED, desc);
|
||||
}
|
||||
|
||||
int dvar_command_patch() // game makes this return an int and compares with eax instead of al -_-
|
||||
@ -104,6 +105,34 @@ namespace patches
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* db_read_raw_file_stub(const char* filename, char* buf, int size)
|
||||
{
|
||||
std::string file_name = filename;
|
||||
if (file_name.find(".cfg") == std::string::npos)
|
||||
{
|
||||
file_name.append(".cfg");
|
||||
}
|
||||
|
||||
const auto file = filesystem::file(file_name);
|
||||
if (file.exists())
|
||||
{
|
||||
snprintf(buf, size, "%s\n", file.get_buffer().data());
|
||||
printf("%s\n", buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
// DB_ReadRawFile
|
||||
return reinterpret_cast<const char*(*)(const char*, char*, int)>(SELECT_VALUE(0x140180E30, 0x140273080))(filename, buf, size);
|
||||
}
|
||||
|
||||
void aim_assist_add_to_target_list(void* a1, void* a2)
|
||||
{
|
||||
if (!dvars::aimassist_enabled->current.enabled)
|
||||
return;
|
||||
|
||||
game::AimAssist_AddToTargetList(a1, a2);
|
||||
}
|
||||
|
||||
void missing_content_error_stub(int /*mode*/, const char* /*message*/)
|
||||
{
|
||||
game::Com_Error(game::ERR_DROP, utils::string::va("MISSING FILE\n%s.ff", fastfiles::get_current_fastfile()));
|
||||
@ -152,6 +181,9 @@ namespace patches
|
||||
// Show missing fastfiles
|
||||
utils::hook::call(SELECT_VALUE(0x1401817AF, 0x1402742A8), missing_content_error_stub);
|
||||
|
||||
// Allow executing custom cfg files with the "exec" command
|
||||
utils::hook::call(SELECT_VALUE(0x1402EE225, 0x1403AF7CD), db_read_raw_file_stub);
|
||||
|
||||
// Fix mouse lag
|
||||
utils::hook::nop(SELECT_VALUE(0x14038FAFF, 0x1404DB1AF), 6);
|
||||
scheduler::loop([]()
|
||||
@ -179,6 +211,12 @@ namespace patches
|
||||
|
||||
// patch "Couldn't find the bsp for this map." error to not be fatal in mp
|
||||
utils::hook::call(0x14026E63B, bsp_sys_error_stub);
|
||||
|
||||
//client side aim assist dvar
|
||||
dvars::aimassist_enabled = game::Dvar_RegisterBool("aimassist_enabled", true,
|
||||
game::DvarFlags::DVAR_FLAG_SAVED,
|
||||
"Enables aim assist for controllers");
|
||||
utils::hook::call(0x140003609, aim_assist_add_to_target_list);
|
||||
}
|
||||
|
||||
static void patch_sp()
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
namespace dvars
|
||||
{
|
||||
game::dvar_t* aimassist_enabled = nullptr;
|
||||
|
||||
game::dvar_t* con_inputBoxColor = nullptr;
|
||||
game::dvar_t* con_inputHintBoxColor = nullptr;
|
||||
game::dvar_t* con_outputBarColor = nullptr;
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
namespace dvars
|
||||
{
|
||||
extern game::dvar_t* aimassist_enabled;
|
||||
|
||||
extern game::dvar_t* con_inputBoxColor;
|
||||
extern game::dvar_t* con_inputHintBoxColor;
|
||||
extern game::dvar_t* con_outputBarColor;
|
||||
|
Loading…
Reference in New Issue
Block a user