Compare commits

...

6 commits

Author SHA1 Message Date
19d2d6d334 Check if getting IP worked 2024-11-26 16:33:16 -06:00
7661a95f0e Only run setup once per user 2024-11-26 16:28:32 -06:00
a010498b29 Fix race condition, other issues 2024-11-26 16:17:00 -06:00
3ffe0540ac Fixes 2024-11-26 16:03:36 -06:00
c69c03a42b Update plugin info 2024-11-26 15:57:22 -06:00
2ade39fd28 Track users, names 2024-11-26 15:57:18 -06:00
7 changed files with 145 additions and 18 deletions

Binary file not shown.

Binary file not shown.

View file

@ -7,6 +7,8 @@
#define DEFAULT_SERVER_PORT 7888
#define SOCKET_TIMEOUT_DURATION 90.0
#define DATABASE_NAME "adminpanel"
#include <sourcemod>
#include <sdktools>
#include <ripext>
@ -14,6 +16,7 @@
#include <multicolors>
#include <jutils>
#include <socket>
#include <geoip>
#undef REQUIRE_PLUGIN
#tryinclude <SteamWorks>
@ -89,12 +92,20 @@ GameState g_gameState = State_Hibernating;
Buffer sendBuffer;
Buffer receiveBuffer; // Unfortunately there's no easy way to have this not be the same as BUFFER_SIZE
Database g_db;
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) {
// lateLoaded = late;
return APLRes_Success;
}
public void OnPluginStart() {
if(!SQL_CheckConfig(DATABASE_NAME)) {
SetFailState("No database entry for '%s'; no database to connect to.", DATABASE_NAME);
} else if(!ConnectDB()) {
SetFailState("Failed to connect to database.");
}
g_socket = new Socket(SOCKET_TCP, OnSocketError);
g_socket.SetOption(SocketKeepAlive, 1);
g_socket.SetOption(SocketReuseAddr, 1);
@ -126,6 +137,7 @@ public void OnPluginStart() {
cvar_difficulty.AddChangeHook(OnCvarChanged);
gameDifficulty = GetDifficultyInt();
HookEvent("player_info", Event_PlayerInfo);
HookEvent("game_init", Event_GameStart);
HookEvent("game_end", Event_GameEnd);
HookEvent("heal_begin", Event_HealStart);
@ -139,6 +151,7 @@ public void OnPluginStart() {
HookEvent("player_death", Event_PlayerDeath);
HookEvent("player_bot_replace", Event_PlayerToBot);
HookEvent("bot_player_replace", Event_BotToPlayer);
HookEvent("player_first_spawn", Event_PlayerFirstSpawn);
campaignStartTime = GetTime();
char auth[32];
@ -160,6 +173,101 @@ public void OnPluginStart() {
CreateTimer(300.0, Timer_FullSync, _, TIMER_REPEAT);
}
bool ConnectDB() {
char error[255];
g_db = SQL_Connect(DATABASE_NAME, true, error, sizeof(error));
if (g_db == null) {
LogError("Database error %s", error);
delete g_db;
return false;
} else {
PrintToServer("Connected to database %s", DATABASE_NAME);
SQL_LockDatabase(g_db);
SQL_FastQuery(g_db, "SET NAMES \"UTF8mb4\"");
SQL_UnlockDatabase(g_db);
g_db.SetCharset("utf8mb4");
return true;
}
}
//Setups a user, this tries to fetch user by steamid
void SetupUserInDB(int client) {
if(client > 0 && !IsFakeClient(client)) {
char country[128];
char region[128];
char ip[64];
if(GetClientIP(client, ip, sizeof(ip))) {
GeoipCountry(ip, country, sizeof(country));
GeoipRegion(ip, region, sizeof(region));
}
int time = GetTime();
char query[512];
g_db.Format(query, sizeof(query), "INSERT INTO panel_user "
..."(account_id,last_join_time,last_ip,last_country,last_region)"
..."VALUES ('%s',%d,'%s','%s','%s')"
..."ON DUPLICATE KEY UPDATE last_join_time=%d,last_ip='%s',last_country='%s',last_region='%s';",
steamidCache[client][10], // strip STEAM_#:#:##### returning only ending #######
// insert:
time,
ip,
country,
region,
// update:
time,
ip,
country,
region
);
g_db.Query(DBCT_PanelUser, query, GetClientUserId(client));
}
}
void DBCT_PanelUser(Database db, DBResultSet results, const char[] error, int userId) {
if(db == null || results == null) {
LogError("DBCT_Insert returned error: %s", error);
}
int client = GetClientOfUserId(userId);
if(client > 0) {
char query[128];
g_db.Format(query, sizeof(query), "SELECT name FROM panel_user_names WHERE account_id = '%s' ORDER BY name_update_time DESC LIMIT 1", steamidCache[client][10]); // strip STEAM_#:#:##### returning only ending #######
g_db.Query(DBCT_CheckUserName, query, userId);
}
}
void DBCT_Insert(Database db, DBResultSet results, const char[] error, any data) {
if(db == null || results == null) {
LogError("DBCT_Insert returned error: %s", error);
}
}
void DBCT_CheckUserName(Database db, DBResultSet results, const char[] error, int userId) {
if(db == null || results == null) {
LogError("DBCT_CheckUserName returned error: %s", error);
} else {
int client = GetClientOfUserId(userId);
if(client == 0) return; // Client left, ignore
// Insert new name if we have none, or prev differs
bool insertNewName = true;
if(results.FetchRow()) {
if(nameCache[client][0] == '\0') {
LogError("DBCT_CheckUserName user %N(#%d) missing namecache", client, userId);
}
char prevName[64];
results.FetchString(0, prevName, sizeof(prevName));
if(StrEqual(prevName, nameCache[client])) {
insertNewName = false;
}
}
if(insertNewName) {
PrintToServer("[AdminPanel] Updating/Inserting name '%s' for %s", nameCache[client], steamidCache[client]);
char query[255];
g_db.Format(query, sizeof(query), "INSERT INTO panel_user_names (account_id,name,name_update_time) VALUES ('%s','%s',%d)", steamidCache[client][10], nameCache[client], GetTime());
g_db.Query(DBCT_Insert, query);
}
}
}
stock void Debug(const char[] format, any ...) {
if(!cvar_debug.BoolValue) return;
@ -654,6 +762,20 @@ void StopServer() {
ServerCommand("exit");
}
void Event_PlayerInfo(Event event, const char[] name, bool dontBroadcast) {
int client = GetClientOfUserId(event.GetInt("userid"));
if(client && !IsFakeClient(client)) {
GetClientName(client, nameCache[client], 32);
}
}
void Event_PlayerFirstSpawn(Event event, const char[] name, bool dontBroadcast) {
int userid = event.GetInt("userid");
int client = GetClientOfUserId(userid);
if(client > 0)
SetupUserInDB(client);
}
void Event_GameStart(Event event, const char[] name, bool dontBroadcast) {
campaignStartTime = GetTime();
g_gameState = State_NewGame;
@ -925,7 +1047,8 @@ void OnCvarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
if(serverPort == 0) serverPort = DEFAULT_SERVER_PORT;
}
PrintToServer("[AdminPanel] Sending data to %s:%d", serverIp, serverPort);
ConnectSocket();
if(authToken[0] != '\0')
ConnectSocket();
}
} else if(cvar_gamemode == convar) {
strcopy(gamemode, sizeof(gamemode), newValue);

View file

@ -336,7 +336,6 @@ Action Command_DoAHat(int client, int args) {
// Find a new hatable entity
int flags = 0;
if(args > 0 && isForced) {
char arg[16];
entity = GetCmdArgInt(1);
} else {
entity = GetLookingEntity(client, Filter_ValidHats);
@ -814,10 +813,6 @@ void EquipHat(int client, int entity, const char[] classname = "", int flags = H
SetParentAttachment(modifyEntity, attachPoint, true);
}
if(HasFlag(client, HAT_COMMANDABLE)) {
ChooseRandomPosition(hatData[client].offset);
L4D2_CommandABot(entity, client, BOT_CMD_MOVE, hatData[client].offset);
}
} else {
SetParent(entity, client);
SetParentAttachment(modifyEntity, attachPoint, true);

View file

@ -34,9 +34,9 @@ ConVar enabledBlacklist;
#include <editor>
public Plugin myinfo = {
name = "L4D2 Hats & Editor",
name = "L4D2 Editor",
author = "jackzmc",
description = "",
description = "Advanced prop spawner and entity editing",
version = PLUGIN_VERSION,
url = "https://github.com/Jackzmc/sourcemod-plugins"
};

View file

@ -78,7 +78,7 @@ PlayerItems items[MAXPLAYERS+1];
public Plugin myinfo =
{
name = "L4D2 Extra Player Tools",
name = "L4D2 5+ Extra Tools & Director",
author = "jackzmc",
description = "Automatic system for management of 5+ player games. Provides extra kits, items, and more",
version = PLUGIN_VERSION,

View file

@ -15,6 +15,7 @@ static float EMPTY_ANG[3] = { 0.0, 0.0, 0.0 };
#include <gamemodes/ents>
#include <smlib/effects>
#include <multicolors>
#include <left4dhooks>
#include <adminmenu>
@ -41,14 +42,13 @@ char g_currentMap[64];
#include <hats/hat_presets.sp>
public Plugin myinfo = {
name = "L4D2 Hats & Editor",
name = "L4D2 Hats",
author = "jackzmc",
description = "",
description = "Hat props and cause problems",
version = PLUGIN_VERSION,
url = "https://github.com/Jackzmc/sourcemod-plugins"
};
ArrayList NavAreas;
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) {
return APLRes_Success;
}
@ -343,10 +343,10 @@ void Event_PlayerOutOfIdle(Event event, const char[] name, bool dontBroadcast) {
void Frame_FixClient(int client) {
if(IsClientConnected(client) && GetClientTeam(client) == 2) {
ClearParent(client);
SetEntProp(client, Prop_Send, "m_CollisionGroup", 5);
SetEntProp(client, Prop_Send, "m_nSolidType", 2);
SetEntityMoveType(client, MOVETYPE_WALK);
ClearParent(client);
SetEntProp(client, Prop_Send, "m_CollisionGroup", 5);
SetEntProp(client, Prop_Send, "m_nSolidType", 2);
SetEntityMoveType(client, MOVETYPE_WALK);
}
// SetEntProp(client, Prop_Send, "movetype", MOVETYPE_ISOMETRIC);
}
@ -574,12 +574,21 @@ public void OnMapStart() {
tempGod[i] = false;
}
GetCurrentMap(g_currentMap, sizeof(g_currentMap));
NavAreas = GetSpawnLocations();
}
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;
}
public void OnMapEnd() {
delete NavAreas;
ClearHats();
}
public void OnPluginEnd() {