mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-08 04:33:20 +00:00
Compare commits
4 commits
c935aec511
...
863f5d1ce6
Author | SHA1 | Date | |
---|---|---|---|
863f5d1ce6 | |||
247dca0087 | |||
e54f7aa61a | |||
4285178c24 |
11 changed files with 233 additions and 95 deletions
Binary file not shown.
Binary file not shown.
|
@ -585,14 +585,12 @@ bool CheckBlacklist(int entity) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(StrContains(buffer, "prop_") > -1) {
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
|
GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
|
||||||
for(int i = 0; i < MAX_FORBIDDEN_MODELS; i++) {
|
for(int i = 0; i < MAX_FORBIDDEN_MODELS; i++) {
|
||||||
if(StrEqual(FORBIDDEN_MODELS[i], buffer)) {
|
if(StrEqual(FORBIDDEN_MODELS[i], buffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iName", buffer, sizeof(buffer));
|
GetEntPropString(entity, Prop_Data, "m_iName", buffer, sizeof(buffer));
|
||||||
if(StrContains(buffer, "randomizer") == 0) {
|
if(StrContains(buffer, "randomizer") == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -31,6 +31,7 @@ public Plugin myinfo =
|
||||||
int LIVESTATUS_VERSION = 0;
|
int LIVESTATUS_VERSION = 0;
|
||||||
Regex CommandArgRegex;
|
Regex CommandArgRegex;
|
||||||
|
|
||||||
|
ConVar cvar_flags;
|
||||||
ConVar cvar_debug;
|
ConVar cvar_debug;
|
||||||
ConVar cvar_gamemode; char gamemode[32];
|
ConVar cvar_gamemode; char gamemode[32];
|
||||||
ConVar cvar_difficulty; int gameDifficulty;
|
ConVar cvar_difficulty; int gameDifficulty;
|
||||||
|
@ -58,6 +59,7 @@ int pendingTries = 3;
|
||||||
bool lateLoaded;
|
bool lateLoaded;
|
||||||
|
|
||||||
Socket g_socket;
|
Socket g_socket;
|
||||||
|
int g_lastPayloadSent;
|
||||||
enum AuthState {
|
enum AuthState {
|
||||||
Auth_Fail = -1,
|
Auth_Fail = -1,
|
||||||
Auth_Pending,
|
Auth_Pending,
|
||||||
|
@ -70,6 +72,10 @@ enum GameState {
|
||||||
State_Hibernating = 2,
|
State_Hibernating = 2,
|
||||||
State_NewGame = 3
|
State_NewGame = 3
|
||||||
}
|
}
|
||||||
|
enum PanelSettings {
|
||||||
|
Setting_None = 0,
|
||||||
|
Setting_DisableWithNoViewers = 1
|
||||||
|
}
|
||||||
GameState g_gameState;
|
GameState g_gameState;
|
||||||
#define BUFFER_SIZE 2048
|
#define BUFFER_SIZE 2048
|
||||||
Buffer sendBuffer;
|
Buffer sendBuffer;
|
||||||
|
@ -87,6 +93,7 @@ public void OnPluginStart() {
|
||||||
g_socket.SetOption(SocketSendBuffer, BUFFER_SIZE);
|
g_socket.SetOption(SocketSendBuffer, BUFFER_SIZE);
|
||||||
|
|
||||||
uptime = GetTime();
|
uptime = GetTime();
|
||||||
|
cvar_flags = CreateConVar("sm_adminpanel_flags", "1", "Bit Flags.\n1=Disable when no viewers", FCVAR_NONE, true, 0.0);
|
||||||
cvar_debug = CreateConVar("sm_adminpanel_debug", "0", "Turn on debug mode", FCVAR_DONTRECORD, true, 0.0, true, 1.0);
|
cvar_debug = CreateConVar("sm_adminpanel_debug", "0", "Turn on debug mode", FCVAR_DONTRECORD, true, 0.0, true, 1.0);
|
||||||
|
|
||||||
cvar_authToken = CreateConVar("sm_adminpanel_authtoken", "", "The token for authentication", FCVAR_PROTECTED);
|
cvar_authToken = CreateConVar("sm_adminpanel_authtoken", "", "The token for authentication", FCVAR_PROTECTED);
|
||||||
|
@ -237,7 +244,7 @@ void OnSocketReceive(Socket socket, const char[] receiveData, int dataSize, int
|
||||||
int client = GetClientOfUserId(userid);
|
int client = GetClientOfUserId(userid);
|
||||||
if(client > 0 && StartPayload(true)) {
|
if(client > 0 && StartPayload(true)) {
|
||||||
PrintToServer("[AdminPanel] Sync requested for #%d, performing", userid);
|
PrintToServer("[AdminPanel] Sync requested for #%d, performing", userid);
|
||||||
AddPlayerRecord(client, Client_Normal);
|
AddPlayerRecord(client, Client_Connected);
|
||||||
SendPayload();
|
SendPayload();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -519,6 +526,8 @@ Action Command_PanelDebug(int client, int args) {
|
||||||
ConnectSocket();
|
ConnectSocket();
|
||||||
} else if(StrEqual(arg, "info")) {
|
} else if(StrEqual(arg, "info")) {
|
||||||
ReplyToCommand(client, "Connected: %b\tAuthenticated: %d\tState: %d", g_socket.Connected, authState, g_gameState);
|
ReplyToCommand(client, "Connected: %b\tAuthenticated: %d\tState: %d", g_socket.Connected, authState, g_gameState);
|
||||||
|
int timeFromLastPayload = GetTime() - g_lastPayloadSent;
|
||||||
|
ReplyToCommand(client, "Last Payload: %ds", timeFromLastPayload);
|
||||||
ReplyToCommand(client, "#Viewers: %d\t#Players: %d", numberOfViewers, numberOfPlayers);
|
ReplyToCommand(client, "#Viewers: %d\t#Players: %d", numberOfViewers, numberOfPlayers);
|
||||||
ReplyToCommand(client, "Target Host: %s:%d", serverIp, serverPort);
|
ReplyToCommand(client, "Target Host: %s:%d", serverIp, serverPort);
|
||||||
ReplyToCommand(client, "Buffer Size: %d", BUFFER_SIZE);
|
ReplyToCommand(client, "Buffer Size: %d", BUFFER_SIZE);
|
||||||
|
@ -617,7 +626,7 @@ void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) {
|
||||||
public void Event_PlayerToBot(Handle event, char[] name, bool dontBroadcast) {
|
public void Event_PlayerToBot(Handle event, char[] name, bool dontBroadcast) {
|
||||||
int player = GetClientOfUserId(GetEventInt(event, "player"));
|
int player = GetClientOfUserId(GetEventInt(event, "player"));
|
||||||
int bot = GetClientOfUserId(GetEventInt(event, "bot"));
|
int bot = GetClientOfUserId(GetEventInt(event, "bot"));
|
||||||
if(player > 0 && !IsFakeClient(player) && StartPayload(true)) {
|
if(player > 0 && !IsFakeClient(player) && StartPayload()) {
|
||||||
AddSurvivorRecord(player);
|
AddSurvivorRecord(player);
|
||||||
SendPayload();
|
SendPayload();
|
||||||
}
|
}
|
||||||
|
@ -626,7 +635,7 @@ public void Event_PlayerToBot(Handle event, char[] name, bool dontBroadcast) {
|
||||||
public void Event_BotToPlayer(Handle event, char[] name, bool dontBroadcast) {
|
public void Event_BotToPlayer(Handle event, char[] name, bool dontBroadcast) {
|
||||||
int player = GetClientOfUserId(GetEventInt(event, "player"));
|
int player = GetClientOfUserId(GetEventInt(event, "player"));
|
||||||
int bot = GetClientOfUserId(GetEventInt(event, "bot"));
|
int bot = GetClientOfUserId(GetEventInt(event, "bot"));
|
||||||
if(player > 0 && !IsFakeClient(player) && StartPayload(true)) {
|
if(player > 0 && !IsFakeClient(player) && StartPayload()) {
|
||||||
// Bot is going away, remove it: (prob unnecessary OnClientDisconnect happens)
|
// Bot is going away, remove it: (prob unnecessary OnClientDisconnect happens)
|
||||||
AddPlayerRecord(bot, Client_Disconnected);
|
AddPlayerRecord(bot, Client_Disconnected);
|
||||||
AddPlayerRecord(player, Client_Normal);
|
AddPlayerRecord(player, Client_Normal);
|
||||||
|
@ -658,7 +667,7 @@ void Event_HealInterrupted(Event event, const char[] name, bool dontBroadcast) {
|
||||||
void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||||
RecalculatePlayerCount();
|
RecalculatePlayerCount();
|
||||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
int client = GetClientOfUserId(event.GetInt("userid"));
|
||||||
if(client > 0 && StartPayload()) {
|
if(client > 0 && StartPayload(true)) {
|
||||||
AddPlayerRecord(client, Client_Normal);
|
AddPlayerRecord(client, Client_Normal);
|
||||||
SendPayload();
|
SendPayload();
|
||||||
}
|
}
|
||||||
|
@ -678,7 +687,7 @@ void SendPlayers() {
|
||||||
for(int i = 1; i <= MaxClients; i++) {
|
for(int i = 1; i <= MaxClients; i++) {
|
||||||
if(IsClientInGame(i)) {
|
if(IsClientInGame(i)) {
|
||||||
if(StartPayload(true)) {
|
if(StartPayload(true)) {
|
||||||
AddPlayerRecord(i, Client_Normal);
|
AddPlayerRecord(i, Client_Connected);
|
||||||
SendPayload();
|
SendPayload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -805,15 +814,14 @@ Action Timer_UpdateItems(Handle h, int client) {
|
||||||
|
|
||||||
void SendNewClient(int client) {
|
void SendNewClient(int client) {
|
||||||
if(!IsClientInGame(client)) return;
|
if(!IsClientInGame(client)) return;
|
||||||
if(StartPayload()) {
|
if(StartPayload(true)) {
|
||||||
PrintToServer("SendNewClient(%N)", client);
|
|
||||||
AddPlayerRecord(client, Client_Connected);
|
AddPlayerRecord(client, Client_Connected);
|
||||||
SendPayload();
|
SendPayload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnClientDisconnect(int client) {
|
public void OnClientDisconnect(int client) {
|
||||||
if(StartPayload()) {
|
if(StartPayload(true)) {
|
||||||
// hopefully userid is valid here?
|
// hopefully userid is valid here?
|
||||||
AddPlayerRecord(client, Client_Disconnected);
|
AddPlayerRecord(client, Client_Disconnected);
|
||||||
SendPayload();
|
SendPayload();
|
||||||
|
@ -1024,7 +1032,7 @@ bool CanSendPayload(bool ignorePause = false) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!ignorePause && (numberOfViewers == 0 || numberOfPlayers == 0)) return false;
|
if(cvar_flags.IntValue & view_as<int>(Setting_DisableWithNoViewers) && !ignorePause && (numberOfViewers == 0 || numberOfPlayers == 0)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1209,6 +1217,7 @@ void SendPayload() {
|
||||||
if(cvar_debug.BoolValue) {
|
if(cvar_debug.BoolValue) {
|
||||||
PrintToServer("[AdminPanel] Sending %d bytes of data (records = %s)", len, pendingRecords);
|
PrintToServer("[AdminPanel] Sending %d bytes of data (records = %s)", len, pendingRecords);
|
||||||
}
|
}
|
||||||
|
g_lastPayloadSent = GetTime();
|
||||||
g_socket.Send(sendBuffer.buffer, len);
|
g_socket.Send(sendBuffer.buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#define DIRECTOR_WITCH_MIN_TIME 120 // The minimum amount of time to pass since last witch spawn for the next extra witch to spawn
|
#define DIRECTOR_WITCH_MIN_TIME 120 // The minimum amount of time to pass since last witch spawn for the next extra witch to spawn
|
||||||
#define DIRECTOR_WITCH_CHECK_TIME 30.0 // How often to check if a witch should be spawned
|
#define DIRECTOR_WITCH_CHECK_TIME 30.0 // How often to check if a witch should be spawned
|
||||||
#define DIRECTOR_WITCH_MAX_WITCHES 5 // The maximum amount of extra witches to spawn
|
#define DIRECTOR_WITCH_MAX_WITCHES 5 // The maximum amount of extra witches to spawn
|
||||||
#define DIRECTOR_WITCH_ROLLS 3 // The number of dice rolls, increase if you want to increase freq
|
#define DIRECTOR_WITCH_ROLLS 4 // The number of dice rolls, increase if you want to increase freq
|
||||||
#define DIRECTOR_MIN_SPAWN_TIME 13.0 // Possibly randomized, per-special, in seconds
|
#define DIRECTOR_MIN_SPAWN_TIME 13.0 // Possibly randomized, per-special, in seconds
|
||||||
ConVar directorSpawnChance; // Base chance of a special spawning, changed by player stress
|
ConVar directorSpawnChance; // Base chance of a special spawning, changed by player stress
|
||||||
#define DIRECTOR_CHANGE_LIMIT_CHANCE 0.05 // The chance that the maximum amount per-special is changed
|
#define DIRECTOR_CHANGE_LIMIT_CHANCE 0.05 // The chance that the maximum amount per-special is changed
|
||||||
|
|
94
scripting/include/l4d_info_editor.inc
Normal file
94
scripting/include/l4d_info_editor.inc
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Info Editor
|
||||||
|
* Copyright (C) 2022 Silvers
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _info_editor_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _info_editor_included
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SharedPlugin __pl_info_editor_ =
|
||||||
|
{
|
||||||
|
name = "info_editor",
|
||||||
|
file = "l4d_info_editor.smx",
|
||||||
|
#if defined REQUIRE_PLUGIN
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_PLUGIN
|
||||||
|
public void __pl_info_editor__SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("InfoEditor_GetString");
|
||||||
|
MarkNativeAsOptional("InfoEditor_SetString");
|
||||||
|
MarkNativeAsOptional("InfoEditor_ReloadData");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value of a specified key from the games mission info keyvalue system. "N/A" is returned when not found.
|
||||||
|
*
|
||||||
|
* @param pThis Enter the pThis value from OnGetMissionInfo/OnGetWeaponsInfo. Can specify 0 when reading Mission data.
|
||||||
|
* @param keyname Key name to check.
|
||||||
|
* @param dest Destination string buffer to copy to.
|
||||||
|
* @param destLen Destination buffer length (includes null terminator).
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void InfoEditor_GetString(int pThis, const char[] keyname, char[] dest, int destLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a specified key from the games mission info keyvalue system.
|
||||||
|
*
|
||||||
|
* @param pThis Enter the pThis value from OnGetMissionInfo/OnGetWeaponsInfo. Can specify 0 when writing Mission data.
|
||||||
|
* @param keyname Key name to set.
|
||||||
|
* @param value Value to set.
|
||||||
|
* @param create Optionally create the keyvalue if it doesn't exist.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void InfoEditor_SetString(int pThis, const char[] keyname, const char[] value, bool create = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads the mission and weapons data configs and forces the game to reload them.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native void InfoEditor_ReloadData();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fired multiple times when the mission info data is parsed.
|
||||||
|
*
|
||||||
|
* @param pThis This pointer used for InfoEditor_GetString/InfoEditor_SetString.
|
||||||
|
*/
|
||||||
|
forward void OnGetMissionInfo(int pThis);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired multiple times when the weapon info data is parsed for a specific weapon classname.
|
||||||
|
*
|
||||||
|
* @param pThis This pointer used for InfoEditor_GetString/InfoEditor_SetString.
|
||||||
|
* @param classname Classname of the weapon being parsed.
|
||||||
|
*/
|
||||||
|
forward void OnGetWeaponsInfo(int pThis, const char[] classname);
|
|
@ -2,6 +2,7 @@
|
||||||
#endinput
|
#endinput
|
||||||
#endif
|
#endif
|
||||||
#define _overlay_included
|
#define _overlay_included
|
||||||
|
#include <ripext>
|
||||||
|
|
||||||
public SharedPlugin __pl_overlay = {
|
public SharedPlugin __pl_overlay = {
|
||||||
name = "overlay",
|
name = "overlay",
|
||||||
|
@ -25,18 +26,38 @@ native bool IsOverlayConnected();
|
||||||
|
|
||||||
// myplugin:action_name
|
// myplugin:action_name
|
||||||
// Handles any action for actionNamespace and actionName
|
// Handles any action for actionNamespace and actionName
|
||||||
native void RegisterActionHandler(const char[] actionNamespace, const char[] actionName, ActionFallbackHandlerCallback cb);
|
native void RegisterActionHandler(const char[] actionNamespace, const char[] commandName, ActionFallbackHandlerCallback cb);
|
||||||
// Handles all actions for namespace that were not caught by RegisterActionHandler
|
// Handles all actions for namespace that were not caught by RegisterActionHandler
|
||||||
native void RegisterActionAnyHandler(const char[] actionNamespace, ActionHandlerCallback cb);
|
native void RegisterActionAnyHandler(const char[] actionNamespace, ActionHandlerCallback cb);
|
||||||
|
|
||||||
|
enum struct ClientAction {
|
||||||
|
char steamid[32];
|
||||||
|
char ns[64];
|
||||||
|
char instanceId[64];
|
||||||
|
char command[128];
|
||||||
|
char input[512];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility to get arguments from an action input.
|
||||||
methodmap UIActionEvent {
|
methodmap UIActionEvent {
|
||||||
public UIActionEvent(ArrayList list) {
|
public UIActionEvent(ArrayList list) {
|
||||||
return view_as<UIActionEvent>(list);
|
return view_as<UIActionEvent>(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1 indexed. 0 returns full action string
|
||||||
public void GetArg(int argNum, char[] output, int maxlen) {
|
public void GetArg(int argNum, char[] output, int maxlen) {
|
||||||
view_as<ArrayList>(this).GetString(argNum, output, maxlen);
|
view_as<ArrayList>(this).GetString(argNum, output, maxlen);
|
||||||
}
|
}
|
||||||
|
public int GetArgInt(int argNum) {
|
||||||
|
char buffer[32];
|
||||||
|
this.GetArg(argNum, buffer, sizeof(buffer));
|
||||||
|
return StringToInt(buffer);
|
||||||
|
}
|
||||||
|
public float GetArgFloat(int argNum) {
|
||||||
|
char buffer[32];
|
||||||
|
this.GetArg(argNum, buffer, sizeof(buffer));
|
||||||
|
return StringToFloat(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
public void _Delete() {
|
public void _Delete() {
|
||||||
delete view_as<ArrayList>(this);
|
delete view_as<ArrayList>(this);
|
||||||
|
@ -48,10 +69,11 @@ methodmap UIActionEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
methodmap UIElement < JSONObject {
|
methodmap UIElement < JSONObject {
|
||||||
public UIElement(const char[] elemNamespace, const char[] elemId) {
|
public UIElement(const char[] elemNamespace, const char[] templateId, const char[] instanceId) {
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.SetString("namespace", elemNamespace);
|
obj.SetString("namespace", elemNamespace);
|
||||||
obj.SetString("elem_id", elemId);
|
obj.SetString("instance_id", instanceId);
|
||||||
|
obj.SetString("template_id", templateId);
|
||||||
obj.SetBool("visibility", false);
|
obj.SetBool("visibility", false);
|
||||||
obj.Set("steamids", new JSONArray());
|
obj.Set("steamids", new JSONArray());
|
||||||
obj.Set("variables", new JSONObject());
|
obj.Set("variables", new JSONObject());
|
||||||
|
@ -68,23 +90,31 @@ methodmap UIElement < JSONObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariable(const char[] id, JSON json) {
|
public void GetTemplateId(char[] buffer, int maxlen) {
|
||||||
|
view_as<JSONObject>(this).GetString("template_id", buffer, maxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetInstanceId(char[] buffer, int maxlen) {
|
||||||
|
view_as<JSONObject>(this).GetString("instance_id", buffer, maxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetVar(const char[] id, JSON json) {
|
||||||
view_as<JSONObject>(this).Set(id, json);
|
view_as<JSONObject>(this).Set(id, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariableInt(const char[] id, int value) {
|
public void SetVarInt(const char[] id, int value) {
|
||||||
view_as<JSONObject>(this).SetInt(id, value);
|
view_as<JSONObject>(this).SetInt(id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariableFloat(const char[] id, float value) {
|
public void SetVarFloat(const char[] id, float value) {
|
||||||
view_as<JSONObject>(this).SetFloat(id, value);
|
view_as<JSONObject>(this).SetFloat(id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariableString(const char[] id, const char[] value) {
|
public void SetVarString(const char[] id, const char[] value) {
|
||||||
view_as<JSONObject>(this).SetString(id, value);
|
view_as<JSONObject>(this).SetString(id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariableBool(const char[] id, bool value) {
|
public void SetVarBool(const char[] id, bool value) {
|
||||||
view_as<JSONObject>(this).SetBool(id, value);
|
view_as<JSONObject>(this).SetBool(id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +406,7 @@ enum AudioState {
|
||||||
Audio_Play
|
Audio_Play
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List of clients to send an element to. If empty, it will default to all connected clients.
|
||||||
methodmap ClientList < JSONArray {
|
methodmap ClientList < JSONArray {
|
||||||
public ClientList() {
|
public ClientList() {
|
||||||
return view_as<ClientList>(new JSONArray());
|
return view_as<ClientList>(new JSONArray());
|
||||||
|
@ -449,6 +480,8 @@ methodmap AudioResource < JSONObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
native int FindClientBySteamId2(const char[] steamid);
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
#if !defined REQUIRE_PLUGIN
|
||||||
public void __pl_overlay_SetNTVOptional() {
|
public void __pl_overlay_SetNTVOptional() {
|
||||||
MarkNativeAsOptional("IsOverlayConnected");
|
MarkNativeAsOptional("IsOverlayConnected");
|
||||||
|
@ -462,5 +495,7 @@ public void __pl_overlay_SetNTVOptional() {
|
||||||
MarkNativeAsOptional("AudioResource.Play");
|
MarkNativeAsOptional("AudioResource.Play");
|
||||||
MarkNativeAsOptional("AudioResource.Stop");
|
MarkNativeAsOptional("AudioResource.Stop");
|
||||||
MarkNativeAsOptional("AudioResource.Pause");
|
MarkNativeAsOptional("AudioResource.Pause");
|
||||||
|
|
||||||
|
MarkNativeAsOptional("FindClientBySteamId2");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -37,7 +37,14 @@ void OpenVariantsMenu(int client) {
|
||||||
char id[8], display[32];
|
char id[8], display[32];
|
||||||
menu.AddItem("new", "New Variant");
|
menu.AddItem("new", "New Variant");
|
||||||
menu.AddItem("-1", "Global Scene Variant");
|
menu.AddItem("-1", "Global Scene Variant");
|
||||||
|
if(!g_builder.selectedSceneData) {
|
||||||
|
ReplyToCommand(client, "Error: Missing scene data for %s", g_builder.selectedSceneId);
|
||||||
|
PrintToServer("[Randomizer] Warn: Scene %s has no data", g_builder.selectedSceneId);
|
||||||
|
} else if(!g_builder.selectedSceneData.HasKey("variants")) {
|
||||||
|
ReplyToCommand(client, "Error: Missing variants for %d", g_builder.selectedSceneId);
|
||||||
|
PrintToServer("[Randomizer] Warn: Selected scene %s has no variants", g_builder.selectedSceneId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
JSONArray variants = view_as<JSONArray>(g_builder.selectedSceneData.Get("variants"));
|
JSONArray variants = view_as<JSONArray>(g_builder.selectedSceneData.Get("variants"));
|
||||||
JSONObject varObj;
|
JSONObject varObj;
|
||||||
JSONArray entities;
|
JSONArray entities;
|
||||||
|
@ -102,8 +109,11 @@ int BuilderHandler_ScenesMenu(Menu menu, MenuAction action, int client, int para
|
||||||
FakeClientCommand(client, "sm_rbuild scenes new");
|
FakeClientCommand(client, "sm_rbuild scenes new");
|
||||||
OpenScenesMenu(client);
|
OpenScenesMenu(client);
|
||||||
} else {
|
} else {
|
||||||
FakeClientCommand(client, "sm_rbuild scenes select %s", info);
|
if(g_builder.SelectScene(info)) {
|
||||||
OpenVariantsMenu(client);
|
OpenVariantsMenu(client);
|
||||||
|
} else {
|
||||||
|
PrintToChat(client, "Error: Scene not found");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(action == MenuAction_Cancel) {
|
} else if(action == MenuAction_Cancel) {
|
||||||
if(param2 == MenuCancel_ExitBack) {
|
if(param2 == MenuCancel_ExitBack) {
|
||||||
|
|
|
@ -10,7 +10,6 @@ static float EMPTY_ANG[3] = { 0.0, 0.0, 0.0 };
|
||||||
|
|
||||||
#include <sourcemod>
|
#include <sourcemod>
|
||||||
#include <sdktools>
|
#include <sdktools>
|
||||||
#include <left4dhooks>
|
|
||||||
#include <clientprefs>
|
#include <clientprefs>
|
||||||
#include <jutils>
|
#include <jutils>
|
||||||
#include <gamemodes/ents>
|
#include <gamemodes/ents>
|
||||||
|
@ -399,35 +398,6 @@ public void Event_HatsEnableChanged(ConVar convar, const char[] sOldValue, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList GetSpawnLocations() {
|
|
||||||
ArrayList list = new ArrayList();
|
|
||||||
ArrayList newList = new ArrayList();
|
|
||||||
L4D_GetAllNavAreas(list);
|
|
||||||
for(int i = 0; i < list.Length; i++) {
|
|
||||||
Address nav = list.Get(i);
|
|
||||||
if(L4D_GetNavArea_SpawnAttributes(nav) & NAV_SPAWN_THREAT) {
|
|
||||||
newList.Push(nav);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete list;
|
|
||||||
PrintToServer("[Hats] Got %d valid locations", newList.Length);
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ChooseRandomPosition(float pos[3], int ignoreClient = 0) {
|
|
||||||
if(NavAreas.Length > 0 && GetURandomFloat() > 0.5) {
|
|
||||||
int nav = NavAreas.Get(GetURandomInt() % (NavAreas.Length - 1));
|
|
||||||
L4D_FindRandomSpot(nav, pos);
|
|
||||||
} else {
|
|
||||||
int survivor = GetRandomClient(5, 1);
|
|
||||||
if(ignoreClient > 0 && survivor == ignoreClient) survivor = GetRandomClient(5, 1);
|
|
||||||
if(survivor > 0) {
|
|
||||||
GetClientAbsOrigin(survivor, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) {
|
public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) {
|
||||||
float tick = GetGameTime();
|
float tick = GetGameTime();
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
@ -492,12 +462,12 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
||||||
EquipHat(client, entity);
|
EquipHat(client, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If bot is commandable and reversed (player reverse-hat common/survivor), change position:
|
// // If bot is commandable and reversed (player reverse-hat common/survivor), change position:
|
||||||
if(HasFlag(client, HAT_COMMANDABLE | HAT_REVERSED) && tickcount % 200 == 0) {
|
// if(HasFlag(client, HAT_COMMANDABLE | HAT_REVERSED) && tickcount % 200 == 0) {
|
||||||
float pos[3];
|
// float pos[3];
|
||||||
ChooseRandomPosition(pos, client);
|
// ChooseRandomPosition(pos, client);
|
||||||
L4D2_CommandABot(entity, client, BOT_CMD_MOVE, pos);
|
// L4D2_CommandABot(entity, client, BOT_CMD_MOVE, pos);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
// Detect E + R to offset hat or place down
|
// Detect E + R to offset hat or place down
|
||||||
if(buttons & IN_USE && buttons & IN_RELOAD) {
|
if(buttons & IN_USE && buttons & IN_RELOAD) {
|
||||||
|
@ -682,14 +652,12 @@ bool CheckBlacklist(int entity) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(StrContains(buffer, "prop_") > -1) {
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
|
GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
|
||||||
for(int i = 0; i < MAX_FORBIDDEN_MODELS; i++) {
|
for(int i = 0; i < MAX_FORBIDDEN_MODELS; i++) {
|
||||||
if(StrEqual(FORBIDDEN_MODELS[i], buffer)) {
|
if(StrEqual(FORBIDDEN_MODELS[i], buffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iName", buffer, sizeof(buffer));
|
GetEntPropString(entity, Prop_Data, "m_iName", buffer, sizeof(buffer));
|
||||||
if(StrContains(buffer, "randomizer") == 0) {
|
if(StrContains(buffer, "randomizer") == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -726,16 +694,6 @@ stock bool FindGround(const float start[3], float end[3]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stock bool L4D_IsPlayerCapped(int client) {
|
|
||||||
if(GetEntPropEnt(client, Prop_Send, "m_pummelAttacker") > 0 ||
|
|
||||||
GetEntPropEnt(client, Prop_Send, "m_carryAttacker") > 0 ||
|
|
||||||
GetEntPropEnt(client, Prop_Send, "m_pounceAttacker") > 0 ||
|
|
||||||
GetEntPropEnt(client, Prop_Send, "m_jockeyAttacker") > 0 ||
|
|
||||||
GetEntPropEnt(client, Prop_Send, "m_pounceAttacker") > 0 ||
|
|
||||||
GetEntPropEnt(client, Prop_Send, "m_tongueOwner") > 0)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
stock void LookAtPoint(int entity, const float destination[3]){
|
stock void LookAtPoint(int entity, const float destination[3]){
|
||||||
float angles[3], pos[3], result[3];
|
float angles[3], pos[3], result[3];
|
||||||
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos);
|
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos);
|
||||||
|
|
|
@ -226,6 +226,10 @@ public Action Command_CycleRandom(int client, int args) {
|
||||||
if(client > 0)
|
if(client > 0)
|
||||||
PrintCenterText(client, "Cycled flags=%d", flags);
|
PrintCenterText(client, "Cycled flags=%d", flags);
|
||||||
} else {
|
} else {
|
||||||
|
if(g_MapData.activeScenes == null) {
|
||||||
|
ReplyToCommand(client, "No map data");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
ReplyToCommand(client, "Active Scenes (%d/%d):", g_MapData.activeScenes.Length, g_MapData.scenes.Length);
|
ReplyToCommand(client, "Active Scenes (%d/%d):", g_MapData.activeScenes.Length, g_MapData.scenes.Length);
|
||||||
ActiveSceneData scene;
|
ActiveSceneData scene;
|
||||||
for(int i = 0; i < g_MapData.activeScenes.Length; i++) {
|
for(int i = 0; i < g_MapData.activeScenes.Length; i++) {
|
||||||
|
@ -389,6 +393,18 @@ Action Command_RandomizerBuild(int client, int args) {
|
||||||
obj.SetString("model", "decals/checkpointarrow01_black.vmt");
|
obj.SetString("model", "decals/checkpointarrow01_black.vmt");
|
||||||
g_builder.AddEntityData(obj);
|
g_builder.AddEntityData(obj);
|
||||||
ReplyToCommand(client, "Added sprite to variant #%d", g_builder.selectedVariantIndex);
|
ReplyToCommand(client, "Added sprite to variant #%d", g_builder.selectedVariantIndex);
|
||||||
|
} else if(StrEqual(arg, "fire")) {
|
||||||
|
if(g_builder.selectedVariantData == null) {
|
||||||
|
ReplyToCommand(client, "Please load map data, select a scene and a variant.");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
float pos[3];
|
||||||
|
GetLookingPosition(client, Filter_IgnorePlayer, pos);
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.SetString("type", "env_fire");
|
||||||
|
obj.Set("origin", VecToArray(pos));
|
||||||
|
g_builder.AddEntityData(obj);
|
||||||
|
ReplyToCommand(client, "Added fire to variant #%d", g_builder.selectedVariantIndex);
|
||||||
} else {
|
} else {
|
||||||
ReplyToCommand(client, "Unknown arg. Try: new, load, save, scenes, cursor");
|
ReplyToCommand(client, "Unknown arg. Try: new, load, save, scenes, cursor");
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,8 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
||||||
CreateNative("UIElement.SendTo", Native_UpdateUI);
|
CreateNative("UIElement.SendTo", Native_UpdateUI);
|
||||||
CreateNative("TempUI.SendAll", Native_UpdateTempUI);
|
CreateNative("TempUI.SendAll", Native_UpdateTempUI);
|
||||||
CreateNative("TempUI.SendTo", Native_UpdateTempUI);
|
CreateNative("TempUI.SendTo", Native_UpdateTempUI);
|
||||||
|
|
||||||
|
CreateNative("FindClientBySteamId2", Native_FindClientBySteamId2);
|
||||||
return APLRes_Success;
|
return APLRes_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,8 +130,11 @@ Action Command_Overlay(int client, int args) {
|
||||||
ReplyToCommand(client, "URL: %s", managerUrl);
|
ReplyToCommand(client, "URL: %s", managerUrl);
|
||||||
ReplyToCommand(client, "Socket Connected: %b | WS Connected: %b", g_ws.SocketOpen(), g_ws.WsOpen());
|
ReplyToCommand(client, "Socket Connected: %b | WS Connected: %b", g_ws.SocketOpen(), g_ws.WsOpen());
|
||||||
ReplyToCommand(client, "Auth State: %d", g_authState);
|
ReplyToCommand(client, "Auth State: %d", g_authState);
|
||||||
|
} else if(StrEqual(arg, "players")) {
|
||||||
|
SendAllPlayers();
|
||||||
} else if(StrEqual(arg, "test")) {
|
} else if(StrEqual(arg, "test")) {
|
||||||
SendAllPlayers();
|
SendAllPlayers();
|
||||||
|
// TODO: server can send: steamids[], steamid, or none (manager knows who was connected)
|
||||||
|
|
||||||
JSONObject temp = new JSONObject();
|
JSONObject temp = new JSONObject();
|
||||||
temp.SetString("type", "text");
|
temp.SetString("type", "text");
|
||||||
|
@ -276,38 +281,45 @@ stock int ExplodeStringToArrayList(const char[] text, const char[] split, ArrayL
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAction(JSONObject obj) {
|
void OnAction(JSONObject obj) {
|
||||||
char steamid[32];
|
ClientAction action;
|
||||||
obj.GetString("steamid", steamid, sizeof(steamid));
|
obj.GetString("steamid", action.steamid, sizeof(action.steamid));
|
||||||
char ns[64];
|
obj.GetString("namespace", action.ns, sizeof(action.ns));
|
||||||
obj.GetString("namespace", ns, sizeof(ns));
|
obj.GetString("instance_id", action.instanceId, sizeof(action.instanceId));
|
||||||
char id[64];
|
obj.GetString("command", action.command, sizeof(action.command));
|
||||||
obj.GetString("elem_id", id, sizeof(id));
|
if(obj.HasKey("input"))
|
||||||
char action[256];
|
obj.GetString("input", action.input, sizeof(action.input));
|
||||||
obj.GetString("action", action, sizeof(action));
|
|
||||||
|
|
||||||
int client = FindClientBySteamId2(steamid);
|
int client = FindClientBySteamId2(action.steamid);
|
||||||
|
if(client <= 0) return;
|
||||||
|
|
||||||
StringMap nsHandler;
|
StringMap nsHandler;
|
||||||
PrivateForward fwd;
|
PrivateForward fwd;
|
||||||
if(!actionNamespaceHandlers.GetValue(ns, nsHandler) || !nsHandler.GetValue(id, fwd)) {
|
if(!actionNamespaceHandlers.GetValue(action.ns, nsHandler) || !nsHandler.GetValue(action.command, fwd)) {
|
||||||
if(!actionFallbackHandlers.GetValue(ns, fwd)) {
|
if(!actionFallbackHandlers.GetValue(action.ns, fwd)) {
|
||||||
// No handler or catch all namespace handler
|
// No handler or catch all namespace handler
|
||||||
|
PrintToServer("[Overlay] Warn: No handler found for action \"%s:%s\"", action.ns, action.command);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList args = new ArrayList(ACTION_ARG_LENGTH);
|
ArrayList args = new ArrayList(ACTION_ARG_LENGTH);
|
||||||
ExplodeStringToArrayList(action, " ", args, ACTION_ARG_LENGTH);
|
args.PushString(action.input);
|
||||||
|
ExplodeStringToArrayList(action.input, " ", args, ACTION_ARG_LENGTH);
|
||||||
UIActionEvent event = UIActionEvent(args);
|
UIActionEvent event = UIActionEvent(args);
|
||||||
|
|
||||||
Call_StartForward(fwd);
|
Call_StartForward(fwd);
|
||||||
Call_PushCell(event);
|
Call_PushCell(event);
|
||||||
Call_PushCell(client);
|
Call_PushCell(client);
|
||||||
Call_Finish();
|
Call_Finish();
|
||||||
|
|
||||||
|
if(StrEqual(action.ns, "game")) {
|
||||||
|
if(CheckCommandAccess(client, action.command, 0)) {
|
||||||
|
FakeClientCommand(client, "%s %s", action.command, action.input);
|
||||||
|
}
|
||||||
|
}
|
||||||
event._Delete();
|
event._Delete();
|
||||||
}
|
}
|
||||||
|
int _FindClientBySteamId2(const char[] steamid) {
|
||||||
int FindClientBySteamId2(const char[] steamid) {
|
|
||||||
for(int i = 1; i <= MaxClients; i++) {
|
for(int i = 1; i <= MaxClients; i++) {
|
||||||
if(StrEqual(steamidCache[i], steamid)) {
|
if(StrEqual(steamidCache[i], steamid)) {
|
||||||
return i;
|
return i;
|
||||||
|
@ -316,7 +328,6 @@ int FindClientBySteamId2(const char[] steamid) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ConnectManager() {
|
bool ConnectManager() {
|
||||||
DisconnectManager();
|
DisconnectManager();
|
||||||
if(authToken[0] == '\0') return false;
|
if(authToken[0] == '\0') return false;
|
||||||
|
@ -537,3 +548,10 @@ any Native_ActionHandler(Handle plugin, int numParams) {
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
any Native_FindClientBySteamId2(Handle plugin, int numParams) {
|
||||||
|
char steamid[32];
|
||||||
|
GetNativeString(1, steamid, sizeof(steamid));
|
||||||
|
return _FindClientBySteamId2(steamid);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue