All pastes #208198 Raw Edit

YSS_logging.pwn

public text v1 · immutable
#208198 ·published 2006-10-18 13:57 UTC
rendered paste body
/*

Alex "Y_Less" Cole's server system

 - callback logging module

Callback logging system, records all events in all callbacks.
Based on previous logging systems I have produced but much improved.

Features:

Single variable settings - MUCH more efficient
Constant saving - log file will always be up to date

Commands:

*/

#include <a_samp>
#include "YSScommon.pwn"

#define YS_LOGGING_ON  // Always on
//#define YS_LOGGING_SEL // INI defined
// Note the lack of YS_LOGGING_OFF - if you don't want it, don't use it!

#define dcmd(%1,%2) if ((strcmp(cmdtext, "/%1", true, %2 + 1) == 0) && (((cmdtext[%2 + 1] == 0) && (dcmd_%1(playerid, ""))) || ((cmdtext[%2 + 1] == 32) && (dcmd_%1(playerid, cmdtext[%2 + 2]))))) return 1

#define YS_ON_FILTER_SCRIPT_INIT			0x00000001
#define YS_ON_FILTER_SCRIPT_EXIT			0x00000002
#define YS_ON_PLAYER_REQUEST_CLASS			0x00000004
#define YS_ON_PLAYER_REQUEST_SPAWN			0x00000008
#define YS_ON_PLAYER_CONNECT				0x00000010
#define YS_ON_PLAYER_DISCONNECT				0x00000020
#define YS_ON_PLAYER_SPAWN					0x00000040
#define YS_ON_PLAYER_DEATH					0x00000080
#define YS_ON_VEHICLE_SPAWN					0x00000100
#define YS_ON_VEHICLE_DEATH					0x00000200
#define YS_ON_PLAYER_TEXT					0x00000400
#define YS_ON_PLAYER_PRIVMSG				0x00000800
#define YS_ON_PLAYER_COMMAND_TEXT			0x00001000
#define YS_ON_PLAYER_INFO_CHANGE			0x00002000
#define YS_ON_PLAYER_ENTER_VEHICLE			0x00004000
#define YS_ON_PLAYER_EXIT_VEHICLE			0x00008000
#define YS_ON_PLAYER_STATE_CHANGE			0x00010000
#define YS_ON_PLAYER_ENTER_CHECKPOINT		0x00020000
#define YS_ON_PLAYER_LEAVE_CHECKPOINT		0x00040000
#define YS_ON_GAME_MODE_INIT				0x00080000
#define YS_ON_GAME_MODE_EXIT				0x00100000
#define YS_ON_PLAYER_ENTER_RACE_CHECKPOINT	0x00200000
#define YS_ON_PLAYER_LEAVE_RACE_CHECKPOINT	0x00400000
#define YS_ON_RCON_COMMAND					0x00800000

#define YS_USE_LOGGING						0x80000000
#define YS_USE_PAR_NAMING					0x40000000
#define YS_USE_EXPANDED_PARS				0x20000000
#define YS_USE_DAILY_SAVES					0x10000000

//#define YS_INI___NONE__			0
#define __NONE__				group = 0;
#define YS_INI_MESSAGES			1
#define YS_INI_MEMBERLEVELS		2
#define YS_INI_COMMANDLEVELS	3
#define YS_INI_ALTNAMES			4
#define YS_INI_SETTINGS			5
#define YS_INI_IGNORECOMMANDS	6
#define YS_INI_FILTERCOMMANDS	7
#define YS_INI_LOGGING			8

#define MAX_SKIPPED_COMMANDS 8

new gIgnoredCommands[MAX_SKIPPED_COMMANDS][MAX_FUNC_NAME];
new gFilteredCommands[MAX_SKIPPED_COMMANDS][MAX_FUNC_NAME];

forward ReadINI(update);

/*enum ST_DAT_ENUM
{
	SS_TXT[40],
	SS_NUM[3]
}

enum RS_DAT_ENUM
{
	RS_TXT[28],
	RS_NUM[3]
}

enum LS_DAT_ENUM
{
	LS_TXT[12],
	LS_NUM[3]
}*/

new gRecArray = -1;
new gDateFormat[11] = "dd:mm:yyyy";

#define LOG_FILE_NAME "YSS_LOG.%s.txt"

