Skip to content

Commit

Permalink
Added interfaces to UTIL_ClientPrint and UTIL_HudMessage. Updated Sen…
Browse files Browse the repository at this point in the history
…dToChat to work with UTIL_ClientPrint.
  • Loading branch information
OrsellGaming committed Nov 10, 2024
1 parent dce9c57 commit f8a16d8
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 25 deletions.
23 changes: 21 additions & 2 deletions globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,34 @@ CBasePlayer* UTIL_PlayerByIndex(int playerIndex)
#endif
}

//---------------------------------------------------------------------------------
// Purpose: Show on screen message to players. msg_dest are defined macros in globals.hpp.
//---------------------------------------------------------------------------------
void UTIL_ClientPrint(CBasePlayer* player, int msg_dest, const char* msg_name, const char* param1, const char* param2, const char* param3, const char* param4)
{
static auto _ClientPrint = reinterpret_cast<void (__cdecl*)(CBasePlayer*, int, const char*, const char*, const char*, const char*, const char*)>(Memory::Scanner::Scan<void*>(SERVERDLL, "55 8B EC 83 EC 20 56 8B 75 08 85 F6 74 4C"));
_ClientPrint(player, msg_dest, msg_name, param1, param2, param3, param4);
}

//---------------------------------------------------------------------------------
// Purpose: Show on text on screen just like game_text does.
//---------------------------------------------------------------------------------
void UTIL_HudMessage(CBasePlayer* pPlayer, const hudtextparms_s &textparms, const char* pMessage)
{
static auto _HudMessage = reinterpret_cast<void(__cdecl*)(CBasePlayer*, const hudtextparms_s&, const char*)>(Memory::Scanner::Scan(SERVERDLL, "55 8B EC 83 EC 20 8D 4D ?? E8 ?? ?? ?? ?? 8B 45 ?? 8D 4D ?? 85 C0 74 ?? 50 E8 ?? ?? ?? ?? EB ?? E8 ?? ?? ?? ?? 56"));
_HudMessage(pPlayer, textparms, pMessage);
}



/// CBaseEntity Class Functions \\\
//---------------------------------------------------------------------------------
// Purpose: Self-explanatory. Thanks to Nanoman2525 for this.
//---------------------------------------------------------------------------------
void CBaseEntity__RemoveEntity(CBaseEntity* pEntity)
{
//reinterpret_cast<IServerEntity*>(pEntity) trust me bro aka, we know its CBaseEntity*, but we want the IServerEntity* so cast to that to get its methods
reinterpret_cast<void (*)(void*)>(Memory::Scanner::Scan<void*>(SERVERDLL, "55 8B EC 57 8B 7D 08 85 FF 74 72"))(reinterpret_cast<IServerEntity*>(pEntity)->GetNetworkable());
reinterpret_cast<void (__cdecl*)(void*)>(Memory::Scanner::Scan<void*>(SERVERDLL, "55 8B EC 57 8B 7D 08 85 FF 74 72"))(reinterpret_cast<IServerEntity*>(pEntity)->GetNetworkable());
}

//---------------------------------------------------------------------------------
Expand Down
37 changes: 32 additions & 5 deletions globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,36 @@ class CPortal_Player;
#define COMMAND_COMPLETION_MAXITEMS 64
#define COMMAND_COMPLETION_ITEM_LENGTH 64

// Team number macros.
#define TEAM_SINGLEPLAYER 0
#define TEAM_SPECTATOR 1
#define TEAM_RED 2
#define TEAM_BLUE 3
// Player team enum.
enum
{
TEAM_SINGLEPLAYER = 0,
TEAM_SPECTATOR,
TEAM_RED,
TEAM_BLUE
};

// ClientPrint msg_dest macros.
#define HUD_PRINTNOTIFY 1 // Works same as HUD_PRINTCONSOLE
#define HUD_PRINTCONSOLE 2
#define HUD_PRINTTALK 3
#define HUD_PRINTCENTER 4

