#pragma semicolon 1
#pragma newdecls required
#define DEBUG

#define PLUGIN_AUTHOR "jenz"
#define PLUGIN_VERSION "6.20"
#define ZONE_PREFIX_RACE "ZONE_PREFIX_RACE"

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <unloze_zones>
#include <colorvariables>
#include <regex>
#include <zombiereloaded>

bool g_bMessage[MAXPLAYERS];
bool g_bStopTimer[MAXPLAYERS];
bool g_bRoundend;
bool g_bSmap;
bool g_bRmap;
char g_cMapname[512];
float g_fEngineRoundtimeSurf[MAXPLAYERS];
float g_fEngineSecondsSurf[MAXPLAYERS];
float g_fPlayertimes[MAXPLAYERS];
float g_fEngineRoundtime;
float g_fEngineSeconds;
int g_iEngine_minutesSurf[MAXPLAYERS];
int g_iCurrentS[MAXPLAYERS];
int g_iSurf[MAXPLAYERS];
int g_iEngine_minutes;
Handle g_hSurfTimer[MAXPLAYERS];

public Plugin myinfo = 
{
	name = "Unloze Map Timer",
	author = PLUGIN_AUTHOR,
	description = "Timers for Race Maps",
	version = PLUGIN_VERSION,
	url = ""
};

//----------------------------------------------------------------------------------------------------
// Purpose: Pluginstart/mapstart
//----------------------------------------------------------------------------------------------------

public void OnPluginStart()
{
	SQL_StartConnection();
	RegConsoleCmd("sm_toptime", cmd_timerCheck, "checking");
	
	RegConsoleCmd("sm_s1", cmd_timerCheckS1, "checking");
	RegConsoleCmd("sm_s2", cmd_timerCheckS2, "checking 2");
	RegConsoleCmd("sm_s3", cmd_timerCheckS3, "checking 3");
	RegConsoleCmd("sm_s4", cmd_timerCheckS4, "checking 4");
	RegConsoleCmd("sm_s5", cmd_timerCheckS5, "checking 5");
	RegConsoleCmd("sm_s6", cmd_timerCheckS6, "checking 6");
	RegConsoleCmd("sm_s7", cmd_timerCheckS7, "checking 7");
	RegConsoleCmd("sm_s8", cmd_timerCheckS8, "checking 8");
	RegConsoleCmd("sm_s9", cmd_timerCheckS9, "checking 9");
	RegConsoleCmd("sm_s10", cmd_timerCheckS010, "checking 10");
	HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
	HookEvent("round_end", Event_RoundEnd);
}

public void OnMapStart()
{
	GetCurrentMap(g_cMapname, sizeof(g_cMapname));
	g_bSmap = false;
	g_bRmap = false;
}

//----------------------------------------------------------------------------------------------------
// Purpose: mysql queries/callbacks
//----------------------------------------------------------------------------------------------------

