#pragma semicolon 1 #include #if defined INFO_INCLUDES #include "../info/constants.sp" #include "../info/enums.sp" #include "../info/variables.sp" #endif /** * Initializes the server. * * @noreturn */ stock void Server_Initialize() { Log(TDLogLevel_Debug, "Initializing server"); StripConVarFlag("sv_cheats", FCVAR_NOTIFY); StripConVarFlag("sv_tags", FCVAR_NOTIFY); StripConVarFlag("tf_bot_count", FCVAR_NOTIFY); StripConVarFlag("sv_password", FCVAR_NOTIFY); HookButtons(); Server_Reset(); int iServerIp[4]; SteamWorks_GetPublicIP(iServerIp); Format(g_sServerIp, sizeof(g_sServerIp), "%d.%d.%d.%d", iServerIp[0], iServerIp[1], iServerIp[2], iServerIp[3]); char sServerPort[6]; GetConVarString(FindConVar("hostport"), sServerPort, sizeof(sServerPort)); g_iServerPort = StringToInt(sServerPort); if (StrEqual(g_sServerIp, "0.0.0.0")) { Log(TDLogLevel_Error, "ServerIP: %s", g_sServerIp); Log(TDLogLevel_Error, "Vac enabled?: %b", SteamWorks_IsVACEnabled()); Log(TDLogLevel_Error, "Is connected to Steam?: %b", SteamWorks_IsConnected()); Log(TDLogLevel_Error, "This can be caused by using GSLT with an expired Token. https://steamcommunity.com/dev/managegameservers"); Log(TDLogLevel_Error, "The server will loop indefinetly if it can't connect to Steam"); Log(TDLogLevel_Info, "Server has been restarted completely, reloading map for initializing"); ReloadMap(); } else { Database_CheckServer(); // Calls Database_OnServerChecked() when finished } } stock void Database_OnServerChecked() { Log(TDLogLevel_Trace, "Database_OnServerChecked"); Database_LoadData(); // Calls Database_OnDataLoaded() when finished } stock void Database_OnDataLoaded() { Log(TDLogLevel_Debug, "Successfully initialized server"); PrintToHudAll("WELCOME TO TF2 TOWER DEFENSE"); g_bServerInitialized = true; } /** * Resets the server. * * @noreturn */ stock void Server_Reset() { g_bEnabled = g_hEnabled.BoolValue && g_bTowerDefenseMap && g_bSteamWorks && g_bTF2Attributes; g_bMapRunning = true; UpdateGameDescription(); if (!g_bEnabled) { if (!g_bTowerDefenseMap) { char sCurrentMap[PLATFORM_MAX_PATH]; GetCurrentMap(sCurrentMap, sizeof(sCurrentMap)); Log(TDLogLevel_Info, "Map \"%s\" is not supported, thus Tower Defense has been disabled.", sCurrentMap); } else { Log(TDLogLevel_Info, "Tower Defense is disabled."); } return; } g_iBuildingLimit[TDBuilding_Sentry] = 1; g_iBuildingLimit[TDBuilding_Dispenser] = 0; g_iBuildingLimit[TDBuilding_TeleporterEntry] = 1; g_iBuildingLimit[TDBuilding_TeleporterExit] = 1; // Reset Hint Timer if (hHintTimer != null) { CloseHandle(hHintTimer); hHintTimer = null; } for (int iClient = 1; iClient <= MaxClients; iClient++) { // Reset carry Towers/Sentry if (IsTower(g_iAttachedTower[iClient])) { TF2Attrib_RemoveByName(iClient, "cannot pick up buildings"); g_iLastMover[g_iAttachedTower[iClient]] = 0; g_bCarryingObject[iClient] = false; g_iAttachedTower[iClient] = 0; } // Reset bought Towers if (IsTower(iClient)) { TDTowerId iTowerId = GetTowerId(iClient); // tf_bot_quota > 0 breaks this here if (iTowerId != TDTower_Invalid) { g_bTowerBought[view_as(iTowerId)] = false; } } if (IsAttacker(iClient) && g_iSlowAttacker[iClient]) { g_iSlowAttacker[iClient] = false; } if (IsDefender(iClient)) { g_bCarryingObject[iClient] = false; // Remove Beam if there is one if (g_iHealBeamIndex[iClient][0] != 0) { if (IsValidEdict(g_iHealBeamIndex[iClient][0])) { RemoveEdict(g_iHealBeamIndex[iClient][0]); g_iHealBeamIndex[iClient][0] = 0; } } if (g_iHealBeamIndex[iClient][1] != 0) { if (IsValidEdict(g_iHealBeamIndex[iClient][1])) { RemoveEdict(g_iHealBeamIndex[iClient][1]); g_iHealBeamIndex[iClient][1] = 0; } } } } // Reset Multipliers for (int i = 1; i <= iMaxMultiplierTypes; i++) { fMultiplier[i] = 0.0; } g_iTime = GetTime(); g_iMetalPackCount = 0; g_bTowersLocked = false; g_bAoEEngineerAttack = false; g_bStartWaveEarly = false; g_iBotsToSpawn = 0; g_iTotalBotsLeft = 0; g_iCurrentWave = 0; g_iNextWaveType = 0; iAoEEngineerTimer = 0; iAoEKritzMedicTimer = 0; g_iHealthBar = GetHealthBar(); g_bLockable = true; g_bCanGetUnlocks = true; // Reset AoE Timer if (hAoETimer != null) { CloseHandle(hAoETimer); hAoETimer = null; } // Get map max clients g_iMaxClients = PLAYER_LIMIT; char sQuery[256]; char sCurrentMap[PLATFORM_MAX_PATH]; GetCurrentMap(sCurrentMap, sizeof(sCurrentMap)); g_hDatabase.Format(sQuery, sizeof(sQuery), "SELECT `player_limit` " ... "FROM `map` " ... "WHERE `name` = '%s' " ... "LIMIT 1", sCurrentMap); DBResultSet queryResult = SQL_Query(g_hDatabase, sQuery); if (queryResult == null) { char error[255]; SQL_GetError(g_hDatabase, error, sizeof(error)); LogType(TDLogLevel_Error, TDLogType_FileAndConsole, "Failed to query (error: %s)", error); } else { if (queryResult.HasResults && queryResult.FetchRow()) { int iResult = queryResult.FetchInt(0); if (iResult > 0) { g_iMaxClients = iResult; LogType(TDLogLevel_Debug, TDLogType_FileAndConsole, "Max clients for map %s is %d", sCurrentMap, g_iMaxClients); } else { LogType(TDLogLevel_Error, TDLogType_FileAndConsole, "Max clients for map %s is %d. This isnt supported; Please check the database entries. Setting max clients to default %d", sCurrentMap, iResult, g_iMaxClients); } } else { LogType(TDLogLevel_Debug, TDLogType_FileAndConsole, "Couldn't find entry for map '%s'. Setting max clients to default %d", sCurrentMap, g_iMaxClients); } delete queryResult; } int clients = (g_iMaxClients + g_hMaxBotsOnField.IntValue) - MaxClients; if (clients > 0) { char cvarName[32]; g_hMaxBotsOnField.GetName(cvarName, sizeof(cvarName)); LogType(TDLogLevel_Warning, TDLogType_FileAndConsole, "ConVar '%s' value + the allowed max clients '%d' (database) is higher than the server maxplayers '%d'. Shrinking convar value by '%d'", cvarName, g_iMaxClients, MaxClients, clients); g_hMaxBotsOnField.IntValue = g_hMaxBotsOnField.IntValue - clients; } Format(g_sPassword, sizeof(g_sPassword), ""); SetPassword(g_sPassword, false); // Change upon release } /** * Called when a servers data was set. * * @param iServerId The server id (unique for every server). * @param sKey The set key. * @param iDataType The datatype of the set data. * @param iValue The value if the set data is an integer, -1 otherwise. * @param bValue The value if the set data is a boolean, false otherwise. * @param fValue The value if the set data is a float, -1.0 otherwise. * @param sValue The value if the set data is a string, empty string ("") otherwise. * @noreturn */ stock void Server_OnDataSet(int iServerId, const char[] sKey, TDDataType iDataType, int iValue, int bValue, float fValue, const char[] sValue) { switch (iDataType) { case TDDataType_Integer: { Log(TDLogLevel_Trace, "Server_OnDataSet: iServerId=%d, sKey=%s, iDataType=TDDataType_Integer, iValue=%d", iServerId, sKey, iValue); } case TDDataType_Boolean: { Log(TDLogLevel_Trace, "Server_OnDataSet: iServerId=%d, sKey=%s, iDataType=TDDataType_Boolean, bValue=%s", iServerId, sKey, (bValue ? "true" : "false")); } case TDDataType_Float: { Log(TDLogLevel_Trace, "Server_OnDataSet: iServerId=%d, sKey=%s, iDataType=TDDataType_Float, fValue=%f", iServerId, sKey, fValue); } case TDDataType_String: { Log(TDLogLevel_Trace, "Server_OnDataSet: iServerId=%d, sKey=%s, iDataType=TDDataType_String, sValue=%s", iServerId, sKey, sValue); } } } stock void Server_UAddValue(int iServerId, const char[] sKey, int iValue) { char sServerIdKey[128]; int iOldValue; Server_UGetValue(iServerId, sKey, iOldValue); if (iOldValue != -1) iValue = iValue + iOldValue; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Server_OnDataSet(iServerId, sKey, TDDataType_Integer, iValue, false, -1.0, ""); SetTrieValue(g_hServerData, sServerIdKey, iValue); } stock void Server_USetValue(int iServerId, const char[] sKey, int iValue) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Server_OnDataSet(iServerId, sKey, TDDataType_Integer, iValue, false, -1.0, ""); SetTrieValue(g_hServerData, sServerIdKey, iValue); } stock bool Server_UGetValue(int iServerId, const char[] sKey, int &iValue) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Log(TDLogLevel_Trace, "Server_UGetValue: iServerId=%d, sKey=%s", iServerId, sKey); if (!GetTrieValue(g_hServerData, sServerIdKey, iValue)) { iValue = -1; return false; } return true; } stock void Server_USetBool(int iServerId, const char[] sKey, bool bValue) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Server_OnDataSet(iServerId, sKey, TDDataType_Integer, -1, bValue, -1.0, ""); SetTrieValue(g_hServerData, sServerIdKey, (bValue ? 1 : 0)); } stock bool Server_UGetBool(int iServerId, const char[] sKey) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Log(TDLogLevel_Trace, "Server_UGetBool: iServerId=%d, sKey=%s", iServerId, sKey); int iValue = 0; GetTrieValue(g_hServerData, sServerIdKey, iValue); return (iValue != 0); } stock void Server_USetFloat(int iServerId, const char[] sKey, float fValue) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); char sValue[64]; FloatToString(fValue, sValue, sizeof(sValue)); Server_OnDataSet(iServerId, sKey, TDDataType_Integer, -1, false, fValue, ""); SetTrieString(g_hServerData, sServerIdKey, sValue); } stock bool Server_UGetFloat(int iServerId, const char[] sKey, float &fValue) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Log(TDLogLevel_Trace, "Server_UGetFloat: iServerId=%d, sKey=%s", iServerId, sKey); char sValue[64]; if (!GetTrieString(g_hServerData, sServerIdKey, sValue, sizeof(sValue))) { fValue = -1.0; return false; } fValue = StringToFloat(sValue); return true; } stock void Server_USetString(int iServerId, const char[] sKey, const char[] sValue, any...) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); char sFormattedValue[256]; VFormat(sFormattedValue, sizeof(sFormattedValue), sValue, 4); Server_OnDataSet(iServerId, sKey, TDDataType_String, -1, false, -1.0, sValue); SetTrieString(g_hServerData, sServerIdKey, sFormattedValue); } stock bool Server_UGetString(int iServerId, const char[] sKey, char[] sValue, int iMaxLength) { char sServerIdKey[128]; Format(sServerIdKey, sizeof(sServerIdKey), "%d_%s", iServerId, sKey); Log(TDLogLevel_Trace, "Server_UGetString: iServerId=%d, sKey=%s, iMaxLength=%d", iServerId, sKey, iMaxLength); if (!GetTrieString(g_hServerData, sServerIdKey, sValue, iMaxLength)) { Format(sValue, iMaxLength, ""); return false; } return true; }