Merge branch 'develop' of https://github.com/XLabsProject/iw4x-client into better_r_draw_debug
This commit is contained in:
commit
241aed3d92
2
deps/libtommath
vendored
2
deps/libtommath
vendored
@ -1 +1 @@
|
||||
Subproject commit 8355b88db088e41d6f7e19a8d58d46c9ed0333d3
|
||||
Subproject commit 2cec6addaf4acbd8250611ec4cecadf1f4d655ee
|
2
deps/pdcurses
vendored
2
deps/pdcurses
vendored
@ -1 +1 @@
|
||||
Subproject commit 2e15c90f122fef329b83a4c3c011f192d97ec516
|
||||
Subproject commit f1cd4f4569451a5028ddf3d3c202f0ad6b1ae446
|
@ -104,6 +104,9 @@ namespace Components
|
||||
Loader::Register(new Gamepad());
|
||||
Loader::Register(new Chat());
|
||||
Loader::Register(new TextRenderer());
|
||||
Loader::Register(new Movement());
|
||||
Loader::Register(new Elevators());
|
||||
Loader::Register(new ClientCommand());
|
||||
|
||||
Loader::Register(new Client());
|
||||
|
||||
|
@ -132,6 +132,9 @@ namespace Components
|
||||
#include "Modules/SoundMutexFix.hpp"
|
||||
#include "Modules/Chat.hpp"
|
||||
#include "Modules/TextRenderer.hpp"
|
||||
#include "Modules/Movement.hpp"
|
||||
#include "Modules/Elevators.hpp"
|
||||
#include "Modules/ClientCommand.hpp"
|
||||
|
||||
#include "Modules/Gamepad.hpp"
|
||||
#include "Modules/Client.hpp"
|
||||
|
@ -160,7 +160,7 @@ namespace Components
|
||||
{
|
||||
Script::AddFunction("SetPing", [](Game::scr_entref_t id) // gsc: self SetPing(<int>)
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_INTEGER)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_INTEGER)
|
||||
{
|
||||
Game::Scr_Error("^1SetPing: Needs one integer parameter!\n");
|
||||
return;
|
||||
@ -250,7 +250,7 @@ namespace Components
|
||||
|
||||
Script::AddFunction("botWeapon", [](Game::scr_entref_t id) // Usage: <bot> botWeapon(<str>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1botWeapon: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -293,7 +293,7 @@ namespace Components
|
||||
|
||||
Script::AddFunction("botAction", [](Game::scr_entref_t id) // Usage: <bot> botAction(<str action>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1botAction: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -346,7 +346,7 @@ namespace Components
|
||||
|
||||
Script::AddFunction("botMovement", [](Game::scr_entref_t id) // Usage: <bot> botMovement(<int>, <int>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 2 || Game::Scr_GetType(0) != Game::VAR_INTEGER || Game::Scr_GetType(1) != Game::VAR_INTEGER)
|
||||
if (Game::Scr_GetNumParam() != 2u || Game::Scr_GetType(0) != Game::VAR_INTEGER || Game::Scr_GetType(1) != Game::VAR_INTEGER)
|
||||
{
|
||||
Game::Scr_Error("^1botMovement: Needs two integer parameters!\n");
|
||||
return;
|
||||
|
282
src/Components/Modules/ClientCommand.cpp
Normal file
282
src/Components/Modules/ClientCommand.cpp
Normal file
@ -0,0 +1,282 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::unordered_map<std::string, Utils::Slot<ClientCommand::Callback>> ClientCommand::FunctionMap;
|
||||
|
||||
bool ClientCommand::CheatsOk(const Game::gentity_s* ent)
|
||||
{
|
||||
const auto entNum = ent->s.number;
|
||||
|
||||
if (!Dvar::Var("sv_cheats").get<bool>())
|
||||
{
|
||||
Logger::Print("CheatsOk: cheats are disabled!\n");
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_CHEATSNOTENABLED\"", 0x65));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ent->health < 1)
|
||||
{
|
||||
Logger::Print("CheatsOk: entity %u must be alive to use this command!\n", entNum);
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"GAME_MUSTBEALIVECOMMAND\"", 0x65));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClientCommand::CallbackHandler(Game::gentity_s* ent, const char* cmd)
|
||||
{
|
||||
const auto command = Utils::String::ToLower(cmd);
|
||||
|
||||
if (ClientCommand::FunctionMap.find(command) != ClientCommand::FunctionMap.end())
|
||||
{
|
||||
ClientCommand::FunctionMap[command](ent);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientCommand::Add(const char* name, Utils::Slot<Callback> callback)
|
||||
{
|
||||
const auto command = Utils::String::ToLower(name);
|
||||
|
||||
ClientCommand::FunctionMap[command] = callback;
|
||||
}
|
||||
|
||||
void ClientCommand::ClientCommandStub(const int clientNum)
|
||||
{
|
||||
char cmd[1024]{};
|
||||
const auto entity = &Game::g_entities[clientNum];
|
||||
|
||||
if (entity->client == nullptr)
|
||||
{
|
||||
Logger::Print("ClientCommand: client %d is not fully in game yet\n", clientNum);
|
||||
return;
|
||||
}
|
||||
|
||||
Game::SV_Cmd_ArgvBuffer(0, cmd, sizeof(cmd));
|
||||
|
||||
if (!ClientCommand::CallbackHandler(entity, cmd))
|
||||
{
|
||||
// If no callback was found call original game function
|
||||
Utils::Hook::Call<void(const int)>(0x416790)(clientNum);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientCommand::AddCheatCommands()
|
||||
{
|
||||
ClientCommand::Add("noclip", [](Game::gentity_s* ent)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
|
||||
ent->client->flags ^= Game::PLAYER_FLAG_NOCLIP;
|
||||
|
||||
const auto entNum = ent->s.number;
|
||||
Logger::Print("Noclip toggled for entity %u\n", entNum);
|
||||
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
||||
(ent->client->flags & Game::PLAYER_FLAG_NOCLIP) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("ufo", [](Game::gentity_s* ent)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
|
||||
ent->client->flags ^= Game::PLAYER_FLAG_UFO;
|
||||
|
||||
const auto entNum = ent->s.number;
|
||||
Logger::Print("UFO toggled for entity %u\n", entNum);
|
||||
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
||||
(ent->client->flags & Game::PLAYER_FLAG_UFO) ? "GAME_UFOON" : "GAME_UFOOFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("god", [](Game::gentity_s* ent)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
|
||||
ent->flags ^= Game::FL_GODMODE;
|
||||
|
||||
const auto entNum = ent->s.number;
|
||||
Logger::Print("God toggled for entity %u\n", entNum);
|
||||
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
||||
(ent->flags & Game::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("demigod", [](Game::gentity_s* ent)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
|
||||
ent->flags ^= Game::FL_DEMI_GODMODE;
|
||||
|
||||
const auto entNum = ent->s.number;
|
||||
Logger::Print("Demigod toggled for entity %u\n", entNum);
|
||||
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
||||
(ent->flags & Game::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("notarget", [](Game::gentity_s* ent)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
|
||||
ent->flags ^= Game::FL_NOTARGET;
|
||||
|
||||
const auto entNum = ent->s.number;
|
||||
Logger::Print("Notarget toggled for entity %u\n", entNum);
|
||||
|
||||
Game::SV_GameSendServerCommand(entNum, 0, Utils::String::VA("%c \"%s\"", 0x65,
|
||||
(ent->flags & Game::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF"));
|
||||
});
|
||||
}
|
||||
|
||||
void ClientCommand::AddScriptFunctions()
|
||||
{
|
||||
Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(<optional int toggle>);
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
});
|
||||
|
||||
Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(<optional int toggle>);
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO;
|
||||
}
|
||||
});
|
||||
|
||||
Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(<optional int toggle>);
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].flags |= Game::FL_GODMODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].flags &= ~Game::FL_GODMODE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].flags ^= Game::FL_GODMODE;
|
||||
}
|
||||
});
|
||||
|
||||
Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(<optional int toggle>);
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE;
|
||||
}
|
||||
});
|
||||
|
||||
Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(<optional int toggle>);
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1Notarget: entity %u is out of bounds\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].flags |= Game::FL_NOTARGET;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].flags &= ~Game::FL_NOTARGET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].flags ^= Game::FL_NOTARGET;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ClientCommand::ClientCommand()
|
||||
{
|
||||
// Hook call to ClientCommand in SV_ExecuteClientCommand so we may add custom commands
|
||||
Utils::Hook(0x6259FA, ClientCommand::ClientCommandStub, HOOK_CALL).install()->quick();
|
||||
|
||||
ClientCommand::AddCheatCommands();
|
||||
ClientCommand::AddScriptFunctions();
|
||||
}
|
||||
|
||||
ClientCommand::~ClientCommand()
|
||||
{
|
||||
ClientCommand::FunctionMap.clear();
|
||||
}
|
||||
}
|
23
src/Components/Modules/ClientCommand.hpp
Normal file
23
src/Components/Modules/ClientCommand.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class ClientCommand : public Component
|
||||
{
|
||||
public:
|
||||
typedef void(Callback)(Game::gentity_s* entity);
|
||||
|
||||
ClientCommand();
|
||||
~ClientCommand();
|
||||
static void Add(const char* name, Utils::Slot<Callback> callback);
|
||||
static bool CheatsOk(const Game::gentity_s* ent);
|
||||
|
||||
private:
|
||||
static std::unordered_map<std::string, Utils::Slot<Callback>> FunctionMap;
|
||||
|
||||
static bool CallbackHandler(Game::gentity_s* ent, const char* cmd);
|
||||
static void ClientCommandStub(const int clientNum);
|
||||
static void AddCheatCommands();
|
||||
static void AddScriptFunctions();
|
||||
};
|
||||
}
|
@ -164,55 +164,6 @@ namespace Components
|
||||
static int toastDurationMedium = 2500;
|
||||
static int toastDurationLong = 5000;
|
||||
|
||||
// Disable native noclip command
|
||||
Utils::Hook::Nop(0x474846, 5);
|
||||
|
||||
Command::Add("noclip", [](Command::Params*)
|
||||
{
|
||||
int clientNum = Game::CG_GetClientNum();
|
||||
if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client)
|
||||
{
|
||||
Logger::Print("You are not hosting a match!\n");
|
||||
Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Dvar::Var("sv_cheats").get<bool>())
|
||||
{
|
||||
Logger::Print("Cheats disabled!\n");
|
||||
Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium);
|
||||
return;
|
||||
}
|
||||
|
||||
Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_NOCLIP;
|
||||
|
||||
Logger::Print("Noclip toggled\n");
|
||||
Toast::Show("cardicon_abduction", "Success", "Noclip toggled", toastDurationShort);
|
||||
});
|
||||
|
||||
Command::Add("ufo", [](Command::Params*)
|
||||
{
|
||||
int clientNum = Game::CG_GetClientNum();
|
||||
if (!Game::CL_IsCgameInitialized() || clientNum >= 18 || clientNum < 0 || !Game::g_entities[clientNum].client)
|
||||
{
|
||||
Logger::Print("You are not hosting a match!\n");
|
||||
Toast::Show("cardicon_stop", "Error", "You are not hosting a match!", toastDurationMedium);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Dvar::Var("sv_cheats").get<bool>())
|
||||
{
|
||||
Logger::Print("Cheats disabled!\n");
|
||||
Toast::Show("cardicon_stop", "Error", "Cheats disabled!", toastDurationMedium);
|
||||
return;
|
||||
}
|
||||
|
||||
Game::g_entities[clientNum].client->flags ^= Game::PLAYER_FLAG_UFO;
|
||||
|
||||
Logger::Print("UFO toggled\n");
|
||||
Toast::Show("cardicon_abduction", "Success", "UFO toggled", toastDurationShort);
|
||||
});
|
||||
|
||||
Command::Add("setviewpos", [](Command::Params* params)
|
||||
{
|
||||
int clientNum = Game::CG_GetClientNum();
|
||||
@ -252,9 +203,7 @@ namespace Components
|
||||
|
||||
Game::TeleportPlayer(&Game::g_entities[clientNum], pos, orientation);
|
||||
|
||||
//Logging that will spam the console and screen if people use cinematics
|
||||
//Logger::Print("Successfully teleported player!\n");
|
||||
//Toast::Show("cardicon_abduction", "Success", "You have been teleported!", toastDurationShort);
|
||||
// Logging will spam the console and screen if people use cinematics
|
||||
});
|
||||
|
||||
Command::Add("openLink", [](Command::Params* params)
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Components
|
||||
{
|
||||
SteamID Dedicated::PlayerGuids[18][2];
|
||||
Dvar::Var Dedicated::SVRandomMapRotation;
|
||||
|
||||
bool Dedicated::IsEnabled()
|
||||
{
|
||||
@ -96,7 +97,7 @@ namespace Components
|
||||
Game::SV_GameSendServerCommand(-1, 0, list.data());
|
||||
}
|
||||
|
||||
void Dedicated::TimeWrapStub(int code, const char* message)
|
||||
void Dedicated::TimeWrapStub(Game::errorParm_t code, const char* message)
|
||||
{
|
||||
static bool partyEnable;
|
||||
static std::string mapname;
|
||||
@ -119,6 +120,41 @@ namespace Components
|
||||
Game::Com_Error(code, message);
|
||||
}
|
||||
|
||||
void Dedicated::RandomizeMapRotation()
|
||||
{
|
||||
auto rotation = Dvar::Var("sv_mapRotation").get<std::string>();
|
||||
|
||||
const auto tokens = Utils::String::Explode(rotation, ' ');
|
||||
std::vector<std::pair<std::string, std::string>> mapRotationPair;
|
||||
|
||||
for (auto i = 0u; i < (tokens.size() - 1); i += 2)
|
||||
{
|
||||
if (i + 1 >= tokens.size()) break;
|
||||
|
||||
const auto& key = tokens[i];
|
||||
const auto& value = tokens[i + 1];
|
||||
mapRotationPair.push_back(std::make_pair(key, value));
|
||||
}
|
||||
|
||||
const auto seed = Utils::Cryptography::Rand::GenerateInt();
|
||||
std::shuffle(std::begin(mapRotationPair), std::end(mapRotationPair), std::default_random_engine(seed));
|
||||
|
||||
// Rebuild map rotation using the randomized key/values
|
||||
rotation.clear();
|
||||
for (auto j = 0u; j < mapRotationPair.size(); j++)
|
||||
{
|
||||
const auto& pair = mapRotationPair[j];
|
||||
rotation.append(pair.first);
|
||||
rotation.append(" ");
|
||||
rotation.append(pair.second);
|
||||
|
||||
if (j != mapRotationPair.size() - 1)
|
||||
rotation.append(" ");
|
||||
}
|
||||
|
||||
Dvar::Var("sv_mapRotationCurrent").set(rotation);
|
||||
}
|
||||
|
||||
void Dedicated::MapRotate()
|
||||
{
|
||||
if (!Dedicated::IsEnabled() && Dvar::Var("sv_dontrotate").get<bool>())
|
||||
@ -134,9 +170,10 @@ namespace Components
|
||||
}
|
||||
|
||||
Logger::Print("Rotating map...\n");
|
||||
const auto mapRotation = Dvar::Var("sv_mapRotation").get<std::string>();
|
||||
|
||||
// if nothing, just restart
|
||||
if (Dvar::Var("sv_mapRotation").get<std::string>().empty())
|
||||
if (mapRotation.empty())
|
||||
{
|
||||
Logger::Print("No rotation defined, restarting map.\n");
|
||||
|
||||
@ -152,14 +189,23 @@ namespace Components
|
||||
return;
|
||||
}
|
||||
|
||||
// first, check if the string contains nothing
|
||||
// First, check if the string contains nothing
|
||||
if (Dvar::Var("sv_mapRotationCurrent").get<std::string>().empty())
|
||||
{
|
||||
Logger::Print("Current map rotation has finished, reloading...\n");
|
||||
Dvar::Var("sv_mapRotationCurrent").set(Dvar::Var("sv_mapRotation").get<const char*>());
|
||||
|
||||
if (Dedicated::SVRandomMapRotation.get<bool>())
|
||||
{
|
||||
Logger::Print("Randomizing map rotation\n");
|
||||
Dedicated::RandomizeMapRotation();
|
||||
}
|
||||
else
|
||||
{
|
||||
Dvar::Var("sv_mapRotationCurrent").set(mapRotation);
|
||||
}
|
||||
}
|
||||
|
||||
std::string rotation = Dvar::Var("sv_mapRotationCurrent").get<std::string>();
|
||||
auto rotation = Dvar::Var("sv_mapRotationCurrent").get<std::string>();
|
||||
|
||||
auto tokens = Utils::String::Explode(rotation, ' ');
|
||||
|
||||
@ -346,6 +392,7 @@ namespace Components
|
||||
|
||||
Dvar::OnInit([]()
|
||||
{
|
||||
Dedicated::SVRandomMapRotation = Dvar::Register<bool>("sv_randomMapRotation", false, Game::dvar_flag::DVAR_FLAG_SAVED, "Randomize map rotation when true");
|
||||
Dvar::Register<const char*>("sv_sayName", "^7Console", Game::dvar_flag::DVAR_FLAG_NONE, "The name to pose as for 'say' commands");
|
||||
Dvar::Register<const char*>("sv_motd", "", Game::dvar_flag::DVAR_FLAG_NONE, "A custom message of the day for servers");
|
||||
|
||||
|
@ -15,6 +15,9 @@ namespace Components
|
||||
static void Heartbeat();
|
||||
|
||||
private:
|
||||
static Dvar::Var SVRandomMapRotation;
|
||||
|
||||
static void RandomizeMapRotation();
|
||||
static void MapRotate();
|
||||
static void InitDedicatedServer();
|
||||
|
||||
@ -25,6 +28,6 @@ namespace Components
|
||||
|
||||
static void TransmitGuids();
|
||||
|
||||
static void TimeWrapStub(int code, const char* message);
|
||||
static void TimeWrapStub(Game::errorParm_t code, const char* message);
|
||||
};
|
||||
}
|
||||
|
@ -967,7 +967,7 @@ namespace Components
|
||||
Script::AddFunction("httpGet", [](Game::scr_entref_t)
|
||||
{
|
||||
if (!Dedicated::IsEnabled() && !Flags::HasFlag("scriptablehttp")) return;
|
||||
if (Game::Scr_GetNumParam() < 1) return;
|
||||
if (Game::Scr_GetNumParam() < 1u) return;
|
||||
|
||||
std::string url = Game::Scr_GetString(0);
|
||||
unsigned int object = Game::AllocObject();
|
||||
@ -981,7 +981,7 @@ namespace Components
|
||||
Script::AddFunction("httpCancel", [](Game::scr_entref_t)
|
||||
{
|
||||
if (!Dedicated::IsEnabled() && !Flags::HasFlag("scriptablehttp")) return;
|
||||
if (Game::Scr_GetNumParam() < 1) return;
|
||||
if (Game::Scr_GetNumParam() < 1u) return;
|
||||
|
||||
unsigned int object = Game::Scr_GetObject(0);
|
||||
for (auto& download : Download::ScriptDownloads)
|
||||
|
55
src/Components/Modules/Elevators.cpp
Normal file
55
src/Components/Modules/Elevators.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
Game::dvar_t* Elevators::SV_DisableElevators;
|
||||
|
||||
__declspec(naked) void Elevators::PM_GroundTraceStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
mov eax, Elevators::SV_DisableElevators
|
||||
cmp byte ptr [eax + 16], 1
|
||||
pop eax
|
||||
|
||||
// Always skip PM_CorrectAllSolid if SV_DisableElevators is set to 1
|
||||
je noElevators
|
||||
|
||||
// Original code
|
||||
cmp byte ptr [esp + 0x50], 0
|
||||
rep movsd
|
||||
mov esi, [esp + 0x58]
|
||||
|
||||
// Original code flow
|
||||
push 0x573694
|
||||
retn
|
||||
|
||||
noElevators:
|
||||
|
||||
// Original code
|
||||
rep movsd
|
||||
mov esi, [esp + 0x58]
|
||||
|
||||
// Jump over call to PM_CorrectAllSolid
|
||||
push 0x5736AE
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
Elevators::Elevators()
|
||||
{
|
||||
Dvar::OnInit([]
|
||||
{
|
||||
Elevators::SV_DisableElevators = Game::Dvar_RegisterBool("sv_disableElevators",
|
||||
false, Game::DVAR_FLAG_REPLICATED, "Disable elevators");
|
||||
});
|
||||
|
||||
// Hook PM_GroundTrace so me way skip PM_CorrectAllSolid (disable elevators)
|
||||
Utils::Hook(0x573689, Elevators::PM_GroundTraceStub, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
||||
Elevators::~Elevators()
|
||||
{
|
||||
}
|
||||
}
|
16
src/Components/Modules/Elevators.hpp
Normal file
16
src/Components/Modules/Elevators.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Elevators : public Component
|
||||
{
|
||||
public:
|
||||
Elevators();
|
||||
~Elevators();
|
||||
|
||||
private:
|
||||
static Game::dvar_t* SV_DisableElevators;
|
||||
|
||||
static void PM_GroundTraceStub();
|
||||
};
|
||||
}
|
@ -108,7 +108,7 @@ namespace Components
|
||||
{"DPAD_RIGHT", Game::K_DPAD_RIGHT},
|
||||
};
|
||||
|
||||
Game::keyname_t Gamepad::extendedLocalizedKeyNames[]
|
||||
Game::keyname_t Gamepad::extendedLocalizedKeyNamesXenon[]
|
||||
{
|
||||
// Material text icons pattern: 0x01 width height material_name_len
|
||||
{"^\x01\x32\x32\x08""button_a", Game::K_BUTTON_A},
|
||||
@ -128,8 +128,30 @@ namespace Components
|
||||
{"^\x01\x32\x32\x09""dpad_left", Game::K_DPAD_LEFT},
|
||||
{"^\x01\x32\x32\x0A""dpad_right", Game::K_DPAD_RIGHT},
|
||||
};
|
||||
|
||||
Game::keyname_t Gamepad::extendedLocalizedKeyNamesPs3[]
|
||||
{
|
||||
// Material text icons pattern: 0x01 width height material_name_len
|
||||
{"^\x01\x32\x32\x10""button_ps3_cross", Game::K_BUTTON_A},
|
||||
{"^\x01\x32\x32\x11""button_ps3_circle", Game::K_BUTTON_B},
|
||||
{"^\x01\x32\x32\x11""button_ps3_square", Game::K_BUTTON_X},
|
||||
{"^\x01\x32\x32\x13""button_ps3_triangle", Game::K_BUTTON_Y},
|
||||
{"^\x01\x32\x32\x0D""button_ps3_l1", Game::K_BUTTON_LSHLDR},
|
||||
{"^\x01\x32\x32\x0D""button_ps3_r1", Game::K_BUTTON_RSHLDR},
|
||||
{"^\x01\x32\x32\x10""button_ps3_start", Game::K_BUTTON_START},
|
||||
{"^\x01\x32\x32\x0F""button_ps3_back", Game::K_BUTTON_BACK},
|
||||
{"^\x01\x48\x32\x0D""button_ps3_l3", Game::K_BUTTON_LSTICK},
|
||||
{"^\x01\x48\x32\x0D""button_ps3_r3", Game::K_BUTTON_RSTICK},
|
||||
{"^\x01\x32\x32\x0D""button_ps3_l2", Game::K_BUTTON_LTRIG},
|
||||
{"^\x01\x32\x32\x0D""button_ps3_r2", Game::K_BUTTON_RTRIG},
|
||||
{"^\x01\x32\x32\x0B""dpad_ps3_up", Game::K_DPAD_UP},
|
||||
{"^\x01\x32\x32\x0D""dpad_ps3_down", Game::K_DPAD_DOWN},
|
||||
{"^\x01\x32\x32\x0D""dpad_ps3_left", Game::K_DPAD_LEFT},
|
||||
{"^\x01\x32\x32\x0E""dpad_ps3_right", Game::K_DPAD_RIGHT},
|
||||
};
|
||||
Game::keyname_t Gamepad::combinedKeyNames[Game::KEY_NAME_COUNT + std::extent_v<decltype(extendedKeyNames)> + 1];
|
||||
Game::keyname_t Gamepad::combinedLocalizedKeyNames[Game::KEY_NAME_COUNT + std::extent_v<decltype(extendedLocalizedKeyNames)> + 1];
|
||||
Game::keyname_t Gamepad::combinedLocalizedKeyNamesXenon[Game::KEY_NAME_COUNT + std::extent_v<decltype(extendedLocalizedKeyNamesXenon)> + 1];
|
||||
Game::keyname_t Gamepad::combinedLocalizedKeyNamesPs3[Game::KEY_NAME_COUNT + std::extent_v<decltype(extendedLocalizedKeyNamesPs3)> + 1];
|
||||
|
||||
Gamepad::ControllerMenuKeyMapping Gamepad::controllerMenuKeyMappings[]
|
||||
{
|
||||
@ -155,6 +177,7 @@ namespace Components
|
||||
Dvar::Var Gamepad::gpad_debug;
|
||||
Dvar::Var Gamepad::gpad_present;
|
||||
Dvar::Var Gamepad::gpad_in_use;
|
||||
Dvar::Var Gamepad::gpad_style;
|
||||
Dvar::Var Gamepad::gpad_sticksConfig;
|
||||
Dvar::Var Gamepad::gpad_buttonConfig;
|
||||
Dvar::Var Gamepad::gpad_menu_scroll_delay_first;
|
||||
@ -1694,6 +1717,7 @@ namespace Components
|
||||
gpad_debug = Dvar::Register<bool>("gpad_debug", false, Game::DVAR_FLAG_NONE, "Game pad debugging");
|
||||
gpad_present = Dvar::Register<bool>("gpad_present", false, Game::DVAR_FLAG_NONE, "Game pad present");
|
||||
gpad_in_use = Dvar::Register<bool>("gpad_in_use", false, Game::DVAR_FLAG_NONE, "A game pad is in use");
|
||||
gpad_style = Dvar::Register<bool>("gpad_style", false, Game::DVAR_FLAG_SAVED, "Switch between Xbox and PS HUD");
|
||||
gpad_sticksConfig = Dvar::Register<const char*>("gpad_sticksConfig", "", Game::DVAR_FLAG_SAVED, "Game pad stick configuration");
|
||||
gpad_buttonConfig = Dvar::Register<const char*>("gpad_buttonConfig", "", Game::DVAR_FLAG_SAVED, "Game pad button configuration");
|
||||
gpad_menu_scroll_delay_first = Dvar::Register<int>("gpad_menu_scroll_delay_first", 420, 0, 1000, Game::DVAR_FLAG_SAVED, "Menu scroll key-repeat delay, for the first repeat, in milliseconds");
|
||||
@ -1830,21 +1854,53 @@ namespace Components
|
||||
return cl_bypassMouseInput.get<bool>() || IsGamePadInUse();
|
||||
}
|
||||
|
||||
Game::keyname_t* Gamepad::GetLocalizedKeyNameMap()
|
||||
{
|
||||
if(gpad_style.get<bool>())
|
||||
return combinedLocalizedKeyNamesPs3;
|
||||
|
||||
return combinedLocalizedKeyNamesXenon;
|
||||
}
|
||||
|
||||
void __declspec(naked) Gamepad::GetLocalizedKeyName_Stub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push eax
|
||||
pushad
|
||||
|
||||
call GetLocalizedKeyNameMap
|
||||
mov [esp + 0x20], eax
|
||||
|
||||
popad
|
||||
pop eax
|
||||
|
||||
// Re-execute last instruction from game to set flags again for upcoming jump
|
||||
test edi, edi
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
void Gamepad::CreateKeyNameMap()
|
||||
{
|
||||
memcpy(combinedKeyNames, Game::keyNames, sizeof(Game::keyname_t) * Game::KEY_NAME_COUNT);
|
||||
memcpy(&combinedKeyNames[Game::KEY_NAME_COUNT], extendedKeyNames, sizeof(Game::keyname_t) * std::extent_v<decltype(extendedKeyNames)>);
|
||||
combinedKeyNames[std::extent_v<decltype(combinedKeyNames)> - 1] = {nullptr, 0};
|
||||
|
||||
memcpy(combinedLocalizedKeyNames, Game::localizedKeyNames, sizeof(Game::keyname_t) * Game::LOCALIZED_KEY_NAME_COUNT);
|
||||
memcpy(&combinedLocalizedKeyNames[Game::LOCALIZED_KEY_NAME_COUNT], extendedLocalizedKeyNames,
|
||||
sizeof(Game::keyname_t) * std::extent_v<decltype(extendedLocalizedKeyNames)>);
|
||||
combinedLocalizedKeyNames[std::extent_v<decltype(combinedLocalizedKeyNames)> - 1] = {nullptr, 0};
|
||||
memcpy(combinedLocalizedKeyNamesXenon, Game::localizedKeyNames, sizeof(Game::keyname_t) * Game::LOCALIZED_KEY_NAME_COUNT);
|
||||
memcpy(&combinedLocalizedKeyNamesXenon[Game::LOCALIZED_KEY_NAME_COUNT], extendedLocalizedKeyNamesXenon,
|
||||
sizeof(Game::keyname_t) * std::extent_v<decltype(extendedLocalizedKeyNamesXenon)>);
|
||||
combinedLocalizedKeyNamesXenon[std::extent_v<decltype(combinedLocalizedKeyNamesXenon)> - 1] = {nullptr, 0};
|
||||
|
||||
memcpy(combinedLocalizedKeyNamesPs3, Game::localizedKeyNames, sizeof(Game::keyname_t) * Game::LOCALIZED_KEY_NAME_COUNT);
|
||||
memcpy(&combinedLocalizedKeyNamesPs3[Game::LOCALIZED_KEY_NAME_COUNT], extendedLocalizedKeyNamesPs3,
|
||||
sizeof(Game::keyname_t) * std::extent_v<decltype(extendedLocalizedKeyNamesPs3)>);
|
||||
combinedLocalizedKeyNamesPs3[std::extent_v<decltype(combinedLocalizedKeyNamesPs3)> - 1] = {nullptr, 0};
|
||||
|
||||
Utils::Hook::Set<Game::keyname_t*>(0x4A780A, combinedKeyNames);
|
||||
Utils::Hook::Set<Game::keyname_t*>(0x4A7810, combinedKeyNames);
|
||||
Utils::Hook::Set<Game::keyname_t*>(0x435C9F, combinedKeyNames);
|
||||
Utils::Hook::Set<Game::keyname_t*>(0x435C98, combinedLocalizedKeyNames);
|
||||
Utils::Hook(0x435C97, GetLocalizedKeyName_Stub, HOOK_CALL).install()->quick();
|
||||
}
|
||||
|
||||
Gamepad::Gamepad()
|
||||
|
@ -51,9 +51,11 @@ namespace Components
|
||||
static const char* gamePadMappingTypeNames[];
|
||||
static Game::keyNum_t menuScrollButtonList[];
|
||||
static Game::keyname_t extendedKeyNames[];
|
||||
static Game::keyname_t extendedLocalizedKeyNames[];
|
||||
static Game::keyname_t extendedLocalizedKeyNamesXenon[];
|
||||
static Game::keyname_t extendedLocalizedKeyNamesPs3[];
|
||||
static Game::keyname_t combinedKeyNames[];
|
||||
static Game::keyname_t combinedLocalizedKeyNames[];
|
||||
static Game::keyname_t combinedLocalizedKeyNamesXenon[];
|
||||
static Game::keyname_t combinedLocalizedKeyNamesPs3[];
|
||||
static ControllerMenuKeyMapping controllerMenuKeyMappings[];
|
||||
|
||||
static GamePad gamePads[Game::MAX_GAMEPADS];
|
||||
@ -65,6 +67,7 @@ namespace Components
|
||||
static Dvar::Var gpad_debug;
|
||||
static Dvar::Var gpad_present;
|
||||
static Dvar::Var gpad_in_use;
|
||||
static Dvar::Var gpad_style;
|
||||
static Dvar::Var gpad_sticksConfig;
|
||||
static Dvar::Var gpad_buttonConfig;
|
||||
static Dvar::Var gpad_menu_scroll_delay_first;
|
||||
@ -192,6 +195,9 @@ namespace Components
|
||||
static void CL_KeyEvent_Hk(int localClientNum, int key, int down, unsigned int time);
|
||||
static int CL_MouseEvent_Hk(int x, int y, int dx, int dy);
|
||||
static bool UI_RefreshViewport_Hk();
|
||||
|
||||
static Game::keyname_t* GetLocalizedKeyNameMap();
|
||||
static void GetLocalizedKeyName_Stub();
|
||||
static void CreateKeyNameMap();
|
||||
};
|
||||
}
|
||||
|
@ -181,6 +181,7 @@ namespace Components
|
||||
"a231",
|
||||
"AmateurHailbut",
|
||||
"Aoki",
|
||||
"Chase",
|
||||
"civil",
|
||||
"Dasfonia",
|
||||
"Deity",
|
||||
|
@ -51,7 +51,7 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::ErrorPrint(int error, const std::string& message)
|
||||
void Logger::ErrorPrint(Game::errorParm_t error, const std::string& message)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (IsDebuggerPresent()) __debugbreak();
|
||||
@ -60,19 +60,19 @@ namespace Components
|
||||
return Game::Com_Error(error, "%s", message.data());
|
||||
}
|
||||
|
||||
void Logger::Error(int error, const char* message, ...)
|
||||
void Logger::Error(Game::errorParm_t error, const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(error, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::Error(const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(0, Logger::Format(&message));
|
||||
return Logger::ErrorPrint(Game::ERR_FATAL, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::SoftError(const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(2, Logger::Format(&message));
|
||||
return Logger::ErrorPrint(Game::ERR_SERVERDISCONNECT, Logger::Format(&message));
|
||||
}
|
||||
|
||||
std::string Logger::Format(const char** message)
|
||||
|
@ -11,9 +11,9 @@ namespace Components
|
||||
static void MessagePrint(int channel, const std::string& message);
|
||||
static void Print(int channel, const char* message, ...);
|
||||
static void Print(const char* message, ...);
|
||||
static void ErrorPrint(int error, const std::string& message);
|
||||
static void ErrorPrint(Game::errorParm_t error, const std::string& message);
|
||||
static void Error(const char* message, ...);
|
||||
static void Error(int error, const char* message, ...);
|
||||
static void Error(Game::errorParm_t error, const char* message, ...);
|
||||
static void SoftError(const char* message, ...);
|
||||
static bool IsConsoleReady();
|
||||
|
||||
|
161
src/Components/Modules/Movement.cpp
Normal file
161
src/Components/Modules/Movement.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
Dvar::Var Movement::PlayerDuckedSpeedScale;
|
||||
Dvar::Var Movement::PlayerLastStandCrawlSpeedScale;
|
||||
Dvar::Var Movement::PlayerProneSpeedScale;
|
||||
|
||||
int Movement::PMGetEffectiveStance(Game::playerState_s* ps)
|
||||
{
|
||||
auto heightTarget = ps->viewHeightTarget;
|
||||
|
||||
if (heightTarget == 0x16)
|
||||
return Game::PM_EFF_STANCE_LASTSTANDCRAWL;
|
||||
|
||||
if (heightTarget == 0x28)
|
||||
return Game::PM_EFF_STANCE_DUCKED;
|
||||
|
||||
if (heightTarget == 0xB)
|
||||
return Game::PM_EFF_STANCE_PRONE;
|
||||
|
||||
return Game::PM_EFF_STANCE_DEFAULT;
|
||||
}
|
||||
|
||||
float Movement::PMCmdScaleForStance(Game::pmove_s* move)
|
||||
{
|
||||
auto* playerState = move->ps;
|
||||
float scale;
|
||||
|
||||
if (playerState->viewHeightLerpTime != 0 && playerState->viewHeightLerpTarget == 0xB)
|
||||
{
|
||||
scale = move->cmd.serverTime - playerState->viewHeightLerpTime / 400.0f;
|
||||
|
||||
if (0.0f <= scale)
|
||||
{
|
||||
auto flags = 0;
|
||||
|
||||
if (scale < 1.0f)
|
||||
{
|
||||
flags |= 1 << 8;
|
||||
}
|
||||
|
||||
if (scale == 1.0f)
|
||||
{
|
||||
flags |= 1 << 14;
|
||||
}
|
||||
|
||||
if (flags == 0)
|
||||
{
|
||||
scale = 1.0f;
|
||||
return scale * 0.15f + (1.0f - scale) * 0.65f;
|
||||
}
|
||||
|
||||
if (scale != 0.0f)
|
||||
{
|
||||
return scale * 0.15f + (1.0f - scale) * 0.65f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((playerState->viewHeightLerpTime != 0 && playerState->viewHeightLerpTarget == 0x28) &&
|
||||
playerState->viewHeightLerpDown == 0)
|
||||
{
|
||||
scale = 400.0f / move->cmd.serverTime - playerState->viewHeightLerpTime;
|
||||
|
||||
if (0.0f <= scale)
|
||||
{
|
||||
auto flags = 0;
|
||||
|
||||
if (scale < 1.0f)
|
||||
{
|
||||
flags |= 1 << 8;
|
||||
}
|
||||
|
||||
if (scale == 1.0f)
|
||||
{
|
||||
flags |= 1 << 14;
|
||||
}
|
||||
|
||||
if (flags == 0)
|
||||
{
|
||||
scale = 1.0f;
|
||||
}
|
||||
else if (scale != 0.0f)
|
||||
{
|
||||
return scale * 0.65f + (1.0f - scale) * 0.15f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scale = 1.0f;
|
||||
auto stance = Movement::PMGetEffectiveStance(playerState);
|
||||
|
||||
if (stance == Game::PM_EFF_STANCE_PRONE)
|
||||
{
|
||||
scale = Movement::PlayerProneSpeedScale.get<float>();
|
||||
}
|
||||
|
||||
else if (stance == Game::PM_EFF_STANCE_DUCKED)
|
||||
{
|
||||
scale = Movement::PlayerDuckedSpeedScale.get<float>();
|
||||
}
|
||||
|
||||
else if (stance == Game::PM_EFF_STANCE_LASTSTANDCRAWL)
|
||||
{
|
||||
scale = Movement::PlayerLastStandCrawlSpeedScale.get<float>();
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
__declspec(naked) void Movement::PMCmdScaleForStanceStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
push edx
|
||||
call Movement::PMCmdScaleForStance
|
||||
add esp, 4
|
||||
|
||||
popad
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
Game::dvar_t* Movement::Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int, const char* desc)
|
||||
{
|
||||
Movement::PlayerLastStandCrawlSpeedScale = Dvar::Register<float>(name, defaultVal,
|
||||
min, max, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED, desc);
|
||||
|
||||
return Movement::PlayerLastStandCrawlSpeedScale.get<Game::dvar_t*>();
|
||||
}
|
||||
|
||||
Movement::Movement()
|
||||
{
|
||||
Dvar::OnInit([]
|
||||
{
|
||||
Movement::PlayerDuckedSpeedScale = Dvar::Register<float>("player_duckedSpeedScale",
|
||||
0.65f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED,
|
||||
"The scale applied to the player speed when ducking");
|
||||
|
||||
Movement::PlayerProneSpeedScale = Dvar::Register<float>("player_proneSpeedScale",
|
||||
0.15f, 0.0f, 5.0f, Game::DVAR_FLAG_CHEAT | Game::DVAR_FLAG_REPLICATED,
|
||||
"The scale applied to the player speed when crawling");
|
||||
});
|
||||
|
||||
// Hook PM_CmdScaleForStance in PM_CmdScale_Walk
|
||||
Utils::Hook(0x572F34, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick();
|
||||
|
||||
//Hook PM_CmdScaleForStance in PM_GetMaxSpeed
|
||||
Utils::Hook(0x57395F, Movement::PMCmdScaleForStanceStub, HOOK_CALL).install()->quick();
|
||||
|
||||
// Hook Dvar_RegisterFloat. Only thing that's changed is that the 0x80 flag is not used.
|
||||
Utils::Hook(0x448B66, Movement::Dvar_RegisterLastStandSpeedScale, HOOK_CALL).install()->quick();
|
||||
}
|
||||
|
||||
Movement::~Movement()
|
||||
{
|
||||
}
|
||||
}
|
22
src/Components/Modules/Movement.hpp
Normal file
22
src/Components/Modules/Movement.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Movement : public Component
|
||||
{
|
||||
public:
|
||||
Movement();
|
||||
~Movement();
|
||||
|
||||
private:
|
||||
static Dvar::Var PlayerDuckedSpeedScale;
|
||||
static Dvar::Var PlayerLastStandCrawlSpeedScale;
|
||||
static Dvar::Var PlayerProneSpeedScale;
|
||||
|
||||
static int PMGetEffectiveStance(Game::playerState_s* ps);
|
||||
static float PMCmdScaleForStance(Game::pmove_s* move);
|
||||
static void PMCmdScaleForStanceStub();
|
||||
|
||||
static Game::dvar_t* Dvar_RegisterLastStandSpeedScale(const char* name, float defaultVal, float min, float max, int flags, const char* desc);
|
||||
};
|
||||
}
|
@ -151,7 +151,7 @@ namespace Components
|
||||
Party::Party()
|
||||
{
|
||||
static Game::dvar_t* partyEnable = Dvar::Register<bool>("party_enable", Dedicated::IsEnabled(), Game::dvar_flag::DVAR_FLAG_NONE, "Enable party system").get<Game::dvar_t*>();
|
||||
Dvar::Register<bool>("xblive_privatematch", true, Game::dvar_flag::DVAR_FLAG_WRITEPROTECTED, "").get<Game::dvar_t*>();
|
||||
Dvar::Register<bool>("xblive_privatematch", true, Game::dvar_flag::DVAR_FLAG_WRITEPROTECTED, "");
|
||||
|
||||
// various changes to SV_DirectConnect-y stuff to allow non-party joinees
|
||||
Utils::Hook::Set<WORD>(0x460D96, 0x90E9);
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Components
|
||||
{
|
||||
int QuickPatch::FrameTime = 0;
|
||||
Dvar::Var QuickPatch::r_customAspectRatio;
|
||||
|
||||
void QuickPatch::UnlockStats()
|
||||
{
|
||||
@ -139,16 +140,15 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
bool QuickPatch::InvalidNameCheck(char *dest, char *source, int size)
|
||||
bool QuickPatch::InvalidNameCheck(char* dest, const char* source, int size)
|
||||
{
|
||||
strncpy(dest, source, size - 1);
|
||||
dest[size - 1] = 0;
|
||||
Utils::Hook::Call<void(char*, const char*, int)>(0x4D6F80)(dest, source, size); // I_strncpyz
|
||||
|
||||
for (int i = 0; i < size - 1; i++)
|
||||
{
|
||||
if (!dest[i]) break;
|
||||
|
||||
if (dest[i] > 125 || dest[i] < 32 || dest[i] == '%')
|
||||
if (dest[i] > 125 || dest[i] < 32 || dest[i] == '%')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -172,7 +172,7 @@ namespace Components
|
||||
push 1;
|
||||
push kick_reason;
|
||||
push edi;
|
||||
mov eax, 0x004D1600;
|
||||
mov eax, 0x004D1600; // SV_DropClientInternal
|
||||
call eax;
|
||||
add esp, 12;
|
||||
popad;
|
||||
@ -184,7 +184,6 @@ namespace Components
|
||||
}
|
||||
|
||||
Game::dvar_t* QuickPatch::g_antilag;
|
||||
|
||||
__declspec(naked) void QuickPatch::ClientEventsFireWeaponStub()
|
||||
{
|
||||
__asm
|
||||
@ -268,30 +267,31 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
Game::dvar_t* QuickPatch::r_customAspectRatio;
|
||||
Game::dvar_t* QuickPatch::Dvar_RegisterAspectRatioDvar(const char* name, char**, int defaultVal, int flags, const char* description)
|
||||
{
|
||||
static std::vector < char * > values =
|
||||
static const char* r_aspectRatioEnum[] =
|
||||
{
|
||||
const_cast<char*>("auto"),
|
||||
const_cast<char*>("standard"),
|
||||
const_cast<char*>("wide 16:10"),
|
||||
const_cast<char*>("wide 16:9"),
|
||||
const_cast<char*>("custom"),
|
||||
nullptr,
|
||||
"auto",
|
||||
"standard",
|
||||
"wide 16:10",
|
||||
"wide 16:9",
|
||||
"custom",
|
||||
nullptr
|
||||
};
|
||||
|
||||
// register custom aspect ratio dvar
|
||||
r_customAspectRatio = Game::Dvar_RegisterFloat("r_customAspectRatio", 16.0f / 9.0f, 4.0f / 3.0f, 63.0f / 9.0f, flags, "Screen aspect ratio. Divide the width by the height in order to get the aspect ratio value. For example: 16 / 9 = 1,77");
|
||||
QuickPatch::r_customAspectRatio = Dvar::Register<float>("r_customAspectRatio",
|
||||
16.0f / 9.0f, 4.0f / 3.0f, 63.0f / 9.0f, flags,
|
||||
"Screen aspect ratio. Divide the width by the height in order to get the aspect ratio value. For example: 16 / 9 = 1,77");
|
||||
|
||||
// register enumeration dvar
|
||||
return Game::Dvar_RegisterEnum(name, values.data(), defaultVal, flags, description);
|
||||
return Game::Dvar_RegisterEnum(name, r_aspectRatioEnum, defaultVal, flags, description);
|
||||
}
|
||||
|
||||
void QuickPatch::SetAspectRatio()
|
||||
{
|
||||
// set the aspect ratio
|
||||
Utils::Hook::Set<float>(0x66E1C78, r_customAspectRatio->current.value);
|
||||
Utils::Hook::Set<float>(0x66E1C78, r_customAspectRatio.get<float>());
|
||||
}
|
||||
|
||||
__declspec(naked) void QuickPatch::SetAspectRatioStub()
|
||||
@ -483,8 +483,8 @@ namespace Components
|
||||
Utils::Hook(0x578F52, QuickPatch::JavelinResetHookStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Add ultrawide support
|
||||
Utils::Hook(0x0051B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x005063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook(0x51B13B, QuickPatch::Dvar_RegisterAspectRatioDvar, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x5063F3, QuickPatch::SetAspectRatioStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Make sure preDestroy is called when the game shuts down
|
||||
Scheduler::OnShutdown(Loader::PreDestroy);
|
||||
|
@ -28,13 +28,13 @@ namespace Components
|
||||
|
||||
static void JavelinResetHookStub();
|
||||
|
||||
static bool InvalidNameCheck(char *dest, char *source, int size);
|
||||
static bool InvalidNameCheck(char* dest, const char* source, int size);
|
||||
static void InvalidNameStub();
|
||||
|
||||
static Game::dvar_t* sv_enableBounces;
|
||||
static void BounceStub();
|
||||
|
||||
static Game::dvar_t* r_customAspectRatio;
|
||||
static Dvar::Var r_customAspectRatio;
|
||||
static Game::dvar_t* Dvar_RegisterAspectRatioDvar(const char* name, char** enumValues, int defaultVal, int flags, const char* description);
|
||||
static void SetAspectRatioStub();
|
||||
static void SetAspectRatio();
|
||||
|
@ -132,7 +132,7 @@ namespace Components
|
||||
|
||||
void Renderer::R_TextureFromCodeError(const char* sampler, Game::GfxCmdBufState* state)
|
||||
{
|
||||
Game::Com_Error(0, "Tried to use sampler '%s' when it isn't valid for material '%s' and technique '%s'",
|
||||
Game::Com_Error(Game::ERR_FATAL, "Tried to use sampler '%s' when it isn't valid for material '%s' and technique '%s'",
|
||||
sampler, state->material->info.name, state->technique->name);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ namespace Components
|
||||
unsigned short Script::FunctionName;
|
||||
std::unordered_map<std::string, std::string> Script::ScriptStorage;
|
||||
std::unordered_map<int, std::string> Script::ScriptBaseProgramNum;
|
||||
std::unordered_map<const char*, const char*> Script::ReplacedFunctions;
|
||||
const char* Script::ReplacedPos = 0;
|
||||
int Script::LastFrameTime = -1;
|
||||
|
||||
Utils::Signal<Scheduler::Callback> Script::VMShutdownSignal;
|
||||
@ -24,7 +26,7 @@ namespace Components
|
||||
Logger::Print(23, "Error: unknown function %s in %s\n", funcName.data(), Script::ScriptName.data());
|
||||
Logger::Print(23, "************************************\n");
|
||||
|
||||
Logger::Error(5, "script compile error\nunknown function %s\n%s\n\n", funcName.data(), Script::ScriptName.data());
|
||||
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\nunknown function %s\n%s\n\n", funcName.data(), Script::ScriptName.data());
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::StoreFunctionNameStub()
|
||||
@ -168,7 +170,7 @@ namespace Components
|
||||
Script::PrintSourcePos(Script::ScriptName.data(), offset);
|
||||
Logger::Print(23, "************************************\n\n");
|
||||
|
||||
Logger::Error(5, "script compile error\n%s\n%s\n(see console for actual details)\n", msgbuf, Script::ScriptName.data());
|
||||
Logger::Error(Game::ERR_SCRIPT_DROP, "script compile error\n%s\n%s\n(see console for actual details)\n", msgbuf, Script::ScriptName.data());
|
||||
}
|
||||
|
||||
int Script::LoadScriptAndLabel(const std::string& script, const std::string& label)
|
||||
@ -178,7 +180,7 @@ namespace Components
|
||||
if (!Game::Scr_LoadScript(script.data()))
|
||||
{
|
||||
Logger::Print("Script %s encountered an error while loading. (doesn't exist?)", script.data());
|
||||
Logger::Error(1, reinterpret_cast<char*>(0x70B810), script.data());
|
||||
Logger::Error(Game::ERR_DROP, reinterpret_cast<char*>(0x70B810), script.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -382,21 +384,109 @@ namespace Components
|
||||
Utils::Hook::Call<void(int)>(0x421EE0)(num);
|
||||
}
|
||||
|
||||
int Script::SetExpFogStub()
|
||||
unsigned int Script::SetExpFogStub()
|
||||
{
|
||||
if (Game::Scr_GetNumParam() == 6)
|
||||
if (Game::Scr_GetNumParam() == 6u)
|
||||
{
|
||||
std::memmove(&Game::scriptContainer->stack[-4], &Game::scriptContainer->stack[-5], sizeof(Game::VariableValue) * 6);
|
||||
Game::scriptContainer->stack += 1;
|
||||
Game::scriptContainer->stack[-6].type = Game::VAR_FLOAT;
|
||||
Game::scriptContainer->stack[-6].u.floatValue = 0;
|
||||
std::memmove(&Game::scrVmPub->top[-4], &Game::scrVmPub->top[-5], sizeof(Game::VariableValue) * 6);
|
||||
Game::scrVmPub->top += 1;
|
||||
Game::scrVmPub->top[-6].type = Game::VAR_FLOAT;
|
||||
Game::scrVmPub->top[-6].u.floatValue = 0.0f;
|
||||
|
||||
++Game::scriptContainer->numParam;
|
||||
++Game::scrVmPub->outparamcount;
|
||||
}
|
||||
|
||||
return Game::Scr_GetNumParam();
|
||||
}
|
||||
|
||||
const char* Script::GetCodePosForParam(int index)
|
||||
{
|
||||
if (static_cast<unsigned int>(index) >= Game::scrVmPub->outparamcount)
|
||||
{
|
||||
Game::Scr_Error("^1GetCodePosForParam: Index is out of range!\n");
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto value = &Game::scrVmPub->top[-index];
|
||||
|
||||
if (value->type != Game::VAR_FUNCTION)
|
||||
{
|
||||
Game::Scr_Error("^1GetCodePosForParam: Expects a function as parameter!\n");
|
||||
return "";
|
||||
}
|
||||
|
||||
return value->u.codePosValue;
|
||||
}
|
||||
|
||||
void Script::GetReplacedPos(const char* pos)
|
||||
{
|
||||
if (Script::ReplacedFunctions.find(pos) != Script::ReplacedFunctions.end())
|
||||
{
|
||||
Script::ReplacedPos = Script::ReplacedFunctions[pos];
|
||||
}
|
||||
}
|
||||
|
||||
void Script::SetReplacedPos(const char* what, const char* with)
|
||||
{
|
||||
if (what[0] == '\0' || with[0] == '\0')
|
||||
{
|
||||
Logger::Print("Warning: Invalid paramters passed to ReplacedFunctions\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Script::ReplacedFunctions.find(what) != Script::ReplacedFunctions.end())
|
||||
{
|
||||
Logger::Print("Warning: ReplacedFunctions already contains codePosValue for a function\n");
|
||||
}
|
||||
|
||||
Script::ReplacedFunctions[what] = with;
|
||||
}
|
||||
|
||||
__declspec(naked) void Script::VMExecuteInternalStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
pushad
|
||||
|
||||
push edx
|
||||
call Script::GetReplacedPos
|
||||
|
||||
pop edx
|
||||
popad
|
||||
|
||||
cmp Script::ReplacedPos, 0
|
||||
jne SetPos
|
||||
|
||||
movzx eax, byte ptr [edx]
|
||||
inc edx
|
||||
|
||||
Loc1:
|
||||
cmp eax, 0x8B
|
||||
|
||||
push ecx
|
||||
|
||||
mov ecx, 0x2045094
|
||||
mov [ecx], eax
|
||||
|
||||
mov ecx, 0x2040CD4
|
||||
mov [ecx], edx
|
||||
|
||||
pop ecx
|
||||
|
||||
push 0x61E944
|
||||
retn
|
||||
|
||||
SetPos:
|
||||
mov edx, Script::ReplacedPos
|
||||
mov Script::ReplacedPos, 0
|
||||
|
||||
movzx eax, byte ptr [edx]
|
||||
inc edx
|
||||
|
||||
jmp Loc1
|
||||
}
|
||||
}
|
||||
|
||||
Game::gentity_t* Script::getEntFromEntRef(Game::scr_entref_t entref)
|
||||
{
|
||||
Game::gentity_t* gentity = &Game::g_entities[entref];
|
||||
@ -407,13 +497,27 @@ namespace Components
|
||||
{
|
||||
if (!gentity->client)
|
||||
{
|
||||
Logger::Error(5, "Entity: %i is not a client", gentity);
|
||||
Logger::Error(Game::ERR_SCRIPT_DROP, "Entity: %i is not a client", gentity);
|
||||
}
|
||||
return &Game::svs_clients[gentity->s.number];
|
||||
}
|
||||
|
||||
void Script::AddFunctions()
|
||||
{
|
||||
Script::AddFunction("ReplaceFunc", [](Game::scr_entref_t) // gsc: ReplaceFunc(<function>, <function>)
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 2u)
|
||||
{
|
||||
Game::Scr_Error("^1ReplaceFunc: Needs two parameters!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto what = Script::GetCodePosForParam(0);
|
||||
const auto with = Script::GetCodePosForParam(1);
|
||||
|
||||
Script::SetReplacedPos(what, with);
|
||||
});
|
||||
|
||||
// System time
|
||||
Script::AddFunction("GetSystemTime", [](Game::scr_entref_t) // gsc: GetSystemTime()
|
||||
{
|
||||
@ -434,7 +538,7 @@ namespace Components
|
||||
// Print to console, even without being in 'developer 1'.
|
||||
Script::AddFunction("PrintConsole", [](Game::scr_entref_t) // gsc: PrintConsole(<string>)
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1PrintConsole: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -448,7 +552,7 @@ namespace Components
|
||||
// Executes command to the console
|
||||
Script::AddFunction("Exec", [](Game::scr_entref_t) // gsc: Exec(<string>)
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1Exec: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -463,7 +567,7 @@ namespace Components
|
||||
// Script Storage Funcs
|
||||
Script::AddFunction("StorageSet", [](Game::scr_entref_t) // gsc: StorageSet(<str key>, <str data>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 2 || Game::Scr_GetType(0) != Game::VAR_STRING || Game::Scr_GetType(1) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 2u || Game::Scr_GetType(0) != Game::VAR_STRING || Game::Scr_GetType(1) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1StorageSet: Needs two string parameters!\n");
|
||||
return;
|
||||
@ -477,7 +581,7 @@ namespace Components
|
||||
|
||||
Script::AddFunction("StorageRemove", [](Game::scr_entref_t) // gsc: StorageRemove(<str key>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1StorageRemove: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -496,7 +600,7 @@ namespace Components
|
||||
|
||||
Script::AddFunction("StorageGet", [](Game::scr_entref_t) // gsc: StorageGet(<str key>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1StorageGet: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -516,7 +620,7 @@ namespace Components
|
||||
|
||||
Script::AddFunction("StorageHas", [](Game::scr_entref_t) // gsc: StorageHas(<str key>);
|
||||
{
|
||||
if (Game::Scr_GetNumParam() != 1 || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||
{
|
||||
Game::Scr_Error("^1StorageHas: Needs one string parameter!\n");
|
||||
return;
|
||||
@ -531,56 +635,6 @@ namespace Components
|
||||
{
|
||||
Script::ScriptStorage.clear();
|
||||
});
|
||||
|
||||
Script::AddFunction("Noclip", [](Game::scr_entref_t entref)
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1 && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP;
|
||||
}
|
||||
});
|
||||
|
||||
Script::AddFunction("Ufo", [](Game::scr_entref_t entref)
|
||||
{
|
||||
if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr)
|
||||
{
|
||||
Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() == 1 && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||
{
|
||||
if (Game::Scr_GetInt(0))
|
||||
{
|
||||
Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Script::Script()
|
||||
@ -612,6 +666,9 @@ namespace Components
|
||||
|
||||
Utils::Hook(0x5F41A3, Script::SetExpFogStub, HOOK_CALL).install()->quick();
|
||||
|
||||
Utils::Hook(0x61E92E, Script::VMExecuteInternalStub, HOOK_JUMP).install()->quick();
|
||||
Utils::Hook::Nop(0x61E933, 1);
|
||||
|
||||
Utils::Hook(0x47548B, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x4D06BA, Script::ScrShutdownSystemStub, HOOK_CALL).install()->quick();
|
||||
|
||||
@ -640,31 +697,10 @@ namespace Components
|
||||
|
||||
Script::AddFunctions();
|
||||
|
||||
// Script::AddFunction("playviewmodelfx", [](Game::scr_entref_t /*index*/)
|
||||
// {
|
||||
// /*auto Scr_Error = Utils::Hook::Call<void(const char*)>(0x42EF40);
|
||||
// if (index >> 16)
|
||||
// {
|
||||
// Scr_Error("not an entity");
|
||||
// return;
|
||||
// }*/
|
||||
|
||||
// // obtain FX name
|
||||
// auto fxName = Game::Scr_GetString(0);
|
||||
// auto fx = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FX, fxName).fx;
|
||||
|
||||
// auto tagName = Game::Scr_GetString(1);
|
||||
// auto tagIndex = Game::SL_GetString(tagName, 0);
|
||||
|
||||
// /*char boneIndex = -2;
|
||||
// if (!Game::CG_GetBoneIndex(2048, tagIndex, &boneIndex))
|
||||
// {
|
||||
// Scr_Error(Utils::String::VA("Unknown bone %s.\n", tagName));
|
||||
// return;
|
||||
// }*/
|
||||
|
||||
// Game::CG_PlayBoltedEffect(0, fx, 2048, tagIndex);
|
||||
// });
|
||||
Script::OnVMShutdown([]
|
||||
{
|
||||
Script::ReplacedFunctions.clear();
|
||||
});
|
||||
}
|
||||
|
||||
Script::~Script()
|
||||
@ -673,6 +709,7 @@ namespace Components
|
||||
Script::ScriptHandles.clear();
|
||||
Script::ScriptNameStack.clear();
|
||||
Script::ScriptFunctions.clear();
|
||||
Script::ReplacedFunctions.clear();
|
||||
Script::VMShutdownSignal.clear();
|
||||
|
||||
Script::ScriptStorage.clear();
|
||||
|
@ -40,6 +40,8 @@ namespace Components
|
||||
static unsigned short FunctionName;
|
||||
static std::unordered_map<std::string, std::string> ScriptStorage;
|
||||
static std::unordered_map<int, std::string> ScriptBaseProgramNum;
|
||||
static std::unordered_map<const char*, const char*> ReplacedFunctions;
|
||||
static const char* ReplacedPos;
|
||||
static int LastFrameTime;
|
||||
|
||||
static Utils::Signal<Scheduler::Callback> VMShutdownSignal;
|
||||
@ -68,7 +70,12 @@ namespace Components
|
||||
static void Scr_PrintPrevCodePosStub();
|
||||
static void Scr_PrintPrevCodePos(int);
|
||||
|
||||
static int SetExpFogStub();
|
||||
static unsigned int SetExpFogStub();
|
||||
|
||||
static const char* GetCodePosForParam(int index);
|
||||
static void GetReplacedPos(const char* pos);
|
||||
static void SetReplacedPos(const char* what, const char* with);
|
||||
static void VMExecuteInternalStub();
|
||||
|
||||
static void AddFunctions();
|
||||
};
|
||||
|
@ -38,12 +38,12 @@ namespace Components
|
||||
float start = Game::Scr_GetFloat(0);
|
||||
float end = 1.0f;
|
||||
|
||||
if (Game::Scr_GetNumParam() >= 2)
|
||||
if (Game::Scr_GetNumParam() >= 2u)
|
||||
{
|
||||
end = Game::Scr_GetFloat(1);
|
||||
}
|
||||
|
||||
if (Game::Scr_GetNumParam() >= 3)
|
||||
if (Game::Scr_GetNumParam() >= 3u)
|
||||
{
|
||||
duration = static_cast<int>(Game::Scr_GetFloat(2) * 1000.0);
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ namespace Components
|
||||
|
||||
Command::Add("error", [](Command::Params*)
|
||||
{
|
||||
Game::Com_Error(0, "This is a test %s\n", "error");
|
||||
Game::Com_Error(Game::ERR_FATAL, "This is a test %s\n", "error");
|
||||
});
|
||||
|
||||
// now load default assets and shaders
|
||||
@ -1412,7 +1412,7 @@ namespace Components
|
||||
// build final techsets fastfile
|
||||
if (subCount > 24)
|
||||
{
|
||||
Logger::ErrorPrint(1, "How did you have 576 fastfiles?\n");
|
||||
Logger::ErrorPrint(Game::ERR_DROP, "How did you have 576 fastfiles?\n");
|
||||
}
|
||||
|
||||
curTechsets_list.clear();
|
||||
|
@ -314,6 +314,7 @@ namespace Game
|
||||
SV_GameSendServerCommand_t SV_GameSendServerCommand = SV_GameSendServerCommand_t(0x4BC3A0);
|
||||
SV_Cmd_TokenizeString_t SV_Cmd_TokenizeString = SV_Cmd_TokenizeString_t(0x4B5780);
|
||||
SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString = SV_Cmd_EndTokenizedString_t(0x464750);
|
||||
SV_Cmd_ArgvBuffer_t SV_Cmd_ArgvBuffer = SV_Cmd_ArgvBuffer_t(0x40BB60);
|
||||
SV_DirectConnect_t SV_DirectConnect = SV_DirectConnect_t(0x460480);
|
||||
SV_SetConfigstring_t SV_SetConfigstring = SV_SetConfigstring_t(0x4982E0);
|
||||
SV_Loaded_t SV_Loaded = SV_Loaded_t(0x4EE3E0);
|
||||
@ -460,7 +461,7 @@ namespace Game
|
||||
XZone* g_zones = reinterpret_cast<XZone*>(0x14C0F80);
|
||||
unsigned short* db_hashTable = reinterpret_cast<unsigned short*>(0x12412B0);
|
||||
|
||||
ScriptContainer* scriptContainer = reinterpret_cast<ScriptContainer*>(0x2040D00);
|
||||
scrVmPub_t* scrVmPub = reinterpret_cast<scrVmPub_t*>(0x2040CF0);
|
||||
|
||||
clientstate_t* clcState = reinterpret_cast<clientstate_t*>(0xB2C540);
|
||||
|
||||
|
@ -121,7 +121,7 @@ namespace Game
|
||||
typedef void(__cdecl * Com_ClientPacketEvent_t)();
|
||||
extern Com_ClientPacketEvent_t Com_ClientPacketEvent;
|
||||
|
||||
typedef void(__cdecl * Com_Error_t)(int type, const char* message, ...);
|
||||
typedef void(__cdecl * Com_Error_t)(errorParm_t type, const char* message, ...);
|
||||
extern Com_Error_t Com_Error;
|
||||
|
||||
typedef void(__cdecl * Com_Printf_t)(int channel, const char *fmt, ...);
|
||||
@ -247,7 +247,7 @@ namespace Game
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterInt_t)(const char* name, int defaultVal, int min, int max, int flags, const char* description);
|
||||
extern Dvar_RegisterInt_t Dvar_RegisterInt;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterEnum_t)(const char* name, char** enumValues, int defaultVal, int flags, const char* description);
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterEnum_t)(const char* name, const char** enumValues, int defaultVal, int flags, const char* description);
|
||||
extern Dvar_RegisterEnum_t Dvar_RegisterEnum;
|
||||
|
||||
typedef dvar_t* (__cdecl * Dvar_RegisterString_t)(const char* name, const char* defaultVal, int, const char*);
|
||||
@ -660,7 +660,7 @@ namespace Game
|
||||
typedef unsigned int(__cdecl * Scr_GetObject_t)(int);
|
||||
extern Scr_GetObject_t Scr_GetObject;
|
||||
|
||||
typedef int(__cdecl * Scr_GetNumParam_t)();
|
||||
typedef unsigned int(__cdecl * Scr_GetNumParam_t)();
|
||||
extern Scr_GetNumParam_t Scr_GetNumParam;
|
||||
|
||||
typedef int(__cdecl * Scr_GetFunctionHandle_t)(const char*, const char*);
|
||||
@ -687,7 +687,7 @@ namespace Game
|
||||
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
||||
extern Scr_IsSystemActive_t Scr_IsSystemActive;
|
||||
|
||||
typedef int(__cdecl* Scr_GetType_t)(int);
|
||||
typedef int(__cdecl* Scr_GetType_t)(unsigned int);
|
||||
extern Scr_GetType_t Scr_GetType;
|
||||
|
||||
typedef void(__cdecl* Scr_Error_t)(const char*);
|
||||
@ -750,6 +750,9 @@ namespace Game
|
||||
typedef void(__cdecl * SV_Cmd_EndTokenizedString_t)();
|
||||
extern SV_Cmd_EndTokenizedString_t SV_Cmd_EndTokenizedString;
|
||||
|
||||
typedef void(__cdecl* SV_Cmd_ArgvBuffer_t)(int arg, char* buf, int size);
|
||||
extern SV_Cmd_ArgvBuffer_t SV_Cmd_ArgvBuffer;
|
||||
|
||||
typedef void(__cdecl * SV_SetConfigstring_t)(int index, const char* string);
|
||||
extern SV_SetConfigstring_t SV_SetConfigstring;
|
||||
|
||||
@ -969,7 +972,7 @@ namespace Game
|
||||
extern XZone* g_zones;
|
||||
extern unsigned short* db_hashTable;
|
||||
|
||||
extern ScriptContainer* scriptContainer;
|
||||
extern scrVmPub_t* scrVmPub;
|
||||
|
||||
extern clientstate_t* clcState;
|
||||
|
||||
|
@ -109,7 +109,7 @@ namespace Game
|
||||
IMG_CATEGORY_WATER = 0x5,
|
||||
IMG_CATEGORY_RENDERTARGET = 0x6,
|
||||
IMG_CATEGORY_TEMP = 0x7,
|
||||
} ;
|
||||
};
|
||||
|
||||
enum buttons_t
|
||||
{
|
||||
@ -177,6 +177,40 @@ namespace Game
|
||||
CS_ACTIVE = 0x5,
|
||||
} clientstate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERR_FATAL = 0x0,
|
||||
ERR_DROP = 0x1,
|
||||
ERR_SERVERDISCONNECT = 0x2,
|
||||
ERR_DISCONNECT = 0x3,
|
||||
ERR_SCRIPT = 0x4,
|
||||
ERR_SCRIPT_DROP = 0x5,
|
||||
ERR_LOCALIZATION = 0x6,
|
||||
ERR_MAPLOADERRORSUMMARY = 0x7
|
||||
} errorParm_t;
|
||||
|
||||
enum entityFlag
|
||||
{
|
||||
FL_GODMODE = 0x1,
|
||||
FL_DEMI_GODMODE = 0x2,
|
||||
FL_NOTARGET = 0x4,
|
||||
FL_NO_KNOCKBACK = 0x8,
|
||||
FL_NO_RADIUS_DAMAGE = 0x10,
|
||||
FL_SUPPORTS_LINKTO = 0x1000,
|
||||
FL_NO_AUTO_ANIM_UPDATE = 0x2000,
|
||||
FL_GRENADE_TOUCH_DAMAGE = 0x4000,
|
||||
FL_STABLE_MISSILES = 0x20000,
|
||||
FL_REPEAT_ANIM_UPDATE = 0x40000,
|
||||
FL_VEHICLE_TARGET = 0x80000,
|
||||
FL_GROUND_ENT = 0x100000,
|
||||
FL_CURSOR_HINT = 0x200000,
|
||||
FL_MISSILE_ATTRACTOR = 0x800000,
|
||||
FL_WEAPON_BEING_GRABBED = 0x1000000,
|
||||
FL_DELETE = 0x2000000,
|
||||
FL_BOUNCE = 0x4000000,
|
||||
FL_MOVER_SLIDE = 0x8000000
|
||||
};
|
||||
|
||||
struct FxEffectDef;
|
||||
struct pathnode_t;
|
||||
struct pathnode_tree_t;
|
||||
@ -4886,18 +4920,38 @@ namespace Game
|
||||
struct VariableValue
|
||||
{
|
||||
VariableUnion u;
|
||||
int type;
|
||||
VariableType type;
|
||||
};
|
||||
|
||||
struct ScriptContainer
|
||||
struct function_stack_t
|
||||
{
|
||||
VariableValue* stack;
|
||||
char unk1;
|
||||
char unk2;
|
||||
char unk3;
|
||||
char pad;
|
||||
DWORD unk4;
|
||||
int numParam;
|
||||
const char* pos;
|
||||
unsigned int localId;
|
||||
unsigned int localVarCount;
|
||||
VariableValue* top;
|
||||
VariableValue* startTop;
|
||||
};
|
||||
|
||||
struct function_frame_t
|
||||
{
|
||||
function_stack_t fs;
|
||||
int topType;
|
||||
};
|
||||
|
||||
struct scrVmPub_t
|
||||
{
|
||||
unsigned int* localVars;
|
||||
VariableValue* maxStack;
|
||||
int function_count;
|
||||
function_frame_t* function_frame;
|
||||
VariableValue* top;
|
||||
bool debugCode;
|
||||
bool abort_on_error;
|
||||
bool terminal_error;
|
||||
unsigned int inparamcount;
|
||||
unsigned int outparamcount;
|
||||
function_frame_t function_frame_start[32];
|
||||
VariableValue stack[2048];
|
||||
};
|
||||
|
||||
enum UILocalVarType
|
||||
@ -6876,6 +6930,37 @@ namespace Game
|
||||
const char* args[9];
|
||||
};
|
||||
|
||||
struct pmove_s
|
||||
{
|
||||
playerState_s* ps;
|
||||
usercmd_s cmd;
|
||||
usercmd_s oldcmd;
|
||||
int tracemask;
|
||||
int numtouch;
|
||||
int touchents[32];
|
||||
char __pad0[24];
|
||||
float xyspeed;
|
||||
int proneChange;
|
||||
float maxSprintTimeMultiplier;
|
||||
bool mantleStarted;
|
||||
float mantleEndPos[3];
|
||||
int mantleDuration;
|
||||
int viewChangeTime;
|
||||
float viewChange;
|
||||
float fTorsoPitch;
|
||||
float fWaistPitch;
|
||||
unsigned char handler;
|
||||
};
|
||||
|
||||
enum EffectiveStance
|
||||
{
|
||||
PM_EFF_STANCE_DEFAULT = 0,
|
||||
PM_EFF_STANCE_PRONE = 1,
|
||||
PM_EFF_STANCE_DUCKED = 2,
|
||||
PM_EFF_STANCE_LASTSTANDCRAWL = 3,
|
||||
PM_EFF_STANCE_COUNT = 4
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#ifndef IDA
|
||||
|
@ -42,10 +42,9 @@
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
// Experimental C++17 features
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <random>
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user