diff --git a/UNLOZE_ForumIntegration/scripting/UNLOZE_ForumIntegration_active.sp b/UNLOZE_ForumIntegration/scripting/UNLOZE_ForumIntegration_active.sp new file mode 100755 index 0000000..e82d72b --- /dev/null +++ b/UNLOZE_ForumIntegration/scripting/UNLOZE_ForumIntegration_active.sp @@ -0,0 +1,422 @@ +//==================================================================================================== +// +// Name: UNLOZE Forum Integration. +// Author: .George & zaCade (Original by Botox) +// Description: Handles forum access ingame. +// +//==================================================================================================== +#include +#include +#include +#include //#define UNLOZE_APIKEY here +#include +#include + +#pragma newdecls required + +/* STRINGS */ +char G_sGroup[MAXPLAYERS+1][64]; +char G_sName[MAXPLAYERS+1][32]; + +/* BOOLS */ +bool G_bPreAdminChecked[MAXPLAYERS+1]; +bool G_bResponseFailed[MAXPLAYERS+1]; +bool G_bResponsePassed[MAXPLAYERS+1]; + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Plugin myinfo = +{ + name = "UNLOZE Forum Integration", + author = ".George & zaCade (Original by Botox)", + description = "Handles forum access ingame", + version = "1.2.1" +}; + +//---------------------------------------------------------------------------------------------------- +// Purpose: Late load +//---------------------------------------------------------------------------------------------------- +public void OnPluginStart() +{ + + /* Late load */ + for(int client = 1; client <= MaxClients; client++) + { + if(IsClientConnected(client)) + OnClientConnected(client); + + if(IsClientAuthorized(client) && !IsFakeClient(client)) + { + char sSteamID32[32]; + if(GetClientAuthId(client, AuthId_Steam2, sSteamID32, sizeof(sSteamID32))) + OnClientAuthorized(client, sSteamID32); + } + } +} + + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) +{ + CreateNative("AsyncHasSteamIDReservedSlot", Native_AsyncHasSteamIDReservedSlot); + CreateNative("GetClientForumName", Native_GetClientForumName); + + RegPluginLibrary("UNLOZE_ForumIntegration"); + + return APLRes_Success; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnRebuildAdminCache(AdminCachePart part) +{ + if (part != AdminCache_Admins) + return; + + CreateTimer(1.0, OnRebuildAdminCachePost, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Action OnRebuildAdminCachePost(Handle hTimer) +{ + for (int client = 1; client <= MaxClients; client++) + { + if(G_bResponsePassed[client] && G_bPreAdminChecked[client]) + ApplyGroupFlags(client); + } + return Plugin_Handled; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientConnected(int client) +{ + G_bPreAdminChecked[client] = false; + G_bResponseFailed[client] = false; + G_bResponsePassed[client] = false; + + G_sGroup[client][0] = 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientDisconnect(int client) +{ + G_bPreAdminChecked[client] = false; + G_bResponseFailed[client] = false; + G_bResponsePassed[client] = false; + + G_sGroup[client][0] = 0; + G_sName[client][0] = 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientAuthorized(int client, const char[] sSteamID32) +{ + if (IsFakeClient(client)) + return; + char sSteamID64[32]; + SteamID32toSteamID64(sSteamID32, sSteamID64, sizeof(sSteamID64)); + + char sRequest[256]; + FormatEx(sRequest, sizeof(sRequest), "https://unloze.com/api/private_api.php?api_key=%s&steam_id=%s", UNLOZE_APIKEY, sSteamID64); + + int iSerial = GetClientSerial(client); + Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); + if (!hRequest || + !SteamWorks_SetHTTPCallbacks(hRequest, OnClientAuthorized_OnTransferComplete) || + !SteamWorks_SetHTTPRequestContextValue(hRequest, iSerial) || + !SteamWorks_SendHTTPRequest(hRequest)) + { + delete hRequest; + } +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int OnClientAuthorized_OnTransferComplete(Handle hRequest, bool bFailure, bool bSuccessful, EHTTPStatusCode eStatusCode, int iSerial) +{ + int client = GetClientFromSerial(iSerial); + + if (!client) //Player disconnected. + { + delete hRequest; + return 0; + } + + if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK) + { + G_bResponseFailed[client] = true; + + if (G_bPreAdminChecked[client]) + NotifyPostAdminCheck(client); + + delete hRequest; + return 0; + } + + SteamWorks_GetHTTPResponseBodyCallback(hRequest, OnClientAuthorized_OnTransferResponse, iSerial); + return 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int OnClientAuthorized_OnTransferResponse(char[] sData, int iSerial) +{ + char splitData[2][32]; + + int client = GetClientFromSerial(iSerial); + + if (!client) //Player disconnected. + return 0; + + TrimString(sData); + StripQuotes(sData); + + ExplodeString(sData, "\r\n", splitData, 2, sizeof(splitData[])); + + if(strlen(splitData[1]) > 0) + strcopy(G_sName[client], sizeof(G_sName[]), splitData[1]); + + int not_counted_players = 0; + for (int i = 0; i < MaxClients; i++) + { + if (IsValidClient(i) && (IsClientAutismBot(i) || IsFakeClient(i))) + { + not_counted_players++; + } + } + int clientCount = GetClientCount(false) - not_counted_players; + if (clientCount <= 13) + { + //if less than some amount of players just give free vip. + strcopy(G_sGroup[client], sizeof(G_sGroup[]), "Game-Donator"); + G_bResponsePassed[client] = true; + + if (G_bPreAdminChecked[client]) + NotifyPostAdminCheck(client); + + } + else if(!StrEqual(splitData[0], "NOGROUP")) + { + strcopy(G_sGroup[client], sizeof(G_sGroup[]), splitData[0]); + + G_bResponsePassed[client] = true; + + if (G_bPreAdminChecked[client]) + NotifyPostAdminCheck(client); + } + else + G_bResponseFailed[client] = true; //users with just a forum name did not pass the VIP check! so the response "failed" (but we store their forum name for later!) + return 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Action OnClientPreAdminCheck(int client) +{ + G_bPreAdminChecked[client] = true; + + if (G_bResponsePassed[client] || G_bResponseFailed[client]) + return Plugin_Continue; + + RunAdminCacheChecks(client); + return Plugin_Handled; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnClientPostAdminFilter(int client) +{ + ApplyGroupFlags(client); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +stock void ApplyGroupFlags(int client) +{ + if (!G_bResponsePassed[client]) + return; + + AdminId AdmID; + GroupId GrpID; + + if ((AdmID = GetUserAdmin(client)) == INVALID_ADMIN_ID) + { + LogMessage("Creating new admin for %L", client); + + AdmID = CreateAdmin(); + SetUserAdmin(client, AdmID, true); + } + + + if ((GrpID = FindAdmGroup(G_sGroup[client])) != INVALID_GROUP_ID) + { + if (AdminInheritGroup(AdmID, GrpID)) + { + LogMessage("%L added to group %s", client, G_sGroup[client]); + } + } + else + { + LogMessage("%L group not found %s", client, G_sGroup[client]); + } +} + +public int Native_GetClientForumName(Handle plugin, int numParams) +{ + int len = GetNativeCell(2); + int client = GetNativeCell(1); + + SetNativeString(2, G_sName[client], len+1); + return 0; +} + + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int Native_AsyncHasSteamIDReservedSlot(Handle plugin, int numParams) +{ + char sSteamID32[32]; + GetNativeString(1, sSteamID32, sizeof(sSteamID32)); + + Function callback; //https://github.com/alliedmodders/sourcepawn/issues/778 + callback = GetNativeFunction(2); + + any data; + data = GetNativeCell(3); + + char sSteamID64[32]; + SteamID32toSteamID64(sSteamID32, sSteamID64, sizeof(sSteamID64)); + + char sRequest[256]; + FormatEx(sRequest, sizeof(sRequest), "https://unloze.com/api/private_api.php?api_key=%s&steam_id=%s", UNLOZE_APIKEY, sSteamID64); + + DataPack hDataPack = new DataPack(); + hDataPack.WriteString(sSteamID32); + hDataPack.WriteFunction(callback); + hDataPack.WriteCell(plugin); + hDataPack.WriteCell(data); + + Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); + if (!hRequest || + !SteamWorks_SetHTTPCallbacks(hRequest, Native_AsyncHasSteamIDReservedSlot_OnTransferComplete) || + !SteamWorks_SetHTTPRequestContextValue(hRequest, hDataPack) || + !SteamWorks_SendHTTPRequest(hRequest)) + { + delete hRequest; + } + return 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int Native_AsyncHasSteamIDReservedSlot_OnTransferComplete(Handle hRequest, bool bFailure, bool bSuccessful, EHTTPStatusCode eStatusCode, DataPack hDataPack) +{ + if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK) + { + char sData[32] = "NOGROUP"; + Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(sData, hDataPack); + + delete hRequest; + return 0; + } + + SteamWorks_GetHTTPResponseBodyCallback(hRequest, Native_AsyncHasSteamIDReservedSlot_OnTransferResponse, hDataPack); + return 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public int Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(char[] sData, DataPack hDataPack) +{ + hDataPack.Reset(); + + char sSteamID32[32]; + hDataPack.ReadString(sSteamID32, sizeof(sSteamID32)); + + Function callback; + callback = hDataPack.ReadFunction(); + + Handle plugin; + plugin = hDataPack.ReadCell(); + + any data; + data = hDataPack.ReadCell(); + + static char splitData[32]; + + TrimString(sData); + StripQuotes(sData); + + SplitString(sData, "\r\n", splitData, sizeof(splitData)); + + int result; + if (StrEqual(splitData, "Game-Donator", false)) + result = 1; + else + result = 0; + + Call_StartFunction(plugin, callback); + Call_PushString(sSteamID32); + Call_PushCell(result); + Call_PushCell(data); + Call_Finish(); + + delete hDataPack; + return 0; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +stock bool SteamID32toSteamID64(const char[] sSteamID32, char[] sSteamID64, int iSize) +{ + if (strlen(sSteamID32) < 11 || strncmp(sSteamID32[0], "STEAM_", 6)) + { + sSteamID64[0] = 0; + return false; + } + + int iUpper = 765611979; + int isSteam64ID = StringToInt(sSteamID32[10]) * 2 + 60265728 + sSteamID32[8] - 48; + + int iDiv = isSteam64ID / 100000000; + int iIdx = 9 - (iDiv ? (iDiv / 10 + 1) : 0); + + iUpper += iDiv; + + IntToString(isSteam64ID, sSteamID64[iIdx], iSize - iIdx); + iIdx = sSteamID64[9]; + + IntToString(iUpper, sSteamID64, iSize); + sSteamID64[9] = iIdx; + + return true; +} + +stock bool IsValidClient(int client) +{ + if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) + return true; + return false; +} + diff --git a/mapchooser_extended/scripting/mapchooser_extended_avg_mapend.sp b/mapchooser_extended/scripting/mapchooser_extended_avg_mapend.sp index b9f7b1b..752d890 100755 --- a/mapchooser_extended/scripting/mapchooser_extended_avg_mapend.sp +++ b/mapchooser_extended/scripting/mapchooser_extended_avg_mapend.sp @@ -555,10 +555,13 @@ public void OnMapStart() g_Config.Rewind(); //this does not detect obvioulsy when there is more or less than 15 players active because its the mapstart // nobody has connected yet. OnMapEnd also does not work for checking this. so no point setting it to false here. + /* if(InternalAreRestrictionsActive(true)) g_SaveCDOnMapEnd = true; else g_SaveCDOnMapEnd = false; + */ + g_SaveCDOnMapEnd = true; } public void OnConfigsExecuted() @@ -732,10 +735,13 @@ public Action Command_SetNextmap(int client, int args) g_MapVoteCompleted = true; //checking on MapStart and MapEnd is not good enough. Players are not considered alive and on teams at those points in time. //therefore instead applying the bool here after the mapvote completed. + /* if(InternalAreRestrictionsActive(false)) g_SaveCDOnMapEnd = true; else g_SaveCDOnMapEnd = false; + */ + g_SaveCDOnMapEnd = true; return Plugin_Handled; } @@ -1725,10 +1731,13 @@ public void Handler_VoteFinishedGeneric(char[] map, g_MapVoteCompleted = true; //checking on MapStart and MapEnd is not good enough. Players are not considered alive and on teams at those points in time. //therefore instead applying the bool here after the mapvote completed. + /* if(InternalAreRestrictionsActive(false)) g_SaveCDOnMapEnd = true; else g_SaveCDOnMapEnd = false; + */ + g_SaveCDOnMapEnd = true; //PrintToChatAll("map: %s", map); if (g_ChangeTime == MapChange_MapEnd) @@ -2094,20 +2103,21 @@ void CreateNextVote() delete OldMapListSnapshot; } - if(InternalAreRestrictionsActive(false)) + + //if(InternalAreRestrictionsActive(false)) + //{ + StringMapSnapshot TimeMapListSnapshot = g_TimeMapList.Snapshot(); + for(int i = 0; i < TimeMapListSnapshot.Length; i++) { - StringMapSnapshot TimeMapListSnapshot = g_TimeMapList.Snapshot(); - for(int i = 0; i < TimeMapListSnapshot.Length; i++) - { - TimeMapListSnapshot.GetKey(i, map, sizeof(map)); - int Cooldown; - g_TimeMapList.GetValue(map, Cooldown); + TimeMapListSnapshot.GetKey(i, map, sizeof(map)); + int Cooldown; + g_TimeMapList.GetValue(map, Cooldown); - if(Cooldown > GetTime()) - RemoveStringFromArray(tempMaps, map); - } - delete TimeMapListSnapshot; + if(Cooldown > GetTime()) + RemoveStringFromArray(tempMaps, map); } + delete TimeMapListSnapshot; + //} int voteSize = GetVoteSize(0); int limit = (voteSize < GetArraySize(tempMaps) ? voteSize : GetArraySize(tempMaps)); @@ -2153,12 +2163,16 @@ void CreateNextVote() { continue; } + if (InternalGetMapCooldownTime(map) > GetTime()) + continue; //requested by keen in september 2024 that we have a pool that is prioritized when taking random maps. //it might be considered micro management which would indeed be bad. i guess this is mostly about pleasing a regular players request //which does not seem too outlandish to make possible. pickedFromCasualPool++; break; } + if(InternalGetMapCooldownTime(map) > GetTime()) + continue; if(!InternalAreRestrictionsActive(false)) break; @@ -2166,8 +2180,6 @@ void CreateNextVote() if(InternalGetMapVIPRestriction(map)) continue; - if(InternalGetMapCooldownTime(map) > GetTime()) - continue; if(InternalGetMapTimeRestriction(map) != 0) continue;