Skip to content

Commit 5b2eb8b

Browse files
committed
Merge branch 'dev'
2 parents 19e8b80 + 50a56bc commit 5b2eb8b

File tree

7 files changed

+616
-180
lines changed

7 files changed

+616
-180
lines changed

README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,18 @@ bool FirstRunState(); | "Get or s
3636
Note: While represented in C++, below functions are for Squirrel. `const char*` type is translated to `string` type, and `byte`, `short`, and `long` types are translated to `integer` type in Squirrel. `void` types are simply the `function` type in Squirrel.
3737
3838
```c++
39-
void GEClientCommand(short userid, int entindex, const char* pcmd, const char* fargs); | "Called whenever a player runs a console command."
40-
void GEPlayerLanded(short userid); | "Called whenever a player lands on the ground. Game event: 'portal_player_touchedground'"
39+
void GEClientCommand(short userid, int entindex, const char* pcmd, const char* fargs); | "Called when a client inputs a console command."
40+
void GEClientActive(short userid, int entindex); | "Called when a player is 'activated' in the server, meaning fully loaded, not fully connect which happens before that."
41+
void GEGameFrame(bool simulating); | "Called every server frame, used for the VScript loop. Warning: Don't do too intensive tasks with this!"
4142
void GEPlayerPing(short userid, float ping_x, float ping_y, float ping_z); | "Called whenever a player pings. Game event: 'portal_player_ping'"
4243
void GEPlayerPortaled(bool portal2); | "Called whenever a player goes through a portal. `portal2` is false when portal1/blue portal is entered. Game event: 'portal_player_portaled'"
4344
void GETurretHitTurret(); | "Called whenever a turret hits another turret. Game event: 'turret_hit_turret'"
4445
void GECamDetach(); | "Called whenever a camera is detached from a surface. Game event: 'security_camera_detached'"
46+
void GEPlayerLanded(short userid); | "Called whenever a player lands on the ground. Game event: 'player_landed'"
47+
void GEPlayerConnect(const char* name, int index, short userid, const char* xuid,
48+
const char* networkid, const char* address, bool bot, int entindex); | "Called where a player connects to the server. 'index' is the entity index minus 1. Game event: 'player_connect'"
49+
void GEPlayerInfo(const char* name, int index, short userid, const char* networkid,
50+
const char* address, bool bot, int entindex); | "Called when a player changes their name."
51+
4552
void GEPlayerSay(short userid, const char* text, int entindex); | "Called whenever a player inputs a chat message. Game event: 'player_say'"
4653
```

globals.cpp

+135-1
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,35 @@ void P2MMLog(int level, bool dev, const char* pMsgFormat, ...)
4848
}
4949
}
5050