public void SQL_SelectTop_Callback(Database db, DBResultSet results, const char[] error, any data)
{
	if (results == null)
	{
		//LogError("[SS] Selecting players error. Reason: %s", error);
		return;
	}
	
	int client = GetClientFromSerial(data);
	if (client == 0)
	{
		LogError("[SS] Client is not valid. Reason: %s", error);
		return;
	}
	
	Menu menu = new Menu(MenuHandler1);
	if (g_iSurf[client] != 0)
	{
		menu.SetTitle("Maptimer: %s_S%i", g_cMapname, g_iSurf[client]);
	}
	else
	{
		menu.SetTitle("Maptimer: %s", g_cMapname);
	}
	
	
	int iS_Count = 0;
	char gS_MenuContent[524];
	
	while (results.FetchRow())
	{
		float oldTime = 0.0;
		int engine_cMin = 0;
		float engine_cSec = 0.0;
		iS_Count++;
		
		//Player Name
		char[] gS_PlayerName = new char[MAX_NAME_LENGTH];
		results.FetchString(0, gS_PlayerName, MAX_NAME_LENGTH);
		oldTime = results.FetchFloat(1);
		engine_cMin = RoundToFloor(oldTime / 60);
		engine_cSec = oldTime - (engine_cMin * 60);
		
		Format(gS_MenuContent, sizeof(gS_MenuContent), "Position: %i Time: %i:%f - %s", iS_Count, engine_cMin, engine_cSec, gS_PlayerName);
		
		menu.AddItem("-1", gS_MenuContent, ITEMDRAW_DISABLED);
	}
	
	if (!iS_Count)
	{
		menu.AddItem("-1", "No results.", ITEMDRAW_DISABLED);
	}
	
	//menu.AddItem("no", "No", ITEMDRAW_DISABLED);
	menu.ExitButton = true;
	menu.Display(client, 20);
	
	
//////message//////
	
	char sQuery[564];
	char sSID[64];
	GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
	
	if (g_iSurf[client] != 0)
	{
		Format(sQuery, sizeof(sQuery), "SELECT name, `%sS%i` FROM `zetimer_tableSurf` WHERE steam_auth = '%s'", g_cMapname, g_iSurf[client], sSID);
	}
	else
	{
		Format(sQuery, sizeof(sQuery), "SELECT name, `%s` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, sSID);
	}
	DBResultSet rs;
	
	if ((rs = SQL_Query(db, sQuery)) == null)
	{
		delete db;
		delete rs;
		return;
	}
	
	char gS_MessageContent[524];
	if (rs.FetchRow())
	{
		float oldTime = 0.0;
		int engine_cMin = 0;
		float engine_cSec = 0.0;
		
		//Player Name
		char[] gS_PlayerName = new char[MAX_NAME_LENGTH];
		rs.FetchString(0, gS_PlayerName, MAX_NAME_LENGTH);
		oldTime = rs.FetchFloat(1);
		engine_cMin = RoundToFloor(oldTime / 60);
		engine_cSec = oldTime - (engine_cMin * 60);
		
		Format(gS_MessageContent, sizeof(gS_MessageContent), "%i:%f - %s", engine_cMin, engine_cSec, gS_PlayerName);
		if (g_iSurf[client] != 0)
		{
			CPrintToChat(client, "Your best time Stage %i: %s", g_iSurf[client], gS_MessageContent);
		}
		else
		{
			CPrintToChat(client, "Your best time: %s", gS_MessageContent);
		}
	}
	delete db;
	delete rs;
}

public float receiveMYSQL(int client, float f_playerTime)
{
	//variables
	float iCollected;
	char sQuery[255];
	char sSID[64];
	char error[255];
	DBResultSet rs;
	Database db;
	
	if (SQL_CheckConfig("zetimer"))
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
	Format(sQuery, sizeof(sQuery), "SELECT `%s` FROM `zetimer_table` WHERE steam_auth = '%s'", g_cMapname, sSID);
	//PrintToChatAll("receiveMYSQL sQuery: %s", sQuery);
	if ((rs = SQL_Query(db, sQuery)) == null)
	{
		delete db;
		delete rs;
		return 0.0;
	}
	
	if(SQL_FetchRow(rs))
	{
		iCollected = SQL_FetchFloat(rs, 0);
	}
	
	delete rs;
	delete db;
	return iCollected;
}

public void sendMYSQLSurf(int client, float f_playerTime, int Entry)
{
	char error[255];
	Database db;
	if (SQL_CheckConfig("zetimer"))
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] Error! Could not connect to MYSQL-DB!");
		delete db;
		return;
	}
	
	char sSID[64];
	GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
	char sQuery[255];
	//Format(sQuery, sizeof(sQuery), "SELECT `%sS1` FROM `zetimer_tableSurf` LIMIT 10", g_cMapname);
	Format(sQuery, sizeof(sQuery), "SELECT `%sS%i` FROM `zetimer_tableSurf` LIMIT 10", g_cMapname, Entry);
	//PrintToChatAll("sendMYSQLSurf sQuery: %s", sQuery);
	DBResultSet rs;
	if ((rs = SQL_Query(db, sQuery)) == null)
	{
		Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_tableSurf` ADD COLUMN `%sS%i` DECIMAL(13,3) NOT NULL", g_cMapname, Entry);
		SQL_TQuery(db, DummyCallbackSimple, sQuery);
		PrintToChat(client, "Sorry but the time was not counted since the Table had to be created first EKSDEE- jenz");
	}
	else
	{
		char l_cName[256];
		SQL_FetchClientName(client, db, l_cName, sizeof(l_cName));
		Format(sQuery, sizeof(sQuery), "INSERT INTO `zetimer_tableSurf` (`steam_auth`, `name`, `%sS%i`) VALUES ('%s', '%s', '%f') ON DUPLICATE KEY UPDATE `name` = '%s', `%sS%i` = '%f'", g_cMapname, Entry, sSID, l_cName, f_playerTime, l_cName, g_cMapname, Entry, f_playerTime);
		SQL_TQuery(db, DummyCallbackSimple, sQuery);
	}
	delete db;
	delete rs;
	//CPrintToChatAll("reaching end, query is: %s", sQuery);
}

public void sendMYSQL(int client, float f_playerTime)
{
	char error[255];
	Database db;
	if (SQL_CheckConfig("zetimer"))
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	
	char sSID[64];
	GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
	char sQuery[255];
	Format(sQuery, sizeof(sQuery), "SELECT `%s` FROM `zetimer_table` LIMIT 10", g_cMapname);
	
	DBResultSet rs;
	if ((rs = SQL_Query(db, sQuery)) == null)
	{
		Format(sQuery, sizeof(sQuery), "ALTER TABLE `zetimer_table` ADD COLUMN `%s` DECIMAL(13,3) NOT NULL", g_cMapname);
		SQL_TQuery(db, DummyCallbackSimple, sQuery);
		PrintToChat(client, "Sorry but the time was not counted since the Table had to be created first EKSDEE- jenz");
	}
	else
	{
		Format(sQuery, sizeof(sQuery), "INSERT INTO `zetimer_table` (`steam_auth`, `name`, `%s`) VALUES ('%s', '%N', '%f') ON DUPLICATE KEY UPDATE `name` = '%N', `%s` = '%f'", g_cMapname, sSID, client, f_playerTime, client, g_cMapname, f_playerTime);
		SQL_TQuery(db, DummyCallbackSimple, sQuery);
	}
	
	delete db;
	delete rs;
	//CPrintToChatAll("reaching end, query is: %s", sQuery);
}

public void SQL_StartConnection()
{
	char error[255];
	Database db;
	if (SQL_CheckConfig("zetimer")) 
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] {white}Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	
	//create tables
	char sQuery[255];
	Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `zetimer_table` (`steam_auth` VARCHAR(254) NOT NULL, `name` VARCHAR(254) NOT NULL, PRIMARY KEY (`steam_auth`))");
	SQL_TQuery(db, DummyCallbackSimple, sQuery);
	Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `zetimer_tableSurf` (`steam_auth` VARCHAR(254) NOT NULL, `name` VARCHAR(254) NOT NULL, PRIMARY KEY (`steam_auth`))");
	SQL_TQuery(db, DummyCallbackSimple, sQuery);
	delete db;
}

public float receiveMYSQLSurf(int client, float f_playerTime, int i_zoneEndIndex)
{
	//variables
	float iCollected;
	char sQuery[255];
	char sSID[64];
	char error[255];
	DBResultSet rs;
	Database db;
	
	if (SQL_CheckConfig("zetimer"))
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
	Format(sQuery, sizeof(sQuery), "SELECT `%sS%i` FROM `zetimer_tableSurf` WHERE steam_auth = '%s'", g_cMapname, i_zoneEndIndex, sSID);
	//PrintToChatAll("receiveMYSQLSurf sQuery: %s", sQuery);
	if ((rs = SQL_Query(db, sQuery)) == null)
	{
		delete db;
		delete rs;
		return 0.0;
	}
	
	if (SQL_FetchRow(rs))
	{
		iCollected = SQL_FetchFloat(rs, 0);
	}
	
	delete rs;
	delete db;
	return iCollected;
}

public void mysqlLoadNames(int client)
{
	char error[255];
	char sQuery[255];
	char sSID[64];
	Database db;
	DBResultSet rs;
	
	if (SQL_CheckConfig("zetimer")) 
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] {white}Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	
	char cClient[250];
	Format(cClient, sizeof(cClient), "%N", client);
	
	if (StrContains(cClient, "'") >= 0)
	{
		ReplaceString(cClient, sizeof(cClient), "'", "", false);
	}
	
	GetClientAuthId(client, AuthId_Steam2, sSID, sizeof(sSID));
	Format(sQuery, sizeof(sQuery), "UPDATE `zetimer_table` SET `name`= '%s' WHERE `steam_auth` = '%s'", cClient, sSID);
	SQL_TQuery(db, DummyCallbackSimple, sQuery);
	Format(sQuery, sizeof(sQuery), "UPDATE `zetimer_tableSurf` SET `name`= '%s' WHERE `steam_auth` = '%s'", cClient, sSID);
	SQL_TQuery(db, DummyCallbackSimple, sQuery);
	delete rs;
	delete db;
}

public Action MysqlCheckSurfStage(int client, int count)
{
	if (g_bSmap == false)
	{
		CPrintToChat(client, "[UNLOZE] Does not support Surf zones");
		return Plugin_Handled;
	}
	
	Database db;
	char sQuery[512];
	char error[255];
	
	if (SQL_CheckConfig("zetimer"))
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	Format(sQuery, sizeof(sQuery), "SELECT name, %sS%i FROM `zetimer_tableSurf` WHERE %sS%i > 0.000 ORDER BY %sS%i ASC LIMIT 10", g_cMapname, count, g_cMapname, count, g_cMapname, count);
	db.Query(SQL_SelectTop_Callback, sQuery, GetClientSerial(client), DBPrio_Normal);
	//CPrintToChat(client, " ");
	delete db;
	return Plugin_Handled;
}

//----------------------------------------------------------------------------------------------------
// Purpose: Chat Command for Race timer
//----------------------------------------------------------------------------------------------------

public Action cmd_timerCheck(int client, int args)
{	
	if (g_bRmap == false)
	{
		CPrintToChat(client, "[UNLOZE] Does not support race zones");
		return Plugin_Handled;
	}
	Database db;
	char sQuery[512];
	char error[555];
	
	if (SQL_CheckConfig("zetimer"))
	{
		db = SQL_Connect("zetimer", true, error, sizeof(error));
	}
	if (db == null)
	{
		CPrintToChatAll("{green}[Unloze] Error! Could not connect to MYSQL-DB!");
		delete db;
	}
	g_iSurf[client] = 0;
	Format(sQuery, sizeof(sQuery), "SELECT name, %s FROM `zetimer_table` WHERE %s > 0.000 ORDER BY %s ASC LIMIT 10", g_cMapname, g_cMapname, g_cMapname);
	db.Query(SQL_SelectTop_Callback, sQuery, GetClientSerial(client), DBPrio_Normal);
	
	delete db;
	return Plugin_Handled;
}

//----------------------------------------------------------------------------------------------------
// Purpose: Chat Command for Surf timer
//----------------------------------------------------------------------------------------------------

public Action cmd_timerCheckS1(int client, int args)
{
	g_iSurf[client] = 1;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS2(int client, int args)
{		
	g_iSurf[client] = 2;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS3(int client, int args)
{		
	g_iSurf[client] = 3;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS4(int client, int args)
{		
	g_iSurf[client] = 4;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS5(int client, int args)
{		
	g_iSurf[client] = 5;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS6(int client, int args)
{		
	g_iSurf[client] = 6;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS7(int client, int args)
{		
	g_iSurf[client] = 7;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS8(int client, int args)
{		
	g_iSurf[client] = 8;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS9(int client, int args)
{		
	g_iSurf[client] = 9;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

public Action cmd_timerCheckS010(int client, int args)
{		
	g_iSurf[client] = 10;
	MysqlCheckSurfStage(client, g_iSurf[client]);
	return Plugin_Handled;
}

//----------------------------------------------------------------------------------------------------
// Purpose: Menus
//----------------------------------------------------------------------------------------------------
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)
{
	
	/* If the menu was cancelled, print a message to the server about it. */
	if (action == MenuAction_Cancel)
	{
		PrintToServer("Client %d's menu was cancelled.  Reason: %d", param1, param2);
	}
	/* If the menu has ended, destroy it */
	else if (action == MenuAction_End)
	{
		delete menu;
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose: Roundstart/roundend, Postadmincheck, disconnect
//----------------------------------------------------------------------------------------------------

public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
{
	for (int i = 1; i < MaxClients; i++)
	{
		if (IsValidClient(i))
		{
			g_fPlayertimes[i] = 0.0;
			g_bMessage[i] = false;
			g_fEngineRoundtimeSurf[i] = 0.0;
			g_fEngineSecondsSurf[i] = 0.0;
			g_iEngine_minutesSurf[i] = 0;
			
			g_iCurrentS[i] = -1;
			g_iSurf[i] = 0;
		}
	}
	g_fEngineRoundtime = 0.0;
	g_iEngine_minutes = 0;
	g_fEngineSeconds = 0.0;
	CreateTimer(0.1, Timer_CountdownRace, _, TIMER_REPEAT);
	g_bRoundend = false;
}

public void Event_RoundEnd(Handle event, const char[] name, bool dontBroadcast)
{
	g_bRoundend = true;
}
public void OnClientDisconnect(int client)
{
	//disconnect is triggered on each map switch
	g_bMessage[client] = false;
	g_fPlayertimes[client] = 0.0;
	g_fEngineRoundtimeSurf[client] = 0.0;
	g_fEngineSecondsSurf[client] = 0.0;
	g_iEngine_minutesSurf[client] = 0;
	g_iCurrentS[client] = 0;
	g_iSurf[client] = 0;
	g_bStopTimer[client] = false;
}

public void OnClientPostAdminCheck(int client)
{
	g_bMessage[client] = false;
	g_fPlayertimes[client] = 0.0;
	g_fEngineRoundtimeSurf[client] = 0.0;
	g_fEngineSecondsSurf[client] = 0.0;
	g_iEngine_minutesSurf[client] = 0;
	g_iCurrentS[client] = 0;
	g_iSurf[client] = 0;
	g_bStopTimer[client] = true;
}

//----------------------------------------------------------------------------------------------------
// Purpose: Counting maptime functions
//----------------------------------------------------------------------------------------------------

//Callback for timer
public Action Timer_CountdownRace(Handle timer, any data)
{	
	if (g_bRoundend)
	{
		return Plugin_Stop;
	}
	
	g_fEngineRoundtime += 0.1;
	g_fEngineSeconds += 0.1;
	if (g_fEngineSeconds >= 60.0)
	{
		g_iEngine_minutes += 1;
		g_fEngineSeconds = 0.0;
	}
	
	return Plugin_Changed;
}


public Action Timer_CountdownSurf(Handle timer, int client)
{	
	if (g_iCurrentS[client] == -1 || !g_bStopTimer[client])
	{
		if (g_hSurfTimer[client] != INVALID_HANDLE)
		{
			delete g_hSurfTimer[client];	
		}
		return Plugin_Stop;
	}
	//PrintToChatAll("g_fEngineRoundtimeSurf: %f", g_fEngineRoundtimeSurf[client]);
	//PrintToChatAll("g_fEngineSecondsSurf: %f", g_fEngineSecondsSurf[client]);
	g_fEngineRoundtimeSurf[client] += 0.1;
	g_fEngineSecondsSurf[client] += 0.1;
	if (g_fEngineSecondsSurf[client] >= 60.0)
	{
		g_iEngine_minutesSurf[client] += 1;
		g_fEngineSecondsSurf[client] = 0.0;
	}
	
	return Plugin_Changed;
}

public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
	g_iCurrentS[client] = -1;
}

//----------------------------------------------------------------------------------------------------
// Purpose: zone forwards
//----------------------------------------------------------------------------------------------------
public void unloze_zoneLeave(int client, char [] zone)
{	
	if (IsValidClient(client) && GetClientTeam(client) == 3 && StrContains(zone, "ZONE_PREFIX_SURF_S", false) >= 0)
	{
		//PrintToChatAll("unloze_zoneLeave succesfull: %s", zone);
		g_fEngineRoundtimeSurf[client] = 0.0;
		g_fEngineSecondsSurf[client] = 0.0;
		g_iEngine_minutesSurf[client] = 0;
		g_iCurrentS[client] = -1;
		
		//createtime only one per player
		g_hSurfTimer[client] = CreateTimer(0.1, Timer_CountdownSurf, client, TIMER_REPEAT);
		g_iCurrentS[client] = 0;
	}
}
public void unloze_zoneEntry(int client, char[] zone)
{	
	float oldTime[MAXPLAYERS];
	//ZONE_PREFIX_RACE
	
	if (IsValidClient(client) && GetClientTeam(client) == 3 && StrContains(zone, ZONE_PREFIX_RACE, false) >= 0)
	{
		g_bRmap = true;
	
		g_fPlayertimes[client] = g_fEngineRoundtime;
		
		if (g_bMessage[client] == true)
		{
			return;
		}
		
		CPrintToChat(client, "{green}[Unloze] Client: %N \nTime: %i:%f", client, g_iEngine_minutes, g_fEngineSeconds);
		oldTime[client] = receiveMYSQL(client, g_fPlayertimes[client]);
	
		int engine_cMin = 0;
		float engine_cSec = 0.0;
		engine_cMin = RoundToFloor(oldTime[client] / 60);
		engine_cSec = oldTime[client] - (engine_cMin * 60);
		CPrintToChat(client, "Your record: 0%i:%f \n Command: !toptime", engine_cMin, engine_cSec);
		
		if (g_fPlayertimes[client] < oldTime[client] || oldTime[client] == -1.000000 || oldTime[client] == 0.000000)
		{	
			sendMYSQL(client, g_fPlayertimes[client]);
			CPrintToChat(client, "Updated timer");
		}
		g_bMessage[client] = true;
		return;
	}
	
	
	//everything below here is only for ZONE_PREFIX_SURF
	
	if (StrContains(zone, "ZONE_PREFIX_SURF_S", false) >= 0)
	{
		//When the first client enters the surf gets unlocked
		//else do nothing with surf start zoneEntry
		g_bSmap = true;
		return;
	}
	
	if (StrContains(zone, "ZONE_PREFIX_SURF_E", false) < 0)
	{
		//if client entered non surf end zone stop
		return;
	}
	
	char out[64];
	//stops timer unsafe?
	g_iCurrentS[client] = -1;
	
	
	if (StrContains(zone, "10", false) < 0)
	{
		Regexmatcher(zone, out, sizeof(out));
	}
	else
	{
		Format(out, sizeof(out), "10");
	}
	if (GetClientTeam(client) != 3)
	{
		return;
	}
	int i_zoneEndIndex;
	int engine_cMinS1 = 0;
	float engine_cSecS1 = 0.0;
	//PrintToChatAll("zone: %s", zone);
	//PrintToChatAll("out: %s", out);
	i_zoneEndIndex = StringToInt(out);
	
	
	g_fPlayertimes[client] = g_fEngineRoundtimeSurf[client];
	oldTime[client] = receiveMYSQLSurf(client, g_fPlayertimes[client], i_zoneEndIndex);
	//CPrintToChat(client, "oldTime[%N] ZONE_PREFIX_SURF: %f", client, oldTime[client]);
	
	CPrintToChat(client, "{green}[UNLOZE] Client: %N \nTime: %i:%f", client, g_iEngine_minutesSurf[client], g_fEngineSecondsSurf[client]);
	
	engine_cMinS1 = RoundToFloor(oldTime[client] / 60);
	engine_cSecS1 = oldTime[client] - (engine_cMinS1 * 60);
	
	CPrintToChat(client, "Your record Stage %i: 0%i:%f \n Command: !s%i", i_zoneEndIndex, engine_cMinS1, engine_cSecS1, i_zoneEndIndex);		
	
	if (g_fPlayertimes[client] < oldTime[client] || oldTime[client] <= 0.000000)
	{
		sendMYSQLSurf(client, g_fPlayertimes[client], i_zoneEndIndex);
		CPrintToChat(client, "Updated surftimer");
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose: stocks
//----------------------------------------------------------------------------------------------------
stock bool IsValidClient(int client)
{
    if (client > 0 && client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client) && IsPlayerAlive(client))
    {
        return true;
    }
    return false;
}

stock void Regexmatcher(const char[] message, char[] out, int maxlen)
{
        Regex regex = CompileRegex("[0-9]");
        //the match is needed for getsubstring apperently
        regex.Match(message);
        regex.GetSubString(0, out, maxlen);
}

public void DummyCallbackSimple(Handle hOwner, Handle hChild, const char[] err, DataPack pack1)
{
	if (hOwner == null || hChild == null)
	{
		LogError("Query error. (%s)", err);
	}
}

stock void SQL_FetchClientName(int client, Database database, char[] buffer, int size)
{
	char sName[MAX_NAME_LENGTH];
	GetClientName(client, sName, sizeof(sName));

	int size2 = 2 * strlen(sName) + 1;
	char[] sEscapedName = new char[size2 + 1];
	SQL_EscapeString(database, sName, sEscapedName, size2 + 1);

	strcopy(buffer, size, sEscapedName);
}