#define PAR_DAT(%1) (gRecArray & YS_USE_PAR_NAMING) ? "%1: " : ""
/*#define ST_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? (statenames[((%1) >= 0 && (%1) < (sizeof (statenames) - 1)) ? (%1) : (sizeof (statenames) - 1)][SS_TXT]) : (statenames[((%1) >= 0 && (%1) < (sizeof (statenames) - 1)) ? (%1) : (sizeof (statenames) - 1)][SS_NUM])
#define RS_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? (reasonnames[((%1) >= 0 && (%1) < (sizeof (reasonnames) - 1)) ? (%1) : (sizeof (reasonnames) - 1)][RS_TXT]) : (reasonnames[((%1) >= 0 && (%1) < (sizeof (reasonnames) - 1)) ? (%1) : (sizeof (reasonnames) - 1)][RS_NUM])
#define LS_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? (reasonnames[((%1) >= 0 && (%1) < (sizeof (reasonnames) - 1)) ? (%1) : (sizeof (reasonnames) - 1)][LS_TXT]) : (reasonnames[((%1) >= 0 && (%1) < (sizeof (reasonnames) - 1)) ? (%1) : (sizeof (reasonnames) - 1)][LS_NUM])*/
//#define PARAMETER_DAT(%1,%2,%3) (gRecArray & YS_USE_EXPANDED_PARS) ? %2[((%1) >= 0 && (%1) < (sizeof (%2) - 1)) ? (%1) : (sizeof (%2) - 1)][%3S_TXT] : %2[((%1) >= 0 && (%1) < (sizeof (%2) - 1)) ? (%1) : (sizeof (%2) - 1)][%3S_NUM]
/*#define ST_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? statenames[(%1)][SS_TXT] : statenames[(%1)][SS_NUM]
#define RS_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? reasonnames[(%1)][RS_TXT] : reasonnames[(%1)][RS_NUM]
#define LS_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? reasonnames[(%1)][LS_TXT] : reasonnames[(%1)][LS_NUM]*/

#define REASON_DAT(%1) (gRecArray & YS_USE_EXPANDED_PARS) ? reasonnames[(%1)] : ""
//#define REASON_NUM(%1) ((%1) >= 0 && (%1) <= (sizeof (reasonnames) - 1))

#define ID_DAT ReturnPlayerIDData(playerid)

#if defined YS_LOGGING_ON
	#define YS_LOG_CODE(%1,%2) new str[256]; if (gRecArray & (%1)) { format(str, sizeof (str), %2); yLog(str); }
#else
    #define YS_LOG_CODE(%1,%2) new str[256]; if ((gRecArray & YS_USE_LOGGING) && (gRecArray & (%1))) { format(str, sizeof (str), %2); yLog(str); }
#endif

#define FILTERSCRIPT

#if defined FILTERSCRIPT

public OnFilterScriptInit()
{
	/*print("\n====================================");
	print("|                                  |");
	print("|        YSS logging module        |");
	print("|       --------------------       |");
	print("|                                  |");
	print("| By Alex \"Y_Less\" Cole - (c) 2006 |");
	print("|                                  |");
	print("====================================\n");*/

	ADD_MODULE("logging", "YSS logging module v0.1 (c) Alex \"Y_Less\" Cole")
	
	READINI

	YS_LOG_CODE(YS_ON_FILTER_SCRIPT_INIT, "OnFilterScriptInit()")
	
	return 1;
}

public OnFilterScriptExit()
{
	YS_LOG_CODE(YS_ON_FILTER_SCRIPT_EXIT, "OnFilterScriptExit()")
	REMOVE_MODULE("logging")
	return 1;
}

#else

main()
{
	print("\n====================================");
	print("|                                  |");
	print("|      Blank Gamemode Script!      |");
	print("|     ------------------------     |");
	print("|                                  |");
	print("| By Alex \"Y_Less\" Cole - (c) 2006 |");
	print("|                                  |");
	print("====================================\n");
}

#endif

public OnGameModeInit()
{
	YS_LOG_CODE(YS_ON_FILTER_SCRIPT_EXIT, "OnGameModeInit()")
	return 1;
}

public OnGameModeExit()
{
	YS_LOG_CODE(YS_ON_FILTER_SCRIPT_EXIT, "OnGameModeExit()")
	return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
	YS_LOG_CODE(YS_ON_PLAYER_REQUEST_CLASS, "OnPlayerRequestClass(%s%s, %s%d)", PAR_DAT(playerid), ID_DAT, PAR_DAT(classid), classid)
	return 1;
}