51+
void ReplacePattern(std::string target_module, std::string patternBytes, std::string replace_with)
52+
{
53+
void* addr = Memory::Scanner::Scan<void*>(Memory::Modules::Get(target_module), patternBytes);
54+
if (!addr)
55+
{
56+
P2MMLog(1, false, "Failed to replace pattern!");
57+
return;
58+
}
59+
60+
std::vector<uint8_t> replace;
61+
62+
std::istringstream patternStream(replace_with);
63+
std::string patternByte;
64+
while (patternStream >> patternByte)
65+
{
66+
replace.push_back((uint8_t)std::stoul(patternByte, nullptr, 16));
67+
}
68+
69+
DWORD oldprotect = 0;
70+
DWORD newprotect = PAGE_EXECUTE_READWRITE;
71+
VirtualProtect(addr, replace.size(), newprotect, &oldprotect);
72+
memcpy_s(addr, replace.size(), replace.data(), replace.size());
73+
VirtualProtect(addr, replace.size(), oldprotect, &newprotect);
74+
}
75+
5176
//---------------------------------------------------------------------------------
5277
// Purpose: Gets player entity index by userid.
5378
//---------------------------------------------------------------------------------
54-
int GetPlayerIndex(int userid)
79+
int GFunc::UserIDToPlayerIndex(int userid)
5580
{
5681
for (int i = 1; i <= gpGlobals->maxClients; i++)
5782
{
@@ -68,3 +93,112 @@ int GetPlayerIndex(int userid)
6893
}
6994
return NULL; // Return NULL if the index can't be found
7095
}
96+
97+
// Get the script scope of a entity, thanks to Nullderef/Vista for this.
98+
HSCRIPT GFunc::GetScriptScope(CBaseEntity* entity)
99+
{
100+
if (entity == NULL)
101+
{
102+
103+
return NULL;
104+
}
105+
return reinterpret_cast<HSCRIPT>(reinterpret_cast<uintptr_t>(entity) + 0x33c);
106+
}
107+
108+
//---------------------------------------------------------------------------------
109+
// Purpose: Gets player base class by player entity index. Thanks to Nanoman2525 for this.
110+
//---------------------------------------------------------------------------------
111+
CBasePlayer* GFunc::PlayerIndexToPlayer(int playerIndex)
112+
{
113+
#ifdef _WIN32
114+
static auto _PlayerIndexToPlayer = reinterpret_cast<CBasePlayer* (__cdecl*)(int)>(Memory::Scanner::Scan<void*>(Memory::Modules::Get("server"), "55 8B EC 8B 4D 08 33 C0 85 C9 7E 30"));
115+
return _PlayerIndexToPlayer(playerIndex);
116+
#else // Linux support TODO
117+
return NULL;
118+
#endif
119+
}
120+
121+
//---------------------------------------------------------------------------------
122+
// Purpose: Gets player username by index.
123+
//---------------------------------------------------------------------------------
124+
const char* GFunc::GetPlayerName(int index)
125+
{
126+
if (index <= 0)
127+
{
128+
return "";
129+
}
130+
131+
player_info_t playerinfo;
132+
if (!engineServer->GetPlayerInfo(index, &playerinfo))
133+
{
134+
return "";
135+
}
136+
137+
return playerinfo.name;
138+
}
139+
140+
//---------------------------------------------------------------------------------
141+
// Purpose: Gets the account ID component of player SteamID by index.
142+
//---------------------------------------------------------------------------------
143+
int GFunc::GetSteamID(int index)
144+
{
145+
edict_t* pEdict = NULL;
146+
if (index >= 0 && index < gpGlobals->maxEntities)
147+
{
148+
pEdict = (edict_t*)(gpGlobals->pEdicts + index);
149+
}
150+
if (!pEdict)
151+
{
152+
return -1;
153+
}
154+
155+
player_info_t playerinfo;
156+
if (!engineServer->GetPlayerInfo(index, &playerinfo))
157+
{
158+
return -1;
159+
}
160+
161+
const CSteamID* pSteamID = engineServer->GetClientSteamID(pEdict);
162+
if (!pSteamID || pSteamID->GetAccountID() == 0)
163+
{
164+
return -1;
165+
}
166+
167+
return pSteamID->GetAccountID();
168+
}
169+
170+
void GFunc::RemoveEntity(CBaseEntity* pEntity)
171+
{
172+
reinterpret_cast<void (*)(void*)>(Memory::Scanner::Scan<void*>(Memory::Modules::Get("server"), "55 8B EC 57 8B 7D 08 85 FF 74 72"))(reinterpret_cast<IServerEntity*>(pEntity)->GetNetworkable());
173+
}
174+
175+
176+
//---------------------------------------------------------------------------------
177+
// Purpose: Self-explanatory.
178+
//---------------------------------------------------------------------------------
179+
int GFunc::GetConVarInt(const char* cvname)
180+
{
181+
ConVar* pVar = g_pCVar->FindVar(cvname);
182+
if (!pVar)
183+
{
184+
P2MMLog(1, false, "Could not find ConVar: \"%s\"! Returning -1!", cvname);
185+
return -1;
186+
}
187+
188+
return pVar->GetInt();
189+
}
190+
191+
//---------------------------------------------------------------------------------
192+
// Purpose: Self-explanatory.
193+
//---------------------------------------------------------------------------------
194+
const char* GFunc::GetConVarString(const char* cvname)
195+
{
196+
ConVar* pVar = g_pCVar->FindVar(cvname);
197+
if (!pVar)
198+
{
199+
P2MMLog(1, false, "Could not find ConVar: \"%s\"! Returning \"\"!", cvname);
200+
return "";
201+
}
202+
203+
return pVar->GetString();
204+
}

globals.hpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,25 @@
1212
#include "game/server/iplayerinfo.h"
1313
#include "engine/iserverplugin.h"
1414
#include "public/localize/ilocalize.h"
15+
#include "public/steam/steamclientpublic.h"
16+
17+
#include "scanner.hpp"
18+
#include "modules.hpp"
19+
20+
#ifdef _WIN32
21+
#pragma once
22+
#include <Windows.h>
23+
#endif
24+
25+
#include <sstream>
26+
27+
class CBasePlayer;
1528

1629
#define P2MM_PLUGIN_CONSOLE_COLOR Color(100, 192, 252, 255)
1730
#define P2MM_VSCRIPT_CONSOLE_COLOR Color(110, 247, 76, 255)
1831

32+
#define CURRENTMAPNAME STRING(gpGlobals->mapname)
33+
1934
//---------------------------------------------------------------------------------
2035
// Any ConVars or CON_COMMANDS that need to be globally available
2136
//---------------------------------------------------------------------------------
@@ -32,11 +47,20 @@ extern IScriptVM* g_pScriptVM;
3247
extern IServerTools* g_pServerTools;
3348
extern IGameEventManager2* gameeventmanager_;
3449
extern IServerPluginHelpers* pluginHelpers;
35-
extern ILocalize* localize;
3650

3751
void P2MMLog(int level, bool dev, const char* pMsgFormat, ...);
52+
void ReplacePattern(std::string target_module, std::string patternBytes, std::string replace_with);
3853

39-
extern int GetPlayerIndex(int userid);
54+
namespace GFunc {
55+
int UserIDToPlayerIndex(int userid);
56+
HSCRIPT GetScriptScope(CBaseEntity* entity);
57+
CBasePlayer* PlayerIndexToPlayer(int playerIndex);
58+
const char* GetPlayerName(int index);
59+
int GetSteamID(int index);
60+
void RemoveEntity(CBaseEntity* pEntity);
61+
int GetConVarInt(const char* cvname);
62+
const char* GetConVarString(const char* cvname);
63+
}
4064

4165
// If String Equals String helper function
4266
inline bool FStrEq(const char* sz1, const char* sz2)
@@ -50,7 +74,7 @@ inline bool FSubStr(const char* sz1, const char* search)
5074
return (Q_strstr(sz1, search));
5175
}
5276

53-
// Helper functions taken from utils.h which entity to entity index and entity index to entity conversion
77+
// Helper functions taken from utils.h which involves entity to entity index and entity index to entity conversion
5478
// Entity to entity index
5579
inline int ENTINDEX(edict_t* pEdict)
5680
{

0 commit comments

Comments
 (0)