//==================================================================================================== // // Name: [entWatch] Restrictions // Author: zaCade & Prometheum // Description: Handle the restrictions of [entWatch] // //==================================================================================================== #include #pragma newdecls required #include #include #include #include #include //2026: add playtime requirements for being unrestricted #include /* FORWARDS */ Handle g_hFwd_OnClientRestricted; Handle g_hFwd_OnClientUnrestricted; /* COOKIES */ Handle g_hCookie_RestrictIssued; Handle g_hCookie_RestrictExpire; Handle g_hCookie_RestrictLength; /* BOOLEANS */ bool g_bRestrictedTemp[MAXPLAYERS+1]; bool g_bDontSpamMsg[MAXPLAYERS+1] /* INTERGERS */ int g_iRestrictIssued[MAXPLAYERS+1]; int g_iRestrictLength[MAXPLAYERS+1]; int g_iRestrictExpire[MAXPLAYERS+1]; int g_iClientHours[MAXPLAYERS + 1]; /* STRINGMAPS */ StringMap g_hTrie_Storage; /* CONVARS */ ConVar g_cvarHourRequirement = null; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Plugin myinfo = { name = "[entWatch] Restrictions", author = "zaCade & Prometheum", description = "Handle the restrictions of [entWatch]", version = "4.0.1" }; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int errorSize) { CreateNative("EW_ClientRestrict", Native_ClientRestrict); CreateNative("EW_ClientUnrestrict", Native_ClientUnrestrict); CreateNative("EW_ClientRestricted", Native_ClientRestricted); RegPluginLibrary("entWatch-restrictions"); return APLRes_Success; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginStart() { LoadTranslations("common.phrases"); LoadTranslations("entWatch.restrictions.phrases"); g_hFwd_OnClientRestricted = CreateGlobalForward("EW_OnClientRestricted", ET_Ignore, Param_Cell, Param_Cell, Param_Cell); g_hFwd_OnClientUnrestricted = CreateGlobalForward("EW_OnClientUnrestricted", ET_Ignore, Param_Cell, Param_Cell); g_hCookie_RestrictIssued = RegClientCookie("EW_RestrictIssued", "", CookieAccess_Private); g_hCookie_RestrictExpire = RegClientCookie("EW_RestrictExpire", "", CookieAccess_Private); g_hCookie_RestrictLength = RegClientCookie("EW_RestrictLength", "", CookieAccess_Private); g_hTrie_Storage = new StringMap(); RegAdminCmd("sm_eban", Command_ClientRestrict, ADMFLAG_BAN); RegAdminCmd("sm_eunban", Command_ClientUnrestrict, ADMFLAG_UNBAN); RegConsoleCmd("sm_restrictions", Command_DisplayRestrictions); RegConsoleCmd("sm_ebanlist", Command_DisplayRestrictions); RegConsoleCmd("sm_status", Command_DisplayStatus); for (int client = 1; client <= MaxClients; client++) { if (IsClientConnected(client)) OnClientPutInServer(client); if (AreClientCookiesCached(client)) OnClientCookiesCached(client); } g_cvarHourRequirement = CreateConVar("sm_entwatch_hour_requirement", "10", "Using the unloze play time plugin to set a minimum amount of hours for allowing players access to items."); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnMapStart() { g_hTrie_Storage.Clear(); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPutInServer(int client) { char sAddress[32]; GetClientIP(client, sAddress, sizeof(sAddress)); g_bDontSpamMsg[client] = false; bool bRestrictedTemp; if (g_hTrie_Storage.GetValue(sAddress, bRestrictedTemp)) { g_bRestrictedTemp[client] = bRestrictedTemp; } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientCookiesCached(int client) { g_iRestrictIssued[client] = GetClientCookieInt(client, g_hCookie_RestrictIssued); g_iRestrictExpire[client] = GetClientCookieInt(client, g_hCookie_RestrictExpire); g_iRestrictLength[client] = GetClientCookieInt(client, g_hCookie_RestrictLength); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientDisconnect(int client) { if (g_bRestrictedTemp[client]) { char sAddress[32]; GetClientIP(client, sAddress, sizeof(sAddress)); g_hTrie_Storage.SetArray(sAddress, g_bRestrictedTemp[client], true); } g_bDontSpamMsg[client] = false; g_bRestrictedTemp[client] = false; g_iRestrictIssued[client] = 0; g_iRestrictExpire[client] = 0; g_iRestrictLength[client] = 0; g_iClientHours[client] = 0; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_ClientRestrict(int client, int args) { if (!GetCmdArgs()) { CReplyToCommand(client, "\x07%s[entWatch] \x07%sUsage: sm_eban <#userid/name> [duration]", "E01B5D", "F16767"); return Plugin_Handled; } char sArguments[2][32]; GetCmdArg(1, sArguments[0], sizeof(sArguments[])); GetCmdArg(2, sArguments[1], sizeof(sArguments[])); int target; if ((target = FindTarget(client, sArguments[0], true)) == -1) return Plugin_Handled; if (GetCmdArgs() >= 2) { int length = StringToInt(sArguments[1]); if (ClientRestrict(client, target, length)) { if (length && length >= 60) { length /= 60; CPrintToChatAll("\x07%s[entWatch] \x07%s%N\x07%s restricted \x07%s%N\x07%s for \x07%s%d\x07%s hours Playtime.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767", "EDEDED", length, "F16767"); LogAction(client, target, "%L restricted %L for %d hours playtime.", client, target, length); } else if (!length) { CPrintToChatAll("\x07%s[entWatch] \x07%s%N\x07%s restricted \x07%s%N\x07%s permanently.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767"); LogAction(client, target, "%L restricted %L permanently.", client, target); } } } else { if (ClientRestrict(client, target, -1)) { CPrintToChatAll("\x07%s[entWatch] \x07%s%N\x07%s restricted \x07%s%N\x07%s temporarily.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767"); LogAction(client, target, "%L restricted %L temporarily.", client, target); } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_ClientUnrestrict(int client, int args) { if (!GetCmdArgs()) { CReplyToCommand(client, "\x07%s[entWatch] \x07%sUsage: sm_eunban <#userid/name>", "E01B5D", "F16767"); return Plugin_Handled; } char sArguments[1][32]; GetCmdArg(1, sArguments[0], sizeof(sArguments[])); int target; if ((target = FindTarget(client, sArguments[0], true)) == -1) return Plugin_Handled; if (ClientUnrestrict(client, target)) { CPrintToChatAll("\x07%s[entWatch] \x07%s%N\x07%s unrestricted \x07%s%N\x07%s.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767"); LogAction(client, target, "%L unrestricted %L.", client, target); } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_DisplayRestrictions(int client, int args) { char aBuf[1024]; char aBuf_time_requirement[1024]; char aBuf2[MAX_NAME_LENGTH]; char aBuf2_time_requirement[MAX_NAME_LENGTH]; for (int i = 1; i <= MaxClients; i++) { if (IsClientInGame(i) && !IsFakeClient(i)) { if (ClientRestricted(i)) { if (g_iClientHours[i] <= g_cvarHourRequirement.IntValue) { GetClientName(i, aBuf2_time_requirement, sizeof(aBuf2_time_requirement)); StrCat(aBuf_time_requirement, sizeof(aBuf_time_requirement), aBuf2_time_requirement); StrCat(aBuf_time_requirement, sizeof(aBuf_time_requirement), ", "); } else { GetClientName(i, aBuf2, sizeof(aBuf2)); StrCat(aBuf, sizeof(aBuf), aBuf2); StrCat(aBuf, sizeof(aBuf), ", "); } } } } if (strlen(aBuf)) { aBuf[strlen(aBuf) - 2] = 0; CReplyToCommand(client, "\x07%s[entWatch] \x07%sCurrently restricted clients: \x07%s%s", "E01B5D", "F16767", "EDEDED", aBuf); } else CReplyToCommand(client, "\x07%s[entWatch] \x07%sCurrently restricted clients: \x07%snone", "E01B5D", "F16767", "EDEDED"); if (strlen(aBuf_time_requirement)) { aBuf_time_requirement[strlen(aBuf_time_requirement) - 2] = 0; CReplyToCommand(client, "\x07%s[entWatch] \x07%sCurrent clients with not enough playtime: \x07%s%s", "E01B5D", "F16767", "EDEDED", aBuf_time_requirement); } else CReplyToCommand(client, "\x07%s[entWatch] \x07%sCurrent clients with not enough playtime: \x07%snone", "E01B5D", "F16767", "EDEDED"); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_DisplayStatus(int client, int args) { if (CheckCommandAccess(client, "", ADMFLAG_BAN) && GetCmdArgs()) { char sArguments[1][32]; GetCmdArg(1, sArguments[0], sizeof(sArguments[])); int target; if ((target = FindTarget(client, sArguments[0], true)) == -1) return Plugin_Handled; if (!AreClientCookiesCached(target)) { CReplyToCommand(client, "\x07%s[entWatch] \x07%s%N\x07%s their cookies are still loading.", "E01B5D", "EDEDED", target, "F16767"); return Plugin_Handled; } else if (g_bRestrictedTemp[target]) { CReplyToCommand(client, "\x07%s[entWatch] \x07%s%N\x07%s is currently temporarily restricted.", "E01B5D", "EDEDED", target, "F16767"); return Plugin_Handled; } else if (g_iRestrictIssued[target] && g_iRestrictExpire[target] == 0) { CReplyToCommand(client, "\x07%s[entWatch] \x07%s%N\x07%s is currently permanently restricted.", "E01B5D", "EDEDED", target, "F16767"); return Plugin_Handled; } else if (g_iRestrictIssued[target] && g_iRestrictExpire[target] >= g_iClientHours[target]) { char sTimeRemaining[64]; int iTimeRemaining = g_iRestrictExpire[target] - g_iClientHours[target]; //its just hours now Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Hours Playtime", iTimeRemaining); CReplyToCommand(client, "\x07%s[entWatch] \x07%s%N\x07%s is currently restricted for another \x07%s%s\x07%s.", "E01B5D", "EDEDED", target, "F16767", "EDEDED", sTimeRemaining, "F16767"); return Plugin_Handled; } else { CReplyToCommand(client, "\x07%s[entWatch] \x07%s%N\x07%s is currently not restricted.", "E01B5D", "EDEDED", target, "F16767"); return Plugin_Handled; } } else { if (!AreClientCookiesCached(client)) { CReplyToCommand(client, "\x07%s[entWatch] \x07%sYour cookies are still loading.", "E01B5D", "F16767"); return Plugin_Handled; } else if (g_bRestrictedTemp[client]) { CReplyToCommand(client, "\x07%s[entWatch] \x07%sYou are currently temporarily restricted.", "E01B5D", "F16767"); return Plugin_Handled; } else if (g_iRestrictIssued[client] && g_iRestrictExpire[client] == 0) { CReplyToCommand(client, "\x07%s[entWatch] \x07%sYou are currently permanently restricted.", "E01B5D", "F16767"); return Plugin_Handled; } else if (g_iRestrictIssued[client] && g_iRestrictExpire[client] >= g_iClientHours[client]) { char sTimeRemaining[64]; int iTimeRemaining = g_iRestrictExpire[client] - g_iClientHours[client]; //its just hours now Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Hours Playtime", iTimeRemaining); CReplyToCommand(client, "\x07%s[entWatch] \x07%sYou are currently restricted for another \x07%s%s\x07%s.", "E01B5D", "F16767", "EDEDED", sTimeRemaining, "F16767"); return Plugin_Handled; } else { CReplyToCommand(client, "\x07%s[entWatch] \x07%sYou are currently not restricted.", "E01B5D", "F16767"); return Plugin_Handled; } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action EW_OnClientItemCanPickup(int client, int index) { return ClientRestricted(client)?Plugin_Handled:Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action EW_OnClientItemCanActivate(int client, int index) { return ClientRestricted(client)?Plugin_Handled:Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool ClientRestrict(int client, int target, int length) { if (!Client_IsValid(client) || !Client_IsValid(target) || !AreClientCookiesCached(target) || ClientRestricted(target)) { if (Client_IsValid(client) && Client_IsValid(target) && ClientRestricted(target)) { CPrintToChat(client, "\x07%s[entWatch] \x07%s The player \x07%s%N\x07%s is already restricted.", "E01B5D", "EDEDED", "EDEDED", target, "F16767"); } return false; } if (length == -1) { g_bRestrictedTemp[target] = true; } else if (length == 0) { g_bRestrictedTemp[target] = false; g_iRestrictIssued[target] = g_iClientHours[target]; g_iRestrictExpire[target] = 0; g_iRestrictLength[target] = 0; SetClientCookieInt(target, g_hCookie_RestrictIssued, GetTime()); SetClientCookieInt(target, g_hCookie_RestrictExpire, 0); SetClientCookieInt(target, g_hCookie_RestrictLength, 0); } else { if (length < 60) { CPrintToChat(client, "\x07%s[entWatch] \x07%sEban length is now rounded in hours so minimum value has to be 60.", "E01B5D", "EDEDED"); return false; } //2026 edit. we now use ingame play time of the client instead of real time. length /= 60; g_bRestrictedTemp[target] = false; g_iRestrictIssued[target] = g_iClientHours[target]; g_iRestrictExpire[target] = g_iClientHours[target] + length; g_iRestrictLength[target] = length; SetClientCookieInt(target, g_hCookie_RestrictIssued, g_iRestrictIssued[target]); SetClientCookieInt(target, g_hCookie_RestrictExpire, g_iRestrictExpire[target]); SetClientCookieInt(target, g_hCookie_RestrictLength, length); } Call_StartForward(g_hFwd_OnClientRestricted); Call_PushCell(client); Call_PushCell(target); Call_PushCell(length); Call_Finish(); return true; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool ClientUnrestrict(int client, int target) { if (!Client_IsValid(client) || !Client_IsValid(target) || !AreClientCookiesCached(target) || !ClientRestricted(target)) return false; g_bRestrictedTemp[target] = false; g_iRestrictIssued[target] = 0; g_iRestrictExpire[target] = 0; g_iRestrictLength[target] = 0; SetClientCookieInt(target, g_hCookie_RestrictIssued, 0); SetClientCookieInt(target, g_hCookie_RestrictExpire, 0); SetClientCookieInt(target, g_hCookie_RestrictLength, 0); Call_StartForward(g_hFwd_OnClientUnrestricted); Call_PushCell(client); Call_PushCell(target); Call_Finish(); return true; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool ClientRestricted(int client) { if (!Client_IsValid(client)) return false; //Block them when loading cookies.. if (!AreClientCookiesCached(client)) return true; //Temporary restriction. if (g_bRestrictedTemp[client]) return true; //Permanent restriction. if (g_iRestrictIssued[client] && g_iRestrictExpire[client] == 0) return true; //Normal restriction. if (g_iRestrictIssued[client] && g_iRestrictExpire[client] >= g_iClientHours[client]) return true; //hour requirement for picking up items if (g_iClientHours[client] <= g_cvarHourRequirement.IntValue) { if (!g_bDontSpamMsg[client]) { CPrintToChat(client, "\x07%s[entWatch] \x07%s You have \x07%s%i\x07%s hours playtime and need more than %i hours for picking up items.", "E01B5D", "EDEDED", "EDEDED", g_iClientHours[client], "EDEDED", g_cvarHourRequirement.IntValue); g_bDontSpamMsg[client] = true; CreateTimer(1.0, allow_message_again, GetClientSerial(client)); } return true; } return false; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_ClientRestrict(Handle hPlugin, int numParams) { return ClientRestrict(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3)); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_ClientUnrestrict(Handle hPlugin, int numParams) { return ClientUnrestrict(GetNativeCell(1), GetNativeCell(2)); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_ClientRestricted(Handle hPlugin, int numParams) { return ClientRestricted(GetNativeCell(1)); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock void SetClientCookieInt(int client, Handle hCookie, int value) { char sValue[32]; IntToString(value, sValue, sizeof(sValue)); SetClientCookie(client, hCookie, sValue); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock int GetClientCookieInt(int client, Handle hCookie) { char sValue[32]; GetClientCookie(client, hCookie, sValue, sizeof(sValue)); return StringToInt(sValue); } //---------------------------------------------------------------------------------------------------- // Purpose: 2026 getting the ingame play time of the players. called with OnClientPostAdminCheck() forward and timer every 10 minutes //---------------------------------------------------------------------------------------------------- public void GetPlayerHoursServer(int client, int hours) { g_iClientHours[client] = hours; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action allow_message_again(Handle hTimer, int Serial) { int client; if ((client = GetClientFromSerial(Serial)) == 0) { return Plugin_Handled; } if (Client_IsValid(client)) { g_bDontSpamMsg[client] = false; } return Plugin_Handled; }