mirror of
https://github.com/fedddddd/iw5-gsc-utils.git
synced 2025-07-04 02:01:52 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
12562eb8fd | |||
286481cbcd | |||
e9a877bd74 | |||
3060df1f05 | |||
aa1ae8c574 | |||
ccd8176c25
|
|||
c230a1d916
|
|||
2785a60dc0
|
|||
1b65bda323 | |||
9ca07aca55 |
@ -49,6 +49,7 @@ namespace command
|
|||||||
if (i > index) result.append(" ");
|
if (i > index) result.append(" ");
|
||||||
result.append(this->get(i));
|
result.append(this->get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +97,6 @@ namespace command
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -380,6 +380,20 @@ namespace gsc
|
|||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function::add("dropallbots", [](const function_args& args) -> scripting::script_value
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < *game::svs_clientCount; i++)
|
||||||
|
{
|
||||||
|
if (game::svs_clients[i].header.state != game::CS_FREE
|
||||||
|
&& game::svs_clients[i].header.netchan.remoteAddress.type == game::NA_BOT)
|
||||||
|
{
|
||||||
|
game::SV_GameDropClient(i, "GAME_GET_TO_COVER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
method::add("tell", [](const game::scr_entref_t ent, const function_args& args) -> scripting::script_value
|
method::add("tell", [](const game::scr_entref_t ent, const function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
if (ent.classnum != 0)
|
if (ent.classnum != 0)
|
||||||
@ -388,8 +402,13 @@ namespace gsc
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto client = ent.entnum;
|
const auto client = ent.entnum;
|
||||||
const auto message = args[0].as<std::string>();
|
|
||||||
|
|
||||||
|
if (game::g_entities[client].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto message = args[0].as<std::string>();
|
||||||
game::SV_GameSendServerCommand(client, 0, utils::string::va("%c \"%s\"", 84, message.data()));
|
game::SV_GameSendServerCommand(client, 0, utils::string::va("%c \"%s\"", 84, message.data()));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -402,16 +421,18 @@ namespace gsc
|
|||||||
throw std::runtime_error("Invalid entity");
|
throw std::runtime_error("Invalid entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto num = ent.entnum;
|
const auto client = ent.entnum;
|
||||||
|
|
||||||
|
if (game::g_entities[client].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
const auto toggle = args[0].as<int>();
|
const auto toggle = args[0].as<int>();
|
||||||
|
auto flags = game::g_entities[client].client->ps.perks[0];
|
||||||
|
|
||||||
auto g_client = game::g_entities[num].client;
|
game::g_entities[client].client->ps.perks[0] = toggle
|
||||||
auto playerState = &g_client->ps;
|
? flags | 0x4000u : flags & ~0x4000u;
|
||||||
auto flags = playerState->perks[0];
|
|
||||||
|
|
||||||
playerState->perks[0] = toggle
|
|
||||||
? flags | 0x4000u
|
|
||||||
: flags & ~0x4000u;
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
@ -424,9 +445,10 @@ namespace gsc
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto client = ent.entnum;
|
const auto client = ent.entnum;
|
||||||
|
|
||||||
if (game::g_entities[client].client == nullptr)
|
if (game::g_entities[client].client == nullptr)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("entity is not a player");
|
throw std::runtime_error("Not a player entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
return game::svs_clients[client].bIsTestClient;
|
return game::svs_clients[client].bIsTestClient;
|
||||||
|
@ -15,6 +15,12 @@ namespace notifies
|
|||||||
void client_command_stub(int clientNum)
|
void client_command_stub(int clientNum)
|
||||||
{
|
{
|
||||||
char cmd[1024] = {0};
|
char cmd[1024] = {0};
|
||||||
|
const auto* entity = &game::g_entities[clientNum];
|
||||||
|
|
||||||
|
if (entity->client == nullptr)
|
||||||
|
{
|
||||||
|
return; // Client is not fully in game yet
|
||||||
|
}
|
||||||
|
|
||||||
game::SV_Cmd_ArgvBuffer(0, cmd, 1024);
|
game::SV_Cmd_ArgvBuffer(0, cmd, 1024);
|
||||||
|
|
||||||
|
@ -92,13 +92,18 @@ namespace userinfo
|
|||||||
|
|
||||||
gsc::method::add("setname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
gsc::method::add("setname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
const auto name = args[0].as<std::string>();
|
if (ent.classnum != 0)
|
||||||
|
|
||||||
if (ent.classnum != 0 || ent.entnum > 17)
|
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid entity");
|
throw std::runtime_error("Invalid entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game::g_entities[ent.entnum].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto name = args[0].as<std::string>();
|
||||||
|
|
||||||
userinfo_overrides[ent.entnum]["name"] = name;
|
userinfo_overrides[ent.entnum]["name"] = name;
|
||||||
game::ClientUserinfoChanged(ent.entnum);
|
game::ClientUserinfoChanged(ent.entnum);
|
||||||
|
|
||||||
@ -107,11 +112,16 @@ namespace userinfo
|
|||||||
|
|
||||||
gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
gsc::method::add("resetname", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
if (ent.classnum != 0 || ent.entnum > 17)
|
if (ent.classnum != 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid entity");
|
throw std::runtime_error("Invalid entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game::g_entities[ent.entnum].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
userinfo_overrides[ent.entnum].erase("name");
|
userinfo_overrides[ent.entnum].erase("name");
|
||||||
game::ClientUserinfoChanged(ent.entnum);
|
game::ClientUserinfoChanged(ent.entnum);
|
||||||
|
|
||||||
@ -120,13 +130,18 @@ namespace userinfo
|
|||||||
|
|
||||||
gsc::method::add("setclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
gsc::method::add("setclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
const auto name = args[0].as<std::string>();
|
if (ent.classnum != 0)
|
||||||
|
|
||||||
if (ent.classnum != 0 || ent.entnum > 17)
|
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid entity");
|
throw std::runtime_error("Invalid entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game::g_entities[ent.entnum].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto name = args[0].as<std::string>();
|
||||||
|
|
||||||
userinfo_overrides[ent.entnum]["clantag"] = name;
|
userinfo_overrides[ent.entnum]["clantag"] = name;
|
||||||
userinfo_overrides[ent.entnum]["ec_TagText"] = name;
|
userinfo_overrides[ent.entnum]["ec_TagText"] = name;
|
||||||
userinfo_overrides[ent.entnum]["ec_usingTag"] = "1";
|
userinfo_overrides[ent.entnum]["ec_usingTag"] = "1";
|
||||||
@ -137,11 +152,16 @@ namespace userinfo
|
|||||||
|
|
||||||
gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
gsc::method::add("resetclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
if (ent.classnum != 0 || ent.entnum > 17)
|
if (ent.classnum != 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid entity");
|
throw std::runtime_error("Invalid entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game::g_entities[ent.entnum].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
userinfo_overrides[ent.entnum].erase("clantag");
|
userinfo_overrides[ent.entnum].erase("clantag");
|
||||||
userinfo_overrides[ent.entnum].erase("ec_TagText");
|
userinfo_overrides[ent.entnum].erase("ec_TagText");
|
||||||
userinfo_overrides[ent.entnum].erase("ec_usingTag");
|
userinfo_overrides[ent.entnum].erase("ec_usingTag");
|
||||||
@ -152,11 +172,16 @@ namespace userinfo
|
|||||||
|
|
||||||
gsc::method::add("removeclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
gsc::method::add("removeclantag", [](const game::scr_entref_t ent, const gsc::function_args& args) -> scripting::script_value
|
||||||
{
|
{
|
||||||
if (ent.classnum != 0 || ent.entnum > 17)
|
if (ent.classnum != 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Invalid entity");
|
throw std::runtime_error("Invalid entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game::g_entities[ent.entnum].client == nullptr)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Not a player entity");
|
||||||
|
}
|
||||||
|
|
||||||
userinfo_overrides[ent.entnum]["clantag"] = "";
|
userinfo_overrides[ent.entnum]["clantag"] = "";
|
||||||
userinfo_overrides[ent.entnum]["ec_TagText"] = "";
|
userinfo_overrides[ent.entnum]["ec_TagText"] = "";
|
||||||
userinfo_overrides[ent.entnum]["ec_usingTag"] = "0";
|
userinfo_overrides[ent.entnum]["ec_usingTag"] = "0";
|
||||||
|
@ -5,13 +5,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
{
|
{
|
||||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
const auto value = *reinterpret_cast<DWORD*>(0x20900000);
|
const auto value = *reinterpret_cast<DWORD*>(0x21600000);
|
||||||
if (value != 0xF0681B6A)
|
if (value != 0x8A94852)
|
||||||
{
|
{
|
||||||
MessageBoxA(NULL,
|
MessageBoxA(NULL,
|
||||||
"This version of iw5-gsc-utils is outdated.\n" \
|
"This version of iw5-gsc-utils is outdated.\n" \
|
||||||
"Download the latest dll from here: https://github.com/fedddddd/iw5-gsc-utils/releases" \
|
"Download the latest dll from here: https://github.com/fedddddd/iw5-gsc-utils/releases",
|
||||||
, "ERROR", MB_ICONERROR);
|
"ERROR", MB_ICONERROR);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,11 @@
|
|||||||
|
|
||||||
namespace game
|
namespace game
|
||||||
{
|
{
|
||||||
|
void SV_GameDropClient(int clientNum, const char* reason)
|
||||||
|
{
|
||||||
|
if (clientNum >= 0 && clientNum < sv_maxclients->current.integer)
|
||||||
|
{
|
||||||
|
SV_DropClient(&svs_clients[clientNum], reason, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ namespace game
|
|||||||
private:
|
private:
|
||||||
T* dedi_;
|
T* dedi_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SV_GameDropClient(int clientNum, const char* reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "symbols.hpp"
|
#include "symbols.hpp"
|
@ -26,20 +26,35 @@ namespace game
|
|||||||
const char** argv[8];
|
const char** argv[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum netsrc_t
|
||||||
|
{
|
||||||
|
NS_CLIENT1 = 0x0,
|
||||||
|
NS_CLIENT2 = 0x1,
|
||||||
|
NS_CLIENT3 = 0x2,
|
||||||
|
NS_CLIENT4 = 0x3,
|
||||||
|
NS_MAXCLIENTS = 0x4,
|
||||||
|
NS_SERVER = 0x4,
|
||||||
|
NS_PACKET = 0x5,
|
||||||
|
NS_INVALID_NETSRC = 0x6
|
||||||
|
};
|
||||||
|
|
||||||
struct msg_t
|
struct msg_t
|
||||||
{
|
{
|
||||||
int overflowed;
|
int overflowed;
|
||||||
int readOnly;
|
int readOnly;
|
||||||
char* data;
|
unsigned char* data;
|
||||||
char* splitData;
|
unsigned char* splitData;
|
||||||
int maxsize;
|
int maxsize;
|
||||||
int cursize;
|
int cursize;
|
||||||
int splitSize;
|
int splitSize;
|
||||||
int readcount;
|
int readcount;
|
||||||
int bit;
|
int bit;
|
||||||
int lastEntityRef;
|
int lastEntityRef;
|
||||||
|
netsrc_t targetLocalNetID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(msg_t) == 0x2C);
|
||||||
|
|
||||||
struct XZoneInfo
|
struct XZoneInfo
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -328,9 +343,82 @@ namespace game
|
|||||||
char __pad2[0xEC];
|
char __pad2[0xEC];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum netadrtype_t
|
||||||
|
{
|
||||||
|
NA_BOT = 0x0,
|
||||||
|
NA_BAD = 0x1,
|
||||||
|
NA_LOOPBACK = 0x2,
|
||||||
|
NA_BROADCAST = 0x3,
|
||||||
|
NA_IP = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct netadr_s
|
||||||
|
{
|
||||||
|
netadrtype_t type;
|
||||||
|
unsigned char ip[4];
|
||||||
|
unsigned __int16 port;
|
||||||
|
unsigned char ipx[10];
|
||||||
|
unsigned int addrHandleIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(netadr_s) == 24);
|
||||||
|
|
||||||
|
struct netchan_t
|
||||||
|
{
|
||||||
|
int outgoingSequence;
|
||||||
|
netsrc_t sock;
|
||||||
|
int dropped;
|
||||||
|
int incomingSequence;
|
||||||
|
netadr_s remoteAddress;
|
||||||
|
int qport;
|
||||||
|
int fragmentSequence;
|
||||||
|
int fragmentLength;
|
||||||
|
unsigned char* fragmentBuffer;
|
||||||
|
int fragmentBufferSize;
|
||||||
|
int unsentFragments;
|
||||||
|
int unsentFragmentStart;
|
||||||
|
int unsentLength;
|
||||||
|
unsigned char* unsentBuffer;
|
||||||
|
int unsentBufferSize;
|
||||||
|
unsigned char __pad0[0x5E0];
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(netchan_t) == 0x630);
|
||||||
|
|
||||||
|
enum clientState_t
|
||||||
|
{
|
||||||
|
CS_FREE = 0,
|
||||||
|
CS_ZOMBIE = 1,
|
||||||
|
CS_RECONNECTING = 2,
|
||||||
|
CS_CONNECTED = 3,
|
||||||
|
CS_CLIENTLOADING = 4,
|
||||||
|
CS_ACTIVE = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
struct clientHeader_t
|
||||||
|
{
|
||||||
|
clientState_t state; // 0
|
||||||
|
int sendAsActive; // 4
|
||||||
|
int deltaMessage; // 8
|
||||||
|
int rateDealyed; // 12
|
||||||
|
int hasAckedBaselineData; // 16
|
||||||
|
int hugeSnapshotSent; // 20
|
||||||
|
netchan_t netchan; // 24
|
||||||
|
vec3_t predictedOrigin;
|
||||||
|
int predictedOriginServerTime;
|
||||||
|
int migrationState;
|
||||||
|
vec3_t predictedVehicleOrigin;
|
||||||
|
int predictedVehicleServerTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(clientHeader_t) == 0x66C);
|
||||||
|
|
||||||
struct client_s
|
struct client_s
|
||||||
{
|
{
|
||||||
char __pad0[0x41CB2];
|
clientHeader_t header;
|
||||||
|
const char* dropReason;
|
||||||
|
char userinfo[1024];
|
||||||
|
char __pad0[0x41242];
|
||||||
unsigned __int16 scriptId; // 269490
|
unsigned __int16 scriptId; // 269490
|
||||||
int bIsTestClient; // 269492
|
int bIsTestClient; // 269492
|
||||||
int serverId; // 269496
|
int serverId; // 269496
|
||||||
|
@ -57,6 +57,7 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x573220};
|
WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x573220};
|
||||||
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x5459F0};
|
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x5459F0};
|
||||||
|
WEAK symbol<void(client_s* drop, const char* reason, bool tellThem)> SV_DropClient{0x570980};
|
||||||
|
|
||||||
WEAK symbol<void(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top)> VM_Notify{0x569720};
|
WEAK symbol<void(unsigned int notifyListOwnerId, unsigned int stringValue, VariableValue* top)> VM_Notify{0x569720};
|
||||||
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0};
|
WEAK symbol<unsigned int(unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x56DFE0};
|
||||||
@ -79,15 +80,17 @@ namespace game
|
|||||||
WEAK symbol<gentity_s> g_entities{0x1A66E28};
|
WEAK symbol<gentity_s> g_entities{0x1A66E28};
|
||||||
WEAK symbol<unsigned int> levelEntityId{0x208E1A4};
|
WEAK symbol<unsigned int> levelEntityId{0x208E1A4};
|
||||||
|
|
||||||
|
WEAK symbol<dvar_t> sv_maxclients{0x1BA0E4C};
|
||||||
|
WEAK symbol<int> svs_clientCount{0x4B5CF8C};
|
||||||
WEAK symbol<client_s> svs_clients{0x4B5CF90};
|
WEAK symbol<client_s> svs_clients{0x4B5CF90};
|
||||||
|
|
||||||
namespace plutonium
|
namespace plutonium
|
||||||
{
|
{
|
||||||
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> function_map_rev{0x20693038};
|
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> function_map_rev{0x2074C520};
|
||||||
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> method_map_rev{0x20693058};
|
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> method_map_rev{0x2074C540};
|
||||||
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> token_map_rev{0x20693098};
|
WEAK symbol<std::unordered_map<std::string, std::uint16_t>> token_map_rev{0x2074C580};
|
||||||
WEAK symbol<int(const char* fmt, ...)> printf{0x208879B0};
|
WEAK symbol<int(const char* fmt, ...)> printf{0x2093E120};
|
||||||
WEAK symbol<void*> function_table{0x2068BCF0};
|
WEAK symbol<void*> function_table{0x206FAA70};
|
||||||
WEAK symbol<void*> method_table{0x2068C4C0};
|
WEAK symbol<void*> method_table{0x206FB240};
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user