public OnPlayerRequestSpawn(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_REQUEST_SPAWN, "OnPlayerRequestSpawn(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnPlayerConnect(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_CONNECT, "OnPlayerConnect(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

// --------------------------------
// Needs updating with reason texts
// --------------------------------

public OnPlayerDisconnect(playerid, reason)
{
	// 0 - Connection lost
	// 1 - Disconnected
	// 2 - Kicked
	/*static reasonnames[][LS_DAT_ENUM] =
	{
		{"0: LOST",		"0"},
		{"1: LEFT",		"1"},
		{"2: KICKED",	"2"},
		{"-1: UNKNOWN",	"-1"}
	};*/
	static reasonnames[][] =
	{
		{": LOST"},
		{": LEFT"},
		{": KICKED"},
		{": UNKNOWN"}
	};
	myclamp(reason, sizeof (reasonnames) - 1);
	//YS_LOG_CODE(YS_ON_PLAYER_DISCONNECT, "OnPlayerDisconnect(%s%s, %s%d)", PAR_DAT(playerid), ID_DAT, PAR_DAT(reason), PARAMETER_DAT(reason, reasonnames, L))
	YS_LOG_CODE(YS_ON_PLAYER_DISCONNECT, "OnPlayerDisconnect(%s%s, %s%d%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(reason), (reason == sizeof (reasonnames) - 1) ? -1 : reason, REASON_DAT(reason))
	return 1;
}

public OnPlayerSpawn(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_SPAWN, "OnPlayerSpawn(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
	/*static reasonnames[][RS_DAT_ENUM] =
	{
		{"0: UNKNOWN_DEATH_REASON",		"0"},
		{"1: WEAPON_BRASSKNUCKLE",		"1"},
		{"2: WEAPON_GOLFCLUB",			"2"},
		{"3: WEAPON_NITESTICK",			"3"},
		{"4: WEAPON_KNIFE",				"4"},
		{"5: WEAPON_BAT",				"5"},
		{"6: WEAPON_SHOVEL",			"6"},
		{"7: WEAPON_POOLSTICK",			"7"},
		{"8: WEAPON_KATANA",			"8"},
		{"9: WEAPON_CHAINSAW",			"9"},
		{"10: WEAPON_DILDO",			"10"},
		{"11: WEAPON_DILDO2",			"11"},
		{"12: WEAPON_VIBRATOR",			"12"},
		{"13: WEAPON_VIBRATOR2",		"13"},
		{"14: WEAPON_FLOWER",			"14"},
		{"15: WEAPON_CANE",				"15"},
		{"16: WEAPON_GRENADE",			"16"},
		{"17: WEAPON_TEARGAS",			"17"},
		{"18: WEAPON_MOLTOV",			"18"},
		{"19: UNKNOWN_DEATH_REASON",	"19"},
		{"20: UNKNOWN_DEATH_REASON",	"20"},
		{"21: UNKNOWN_DEATH_REASON",	"21"},
		{"22: WEAPON_COLT45",			"22"},
		{"23: WEAPON_SILENCED",			"23"},
		{"24: WEAPON_DEAGLE",			"24"},
		{"25: WEAPON_SHOTGUN",			"25"},
		{"26: WEAPON_SAWEDOFF",			"26"},
		{"27: WEAPON_SHOTGSPA",			"27"},
		{"28: WEAPON_UZI",				"28"},
		{"29: WEAPON_MP5",				"29"},
		{"30: WEAPON_AK47",				"30"},
		{"31: WEAPON_M4",				"31"},
		{"32: WEAPON_TEC9",				"32"},
		{"33: WEAPON_RIFLE",			"33"},
		{"34: WEAPON_SNIPER",			"34"},
		{"35: WEAPON_ROCKETLAUNCHER",	"35"},
		{"36: WEAPON_HEATSEEKER",		"36"},
		{"37: WEAPON_FLAMETHROWER",		"37"},
		{"38: WEAPON_MINIGUN",			"38"},
		{"39: WEAPON_SATCHEL",			"39"},
		{"40: WEAPON_BOMB",				"40"},
		{"41: WEAPON_SPRAYCAN",			"41"},
		{"42: WEAPON_FIREEXTINGUISHER",	"42"},
		{"43: WEAPON_CAMERA",			"43"},
		{"44: UNKNOWN_DEATH_REASON",	"44"},
		{"45: UNKNOWN_DEATH_REASON",	"45"},
		{"46: WEAPON_PARACHUTE",		"46"},
		{"47: UNKNOWN_DEATH_REASON",	"47"},
		{"48: UNKNOWN_DEATH_REASON",	"48"},
		{"49: WEAPON_VEHICLE",			"49"},
		{"50: UNKNOWN_DEATH_REASON",	"50"},
		{"51: UNKNOWN_DEATH_REASON",	"51"},
		{"52: UNKNOWN_DEATH_REASON",	"52"},
		{"53: WEAPON_DROWN",			"53"},
		{"54: WEAPON_COLLISION",		"54"},
		{"-1: REASON_OUT_OF_BOUNDS",	"-1"}
	};*/
	static reasonnames[][] =
	{
		{": UNKNOWN_DEATH_REASON"},
		{": WEAPON_BRASSKNUCKLE"},
		{": WEAPON_GOLFCLUB"},
		{": WEAPON_NITESTICK"},
		{": WEAPON_KNIFE"},
		{": WEAPON_BAT"},
		{": WEAPON_SHOVEL"},
		{": WEAPON_POOLSTICK"},
		{": WEAPON_KATANA"},
		{": WEAPON_CHAINSAW"},
		{": WEAPON_DILDO"},
		{": WEAPON_DILDO2"},
		{": WEAPON_VIBRATOR"},
		{": WEAPON_VIBRATOR2"},
		{": WEAPON_FLOWER"},
		{": WEAPON_CANE"},
		{": WEAPON_GRENADE"},
		{": WEAPON_TEARGAS"},
		{": WEAPON_MOLTOV"},
		{": UNKNOWN_DEATH_REASON"},
		{": UNKNOWN_DEATH_REASON"},
		{": UNKNOWN_DEATH_REASON"},
		{": WEAPON_COLT45"},
		{": WEAPON_SILENCED"},
		{": WEAPON_DEAGLE"},
		{": WEAPON_SHOTGUN"},
		{": WEAPON_SAWEDOFF"},
		{": WEAPON_SHOTGSPA"},
		{": WEAPON_UZI"},
		{": WEAPON_MP5"},
		{": WEAPON_AK47"},
		{": WEAPON_M4"},
		{": WEAPON_TEC9"},
		{": WEAPON_RIFLE"},
		{": WEAPON_SNIPER"},
		{": WEAPON_ROCKETLAUNCHER"},
		{": WEAPON_HEATSEEKER"},
		{": WEAPON_FLAMETHROWER"},
		{": WEAPON_MINIGUN"},
		{": WEAPON_SATCHEL"},
		{": WEAPON_BOMB"},
		{": WEAPON_SPRAYCAN"},
		{": WEAPON_FIREEXTINGUISHER"},
		{": WEAPON_CAMERA"},
		{": UNKNOWN_DEATH_REASON"},
		{": UNKNOWN_DEATH_REASON"},
		{": WEAPON_PARACHUTE"},
		{": UNKNOWN_DEATH_REASON"},
		{": UNKNOWN_DEATH_REASON"},
		{": WEAPON_VEHICLE"},
		{": UNKNOWN_DEATH_REASON"},
		{": UNKNOWN_DEATH_REASON"},
		{": UNKNOWN_DEATH_REASON"},
		{": WEAPON_DROWN"},
		{": WEAPON_COLLISION"},
		{": /KILL_OR_OTHER"},
		{": REASON_OUT_OF_BOUNDS"}
	};
	if (reason == 255) reason = sizeof (reasonnames) - 2; // /kill usually
	myclamp(reason, sizeof (reasonnames) - 1);
	//YS_LOG_CODE(YS_ON_PLAYER_DEATH, "OnPlayerDeath(%s%s, %s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(killerid), ReturnPlayerIDData(killerid), PAR_DAT(reason), RS_DAT(reason))
	YS_LOG_CODE(YS_ON_PLAYER_DEATH, "OnPlayerDeath(%s%s, %s%s, %s%d%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(killerid), ReturnPlayerIDData(killerid), PAR_DAT(reason), (reason == sizeof (reasonnames) - 1) ? -1 : ((reason == sizeof (reasonnames) - 2) ? 255 : reason), REASON_DAT(reason))
	return 1;
}

public OnVehicleSpawn(vehicleid)
{
	YS_LOG_CODE(YS_ON_VEHICLE_SPAWN, "OnVehicleSpawn(%s%d)", PAR_DAT(vehicleid), vehicleid)
	return 1;
}

public OnVehicleDeath(vehicleid, killerid)
{
	YS_LOG_CODE(YS_ON_VEHICLE_DEATH, "OnVehicleDeath(%s%d, %s%s)", PAR_DAT(vehicleid), vehicleid, PAR_DAT(killerid), ReturnPlayerIDData(killerid))
	return 1;
}

public OnPlayerText(playerid, text[])
{
	YS_LOG_CODE(YS_ON_PLAYER_TEXT, "OnPlayerText(%s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(text[]), text)
	return 1;
}

public OnPlayerPrivmsg(playerid, senderid, text[])
{
	YS_LOG_CODE(YS_ON_PLAYER_PRIVMSG, "OnPlayerPrivmsg(%s%s, %s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(senderid), ReturnPlayerIDData(senderid), PAR_DAT(text[]), text)
	return 1;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
	if (IsPlayerConnected(playerid))
	{
		#if !defined YS_LOGGING_ON
			if (gRecArray & YS_USE_LOGGING)
			{
		#endif
				new len = strlen(gPrefix) + 1;
				if (strlen(cmdtext) <= len) len = 1; // Just to be safe
				//if (strcmp(gPrefix, cmdtext, true, len) || (cmdtext[len] != ' ' && cmdtext[len] != 0)) len = 1;
				//else if (cmdtext[len] == ' ') len++;
				if (gRecArray & YS_ON_PLAYER_COMMAND_TEXT)
				{
					new dontrec;
					for (new i = 0; i < MAX_SKIPPED_COMMANDS; i++)
					{
						new k = strlen(gIgnoredCommands[i]);
						if (gIgnoredCommands[i][0] == 0) break;
						else if (strcmp(gIgnoredCommands[i], cmdtext[len], true, k) == 0 || strcmp(gIgnoredCommands[i], cmdtext[1], true, k) == 0)
						{
							dontrec = 1;
							break;
						}
					}
					if (!dontrec)
					{
						for (new i = 0; i < MAX_SKIPPED_COMMANDS; i++)
						{
							new k = strlen(gFilteredCommands[i]);
							if (gFilteredCommands[i][0] == 0) break;
							else if (strcmp(gFilteredCommands[i], cmdtext[len], true, k) == 0)
							{
								dontrec = -1;
								len += k;
								break;
							}
							else if (strcmp(gFilteredCommands[i], cmdtext[1], true, k) == 0)
							{
								dontrec = -1;
								len = k + 1;
								break;
							}
						}
						new str[256];
						if (dontrec)
						{
							strmid(str, cmdtext, 0, len);
							format(str, sizeof (str), "OnPlayerCommandText(%s%s, %s%s <parameters>)", PAR_DAT(playerid), ID_DAT, PAR_DAT(cmdtext[]), str);
							//YS_LOG_CODE(YS_ON_PLAYER_COMMAND_TEXT, "OnPlayerCommandText(%s%s, %s%s <parameters>)", PAR_DAT(playerid), ID_DAT, PAR_DAT(cmdtext[]), str)
						}
						else
						{
							format(str, sizeof (str), "OnPlayerCommandText(%s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(cmdtext[]), cmdtext);
							//YS_LOG_CODE(YS_ON_PLAYER_COMMAND_TEXT, "OnPlayerCommandText(%s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(cmdtext[]), cmdtext)
						}
						yLog(str);
					}
					else
					{
						YS_LOG_CODE(YS_ON_PLAYER_COMMAND_TEXT, "OnPlayerCommandText(%s%s, <command>)", PAR_DAT(playerid), ID_DAT)
					}
				}
		#if !defined YS_LOGGING_ON
			}
		#endif
	}
	else
	{
		YS_LOG_CODE(YS_ON_PLAYER_COMMAND_TEXT, "Exploit attempt: OnPlayerCommandText(%s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(cmdtext[]), cmdtext)
		return 1;
	}
	return 0;
}

public OnPlayerInfoChange(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_INFO_CHANGE, "OnPlayerInfoChange(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
	YS_LOG_CODE(YS_ON_PLAYER_ENTER_VEHICLE, "OnPlayerEnterVehicle(%s%s, %s%d, %s%d)", PAR_DAT(playerid), ID_DAT, PAR_DAT(vehicleid), vehicleid, PAR_DAT(ispassenger), ispassenger)
	return 1;
}

public OnPlayerExitVehicle(playerid, vehicleid)
{
	YS_LOG_CODE(YS_ON_PLAYER_EXIT_VEHICLE, "OnPlayerExitVehicle(%s%s, %s%d)", PAR_DAT(playerid), ID_DAT, PAR_DAT(vehicleid), vehicleid)
	return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
	/*static statenames[][ST_DAT_ENUM] =
	{
		{"0: PLAYER_STATE_NONE",					"0"},
		{"1: PLAYER_STATE_ONFOOT",					"1"},
		{"2: PLAYER_STATE_DRIVER",					"2"},
		{"3: PLAYER_STATE_PASSENGER",				"3"},
		{"4: PLAYER_STATE_EXIT_VEHICLE",			"4"},
		{"5: PLAYER_STATE_ENTER_VEHICLE_DRIVER",	"5"},
		{"6: PLAYER_STATE_ENTER_VEHICLE_PASSENGER",	"6"},
		{"7: PLAYER_STATE_WASTED",					"7"},
		{"8: PLAYER_STATE_SPAWNED",					"8"},
		{"-1: PLAYER_STATE_UNKNOWN",				"-1"}
	};*/
	static reasonnames[][] =
	{
		{": PLAYER_STATE_NONE"},
		{": PLAYER_STATE_ONFOOT"},
		{": PLAYER_STATE_DRIVER"},
		{": PLAYER_STATE_PASSENGER"},
		{": PLAYER_STATE_EXIT_VEHICLE"},
		{": PLAYER_STATE_ENTER_VEHICLE_DRIVER"},
		{": PLAYER_STATE_ENTER_VEHICLE_PASSENGER"},
		{": PLAYER_STATE_WASTED"},
		{": PLAYER_STATE_SPAWNED"},
		{": PLAYER_STATE_UNKNOWN"}
	};
	myclamp(newstate, sizeof (reasonnames) - 1);
	myclamp(oldstate, sizeof (reasonnames) - 1);
	//YS_LOG_CODE(YS_ON_PLAYER_DEATH, "OnPlayerDeath(%s%s, %s%s, %s%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(killerid), ReturnPlayerIDData(killerid), PAR_DAT(reason), RS_DAT(reason))
	//YS_LOG_CODE(YS_ON_PLAYER_DEATH, "OnPlayerDeath(%s%s, %s%s, %s%d%s)", PAR_DAT(playerid), ID_DAT, PAR_DAT(killerid), ReturnPlayerIDData(killerid), PAR_DAT(reason), reason, reasonnames[reason])
	if (gRecArray & YS_USE_PAR_NAMING) // Can't have it on one line - too long!
	{
		//YS_LOG_CODE(YS_ON_PLAYER_STATE_CHANGE, "OnPlayerStateChange(playerid: %s, newstate: %s, oldstate: %s)", ID_DAT, PARAMETER_DAT(newstate, statenames, S), PARAMETER_DAT(oldstate, statenames, S))
		YS_LOG_CODE(YS_ON_PLAYER_STATE_CHANGE, "OnPlayerStateChange(playerid: %s, newstate: %d%s, oldstate: %d%s)", ID_DAT, (newstate == sizeof (reasonnames) - 1) ? -1 : newstate, REASON_DAT(newstate), (oldstate == sizeof (reasonnames) - 1) ? -1 : oldstate, REASON_DAT(oldstate))
	}
	else
	{
		//YS_LOG_CODE(YS_ON_PLAYER_STATE_CHANGE, "OnPlayerStateChange(%s, %s, %s)", ID_DAT, PARAMETER_DAT(newstate, statenames, S), PARAMETER_DAT(oldstate, statenames, S))
		YS_LOG_CODE(YS_ON_PLAYER_STATE_CHANGE, "OnPlayerStateChange(%s, %d%s, %d%s)", ID_DAT, (newstate == sizeof (reasonnames) - 1) ? -1 : newstate, REASON_DAT(newstate), (oldstate == sizeof (reasonnames) - 1) ? -1 : oldstate, REASON_DAT(oldstate))
	}
	return 1;
}

public OnPlayerEnterCheckpoint(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_ENTER_CHECKPOINT, "OnPlayerEnterCheckpoint(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnPlayerLeaveCheckpoint(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_LEAVE_CHECKPOINT, "OnPlayerLeaveCheckpoint(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnPlayerEnterRaceCheckpoint(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_ENTER_CHECKPOINT, "OnPlayerEnterRaceCheckpoint(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnPlayerLeaveRaceCheckpoint(playerid)
{
	YS_LOG_CODE(YS_ON_PLAYER_LEAVE_CHECKPOINT, "OnPlayerLeaveRaceCheckpoint(%s%s)", PAR_DAT(playerid), ID_DAT)
	return 1;
}

public OnRconCommand(cmd[])
{
	YS_LOG_CODE(YS_ON_PLAYER_LEAVE_CHECKPOINT, "OnRconCommand(%s%s)", PAR_DAT(cmd[]), cmd)
	return 1;
}

ReturnPlayerIDData(playerid/*, force = 0*/)
{
	new pdat[128];
	if (IsPlayerConnected(playerid))
	{
		if (gRecArray & YS_USE_EXPANDED_PARS) // Change - change what?
		{
		    format(pdat, sizeof (pdat), "%d: %s", playerid, ReturnPlayerName(playerid));
		}
		else
		{
		    format(pdat, sizeof (pdat), "%d", playerid);
		}
	}
	/*else if (force)
	{
		if (gRecArray & YS_USE_EXPANDED_PARS)
		{
		    format(pdat, sizeof (pdat), "%d: Unknown", playerid);
		}
		else
		{
		    format(pdat, sizeof (pdat), "%d", playerid);
		}
	}*/
	else
	{
		if (gRecArray & YS_USE_EXPANDED_PARS)
		{
			pdat = "-1: None";
		}
		else
		{
			pdat = "-1";
		}
	}
	return pdat;
}

ReturnPlayerName(playerid)
{
	new pname[MAX_PLAYER_NAME];
	GetPlayerName(playerid, pname, sizeof (pname));
	return pname;
}

public ReadINI(update)
{
	new File:inifile;
	if (fexist(INI_NAME))
	{
		inifile = fopen(INI_NAME, io_read);
		if (inifile)
		{
			new igdone;
			new fldone;
			new str[MAX_INI_LINE];
			new group = 0;
			while (fread(inifile, str))
			{
				// Read line first
				if (str[0] == '[')
				{
					StripNL(str);
					INI_GROUP(LOGGING)
					else INI_GROUP(IGNORECOMMANDS)
					else INI_GROUP(FILTERCOMMANDS)
					else INI_GROUP(SETTINGS)
					else __NONE__
				}
				else
				{
					switch (group)
					{
						case YS_INI_LOGGING:
						{
							INIT
							INI_GET_B(OnFilterScriptInit,				YS_ON_FILTER_SCRIPT_INIT,			18, gRecArray)
							else INI_GET_B(OnFilterScriptExit,			YS_ON_FILTER_SCRIPT_EXIT,			18, gRecArray)
							else INI_GET_B(OnPlayerRequestClass,		YS_ON_PLAYER_REQUEST_CLASS,			20, gRecArray)
							else INI_GET_B(OnPlayerRequestSpawn,		YS_ON_PLAYER_REQUEST_SPAWN,			20, gRecArray)
							else INI_GET_B(OnPlayerConnect,				YS_ON_PLAYER_CONNECT,				15, gRecArray)
							else INI_GET_B(OnPlayerDisconnect,			YS_ON_PLAYER_DISCONNECT,			18, gRecArray)
							else INI_GET_B(OnPlayerSpawn,				YS_ON_PLAYER_SPAWN,					13, gRecArray)
							else INI_GET_B(OnPlayerDeath,				YS_ON_PLAYER_DEATH,					13, gRecArray)
							else INI_GET_B(OnVehicleSpawn,				YS_ON_VEHICLE_SPAWN,				14, gRecArray)
							else INI_GET_B(OnVehicleDeath,				YS_ON_VEHICLE_DEATH,				14, gRecArray)
							else INI_GET_B(OnPlayerText,				YS_ON_PLAYER_TEXT,					12, gRecArray)
							else INI_GET_B(OnPlayerPrivmsg,				YS_ON_PLAYER_PRIVMSG,				15, gRecArray)
							else INI_GET_B(OnPlayerCommandText,			YS_ON_PLAYER_COMMAND_TEXT,			19, gRecArray)
							else INI_GET_B(OnPlayerInfoChange,			YS_ON_PLAYER_INFO_CHANGE,			18, gRecArray)
							else INI_GET_B(OnPlayerEnterVehicle,		YS_ON_PLAYER_ENTER_VEHICLE,			20, gRecArray)
							else INI_GET_B(OnPlayerExitVehicle,			YS_ON_PLAYER_EXIT_VEHICLE,			19, gRecArray)
							else INI_GET_B(OnPlayerStateChange,			YS_ON_PLAYER_STATE_CHANGE,			19, gRecArray)
							else INI_GET_B(OnPlayerEnterCheckpoint,		YS_ON_PLAYER_ENTER_CHECKPOINT,		23, gRecArray)
							else INI_GET_B(OnPlayerLeaveCheckpoint,		YS_ON_PLAYER_LEAVE_CHECKPOINT,		23, gRecArray)
							else INI_GET_B(OnPlayerEnterRaceCheckpoint,	YS_ON_PLAYER_ENTER_RACE_CHECKPOINT,	27, gRecArray)
							else INI_GET_B(OnPlayerLeaveRaceCheckpoint,	YS_ON_PLAYER_LEAVE_RACE_CHECKPOINT,	27, gRecArray)
							else INI_GET_B(OnGameModeInit,				YS_ON_GAME_MODE_INIT,				14, gRecArray)
							else INI_GET_B(OnGameModeExit,				YS_ON_GAME_MODE_EXIT,				14, gRecArray)
							else INI_GET_B(OnRconCommand,				YS_ON_RCON_COMMAND,					13, gRecArray)
						}
						case YS_INI_IGNORECOMMANDS:
						{
							StripNL(str);
							if (str[0])
							{
								if (igdone < MAX_SKIPPED_COMMANDS)
								{
									strmid(gIgnoredCommands[igdone], str, 0, strlen(str), MAX_FUNC_NAME);
									igdone++;
								}
								else
								{
									print("YSS warning: Max ignored commands reached, some may not be ignored");
								}
							}
						}
						case YS_INI_FILTERCOMMANDS:
						{
							StripNL(str);
							if (str[0])
							{
								if (fldone < MAX_SKIPPED_COMMANDS)
								{
									strmid(gFilteredCommands[fldone], str, 0, strlen(str), MAX_FUNC_NAME);
									fldone++;
								}
								else
								{
									print("YSS warning: Max filtered commands reached, some may not be filtered");
								}
							}
						}
						case YS_INI_SETTINGS:
						{
							INIT
							INI_GET_S(DateFormat,				gDateFormat,			10)
							else INI_GET_B(UseLogging,			YS_USE_LOGGING,			10, gRecArray)
							else INI_GET_B(ExpandParameters,	YS_USE_EXPANDED_PARS,	16, gRecArray)
							else INI_GET_B(NameParameters,		YS_USE_PAR_NAMING,		14, gRecArray)
							else INI_GET_B(UseDailySaves,		YS_USE_DAILY_SAVES,		13,	gRecArray)
							else if (strcmp(str, "Prefix", true, 6) == 0)
							{
								format(gPrefix, sizeof (gPrefix), "%s%s", strfind(str, "/", false, 6) == -1 ? "/" : "", ReturnINIValue(str[6]));
								StripNL(gPrefix);
							}
							//else INI_GET_I(SaveDelay,			gSaveDelay,				9)
						}
						default:
						{
						}
					}
				}
			}
			//print("YSS message: Settings loaded");
		}
		else
		{
			print("YSS warning: Could not read ini file, default settings loaded");
		}
	}
	else
	{
	    print("YSS warning: Could not find ini file, default settings loaded");
	}
}

yLog(string[])//, time = 1, type[] = "LOGGING")
{
	if (CallRemoteFunction("YSWriteData", "ss", "LOGGING", string)) return 1;
	static filename[24];
	static firstcall = 0;
	new temp[MAX_STRING];
	new newfile = 0;
	format(temp, sizeof (temp), "YSS_LOG.%s.txt", MakeFormattedDate(""));
	if (filename[0] == 0 || ((gRecArray & YS_USE_DAILY_SAVES) && strcmp(filename, temp)))
	{
		strmid(filename, temp, 0, strlen(temp));
		newfile = 1;
	}
	new File:bla = fopen(filename, io_append);
	if (bla)
	{
		if (newfile)
		{
			fwrite(bla, "\r\n====================================\r\n");
			fwrite(bla, "|                                  |\r\n");
			fwrite(bla, "|      Y_Less's server script      |\r\n");
			fwrite(bla, "|      ----------------------      |\r\n");
			fwrite(bla, "|                                  |\r\n");
			fwrite(bla, "| By Alex \"Y_Less\" Cole - (c) 2006 |\r\n");
			fwrite(bla, "|                                  |\r\n");
			fwrite(bla, "====================================\r\n\r\n");
		}
		if (!firstcall)
		{
			firstcall = 1;
			format(temp, sizeof (temp), "[%s] Logging started\r\n", MakeFormattedTime());
			fwrite(bla, temp);
		}
		format(temp, sizeof (temp), "[%s] %s\r\n", MakeFormattedTime(), string);
		fwrite(bla, temp);
		fclose(bla);
	}
	else
	{
		printf("YSS logging error: could not open lod file");
	}
	return 1;
}

MakeFormattedTime()
{
	new str[9], h, m, s;
	gettime(h, m, s);
	format(str, sizeof (str), "%d:%02d:%02d", h, m, s);
	return str;
}

MakeFormattedDate(split[])
{
	new str[11], d, m, y, j;
	getdate(y, m, d);
	if (strlen(gDateFormat) == 8) y %= 100;
	for (new i = 0; i < 3; i++)
	{
		if (gDateFormat[j] == 'd') format(str, sizeof (str), "%s%02d", str, d);
		if (gDateFormat[j] == 'm') format(str, sizeof (str), "%s%02d", str, m);
		if (gDateFormat[j] == 'y') format(str, sizeof (str), "%s%02d", str, y);
		if (i < 2)
		{
			j = strfind(gDateFormat, ":", false, j) + 1;
			strcat(str, split);
		}
	}
	return str;
}

myclamp(&var, max)
{
	/*if (var < 0) var = 0;
	if (var > max) var = max;*/
	if (var < 0 || var > max) var = max;
}