// UTIL_HudMessage message parameters struct. Taken from utils.h.
typedef struct hudtextparms_s
{
float x;
float y;
int effect;
byte r1, g1, b1, a1;
byte r2, g2, b2, a2;
float fadeinTime;
float fadeoutTime;
float holdTime;
float fxTime;
int channel;
} hudtextparms_t;


//---------------------------------------------------------------------------------
// Any ConVars or CON_COMMANDS that need to be globally available.
Expand Down Expand Up @@ -79,6 +104,8 @@ namespace GFunc
}

CBasePlayer* UTIL_PlayerByIndex(int playerIndex);
void UTIL_ClientPrint(CBasePlayer* player, int msg_dest, const char* msg_name, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL, const char* param4 = NULL);
void UTIL_HudMessage(CBasePlayer* pPlayer, const hudtextparms_t &textparms, const char* pMessage);

void CBaseEntity__RemoveEntity(CBaseEntity* pEntity);
int CBaseEntity__GetTeamNumber(CBasePlayer* pPlayer);
Expand Down
35 changes: 35 additions & 0 deletions p2mm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,41 @@ CON_COMMAND(p2mm_respawnall, "Respawns all players.")
}
}

CON_COMMAND(p2mm_helloworld, "Hello World!")
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex(1);
UTIL_ClientPrint(pPlayer, HUD_PRINTCENTER, "HELLO WORLD! :D\n%s\n%s", "test1", "test2");
}

CON_COMMAND(p2mm_helloworld2, "Hello World 2: Electric Boogaloo!")
{
hudtextparms_s helloWorldParams;
color32 RGB1 = { 0, 255, 100, 255 };
color32 RGB2 = { 0, 50, 255, 255 };
helloWorldParams.x = -1.f;
helloWorldParams.y = -1.f;
helloWorldParams.effect = 2;
helloWorldParams.r1 = RGB1.r;
helloWorldParams.g1 = RGB1.g;
helloWorldParams.b1 = RGB1.b;
helloWorldParams.a1 = RGB1.a;
helloWorldParams.r2 = RGB2.r;
helloWorldParams.g2 = RGB2.g;
helloWorldParams.b2 = RGB2.b;
helloWorldParams.a2 = RGB2.a;
helloWorldParams.fadeinTime = 0.5f;
helloWorldParams.fadeoutTime = 1.f;
helloWorldParams.holdTime = 1.f;
helloWorldParams.fxTime = 0.2f;
helloWorldParams.channel = V_atoi(args.Arg(2));

const char* msg = "Hello World 2: Electric Boogaloo!";
if (!FStrEq(args.Arg(1), ""))
msg = args.Arg(1);

UTIL_HudMessage(UTIL_PlayerByIndex(1), helloWorldParams, msg);
}

//---------------------------------------------------------------------------------
// Purpose: constructor
//---------------------------------------------------------------------------------
Expand Down
123 changes: 105 additions & 18 deletions vscript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,39 +110,36 @@ static void InitializeEntity(HSCRIPT ent)
}

//---------------------------------------------------------------------------------
// Purpose: Sends a raw message to the chat HUD.
// Purpose: Sends a raw message to the chat HUD. Specifying no playerIndex or 0 sends to all players.
// Supports printing localization strings but those that require formatting can't be formatted.
//---------------------------------------------------------------------------------
static void SendToChat(const char* msg, int playerIndex)
static void SendToChat(int playerIndex, const char* msg)
{
if (!msg)
{
return;
}
bf_write* netmsg;
CFilter recipient_filter;

// Send to all players
if (playerIndex == 0)
if (!playerIndex)
{
for (int i = 1; i < g_pGlobals->maxClients; i++)
for (int i = 1; i < MAX_PLAYERS; i++)
{
player_info_t playerinfo;
if (engineServer->GetPlayerInfo(i, &playerinfo))
{
recipient_filter.AddPlayer(i);
UTIL_ClientPrint(UTIL_PlayerByIndex(i), HUD_PRINTTALK, msg);
}
}
return;
}
else

CBasePlayer* pPlayer = UTIL_PlayerByIndex(playerIndex);
if (!pPlayer)
{
recipient_filter.AddPlayer(playerIndex);
P2MMLog(1, false, "Invalid player index specified for SendToChat!");
return;
}

netmsg = engineServer->UserMessageBegin(&recipient_filter, 3, "SayText");
netmsg->WriteByte(0);
netmsg->WriteString(msg);
netmsg->WriteByte(1);
engineServer->MessageEnd();
UTIL_ClientPrint(pPlayer, HUD_PRINTTALK, msg);
}

