2016-01-19 23:57:32 +01:00
/ * *
* vim : set ts = 4 :
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Nominations Extended
* Allows players to nominate maps for Mapchooser
*
* Nominations Extended ( C ) 2012 - 2013 Powerlord ( Ross Bemrose )
* SourceMod ( C ) 2004 - 2007 AlliedModders LLC . All rights reserved .
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* This program is free software ; you can redistribute it and / or modify it under
* the terms of the GNU General Public License , version 3.0 , as published by the
* Free Software Foundation .
*
* 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 < http : //www.gnu.org/licenses/>.
*
* As a special exception , AlliedModders LLC gives you permission to link the
* code of this program ( as well as its derivative works ) to " Half-Life 2, " the
* " Source Engine, " the " SourcePawn JIT, " and any Game MODs that run on software
* by the Valve Corporation . You must obey the GNU General Public License in
* all respects for all other code used . Additionally , AlliedModders LLC grants
* this exception to all derivative works . AlliedModders LLC defines further
* exceptions , found in LICENSE . txt ( as of this writing , version JULY - 31 - 2007 ) ,
* or < http : //www.sourcemod.net/license.php>.
*
* Version : $ Id $
* /
# pragma semicolon 1
2016-08-11 17:48:20 +02:00
# pragma newdecls required
2016-01-19 23:57:32 +01:00
2017-02-26 00:16:12 +01:00
# include <sourcemod>
# include <mapchooser>
# include <mapchooser_extended>
# include <multicolors>
2018-04-13 22:21:36 +02:00
# include <basecomm>
2017-02-26 00:16:12 +01:00
2019-12-22 14:10:01 +01:00
# define MCE_VERSION "1.3.1"
2016-01-19 23:57:32 +01:00
2016-08-11 17:48:20 +02:00
public Plugin myinfo =
2016-01-19 23:57:32 +01:00
{
name = " Map Nominations Extended " ,
author = " Powerlord and AlliedModders LLC " ,
description = " Provides Map Nominations " ,
version = MCE_VERSION ,
url = " https://forums.alliedmods.net/showthread.php?t=156974 "
} ;
2016-08-11 17:48:20 +02:00
Handle g_Cvar_ExcludeOld = INVALID_HANDLE ;
Handle g_Cvar_ExcludeCurrent = INVALID_HANDLE ;
2016-01-19 23:57:32 +01:00
2016-08-11 17:48:20 +02:00
Handle g_MapList = INVALID_HANDLE ;
Handle g_AdminMapList = INVALID_HANDLE ;
2016-12-19 08:34:52 +01:00
Menu g_MapMenu ;
Menu g_AdminMapMenu ;
2016-08-11 17:48:20 +02:00
int g_mapFileSerial = - 1 ;
int g_AdminMapFileSerial = - 1 ;
2016-01-19 23:57:32 +01:00
# define MAPSTATUS_ENABLED (1<<0)
# define MAPSTATUS_DISABLED (1<<1)
# define MAPSTATUS_EXCLUDE_CURRENT (1<<2)
# define MAPSTATUS_EXCLUDE_PREVIOUS (1<<3)
# define MAPSTATUS_EXCLUDE_NOMINATED (1<<4)
2016-08-11 17:48:20 +02:00
Handle g_mapTrie ;
2016-01-19 23:57:32 +01:00
// Nominations Extended Convars
2016-08-11 17:48:20 +02:00
Handle g_Cvar_MarkCustomMaps = INVALID_HANDLE ;
Handle g_Cvar_NominateDelay = INVALID_HANDLE ;
Handle g_Cvar_InitialDelay = INVALID_HANDLE ;
2018-07-27 21:27:42 +02:00
2018-09-20 11:32:50 +02:00
// VIP Nomination Convars
Handle g_Cvar_VIPTimeframe = INVALID_HANDLE ;
Handle g_Cvar_VIPTimeframeMinTime = INVALID_HANDLE ;
Handle g_Cvar_VIPTimeframeMaxTime = INVALID_HANDLE ;
2016-08-11 17:48:20 +02:00
int g_Player_NominationDelay [ MAXPLAYERS + 1 ] ;
int g_NominationDelay ;
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
//clients ignoring maps that are unavailable
bool g_bClientsIgnoring [ MAXPLAYERS + 1 ] ;
Database g_dDatabase ;
2016-08-11 17:48:20 +02:00
public void OnPluginStart ( )
2016-01-19 23:57:32 +01:00
{
2023-03-31 19:06:56 +02:00
LoadTranslations ( " common.phrases " ) ;
LoadTranslations ( " nominations.phrases " ) ;
LoadTranslations ( " basetriggers.phrases " ) ; // for Next Map phrase
LoadTranslations ( " mapchooser_extended.phrases " ) ;
int arraySize = ByteCountToCells ( PLATFORM_MAX_PATH ) ;
g_MapList = CreateArray ( arraySize ) ;
g_AdminMapList = CreateArray ( arraySize ) ;
g_Cvar_ExcludeOld = CreateConVar ( " sm_nominate_excludeold " , " 1 " , " Specifies if the current map should be excluded from the Nominations list " , 0 , true , 0.00 , true , 1.0 ) ;
g_Cvar_ExcludeCurrent = CreateConVar ( " sm_nominate_excludecurrent " , " 1 " , " Specifies if the MapChooser excluded maps should also be excluded from Nominations " , 0 , true , 0.00 , true , 1.0 ) ;
g_Cvar_InitialDelay = CreateConVar ( " sm_nominate_initialdelay " , " 60.0 " , " Time in seconds before first Nomination can be made " , 0 , true , 0.00 ) ;
g_Cvar_NominateDelay = CreateConVar ( " sm_nominate_delay " , " 3.0 " , " Delay between nominations " , 0 , true , 0.00 , true , 60.00 ) ;
g_Cvar_VIPTimeframe = CreateConVar ( " sm_nominate_vip_timeframe " , " 1 " , " Specifies if the should be a timeframe where only VIPs can nominate maps " , 0 , true , 0.00 , true , 1.0 ) ;
g_Cvar_VIPTimeframeMinTime = CreateConVar ( " sm_nominate_vip_timeframe_mintime " , " 1800 " , " Start of the timeframe where only VIPs can nominate maps (Format: HHMM) " , 0 , true , 0000.00 , true , 2359.0 ) ;
g_Cvar_VIPTimeframeMaxTime = CreateConVar ( " sm_nominate_vip_timeframe_maxtime " , " 2200 " , " End of the timeframe where only VIPs can nominate maps (Format: HHMM) " , 0 , true , 0000.00 , true , 2359.0 ) ;
RegConsoleCmd ( " say " , Command_Say ) ;
RegConsoleCmd ( " say_team " , Command_Say ) ;
RegConsoleCmd ( " sm_nominate " , Command_Nominate ) ;
RegConsoleCmd ( " sm_nom " , Command_Nominate ) ;
RegConsoleCmd ( " sm_nomlist " , Command_NominateList ) ;
RegAdminCmd ( " sm_nominate_addmap " , Command_Addmap , ADMFLAG_CHANGEMAP , " sm_nominate_addmap <mapname> - Forces a map to be on the next mapvote. " ) ;
RegAdminCmd ( " sm_nominate_removemap " , Command_Removemap , ADMFLAG_CHANGEMAP , " sm_nominate_removemap <mapname> - Removes a map from Nominations. " ) ;
RegAdminCmd ( " sm_nominate_exclude " , Command_AddExclude , ADMFLAG_CHANGEMAP , " sm_nominate_exclude <mapname> [cooldown] [mode]- Forces a map to be inserted into the recently played maps. Effectively blocking the map from being nominated. " ) ;
RegAdminCmd ( " sm_nominate_exclude_time " , Command_AddExcludeTime , ADMFLAG_CHANGEMAP , " sm_nominate_exclude_time <mapname> [cooldown] [mode] - Forces a map to be inserted into the recently played maps. Effectively blocking the map from being nominated. " ) ;
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
// Nominations Extended cvars
CreateConVar ( " ne_version " , MCE_VERSION , " Nominations Extended Version " , FCVAR_SPONLY | FCVAR_NOTIFY | FCVAR_DONTRECORD ) ;
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
g_mapTrie = CreateTrie ( ) ;
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
//DB
if ( ! g_dDatabase )
{
//we have too many dbs so i am just re-using racetimercss
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
}
}
public void SQL_OnDatabaseConnect ( Database db , const char [ ] error , any data )
{
if ( ! db | | strlen ( error ) )
{
LogError ( " Database error: %s " , error ) ;
return ;
}
g_dDatabase = db ;
}
2018-09-20 11:32:50 +02:00
2023-03-31 19:06:56 +02:00
public void OnClientPostAdminCheck ( int client )
{
g_bClientsIgnoring [ client ] = false ;
sql_select_hiding_unavailable_maps ( client ) ;
}
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
public void sql_select_hiding_unavailable_maps ( int client )
{
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
return ;
}
char query [ 255 ] ;
char steam_auth [ 64 ] ;
GetClientAuthId ( client , AuthId_Steam2 , steam_auth , sizeof ( steam_auth ) ) ;
//we have way too many dbs, just adding this to unloze_race_timer
Format ( query , sizeof ( query ) , " SELECT is_ignoring FROM `mapchooser_hide_unavailable` where steam_auth = '%s' " , steam_auth ) ;
g_dDatabase . Query ( SQL_OnQueryCompleted_ignoring , query , client ) ;
}
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
public void SQL_OnQueryCompleted_ignoring ( Database db , DBResultSet results , const char [ ] error , int client )
{
if ( ! db )
{
return ;
}
if ( client > 0 & & client < = MaxClients & & IsClientConnected ( client ) & & IsClientInGame ( client ) )
{
int val = 0 ;
if ( results . RowCount & & results . FetchRow ( ) )
val = results . FetchInt ( 0 ) ;
if ( val = = 1 )
{
g_bClientsIgnoring [ client ] = true ;
}
}
}
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
public void sql_insert_update_hiding_unavailable ( int client )
{
if ( client > 0 & & client < = MaxClients & & IsClientConnected ( client ) & & IsClientInGame ( client ) )
{
if ( g_bClientsIgnoring [ client ] )
{
g_bClientsIgnoring [ client ] = false ;
}
else
{
g_bClientsIgnoring [ client ] = true ;
}
char sSID [ 64 ] ;
char sQuery [ 256 ] ;
GetClientAuthId ( client , AuthId_Steam2 , sSID , sizeof ( sSID ) ) ;
if ( ! g_dDatabase )
{
Database . Connect ( SQL_OnDatabaseConnect , " racetimercss " ) ;
return ;
}
if ( StrEqual ( sSID , " STEAM_ID_STOP_IGNORING_RETVALS " ) | | StrEqual ( sSID , " STEAM_ID_PENDING " ) )
{
PrintToChat ( client , " Your steam ID is not working, not updating " ) ;
return ;
}
Format ( sQuery , sizeof ( sQuery ) , " INSERT INTO `mapchooser_hide_unavailable` (`steam_auth`, `is_ignoring`) VALUES ('%s', '%i') ON DUPLICATE KEY UPDATE `is_ignoring` = '%i' " , sSID , g_bClientsIgnoring [ client ] , g_bClientsIgnoring [ client ] ) ;
DataPack hDataPack = new DataPack ( ) ;
hDataPack . WriteString ( sQuery ) ;
g_dDatabase . Query ( SQL_FinishedQuery , sQuery , hDataPack , DBPrio_Normal ) ;
}
}
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
public void SQL_FinishedQuery ( Database db , DBResultSet results , const char [ ] error , DataPack data )
{
if ( ! db | | strlen ( error ) )
{
char sQuery [ 256 ] ;
ResetPack ( data ) ;
data . ReadString ( sQuery , sizeof ( sQuery ) ) ;
LogError ( " Query error 3: %s " , error ) ;
LogError ( " actual query: %s " , sQuery ) ;
}
delete data ;
}
2016-01-19 23:57:32 +01:00
2023-03-31 19:06:56 +02:00
public void OnClientDisconnect ( int client )
{
g_bClientsIgnoring [ client ] = false ;
2016-01-19 23:57:32 +01:00
}
2018-03-20 01:05:31 +01:00
public APLRes AskPluginLoad2 ( Handle hThis , bool bLate , char [ ] err , int iErrLen )
{
RegPluginLibrary ( " nominations " ) ;
CreateNative ( " GetNominationPool " , Native_GetNominationPool ) ;
CreateNative ( " PushMapIntoNominationPool " , Native_PushMapIntoNominationPool ) ;
CreateNative ( " PushMapsIntoNominationPool " , Native_PushMapsIntoNominationPool ) ;
CreateNative ( " RemoveMapFromNominationPool " , Native_RemoveMapFromNominationPool ) ;
CreateNative ( " RemoveMapsFromNominationPool " , Native_RemoveMapsFromNominationPool ) ;
return APLRes_Success ;
}
2016-08-11 17:48:20 +02:00
public void OnAllPluginsLoaded ( )
2016-01-19 23:57:32 +01:00
{
// This is an MCE cvar... this plugin requires MCE to be loaded. Granted, this plugin SHOULD have an MCE dependency.
g_Cvar_MarkCustomMaps = FindConVar ( " mce_markcustommaps " ) ;
}
2016-08-11 17:48:20 +02:00
public void OnConfigsExecuted ( )
2016-01-19 23:57:32 +01:00
{
2016-08-11 17:48:20 +02:00
if ( ReadMapList ( g_MapList ,
2016-01-19 23:57:32 +01:00
g_mapFileSerial ,
" nominations " ,
MAPLIST_FLAG_CLEARARRAY | MAPLIST_FLAG_MAPSFOLDER )
= = INVALID_HANDLE )
{
2016-08-11 17:48:20 +02:00
if ( g_mapFileSerial = = - 1 )
2016-01-19 23:57:32 +01:00
{
SetFailState ( " Unable to create a valid map list. " ) ;
}
}
2016-12-19 08:34:52 +01:00
2016-08-11 17:48:20 +02:00
if ( ReadMapList ( g_AdminMapList ,
2016-01-19 23:57:32 +01:00
g_AdminMapFileSerial ,
" sm_nominate_addmap menu " ,
MAPLIST_FLAG_CLEARARRAY | MAPLIST_FLAG_NO_DEFAULT | MAPLIST_FLAG_MAPSFOLDER )
= = INVALID_HANDLE )
{
2016-08-11 17:48:20 +02:00
if ( g_AdminMapFileSerial = = - 1 )
2016-01-19 23:57:32 +01:00
{
SetFailState ( " Unable to create a valid admin map list. " ) ;
}
}
else
{
2016-08-11 17:48:20 +02:00
for ( int i = 0 ; i < GetArraySize ( g_MapList ) ; i + + )
2016-01-19 23:57:32 +01:00
{
2016-08-11 17:48:20 +02:00
static char map [ PLATFORM_MAX_PATH ] ;
2016-01-19 23:57:32 +01:00
GetArrayString ( g_MapList , i , map , sizeof ( map ) ) ;
2016-08-11 17:48:20 +02:00
int Index = FindStringInArray ( g_AdminMapList , map ) ;
if ( Index ! = - 1 )
2016-01-19 23:57:32 +01:00
RemoveFromArray ( g_AdminMapList , Index ) ;
}
}
g_NominationDelay = GetTime ( ) + GetConVarInt ( g_Cvar_InitialDelay ) ;
2018-03-20 01:05:31 +01:00
UpdateMapTrie ( ) ;
UpdateMapMenus ( ) ;
}
void UpdateMapMenus ( )
{
2023-01-27 21:07:48 +01:00
g_MapMenu = BuildMapMenu ( " " , 0 ) ;
2018-03-20 01:05:31 +01:00
g_AdminMapMenu = BuildAdminMapMenu ( " " ) ;
}
void UpdateMapTrie ( )
{
2016-12-19 08:34:52 +01:00
static char map [ PLATFORM_MAX_PATH ] ;
static char currentMap [ PLATFORM_MAX_PATH ] ;
ArrayList excludeMaps ;
if ( GetConVarBool ( g_Cvar_ExcludeOld ) )
{
excludeMaps = CreateArray ( ByteCountToCells ( PLATFORM_MAX_PATH ) ) ;
GetExcludeMapList ( excludeMaps ) ;
}
if ( GetConVarBool ( g_Cvar_ExcludeCurrent ) )
GetCurrentMap ( currentMap , sizeof ( currentMap ) ) ;
ClearTrie ( g_mapTrie ) ;
2018-03-20 01:05:31 +01:00
2016-12-19 08:34:52 +01:00
for ( int i = 0 ; i < GetArraySize ( g_MapList ) ; i + + )
{
int status = MAPSTATUS_ENABLED ;
GetArrayString ( g_MapList , i , map , sizeof ( map ) ) ;
if ( GetConVarBool ( g_Cvar_ExcludeCurrent ) )
{
if ( StrEqual ( map , currentMap ) )
status = MAPSTATUS_DISABLED | MAPSTATUS_EXCLUDE_CURRENT ;
}
/* Dont bother with this check if the current map check passed */
if ( GetConVarBool ( g_Cvar_ExcludeOld ) & & status = = MAPSTATUS_ENABLED )
{
if ( FindStringInArray ( excludeMaps , map ) ! = - 1 )
status = MAPSTATUS_DISABLED | MAPSTATUS_EXCLUDE_PREVIOUS ;
}
SetTrieValue ( g_mapTrie , map , status ) ;
}
if ( excludeMaps )
delete excludeMaps ;
2016-01-19 23:57:32 +01:00
}
2023-03-23 22:25:20 +01:00
public void OnNominationRemoved ( const char [ ] map )
2016-01-19 23:57:32 +01:00
{
2023-01-27 21:07:48 +01:00
int status ;
/* Is the map in our list? */
if ( ! GetTrieValue ( g_mapTrie , map , status ) )
return ;
2016-01-19 23:57:32 +01:00
2023-01-27 21:07:48 +01:00
/* Was the map disabled due to being nominated */
if ( ( status & MAPSTATUS_EXCLUDE_NOMINATED ) ! = MAPSTATUS_EXCLUDE_NOMINATED )
return ;
2016-01-19 23:57:32 +01:00
2023-01-27 21:07:48 +01:00
SetTrieValue ( g_mapTrie , map , MAPSTATUS_ENABLED ) ;
2016-01-19 23:57:32 +01:00
}
2016-08-11 17:48:20 +02:00
public Action Command_Addmap ( int client , int args )
2016-01-19 23:57:32 +01:00
{
2023-04-09 13:57:09 +02:00
if ( args = = 0 )
{
AttemptAdminNominate ( client ) ;
return Plugin_Handled ;
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
if ( args ! = 1 )
{
CReplyToCommand ( client , " [NE] Usage: sm_nominate_addmap <mapname> " ) ;
return Plugin_Handled ;
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
static char mapname [ PLATFORM_MAX_PATH ] ;
GetCmdArg ( 1 , mapname , sizeof ( mapname ) ) ;
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
if ( ! IsMapValid ( mapname ) )
{
CReplyToCommand ( client , " %t " , " Map was not found " , mapname ) ;
AttemptAdminNominate ( client , mapname ) ;
return Plugin_Handled ;
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
if ( ! CheckCommandAccess ( client , " sm_nominate_ignore " , ADMFLAG_CHEATS , true ) )
{
bool RestrictionsActive = AreRestrictionsActive ( ) ;
2019-09-18 12:36:08 +02:00
2023-04-09 13:57:09 +02:00
int status ;
if ( GetTrieValue ( g_mapTrie , mapname , status ) )
{
if ( ( status & MAPSTATUS_DISABLED ) = = MAPSTATUS_DISABLED )
{
if ( ( status & MAPSTATUS_EXCLUDE_CURRENT ) = = MAPSTATUS_EXCLUDE_CURRENT )
CPrintToChat ( client , " [NE] %t " , " Cant Nominate Current Map " ) ;
2016-08-11 17:48:20 +02:00
2023-04-09 13:57:09 +02:00
if ( RestrictionsActive & & ( status & MAPSTATUS_EXCLUDE_PREVIOUS ) = = MAPSTATUS_EXCLUDE_PREVIOUS )
{
int Cooldown = GetMapCooldown ( mapname ) ;
CPrintToChat ( client , " [NE] %t (%d) " , " Map in Exclude List " , Cooldown ) ;
}
2019-09-18 16:58:30 +02:00
2023-04-09 13:57:09 +02:00
if ( ( status & MAPSTATUS_EXCLUDE_NOMINATED ) = = MAPSTATUS_EXCLUDE_NOMINATED )
CPrintToChat ( client , " [NE] %t " , " Map Already Nominated " ) ;
2019-09-18 16:58:30 +02:00
2023-04-09 13:57:09 +02:00
return Plugin_Handled ;
}
}
2017-10-12 21:52:19 +02:00
2023-04-09 13:57:09 +02:00
int Cooldown = GetMapCooldownTime ( mapname ) ;
if ( RestrictionsActive & & Cooldown > GetTime ( ) )
{
int Seconds = Cooldown - GetTime ( ) ;
CPrintToChat ( client , " [NE] %t " , " Map Cooldown Time Error " , Seconds / 3600 , ( Seconds % 3600 ) / 60 ) ;
2017-10-12 21:52:19 +02:00
2023-04-09 13:57:09 +02:00
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
2023-04-09 13:57:09 +02:00
int TimeRestriction = GetMapTimeRestriction ( mapname ) ;
if ( RestrictionsActive & & TimeRestriction )
{
CPrintToChat ( client , " [NE] %t " , " Map Nominate Time Error " , TimeRestriction / 60 , TimeRestriction % 60 ) ;
2016-08-11 17:48:20 +02:00
2023-04-09 13:57:09 +02:00
return Plugin_Handled ;
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
int AverageHourRestricted = GetAveragePlayerTimeOnServerMapRestriction ( mapname ) ;
if ( AverageHourRestricted > 0 )
{
PrintToChat ( client , " %s requires +%i hours average. Use sm_houravg to check average. " , mapname , AverageHourRestricted ) ;
return Plugin_Handled ;
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
int PlayerRestriction = GetMapPlayerRestriction ( mapname ) ;
if ( RestrictionsActive & & PlayerRestriction )
{
if ( PlayerRestriction < 0 )
CPrintToChat ( client , " [NE] %t " , " Map Nominate MinPlayers Error " , PlayerRestriction * - 1 ) ;
else
CPrintToChat ( client , " [NE] %t " , " Map Nominate MaxPlayers Error " , PlayerRestriction ) ;
return Plugin_Handled ;
}
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
NominateResult result = NominateMap ( mapname , true , 0 ) ;
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
if ( result > Nominate_Replaced )
{
/* We assume already in vote is the casue because the maplist does a Map Validity check and we forced, so it cant be full */
CReplyToCommand ( client , " %t " , " Map Already In Vote " , mapname ) ;
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
return Plugin_Handled ;
}
2016-01-19 23:57:32 +01:00
2023-04-09 13:57:09 +02:00
SetTrieValue ( g_mapTrie , mapname , MAPSTATUS_DISABLED | MAPSTATUS_EXCLUDE_NOMINATED ) ;
CReplyToCommand ( client , " %t " , " Map Inserted " , mapname ) ;
LogAction ( client , - 1 , " \" %L \" inserted map \" %s \" . " , client , mapname ) ;
PrintToChatAll ( " [NE] %N has inserted %s into nominations " , client , mapname ) ;
return Plugin_Handled ;
2016-01-19 23:57:32 +01:00
}
2016-08-11 17:48:20 +02:00
public Action Command_Removemap ( int client , int args )
2016-04-26 12:36:03 +02:00
{
2019-12-22 14:10:01 +01:00
if ( args = = 0 & & client > 0 )
{
AttemptAdminRemoveMap ( client ) ;
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
if ( args ! = 1 )
2016-04-26 12:36:03 +02:00
{
CReplyToCommand ( client , " [NE] Usage: sm_nominate_removemap <mapname> " ) ;
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
static char mapname [ PLATFORM_MAX_PATH ] ;
2016-04-26 12:36:03 +02:00
GetCmdArg ( 1 , mapname , sizeof ( mapname ) ) ;
2016-08-11 17:48:20 +02:00
// int status;
if ( /*!GetTrieValue(g_mapTrie, mapname, status)*/ ! IsMapValid ( mapname ) )
2016-04-26 12:36:03 +02:00
{
CReplyToCommand ( client , " %t " , " Map was not found " , mapname ) ;
2019-12-22 14:10:01 +01:00
AttemptAdminRemoveMap ( client , mapname ) ;
2016-04-26 12:36:03 +02:00
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
if ( ! RemoveNominationByMap ( mapname ) )
2016-04-26 12:36:03 +02:00
{
2023-01-27 21:07:48 +01:00
CReplyToCommand ( client , " This map isnt nominated. " , mapname ) ;
2016-04-26 12:36:03 +02:00
return Plugin_Handled ;
}
CReplyToCommand ( client , " Map '%s' removed from the nominations list. " , mapname ) ;
LogAction ( client , - 1 , " \" %L \" removed map \" %s \" from nominations. " , client , mapname ) ;
PrintToChatAll ( " [NE] %N has removed %s from nominations " , client , mapname ) ;
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
public Action Command_AddExclude ( int client , int args )
2016-01-19 23:57:32 +01:00
{
2016-08-11 17:48:20 +02:00
if ( args < 1 )
2016-01-19 23:57:32 +01:00
{
2019-09-18 16:58:30 +02:00
CReplyToCommand ( client , " [NE] Usage: sm_nominate_exclude <mapname> [cooldown] [mode] " ) ;
2016-01-19 23:57:32 +01:00
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
static char mapname [ PLATFORM_MAX_PATH ] ;
2016-01-19 23:57:32 +01:00
GetCmdArg ( 1 , mapname , sizeof ( mapname ) ) ;
2016-12-05 18:50:44 +01:00
int cooldown = 0 ;
int mode = 0 ;
if ( args > = 2 )
{
static char buffer [ 8 ] ;
GetCmdArg ( 2 , buffer , sizeof ( buffer ) ) ;
cooldown = StringToInt ( buffer ) ;
}
if ( args > = 3 )
{
static char buffer [ 8 ] ;
GetCmdArg ( 3 , buffer , sizeof ( buffer ) ) ;
mode = StringToInt ( buffer ) ;
}
2016-08-11 17:48:20 +02:00
int status ;
2016-01-19 23:57:32 +01:00
if ( ! GetTrieValue ( g_mapTrie , mapname , status ) )
{
ReplyToCommand ( client , " [NE] %t " , " Map was not found " , mapname ) ;
return Plugin_Handled ;
}
ShowActivity ( client , " Excluded map \" %s \" from nomination " , mapname ) ;
LogAction ( client , - 1 , " \" %L \" excluded map \" %s \" from nomination " , client , mapname ) ;
SetTrieValue ( g_mapTrie , mapname , MAPSTATUS_DISABLED | MAPSTATUS_EXCLUDE_PREVIOUS ) ;
// native call to mapchooser_extended
2016-12-05 18:50:44 +01:00
ExcludeMap ( mapname , cooldown , mode ) ;
2016-01-19 23:57:32 +01:00
return Plugin_Handled ;
}
2019-09-18 16:58:30 +02:00
public Action Command_AddExcludeTime ( int client , int args )
{
if ( args < 1 )
{
CReplyToCommand ( client , " [NE] Usage: sm_nominate_exclude_time <mapname> [cooldown] [mode] " ) ;
return Plugin_Handled ;
}
static char mapname [ PLATFORM_MAX_PATH ] ;
GetCmdArg ( 1 , mapname , sizeof ( mapname ) ) ;
int cooldown = 0 ;
int mode = 0 ;
if ( args > = 2 )
{
static char buffer [ 16 ] ;
GetCmdArg ( 2 , buffer , sizeof ( buffer ) ) ;
cooldown = TimeStrToSeconds ( buffer ) ;
}
if ( args > = 3 )
{
static char buffer [ 8 ] ;
GetCmdArg ( 3 , buffer , sizeof ( buffer ) ) ;
mode = StringToInt ( buffer ) ;
}
int status ;
if ( ! GetTrieValue ( g_mapTrie , mapname , status ) )
{
ReplyToCommand ( client , " [NE] %t " , " Map was not found " , mapname ) ;
return Plugin_Handled ;
}
ShowActivity ( client , " ExcludedTime map \" %s \" from nomination " , mapname ) ;
LogAction ( client , - 1 , " \" %L \" excludedTime map \" %s \" from nomination " , client , mapname ) ;
// native call to mapchooser_extended
ExcludeMapTime ( mapname , cooldown , mode ) ;
return Plugin_Handled ;
}
2016-08-11 17:48:20 +02:00
public Action Command_Say ( int client , int args )
2016-01-19 23:57:32 +01:00
{
2016-08-11 17:48:20 +02:00
if ( ! client )
2016-01-19 23:57:32 +01:00
return Plugin_Continue ;
2016-08-11 17:48:20 +02:00
static char text [ 192 ] ;
if ( ! GetCmdArgString ( text , sizeof ( text ) ) )
2016-01-19 23:57:32 +01:00
return Plugin_Continue ;
2016-08-11 17:48:20 +02:00
int startidx = 0 ;
2016-01-19 23:57:32 +01:00
if ( text [ strlen ( text ) - 1 ] = = '"' )
{
text [ strlen ( text ) - 1 ] = '\0' ;
startidx = 1 ;
}
2016-08-11 17:48:20 +02:00
ReplySource old = SetCmdReplySource ( SM_REPLY_TO_CHAT ) ;
2016-01-19 23:57:32 +01:00
2016-08-11 17:48:20 +02:00
if ( strcmp ( text [ startidx ] , " nominate " , false ) = = 0 )
2016-01-19 23:57:32 +01:00
{
2016-08-11 17:48:20 +02:00
if ( IsNominateAllowed ( client ) )
2016-01-19 23:57:32 +01:00
{
2016-08-11 17:48:20 +02:00
if ( g_NominationDelay > GetTime ( ) )
2016-01-19 23:57:32 +01:00
ReplyToCommand ( client , " [NE] Nominations will be unlocked in %d seconds " , g_NominationDelay - GetTime ( ) ) ;
else
AttemptNominate ( client ) ;
}
}
SetCmdReplySource ( old ) ;
return Plugin_Continue ;
}
2016-08-11 17:48:20 +02:00
public Action Command_Nominate ( int client , int args )
2016-01-19 23:57:32 +01:00
{
2023-01-27 21:07:48 +01:00
if ( ! client | | ! IsNominateAllowed ( client ) )
return Plugin_Handled ;
if ( g_NominationDelay > GetTime ( ) )
{
PrintToChat ( client , " [NE] Nominations will be unlocked in %d seconds " , g_NominationDelay - GetTime ( ) ) ;
return Plugin_Handled ;
}
if ( args = = 0 )
{
AttemptNominate ( client ) ;
return Plugin_Handled ;
}
if ( g_Player_NominationDelay [ client ] > GetTime ( ) )
{
PrintToChat ( client , " [NE] Please wait %d seconds before you can nominate again " , g_Player_NominationDelay [ client ] - GetTime ( ) ) ;
return Plugin_Handled ;
}
static char mapname [ PLATFORM_MAX_PATH ] ;
GetCmdArg ( 1 , mapname , sizeof ( mapname ) ) ;
int status ;
if ( ! GetTrieValue ( g_mapTrie , mapname , status ) )
{
CPrintToChat ( client , " %t " , " Map was not found " , mapname ) ;
AttemptNominate ( client , mapname ) ;
return Plugin_Handled ;
}
bool RestrictionsActive = AreRestrictionsActive ( ) ;
if ( ( status & MAPSTATUS_DISABLED ) = = MAPSTATUS_DISABLED )
{
if ( ( status & MAPSTATUS_EXCLUDE_CURRENT ) = = MAPSTATUS_EXCLUDE_CURRENT )
CPrintToChat ( client , " [NE] %t " , " Cant Nominate Current Map " ) ;
if ( RestrictionsActive & & ( status & MAPSTATUS_EXCLUDE_PREVIOUS ) = = MAPSTATUS_EXCLUDE_PREVIOUS )
{
int Cooldown = GetMapCooldown ( mapname ) ;
CPrintToChat ( client , " [NE] %t (%d) " , " Map in Exclude List " , Cooldown ) ;
}
if ( ( status & MAPSTATUS_EXCLUDE_NOMINATED ) = = MAPSTATUS_EXCLUDE_NOMINATED )
CPrintToChat ( client , " [NE] %t " , " Map Already Nominated " ) ;
return Plugin_Handled ;
}
int Cooldown = GetMapCooldownTime ( mapname ) ;
if ( RestrictionsActive & & Cooldown > GetTime ( ) )
{
int Seconds = Cooldown - GetTime ( ) ;
CPrintToChat ( client , " [NE] %t " , " Map Cooldown Time Error " , Seconds / 3600 , ( Seconds % 3600 ) / 60 ) ;
return Plugin_Handled ;
}
bool VIPRestriction = GetMapVIPRestriction ( mapname , client ) ;
if ( RestrictionsActive & & VIPRestriction )
{
CPrintToChat ( client , " [NE] %t " , " Map Nominate VIP Error " ) ;
return Plugin_Handled ;
}
int TimeRestriction = GetMapTimeRestriction ( mapname ) ;
if ( RestrictionsActive & & TimeRestriction )
{
CPrintToChat ( client , " [NE] %t " , " Map Nominate Time Error " , TimeRestriction / 60 , TimeRestriction % 60 ) ;
return Plugin_Handled ;
}
2023-04-09 13:57:09 +02:00
int AverageHourRestricted = GetAveragePlayerTimeOnServerMapRestriction ( mapname ) ;
if ( AverageHourRestricted > 0 )
{
PrintToChat ( client , " %s requires +%i hours average. Use sm_houravg to check average. " , mapname , AverageHourRestricted ) ;
return Plugin_Handled ;
}
2023-01-27 21:07:48 +01:00
int PlayerRestriction = GetMapPlayerRestriction ( mapname ) ;
if ( RestrictionsActive & & PlayerRestriction )
{
if ( PlayerRestriction < 0 )
CPrintToChat ( client , " [NE] %t " , " Map Nominate MinPlayers Error " , PlayerRestriction * - 1 ) ;
else
CPrintToChat ( client , " [NE] %t " , " Map Nominate MaxPlayers Error " , PlayerRestriction ) ;
return Plugin_Handled ;
}
NominateResult result = NominateMap ( mapname , false , client ) ;
if ( result = = Nominate_InvalidMap )
{
CPrintToChat ( client , " [NE] %t " , " You already nominated the map " , mapname ) ;
return Plugin_Handled ;
}
if ( result > Nominate_Replaced )
{
if ( result = = Nominate_AlreadyInVote )
CPrintToChat ( client , " [NE] %t " , " Map Already In Vote " , mapname ) ;
else if ( result = = Nominate_VoteFull )
CPrintToChat ( client , " [NE] %t " , " Max Nominations " ) ;
return Plugin_Handled ;
}
/* Map was nominated! - Disable the menu item and update the trie */
//SetTrieValue(g_mapTrie, mapname, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
static char name [ MAX_NAME_LENGTH ] ;
GetClientName ( client , name , sizeof ( name ) ) ;
2017-10-12 21:52:19 +02:00
2023-01-27 21:07:48 +01:00
if ( result = = Nominate_Added )
PrintToChatAll ( " [NE] %t " , " Map Nominated " , name , mapname ) ;
else if ( result = = Nominate_Replaced )
PrintToChatAll ( " [NE] %t " , " Map Nomination Changed " , name , mapname ) ;
2016-01-19 23:57:32 +01:00
2023-01-27 21:07:48 +01:00
LogMessage ( " %s nominated %s " , name , mapname ) ;
g_Player_NominationDelay [ client ] = GetTime ( ) + GetConVarInt ( g_Cvar_NominateDelay ) ;
return Plugin_Continue ;
2016-01-19 23:57:32 +01:00
}
2016-08-11 17:48:20 +02:00
public Action Command_NominateList ( int client , int args )
2016-01-19 23:57:32 +01:00
{
2018-09-03 20:59:08 +02:00
if ( client = = 0 )
{
2019-12-22 14:10:01 +01:00
int arraySize = ByteCountToCells ( PLATFORM_MAX_PATH ) ;
ArrayList MapList = CreateArray ( arraySize ) ;
GetNominatedMapList ( MapList ) ;
2018-09-03 20:59:08 +02:00
char aBuf [ 2048 ] ;
StrCat ( aBuf , sizeof ( aBuf ) , " [NE] Nominated Maps: " ) ;
2019-12-22 14:10:01 +01:00
static char map [ PLATFORM_MAX_PATH ] ;
2018-09-03 20:59:08 +02:00
for ( int i = 0 ; i < GetArraySize ( MapList ) ; i + + )
{
StrCat ( aBuf , sizeof ( aBuf ) , " \n " ) ;
GetArrayString ( MapList , i , map , sizeof ( map ) ) ;
StrCat ( aBuf , sizeof ( aBuf ) , map ) ;
}
2019-12-22 14:10:01 +01:00
2018-09-03 21:27:03 +02:00
ReplyToCommand ( client , aBuf ) ;
2018-09-03 21:00:29 +02:00
delete MapList ;
2018-09-03 20:59:08 +02:00
return Plugin_Handled ;
}
2019-12-22 14:10:01 +01:00
Menu NominateListMenu = CreateMenu ( Handler_NominateListMenu , MENU_ACTIONS_DEFAULT | MenuAction_DisplayItem ) ;
2016-01-19 23:57:32 +01:00
2019-12-22 14:10:01 +01:00
if ( ! PopulateNominateListMenu ( NominateListMenu , client ) )
2016-01-19 23:57:32 +01:00
{
2019-12-22 14:10:01 +01:00
ReplyToCommand ( client , " [NE] No maps have been nominated. " ) ;
return Plugin_Handled ;
2016-01-19 23:57:32 +01:00
}
SetMenuTitle ( NominateListMenu , " Nominated Maps " , client ) ;
DisplayMenu ( NominateListMenu , client , MENU_TIME_FOREVER ) ;
return Plugin_Handled ;
}
2016-12-19 08:34:52 +01:00
public int Handler_NominateListMenu ( Menu menu , MenuAction action , int param1 , int param2 )
2016-01-19 23:57:32 +01:00
{
2016-12-05 21:14:59 +01:00
switch ( action )
{
case MenuAction_End :
{
delete menu ;
}
}
2016-01-19 23:57:32 +01:00
return 0 ;
}
2016-12-19 08:34:52 +01:00
void AttemptNominate ( int client , const char [ ] filter = " " )
2016-01-19 23:57:32 +01:00
{
2023-01-27 21:07:48 +01:00
if ( ! client )
return ;
2019-12-22 14:10:01 +01:00
2023-01-27 21:07:48 +01:00
Menu menu = g_MapMenu ;
menu = BuildMapMenu ( filter , client ) ;
2016-12-19 08:34:52 +01:00
2023-01-27 21:07:48 +01:00
SetMenuTitle ( menu , " %T " , " Nominate Title " , client ) ;
DisplayMenu ( menu , client , MENU_TIME_FOREVER ) ;
2016-01-19 23:57:32 +01:00
}
2016-12-19 08:34:52 +01:00
void AttemptAdminNominate ( int client , const char [ ] filter = " " )
2016-01-19 23:57:32 +01:00
{
2023-03-23 19:47:48 +01:00
if ( ! client )
return ;
2019-12-22 14:10:01 +01:00
2023-03-23 19:47:48 +01:00
Menu menu = g_AdminMapMenu ;
if ( filter [ 0 ] )
menu = BuildAdminMapMenu ( filter ) ;
2016-12-19 08:34:52 +01:00
2023-03-23 19:47:48 +01:00
SetMenuTitle ( menu , " %T " , " Nominate Title " , client ) ;
DisplayMenu ( menu , client , MENU_TIME_FOREVER ) ;
2019-12-22 14:10:01 +01:00
}
2016-01-19 23:57:32 +01:00
2019-12-22 14:10:01 +01:00
void AttemptAdminRemoveMap ( int client , const char [ ] filter = " " )
{
if ( ! client )
return ;
Menu AdminRemoveMapMenu = CreateMenu ( Handler_AdminRemoveMapMenu , MENU_ACTIONS_DEFAULT | MenuAction_DisplayItem ) ;
if ( ! PopulateNominateListMenu ( AdminRemoveMapMenu , client , filter ) )
{
ReplyToCommand ( client , " [NE] No maps have been nominated. " ) ;
return ;
}
SetMenuTitle ( AdminRemoveMapMenu , " Remove nomination " , client ) ;
DisplayMenu ( AdminRemoveMapMenu , client , MENU_TIME_FOREVER ) ;
}
2023-02-09 10:41:48 +01:00
int NominateListSortCmp ( int index1 , int index2 , Handle array , Handle hndl )
{
char map1 [ PLATFORM_MAX_PATH ] ;
char map2 [ PLATFORM_MAX_PATH ] ;
GetArrayString ( array , index1 , map1 , sizeof ( map1 ) ) ;
GetArrayString ( array , index2 , map2 , sizeof ( map2 ) ) ;
int count1 , count2 ;
StringMap sm = view_as < StringMap > ( hndl ) ;
sm . GetValue ( map1 , count1 ) ;
sm . GetValue ( map2 , count2 ) ;
if ( count1 = = count2 )
return 0 ;
return count1 > count2 ? - 1 : 1 ;
}
2019-12-22 14:10:01 +01:00
bool PopulateNominateListMenu ( Menu menu , int client , const char [ ] filter = " " )
{
2023-02-08 19:20:06 +01:00
int arraySize = ByteCountToCells ( PLATFORM_MAX_PATH ) ;
ArrayList MapList = CreateArray ( arraySize ) ;
ArrayList OwnerList = CreateArray ( ) ;
2019-12-22 14:10:01 +01:00
2023-02-08 19:20:06 +01:00
GetNominatedMapList ( MapList , OwnerList ) ;
if ( ! GetArraySize ( MapList ) )
{
delete MapList ;
delete OwnerList ;
return false ;
}
2019-12-22 14:10:01 +01:00
2023-02-08 19:20:06 +01:00
StringMap sm = new StringMap ( ) ;
static char map [ PLATFORM_MAX_PATH ] ;
static char display [ PLATFORM_MAX_PATH ] ;
for ( int i = 0 ; i < GetArraySize ( MapList ) ; i + + )
{
GetArrayString ( MapList , i , map , sizeof ( map ) ) ;
2019-12-22 20:52:24 +01:00
2023-02-08 19:20:06 +01:00
if ( ! filter [ 0 ] | | StrContains ( map , filter , false ) ! = - 1 )
{
2023-02-23 01:12:50 +01:00
//admin nominations must have most votes shrug
//this should work assuming that admin map nominations always fill the beginning of MapList uniquely
int owner = GetArrayCell ( OwnerList , i ) ;
2023-02-08 19:20:06 +01:00
int nominate_count_for_particular_map = 0 ;
sm . GetValue ( map , nominate_count_for_particular_map ) ;
2023-02-23 01:12:50 +01:00
if ( ! owner )
{
nominate_count_for_particular_map = 999 ;
}
2023-02-09 10:41:48 +01:00
sm . SetValue ( map , nominate_count_for_particular_map + 1 , true ) ;
2023-02-08 19:20:06 +01:00
}
}
2023-02-09 10:41:48 +01:00
StringMapSnapshot sm_snapshot = sm . Snapshot ( ) ;
ArrayList SortedList = CreateArray ( arraySize ) ;
for ( int i = 0 ; i < sm_snapshot . Length ; i + + )
2023-02-08 19:20:06 +01:00
{
2023-02-09 10:41:48 +01:00
sm_snapshot . GetKey ( i , map , sizeof ( map ) ) ;
SortedList . PushString ( map ) ;
}
SortedList . SortCustom ( NominateListSortCmp , sm ) ;
for ( int i = 0 ; i < GetArraySize ( SortedList ) ; i + + )
{
GetArrayString ( SortedList , i , map , sizeof ( map ) ) ;
2019-12-22 14:10:01 +01:00
2023-02-08 19:20:06 +01:00
if ( ! filter [ 0 ] | | StrContains ( map , filter , false ) ! = - 1 )
{
int nominate_count_for_particular_map = 0 ;
sm . GetValue ( map , nominate_count_for_particular_map ) ;
strcopy ( display , sizeof ( display ) , map ) ;
bool VIPRestriction = GetMapVIPRestriction ( map ) ;
if ( ( VIPRestriction ) & & AreRestrictionsActive ( ) )
Format ( display , sizeof ( display ) , " %s (%T) " , display , " VIP Nomination " , client ) ;
int owner = GetArrayCell ( OwnerList , i ) ;
char spelling [ 8 ] ;
2023-02-09 10:41:48 +01:00
Format ( spelling , sizeof ( spelling ) , nominate_count_for_particular_map = = 1 ? " Vote " : " Votes " ) ;
2023-02-08 19:20:06 +01:00
if ( ! owner )
Format ( display , sizeof ( display ) , " %s (Admin) " , display ) ;
else
Format ( display , sizeof ( display ) , " %s (%i %s) " , display , nominate_count_for_particular_map , spelling ) ;
2023-02-09 10:41:48 +01:00
2023-02-08 19:20:06 +01:00
AddMenuItem ( menu , map , display ) ;
}
}
2019-12-22 14:10:01 +01:00
2023-02-08 19:20:06 +01:00
delete MapList ;
delete OwnerList ;
2023-02-09 10:41:48 +01:00
delete SortedList ;
2023-02-08 19:20:06 +01:00
delete sm ;
2023-02-09 10:41:48 +01:00
delete sm_snapshot ;
2023-02-08 19:20:06 +01:00
return true ;
2016-01-19 23:57:32 +01:00
}
2023-01-27 21:07:48 +01:00
Menu BuildMapMenu ( const char [ ] filter , int client )
2016-01-19 23:57:32 +01:00
{
2023-01-27 21:07:48 +01:00
Menu menu = CreateMenu ( Handler_MapSelectMenu , MENU_ACTIONS_DEFAULT | MenuAction_DrawItem | MenuAction_DisplayItem ) ;
static char map [ PLATFORM_MAX_PATH * 2 ] ;
int arraySize = ByteCountToCells ( PLATFORM_MAX_PATH ) ;
ArrayList MapList = CreateArray ( arraySize ) ;
ArrayList OwnerList = CreateArray ( ) ;
StringMap sm = new StringMap ( ) ;
GetNominatedMapList ( MapList , OwnerList ) ;
bool nominated_maps = true ;
if ( ! GetArraySize ( MapList ) )
{
nominated_maps = false ;
}
if ( client ! = 0 & & nominated_maps )
{
for ( int j = 0 ; j < GetArraySize ( MapList ) ; j + + )
{
int owner = GetArrayCell ( OwnerList , j ) ;
if ( client = = owner )
{
GetArrayString ( MapList , j , map , sizeof ( map ) ) ;
sm . SetValue ( map , 1 ) ;
}
}
}
2023-03-31 19:06:56 +02:00
//2023 edit to allow hiding/unhiding unavailable maps
char hiding_unavailable_maps [ MAX_NAME_LENGTH ] ;
if ( g_bClientsIgnoring [ client ] )
{
Format ( hiding_unavailable_maps , sizeof ( hiding_unavailable_maps ) , " Show all unavailable maps " ) ;
}
else
{
Format ( hiding_unavailable_maps , sizeof ( hiding_unavailable_maps ) , " Hide all unavailable maps " ) ;
}
AddMenuItem ( menu , hiding_unavailable_maps , hiding_unavailable_maps ) ;
2023-01-27 21:07:48 +01:00
for ( int i = 0 ; i < GetArraySize ( g_MapList ) ; i + + )
{
GetArrayString ( g_MapList , i , map , sizeof ( map ) ) ;
if ( ! filter [ 0 ] | | StrContains ( map , filter , false ) ! = - 1 )
{
if ( client ! = 0 & & nominated_maps )
{
int map_present = 0 ;
sm . GetValue ( map , map_present ) ;
if ( map_present = = 1 )
{
//PrintToChatAll("client %N here. map: %s", client, map);
StrCat ( map , sizeof ( map ) , " (Nominated) " ) ;
}
}
2023-03-31 19:06:56 +02:00
if ( g_bClientsIgnoring [ client ] )
{
if ( AreRestrictionsActive ( ) & & (
GetMapCooldownTime ( map ) > GetTime ( ) | |
GetMapTimeRestriction ( map ) | |
GetMapPlayerRestriction ( map ) | |
2023-04-09 13:57:09 +02:00
GetAveragePlayerTimeOnServerMapRestriction ( map ) > 0 | |
2023-03-31 19:06:56 +02:00
GetMapVIPRestriction ( map , client ) ) )
{
continue ;
}
}
2023-01-27 21:07:48 +01:00
AddMenuItem ( menu , map , map ) ;
}
}
delete MapList ;
delete OwnerList ;
delete sm ;
SetMenuExitButton ( menu , true ) ;
return menu ;
2016-01-19 23:57:32 +01:00
}
2016-12-19 08:34:52 +01:00
Menu BuildAdminMapMenu ( const char [ ] filter )
2016-01-19 23:57:32 +01:00
{
2016-12-19 08:34:52 +01:00
Menu menu = CreateMenu ( Handler_AdminMapSelectMenu , MENU_ACTIONS_DEFAULT | MenuAction_DrawItem | MenuAction_DisplayItem ) ;
2016-01-19 23:57:32 +01:00
2016-08-11 17:48:20 +02:00
static char map [ PLATFORM_MAX_PATH ] ;
2016-01-19 23:57:32 +01:00
2016-08-11 17:48:20 +02:00
for ( int i = 0 ; i < GetArraySize ( g_AdminMapList ) ; i + + )
2016-01-19 23:57:32 +01:00
{
GetArrayString ( g_AdminMapList , i , map , sizeof ( map ) ) ;
2016-12-19 08:34:52 +01:00
if ( ! filter [ 0 ] | | StrContains ( map , filter , false ) ! = - 1 )
AddMenuItem ( menu , map , map ) ;
2016-01-19 23:57:32 +01:00
}
2017-04-19 19:52:21 +02:00
if ( filter [ 0 ] )
{
// Search normal maps aswell if filter is specified
for ( int i = 0 ; i < GetArraySize ( g_MapList ) ; i + + )
{
GetArrayString ( g_MapList , i , map , sizeof ( map ) ) ;
if ( ! filter [ 0 ] | | StrContains ( map , filter , false ) ! = - 1 )
AddMenuItem ( menu , map , map ) ;
}
}
2016-12-19 08:34:52 +01:00
SetMenuExitButton ( menu , true ) ;
return menu ;
2016-01-19 23:57:32 +01:00
}
2016-12-19 08:34:52 +01:00
public int Handler_MapSelectMenu ( Menu menu , MenuAction action , int param1 , int param2 )
2016-01-19 23:57:32 +01:00
{
2023-01-27 21:07:48 +01:00
switch ( action )
{
case MenuAction_End :
{
if ( menu ! = g_MapMenu )
{
delete menu ;
}
}
case MenuAction_Select :
{
2023-03-23 19:47:48 +01:00
//2023-03-22 edit since client sometimes is 0 which fucks up mapchooser
if ( param1 > 0 & & param1 < = MaxClients & & IsClientConnected ( param1 ) & & IsClientInGame ( param1 ) )
2023-01-27 21:07:48 +01:00
{
2023-03-23 19:47:48 +01:00
if ( g_Player_NominationDelay [ param1 ] > GetTime ( ) )
{
PrintToChat ( param1 , " [NE] Please wait %d seconds before you can nominate again " , g_Player_NominationDelay [ param1 ] - GetTime ( ) ) ;
DisplayMenuAtItem ( menu , param1 , GetMenuSelectionPosition ( ) , MENU_TIME_FOREVER ) ;
return 0 ;
}
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
static char map [ PLATFORM_MAX_PATH ] ;
char name [ MAX_NAME_LENGTH ] ;
GetMenuItem ( menu , param2 , map , sizeof ( map ) ) ;
2023-01-27 21:07:48 +01:00
2023-03-31 19:06:56 +02:00
if ( StrEqual ( map , " Hide all unavailable maps " ) )
{
PrintToChat ( param1 , " Hiding all unavailable maps from the nomination list " ) ;
sql_insert_update_hiding_unavailable ( param1 ) ;
return 0 ;
}
if ( StrEqual ( map , " Show all unavailable maps " ) )
{
PrintToChat ( param1 , " Displaying all unavailable maps from the nomination list " ) ;
sql_insert_update_hiding_unavailable ( param1 ) ;
return 0 ;
}
2023-03-23 19:47:48 +01:00
GetClientName ( param1 , name , MAX_NAME_LENGTH ) ;
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
if ( AreRestrictionsActive ( ) & & (
GetMapCooldownTime ( map ) > GetTime ( ) | |
GetMapTimeRestriction ( map ) | |
GetMapPlayerRestriction ( map ) | |
2023-04-09 13:57:09 +02:00
GetAveragePlayerTimeOnServerMapRestriction ( map ) > 0 | |
2023-03-23 19:47:48 +01:00
GetMapVIPRestriction ( map , param1 ) ) )
{
PrintToChat ( param1 , " [NE] You cant nominate this map right now. " ) ;
return 0 ;
}
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
NominateResult result = NominateMap ( map , false , param1 ) ;
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
if ( result = = Nominate_InvalidMap )
{
PrintToChat ( param1 , " [NE] You already nominated the map %s " , map ) ;
return 0 ;
}
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
/* Dont need to check for InvalidMap because the menu did that already */
if ( result = = Nominate_AlreadyInVote )
{
PrintToChat ( param1 , " [NE] %t " , " Map Already Nominated " ) ;
return 0 ;
}
else if ( result = = Nominate_VoteFull )
{
PrintToChat ( param1 , " [NE] %t " , " Max Nominations " ) ;
return 0 ;
}
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
//SetTrieValue(g_mapTrie, map, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
if ( result = = Nominate_Added )
PrintToChatAll ( " [NE] %t " , " Map Nominated " , name , map ) ;
else if ( result = = Nominate_Replaced )
PrintToChatAll ( " [NE] %t " , " Map Nomination Changed " , name , map ) ;
2023-01-27 21:07:48 +01:00
2023-03-23 19:47:48 +01:00
LogMessage ( " %s nominated %s " , name , map ) ;
g_Player_NominationDelay [ param1 ] = GetTime ( ) + GetConVarInt ( g_Cvar_NominateDelay ) ;
}
2023-01-27 21:07:48 +01:00
}
case MenuAction_DrawItem :
{
static char map [ PLATFORM_MAX_PATH ] ;
GetMenuItem ( menu , param2 , map , sizeof ( map ) ) ;
int status ;
if ( GetTrieValue ( g_mapTrie , map , status ) )
{
if ( ( status & MAPSTATUS_DISABLED ) = = MAPSTATUS_DISABLED )
{
if ( ( status & MAPSTATUS_EXCLUDE_CURRENT ) = = MAPSTATUS_EXCLUDE_CURRENT )
{
return ITEMDRAW_DISABLED ;
}
if ( AreRestrictionsActive ( ) & & ( status & MAPSTATUS_EXCLUDE_PREVIOUS ) = = MAPSTATUS_EXCLUDE_PREVIOUS )
{
return ITEMDRAW_DISABLED ;
}
if ( ( status & MAPSTATUS_EXCLUDE_NOMINATED ) = = MAPSTATUS_EXCLUDE_NOMINATED )
{
return ITEMDRAW_DISABLED ;
}
}
}
if ( AreRestrictionsActive ( ) & & (
GetMapCooldownTime ( map ) > GetTime ( ) | |
GetMapTimeRestriction ( map ) | |
GetMapPlayerRestriction ( map ) | |
2023-04-09 13:57:09 +02:00
GetAveragePlayerTimeOnServerMapRestriction ( map ) > 0 | |
2023-01-27 21:07:48 +01:00
GetMapVIPRestriction ( map , param1 ) ) )
{
return ITEMDRAW_DISABLED ;
}
return ITEMDRAW_DEFAULT ;
}
case MenuAction_DisplayItem :
{
static char map [ PLATFORM_MAX_PATH ] ;
GetMenuItem ( menu , param2 , map , sizeof ( map ) ) ;
int mark = GetConVarInt ( g_Cvar_MarkCustomMaps ) ;
bool official ;
static char buffer [ 100 ] ;
static char display [ 150 ] ;
if ( mark )
official = IsMapOfficial ( map ) ;
if ( mark & & ! official )
{
switch ( mark )
{
case 1 :
{
Format ( buffer , sizeof ( buffer ) , " %T " , " Custom Marked " , param1 , map ) ;
}
case 2 :
{
Format ( buffer , sizeof ( buffer ) , " %T " , " Custom " , param1 , map ) ;
}
}
}
else
strcopy ( buffer , sizeof ( buffer ) , map ) ;
bool RestrictionsActive = AreRestrictionsActive ( ) ;
bool VIPRestriction = GetMapVIPRestriction ( map ) ;
if ( RestrictionsActive & & VIPRestriction )
{
Format ( buffer , sizeof ( buffer ) , " %s (%T) " , buffer , " VIP Restriction " , param1 ) ;
}
int status ;
if ( GetTrieValue ( g_mapTrie , map , status ) )
{
if ( ( status & MAPSTATUS_DISABLED ) = = MAPSTATUS_DISABLED )
{
if ( ( status & MAPSTATUS_EXCLUDE_CURRENT ) = = MAPSTATUS_EXCLUDE_CURRENT )
{
Format ( display , sizeof ( display ) , " %s (%T) " , buffer , " Current Map " , param1 ) ;
return RedrawMenuItem ( display ) ;
}
if ( RestrictionsActive & & ( status & MAPSTATUS_EXCLUDE_PREVIOUS ) = = MAPSTATUS_EXCLUDE_PREVIOUS )
{
int Cooldown = GetMapCooldown ( map ) ;
Format ( display , sizeof ( display ) , " %s (%T %d) " , buffer , " Recently Played " , param1 , Cooldown ) ;
return RedrawMenuItem ( display ) ;
}
if ( ( status & MAPSTATUS_EXCLUDE_NOMINATED ) = = MAPSTATUS_EXCLUDE_NOMINATED )
{
Format ( display , sizeof ( display ) , " %s (%T) " , buffer , " Nominated " , param1 ) ;
return RedrawMenuItem ( display ) ;
}
}
}
int Cooldown = GetMapCooldownTime ( map ) ;
if ( RestrictionsActive & & Cooldown > GetTime ( ) )
{
int Seconds = Cooldown - GetTime ( ) ;
char time [ 16 ] ;
CustomFormatTime ( Seconds , time , sizeof ( time ) ) ;
Format ( display , sizeof ( display ) , " %s (%T %s) " , buffer , " Recently Played " , param1 , time ) ;
return RedrawMenuItem ( display ) ;
}
int TimeRestriction = GetMapTimeRestriction ( map ) ;
if ( RestrictionsActive & & TimeRestriction )
{
Format ( display , sizeof ( display ) , " %s (%T) " , buffer , " Map Time Restriction " , param1 , " + " , TimeRestriction / 60 , TimeRestriction % 60 ) ;
return RedrawMenuItem ( display ) ;
}
2023-04-09 13:57:09 +02:00
int AverageHourRestricted = GetAveragePlayerTimeOnServerMapRestriction ( map ) ;
if ( AverageHourRestricted > 0 )
{
Format ( display , sizeof ( display ) , " %s requires +%i hours average. " , map , AverageHourRestricted ) ;
return RedrawMenuItem ( display ) ;
}
2023-01-27 21:07:48 +01:00
int PlayerRestriction = GetMapPlayerRestriction ( map ) ;
if ( RestrictionsActive & & PlayerRestriction )
{
if ( PlayerRestriction < 0 )
Format ( display , sizeof ( display ) , " %s (%T) " , buffer , " Map Player Restriction " , param1 , " + " , PlayerRestriction * - 1 ) ;
else
Format ( display , sizeof ( display ) , " %s (%T) " , buffer , " Map Player Restriction " , param1 , " - " , PlayerRestriction ) ;
return RedrawMenuItem ( display ) ;
}
if ( RestrictionsActive & & VIPRestriction )
{
return RedrawMenuItem ( buffer ) ;
}
if ( mark & & ! official )
return RedrawMenuItem ( buffer ) ;
return 0 ;
}
}
return 0 ;
2016-01-19 23:57:32 +01:00
}
2016-08-11 17:48:20 +02:00
stock bool IsNominateAllowed ( int client )
2016-01-19 23:57:32 +01:00
{
2018-09-20 11:32:50 +02:00
if ( BaseComm_IsClientGagged ( client ) )
{
CReplyToCommand ( client , " [NE] You are not allowed to nominate maps while you are gagged. " ) ;
2018-04-13 22:21:36 +02:00
return false ;
2018-09-20 11:32:50 +02:00
}
if ( ! CheckCommandAccess ( client , " sm_tag " , ADMFLAG_CUSTOM1 ) )
{
2019-08-17 14:31:28 +02:00
int VIPTimeRestriction = GetVIPTimeRestriction ( ) ;
if ( ( VIPTimeRestriction ) & & AreRestrictionsActive ( ) )
2018-09-20 11:32:50 +02:00
{
2019-09-18 16:58:30 +02:00
CReplyToCommand ( client , " [NE] During peak hours only VIPs are allowed to nominate maps. Wait for %d hours and %d minutes or buy VIP at Unloze.com to nominate maps again. " , VIPTimeRestriction / 60 , VIPTimeRestriction % 60 ) ;
2018-09-20 11:32:50 +02:00
return false ;
}
}
2018-04-13 22:21:36 +02:00
2016-08-11 17:48:20 +02:00
CanNominateResult result = CanNominate ( ) ;
2016-01-19 23:57:32 +01:00
switch ( result )
{
case CanNominate_No_VoteInProgress :
{
2018-07-27 21:27:42 +02:00
CReplyToCommand ( client , " [NE] %t " , " Nextmap Voting Started " ) ;
2016-01-19 23:57:32 +01:00
return false ;
}
case CanNominate_No_VoteComplete :
{
2016-08-11 17:48:20 +02:00
char map [ PLATFORM_MAX_PATH ] ;
2016-01-19 23:57:32 +01:00
GetNextMap ( map , sizeof ( map ) ) ;
CReplyToCommand ( client , " [NE] %t " , " Next Map " , map ) ;
return false ;
}
/ *
case CanNominate_No_VoteFull :
{
2018-07-27 21:27:42 +02:00
CReplyToCommand ( client , " [NE] %t " , " Max Nominations " ) ;
2016-01-19 23:57:32 +01:00
return false ;
}
* /
}
return true ;
}
2016-12-19 08:34:52 +01:00
public int Handler_AdminMapSelectMenu ( Menu menu , MenuAction action , int param1 , int param2 )
2016-01-19 23:57:32 +01:00
{
2023-01-27 21:07:48 +01:00
switch ( action )
{
case MenuAction_End :
{
if ( menu ! = g_AdminMapMenu )
delete menu ;
}
case MenuAction_Select :
{
static char map [ PLATFORM_MAX_PATH ] ;
GetMenuItem ( menu , param2 , map , sizeof ( map ) ) ;
if ( ! CheckCommandAccess ( param1 , " sm_nominate_ignore " , ADMFLAG_CHEATS , true ) )
{
if ( AreRestrictionsActive ( ) & & (
GetMapCooldownTime ( map ) > GetTime ( ) | |
GetMapTimeRestriction ( map ) | |
GetMapPlayerRestriction ( map ) | |
2023-04-09 13:57:09 +02:00
GetAveragePlayerTimeOnServerMapRestriction ( map ) > 0 | |
2023-01-27 21:07:48 +01:00
GetMapVIPRestriction ( map , param1 ) ) )
{
PrintToChat ( param1 , " [NE] You cant nominate this map right now. " ) ;
return 0 ;
}
}
NominateResult result = NominateMap ( map , true , 0 ) ;
if ( result > Nominate_Replaced )
{
/* We assume already in vote is the casue because the maplist does a Map Validity check and we forced, so it cant be full */
PrintToChat ( param1 , " [NE] %t " , " Map Already In Vote " , map ) ;
return 0 ;
}
SetTrieValue ( g_mapTrie , map , MAPSTATUS_DISABLED | MAPSTATUS_EXCLUDE_NOMINATED ) ;
PrintToChat ( param1 , " [NE] %t " , " Map Inserted " , map ) ;
LogAction ( param1 , - 1 , " \" %L \" inserted map \" %s \" . " , param1 , map ) ;
PrintToChatAll ( " [NE] %N has inserted %s into nominations " , param1 , map ) ;
}
case MenuAction_DrawItem :
{
if ( ! CheckCommandAccess ( param1 , " sm_nominate_ignore " , ADMFLAG_CHEATS , true ) )
{
return Handler_MapSelectMenu ( menu , action , param1 , param2 ) ;
}
return ITEMDRAW_DEFAULT ;
}
case MenuAction_DisplayItem :
{
return Handler_MapSelectMenu ( menu , action , param1 , param2 ) ;
}
}
return 0 ;
2016-01-19 23:57:32 +01:00
}
2018-03-20 01:05:31 +01:00
2019-12-22 14:10:01 +01:00
public int Handler_AdminRemoveMapMenu ( Menu menu , MenuAction action , int param1 , int param2 )
{
switch ( action )
{
case MenuAction_End :
{
delete menu ;
}
case MenuAction_Select :
{
static char map [ PLATFORM_MAX_PATH ] ;
GetMenuItem ( menu , param2 , map , sizeof ( map ) ) ;
if ( ! RemoveNominationByMap ( map ) )
{
2023-01-27 21:07:48 +01:00
CReplyToCommand ( param1 , " This map isnt nominated. " , map ) ;
2019-12-22 14:10:01 +01:00
return 0 ;
}
CReplyToCommand ( param1 , " Map '%s' removed from the nominations list. " , map ) ;
LogAction ( param1 , - 1 , " \" %L \" removed map \" %s \" from nominations. " , param1 , map ) ;
PrintToChatAll ( " [NE] %N has removed %s from nominations " , param1 , map ) ;
}
}
return 0 ;
}
2018-03-20 01:05:31 +01:00
public int Native_GetNominationPool ( Handle plugin , int numArgs )
{
SetNativeCellRef ( 1 , g_MapList ) ;
return 0 ;
}
public int Native_PushMapIntoNominationPool ( Handle plugin , int numArgs )
{
char map [ PLATFORM_MAX_PATH ] ;
GetNativeString ( 1 , map , PLATFORM_MAX_PATH ) ;
ShiftArrayUp ( g_MapList , 0 ) ;
SetArrayString ( g_MapList , 0 , map ) ;
UpdateMapTrie ( ) ;
UpdateMapMenus ( ) ;
return 0 ;
}
public int Native_PushMapsIntoNominationPool ( Handle plugin , int numArgs )
{
ArrayList maps = GetNativeCell ( 1 ) ;
for ( int i = 0 ; i < maps . Length ; i + + )
{
char map [ PLATFORM_MAX_PATH ] ;
maps . GetString ( i , map , PLATFORM_MAX_PATH ) ;
if ( FindStringInArray ( g_MapList , map ) = = - 1 )
{
ShiftArrayUp ( g_MapList , 0 ) ;
SetArrayString ( g_MapList , 0 , map ) ;
}
}
delete maps ;
UpdateMapTrie ( ) ;
UpdateMapMenus ( ) ;
return 0 ;
}
public int Native_RemoveMapFromNominationPool ( Handle plugin , int numArgs )
{
char map [ PLATFORM_MAX_PATH ] ;
GetNativeString ( 1 , map , PLATFORM_MAX_PATH ) ;
int idx ;
if ( ( idx = FindStringInArray ( g_MapList , map ) ) ! = - 1 )
RemoveFromArray ( g_MapList , idx ) ;
UpdateMapTrie ( ) ;
UpdateMapMenus ( ) ;
return 0 ;
}
public int Native_RemoveMapsFromNominationPool ( Handle plugin , int numArgs )
{
ArrayList maps = GetNativeCell ( 1 ) ;
for ( int i = 0 ; i < maps . Length ; i + + )
{
char map [ PLATFORM_MAX_PATH ] ;
maps . GetString ( i , map , PLATFORM_MAX_PATH ) ;
int idx = - 1 ;
if ( ( idx = FindStringInArray ( g_MapList , map ) ) ! = - 1 )
RemoveFromArray ( g_MapList , idx ) ;
}
delete maps ;
UpdateMapTrie ( ) ;
UpdateMapMenus ( ) ;
return 0 ;
}
2018-09-20 11:32:50 +02:00
stock int GetVIPTimeRestriction ( )
{
if ( ! GetConVarBool ( g_Cvar_VIPTimeframe ) )
return 0 ;
char sTime [ 8 ] ;
FormatTime ( sTime , sizeof ( sTime ) , " %H%M " ) ;
int CurTime = StringToInt ( sTime ) ;
int MinTime = GetConVarInt ( g_Cvar_VIPTimeframeMinTime ) ;
int MaxTime = GetConVarInt ( g_Cvar_VIPTimeframeMaxTime ) ;
//Wrap around.
CurTime = ( CurTime < = MinTime ) ? CurTime + 2400 : CurTime ;
MaxTime = ( MaxTime < = MinTime ) ? MaxTime + 2400 : MaxTime ;
if ( ( MinTime < = CurTime < = MaxTime ) )
{
//Wrap around.
MinTime = ( MinTime < = CurTime ) ? MinTime + 2400 : MinTime ;
MinTime = ( MinTime < = MaxTime ) ? MinTime + 2400 : MinTime ;
2023-01-27 21:07:48 +01:00
// Convert our time to minutes.
2019-09-18 16:58:30 +02:00
CurTime = ( ( CurTime / 100 ) * 60 ) + ( CurTime % 100 ) ;
MinTime = ( ( MinTime / 100 ) * 60 ) + ( MinTime % 100 ) ;
MaxTime = ( ( MaxTime / 100 ) * 60 ) + ( MaxTime % 100 ) ;
2018-09-20 11:32:50 +02:00
return MaxTime - CurTime ;
}
return 0 ;
}
2019-09-18 12:36:08 +02:00
stock void CustomFormatTime ( int seconds , char [ ] buffer , int maxlen )
{
if ( seconds < = 60 )
Format ( buffer , maxlen , " %ds " , seconds ) ;
else if ( seconds < = 3600 )
2019-09-18 16:58:30 +02:00
Format ( buffer , maxlen , " %dm " , seconds / 60 ) ;
else if ( seconds < 10 * 3600 )
Format ( buffer , maxlen , " %dh%dm " , seconds / 3600 , ( seconds % 3600 ) / 60 ) ;
2019-09-18 12:36:08 +02:00
else
2019-09-18 16:58:30 +02:00
Format ( buffer , maxlen , " %dh " , seconds / 3600 ) ;
}
stock int TimeStrToSeconds ( const char [ ] str )
{
int seconds = 0 ;
int maxlen = strlen ( str ) ;
2019-09-18 17:11:29 +02:00
for ( int i = 0 ; i < maxlen ; )
2019-09-18 16:58:30 +02:00
{
int val = 0 ;
i + = StringToIntEx ( str [ i ] , val ) ;
if ( str [ i ] = = 'h' )
{
val * = 60 ;
i + + ;
}
seconds + = val * 60 ;
}
return seconds ;
2019-09-18 12:36:08 +02:00
}