//---------------------------------------------------------------------------------
Expand Down Expand Up @@ -202,6 +199,88 @@ static void CallFirstRunPrompt()
g_P2MMServerPlugin.m_bSeenFirstRunPrompt = true;
}

//---------------------------------------------------------------------------------
// Purpose: Print a message to a player's console, unlike printl() which is just the host.
// Supports printing localization strings but those that require formatting can't be formatted.
//---------------------------------------------------------------------------------
void ConsolePrint(int playerIndex, const char* msg)
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex(playerIndex);
if (!pPlayer)
{
P2MMLog(1, false, "Invalid playerIndex passed into ConsolePrint! playerIndex: \"%i\"", playerIndex);
return;
}

std::string fixedMsg = std::string(msg) + "\n";
UTIL_ClientPrint(pPlayer, HUD_PRINTCONSOLE, fixedMsg.c_str());
}

//---------------------------------------------------------------------------------
// Purpose: Print a message to the top center position of a player's screen.
// Supports printing localization strings but those that require formatting can't be formatted.
//---------------------------------------------------------------------------------
void ClientPrint(int playerIndex, const char* msg)
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex(playerIndex);
if (!pPlayer)
{
P2MMLog(1, false, "Invalid playerIndex passed into ClientPrint! playerIndex: \"%i\"", playerIndex);
return;
}

UTIL_ClientPrint(pPlayer, HUD_PRINTCENTER, msg);
}

//---------------------------------------------------------------------------------
// Purpose: Print a message to the screen based on what the game_text entity does.
// See the Valve Developer Commentary page for the game_text entity to read
// what each field does. Vectors are in place for sets of RGB values.
// Supports printing localization strings but those that require formatting can't be formatted.
//---------------------------------------------------------------------------------
void HudPrint(int playerIndex, const char* msg,
float x, float y,
int effect,
Vector RGB1, float alpha1, Vector RGB2, float alpha2,
float fadeinTime, float fadeoutTime, float holdTime, float fxTime,
int channel)
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex(playerIndex);
if (!pPlayer)
{
P2MMLog(1, false, "Invalid playerIndex passed into HudPrint! playerIndex: \"%i\"", playerIndex);
return;
}

hudtextparms_t hudTextParams;
hudTextParams.x = x;
hudTextParams.y = y;
hudTextParams.effect = effect;
hudTextParams.r1 = RGB1.x;
hudTextParams.g1 = RGB1.y;
hudTextParams.b1 = RGB1.z;
hudTextParams.a1 = alpha1;
hudTextParams.r2 = RGB2.x;
hudTextParams.g2 = RGB2.y;
hudTextParams.b2 = RGB2.z;
hudTextParams.a2 = alpha2;
hudTextParams.fadeinTime = fadeinTime;
hudTextParams.fadeoutTime = fadeoutTime;
hudTextParams.holdTime = holdTime;
hudTextParams.fxTime = fxTime;
hudTextParams.channel = channel;

UTIL_HudMessage(pPlayer, hudTextParams, msg);
}

//---------------------------------------------------------------------------------
// Purpose: Self-explanatory.
//---------------------------------------------------------------------------------
int GetMaxPlayers()
{
return MAX_PLAYERS;
}

void RegisterFuncsAndRun()
{
g_pScriptVM = **Memory::Scanner::Scan<IScriptVM***>(SERVERDLL, "8B 1D ?? ?? ?? ?? 57 85 DB", 2);
Expand All @@ -221,17 +300,25 @@ void RegisterFuncsAndRun()
ScriptRegisterFunction (g_pScriptVM, SetMaxPortalSeparationConvar, "Sets 'portal_max_separation_force' to the supplied integer value.");
ScriptRegisterFunction (g_pScriptVM, IsDedicatedServer, "Returns true if this is a dedicated server.");
ScriptRegisterFunction (g_pScriptVM, InitializeEntity, "Initializes an entity. Note: Not all entities will work even after being initialized with this function.");
ScriptRegisterFunction (g_pScriptVM, SendToChat, "Sends a raw message to the chat HUD.");
ScriptRegisterFunction (g_pScriptVM, SendToChat, "Sends a raw message to the chat HUD. Specifying no playerIndex or 0 sends to all players. Supports printing localization strings but those that require formatting can't be formatted.");
ScriptRegisterFunctionNamed(g_pScriptVM, GFunc::GetGameMainDir, "GetGameMainDir", "Returns the game directory. Ex. portal2");
ScriptRegisterFunctionNamed(g_pScriptVM, GFunc::GetGameBaseDir, "GetGameBaseDir", "Get the main game directory being used. Ex. Portal 2");
ScriptRegisterFunction (g_pScriptVM, GetLastMap, "Returns the last map recorded by the launcher's Last Map system.");
ScriptRegisterFunction (g_pScriptVM, FirstRunState, "Get or set the state of whether the first map was run or not. Set false/true = 0/1 | -1 to get state.");
ScriptRegisterFunction (g_pScriptVM, CallFirstRunPrompt, "Shows the first run prompt if enabled in config.nut.");
ScriptRegisterFunctionNamed(g_pScriptVM, GFunc::GetConVarInt, "GetConVarInt", "Get the integer value of a ConVar.");
ScriptRegisterFunctionNamed(g_pScriptVM, GFunc::GetConVarString, "GetConVarString", "Get the string value of a ConVar.");
ScriptRegisterFunctionNamed(g_pScriptVM, INDEXHANDLE, "PlayerIndexToPlayerHandle", "Takes the player's entity index and returns the player's script handle.");
ScriptRegisterFunctionNamed(g_pScriptVM, INDEXHANDLE, "UTIL_PlayerByIndex", "Takes the player's entity index and returns the player's script handle.");
ScriptRegisterFunctionNamed(g_pScriptVM, CPortal_Player__RespawnPlayer, "RespawnPlayer", "Respawn the a player by their entity index.");
ScriptRegisterFunctionNamed(g_pScriptVM, CPortal_Player__SetFlashlightState, "SetFlashlightState", "Set the flashlight for a player on or off.");
ScriptRegisterFunction (g_pScriptVM, ConsolePrint, "Print a message to the top center position of a player's screen. Supports printing localization strings but those that require formatting can't be formatted.");
ScriptRegisterFunction (g_pScriptVM, ClientPrint, "Print a message to the top center position of a player's screen. Supports printing localization strings but those that require formatting can't be formatted.");
ScriptRegisterFunction (g_pScriptVM, HudPrint, "Print a message to the screen based on what the game_text entity does.\
See the Valve Developer Commentary page for the game_text entity to read\
what each field does. Vectors are in place for sets of RGB values.\
Supports printing localization strings but those that require formatting can't be formatted."
);
ScriptRegisterFunction (g_pScriptVM, GetMaxPlayers, "Self-explanatory.");

// Load up the main P2:MM VScript and set
g_pScriptVM->Run("IncludeScript(\"multiplayermod/p2mm\");");
Expand Down

0 comments on commit f8a16d8

Please sign in to comment.