All pastes #121464 Raw Edit

Y_Less

public text v1 · immutable
·published 2006-08-08 01:16 UTC
rendered paste body
/*
================================================================================
|                                                                              |
|               Alex "Y_Less" Cole's server logging system v0.4                |
|              -------------------------------------------------               |
|                                                                              |
| Features/ changelog:                                                         |
|                                                                              |
| v0.4a                                                                        |
| - Fixed a bug with killing yourself                                          |
|                                                                              |
| v0.4:                                                                        |
| - Changed commads:                                                           |
|   skip1 = skipc                                                              |
|   skip2 = skipp                                                              |
|   add1 = addc                                                                |
|   add2 = addp                                                                |
| - Added callbacks OnPlayerRequestSpawn and OnPlayerPrivMsg                   |
|                                                                              |
| v0.3:                                                                        |
| - Added commands:                                                            |
|   /ylog +                                                                    |
|     skip1 - list skipped commands                                            |
|     skip2 - list skipped parameter commands                                  |
|     add1 - add a skipped command                                             |
|     add2 - add a skipped parameter command                                   |
|     reset - reload te settings from file                                     |
|     saveset - save the settings to file                                      |
|     settings - list the settings                                             |
|     callback - toggle recording of the selected callback                     |
|     savedelay - set the save delay                                           |
|     expand - toggle expansion of saved parameters                            |
|     dailysave - toggle new files every day                                   |
| - Autosaves when the last player leaves (fix for OnFilterScriptExit)         |
| - Fixed a bug with save delays of 0                                          |
| - Rewrote some of the settings file load code to be more flexible            |
| - Added parameter expansion option, gives some text with numeric parameters  |
| - Removed autosave on first player connect                                   |
|                                                                              |
| v0.2:                                                                        |
| - Automatic saving (default every hour)                                      |
| - Settings controlled through a cfg file (ylog.cfg)                          |
| - Optional exclusion of any callbacks                                        |
| - Automatic creation of settings file on the first run                       |
|                                                                              |
| v0.1:                                                                        |
| - Logging of standard filterscript callbacks and parameters                  |
| - Optional exclusion of certain commands or parameter (for login security)   |
| - Optional new file every day                                                |
| - Commands:                                                                  |
|   /ylog +                                                                    |
|     save - saves the log file                                                |
|     exit - shuts down the logging system                                     |
|                                                                              |
================================================================================
*/

#include <a_samp>
#include <string>
#include <time>

#define SAVE_DELAY 3600000
// Use for the frequency of you saves

#define DAILY_FILES 1
// Set to 1 to start a new file every day

#define MAX_COMMANDS 64
// Maximum number of commands to filter in either category

new gSkipCommands[MAX_COMMANDS][256];
// Use this to skip entire commands

new gComCount;
// Number of skipped commands

// There is a slight bug, these two must have at least 1 parameter
// using RCON is a bit of a cheat as it's never passed to this system anyway
// Hardcoded commands won't be recorded (they can't be :()

new gSkipParameters[MAX_COMMANDS][256];
// Use this to skip only parameters

new gParCount;
// Number of skipped parameters

new gPlayers = 0;
// Number of players on the server
// When this hits 0 autosave the file as OnFilterScriptExit doesn't work

new gSaving = 1;
// When 0 you can write to the file, when 1 write to the temporary buffer.

new gExpandParams = 1;

new gTempBuf[1024];
// The temporary buffer, used during saves (which take fractions of nothing).

new File:g_fLogFile;
// The file we'll save stuff to

new gDailyFiles = DAILY_FILES;
// Wether or not to save in a new file every day
// Note: new datestamped files are always started on a script restart

new gSaveTimer;
// The timer for saving every hour

new gFileName[256];
// Used to store the current file

new gRecordArray[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
// Array of which callbacks to record

new gSaveDelay = SAVE_DELAY;
// Save delay

new gLastSave = 0;
// Tick count of the last time the thing was saved.

public OnFilterScriptInit()
{
	new string[256];
	//new h, m, s;
	
	gSkipParameters[0] = "/login";
	gSkipParameters[1] = "/identify";
	gSkipParameters[2] = "/register";
	
	gParCount = 3;
	gComCount = 0;

	string = MakeFilename();

	if (fexist(string))
	{
        g_fLogFile = fopen(string, io_append);
	}
	else
	{
        g_fLogFile = fopen(string, io_write);
	}
	
	gSaving = 0;
	/*print("\r\n======================================================");
	print("|                                                    |");
	print("| Alex \"Y_Less\" Cole's server logging system started |");
	print("|                  v0.3 - (c) 2006                   |");
	print("|                                                    |");
	print("======================================================\r\n");*/
	
	print("\r\n====================================");
	print("|                                  |");
	print("|    yLog server logging system    |");
	print("|    --------------------------    |");
	print("|                                  |");
	print("| By Alex \"Y_Less\" Cole - (c) 2006 |");
	print("|               v0.4               |");
	print("====================================\r\n");

	new h, m, s;
	gettime(h, m, s);
	
	gLastSave = ((h * 3600) + (m * 60) + s) * 1000;

    format(gFileName, sizeof (gFileName), "%s", string);

	yLog("======================================================");
	yLog("|                                                    |");
	yLog("| Alex \"Y_Less\" Cole's server logging system started |");
	yLog("|                  v0.4 - (c) 2006                   |");
	format(string, sizeof (string), "|                 Date: %s                 |", MakeFormattedDate());
	yLog(string);
	yLog("|                                                    |");
	yLog("======================================================\r\n");

	if (!ReadConfigs())
	{
	    print("yLog: Warning: config file not found");
	    print("      Default settings loaded\r\n");
	    yLog("yLog: Warning: config file not found");
	    yLog("      Default settings loaded\r\n");
	}

	return 0;
}

/*public savestart(u)
{
	SetTimer("savestart2", u, 0);
	//print("hi");
	// Start it on the hour (or on the SAVE_DELAY)
	//print("hi");

	//gSaveTimer = SetTimer("saveloop", h, 0);
	//saveloop();
	// Set the repeating timer and run it once
}

public savestart2()
{
	//SetTimer("savestart2", h, 0);
	gSaveTimer = SetTimer("saveloop", gSaveDelay, 1);
	saveloop();
}*/


public ReadConfigs()
{
	new pars = 0, coms = 0;
    new File:conf_f;
    new line[256], word[256], index = 0, i = 0;
	if (fexist("ylog.cfg"))
	{
	    conf_f = fopen("ylog.cfg", io_read);

	    while (fread(conf_f, line, sizeof (line)))
	    {
	        index = 0;
        	word = strtok(line, index);
        	if (coms)
        	{
        	    if (gComCount < MAX_COMMANDS)
        	    {
					if (word[0] == '/')
					{
					    stripnl(word);
					    format(gSkipCommands[gComCount], 256, "%s", word);
					    //printf("command: %s", gSkipCommands[gComCount]);
					    gComCount++;
					}
					else
					{
						coms = 0;
					}
				}
				else if (coms != 2)
				{
				    yLog("yLog: Warning: MAX_COMMANDS reached, some commands may not be ignored");
				    print("yLog: Warning: MAX_COMMANDS reached, some commands may not be ignored");
				    coms = 2;
				}
        	}
        	else if (pars)
        	{
        	    if (gParCount < MAX_COMMANDS)
        	    {
					if (word[0] == '/')
					{
					    stripnl(word);
					    format(gSkipParameters[gParCount], 256, "%s", word);
					    //printf("parameter: %s", gSkipParameters[gParCount]);
					    gParCount++;
					}
					else
					{
						pars = 0;
					}
				}
				else if (pars != 2)
				{
				    yLog("yLog: Warning: MAX_COMMANDS reached, some commands may not be partially recorded");
				    print("yLog: Warning: MAX_COMMANDS reached, some commands may not be partially recorded");
				    pars = 2;
				}
	       	}
	       	if (!coms && !pars && word[0])
	       	{
	       		if (strcmp(word, "savedelay", true) == 0)
	       		{
	       		    gSaveDelay = strval(strtok(line, index));
	       		    //printf("savedelay: %d", gSaveDelay);
	       		    if (!gSaveDelay)
	       		    {
	       		        gSaveDelay = SAVE_DELAY;
	       		    }
	       		}
	       		else if (strcmp(word, "recarray", true) == 0)
	       		{
					for (i = 0; i < sizeof (gRecordArray); i++)
					{
					    gRecordArray[i] = strval(strtok(line, index));
					}
	       		}
	       		else if (strcmp(word, "expand", true) == 0)
	       		{
					gExpandParams = strval(strtok(line, index));
	       		    //printf("expand: %d", gExpandParams);
	       		}
	       		else if (strcmp(word, "dailysave", true) == 0)
	       		{
				    gDailyFiles = strval(strtok(line, index));
	       		    //printf("dailysave: %d", gDailyFiles);
	       		}
	       		else if (strcmp(word, "skipcoms", true) == 0)
	       		{
	       		    gComCount = 0;
					coms = 1;
	       		}
	  			else if (strcmp(word, "skippars", true) == 0)
	       		{
	       		    gParCount = 0;
	       		    pars = 1;
				}
			}
	    }
	    fclose(conf_f);
		return 1;
	}
	else
	{
		WriteConfigs();
	}
	return 0;
}

public WriteConfigs()
{
    new File:conf_f;
    new line[256], i = 0;

	conf_f = fopen("ylog.cfg", io_write);
	format(line, sizeof (line), "savedelay %d\r\ndailysave %d\r\nexpand %d\r\n", gSaveDelay, gDailyFiles, gExpandParams);
	fwrite(conf_f, line);
	line = "recarray";

	for (i = 0; i < sizeof (gRecordArray); i++)
	{
	    format(line, sizeof (line), "%s %d", line, gRecordArray[i]);
	}
	fwrite(conf_f, line);

	fwrite(conf_f, "\r\nskipcoms\r\n");
	for (i = gComCount; i > 0; i--)
	//while (gSkipCommands[i][0])
	{
	    fwrite(conf_f, gSkipCommands[i - 1]);
	    fwrite(conf_f, "\r\n");
	}

	//i = 0;
	fwrite(conf_f, "skippars\r\n");
	for (i = gParCount; i > 0; i--)
	//while (gSkipParameters[i][0])
	{
	    fwrite(conf_f, gSkipParameters[i - 1]);
	    fwrite(conf_f, "\r\n");
	}

	/*for (i = 0; i < sizeof (gSkipCommands); i++);
	{
	    fwrite(conf_f, gSkipCommands[i]);
	    fwrite(conf_f, "\r\n");
	}
	fwrite(conf_f, "skippars\r\n");

	for (i = 0; i < sizeof (gSkipParameters); i++);
	{
	    fwrite(conf_f, gSkipParameters[i]);
	    fwrite(conf_f, "\r\n");
	}*/
	
    fclose(conf_f);
    
	return 0;
}

saveloop(call = false)
{
	if (call)
	{
		fwrite(g_fLogFile, "\r\n");
		yLog("==========");
		yLog("Data Saved");
		yLog("==========\r\n");
	}
	else
	{
		fwrite(g_fLogFile, "\r\n");
		yLog("==========");
		yLog("Auto Saved");
		yLog("==========\r\n");
	}
	
    gSaving = 1;
    new string[256];
	// Mark as saving (just in case, though I doubt it matters)
    fclose(g_fLogFile);
    if (gDailyFiles)
    {
		string = MakeFilename();
	}
	else
	{
	    format(string, sizeof (string), "%s", gFileName);
	}
	
	if (fexist(string))
	{
        g_fLogFile = fopen(string, io_append);
	}
	else
	{
        g_fLogFile = fopen(string, io_write);
	}

	if (strcmp(string, gFileName))
	{
		new timestr[256];
		timestr = MakeFormattedTime();
		fwrite(g_fLogFile, timestr);
		fwrite(g_fLogFile, ": ======================================================\r\n");
		fwrite(g_fLogFile, timestr);
		fwrite(g_fLogFile, ": |                                                    |");
		fwrite(g_fLogFile, timestr);
		fwrite(g_fLogFile, ": | Alex \"Y_Less\" Cole's server logging system running |\r\n");
		fwrite(g_fLogFile, timestr);
		fwrite(g_fLogFile, ": |                  v0.4 - (c) 2006                   |");
		fwrite(g_fLogFile, timestr);
		format(string, sizeof (string), ": |                 Date: %s                 |", MakeFormattedDate());
		fwrite(g_fLogFile, string);
		fwrite(g_fLogFile, timestr);
		fwrite(g_fLogFile, ": |                                                    |");
		fwrite(g_fLogFile, timestr);
		fwrite(g_fLogFile, ": ======================================================\r\n\r\n");
	    format(gFileName, sizeof (gFileName), "%s", string);
	}
	
	fwrite(g_fLogFile, gTempBuf);
	strdel(gTempBuf, 0, strlen(gTempBuf));
	// Completely blank it fully
	gSaving = 0;

}

yLog(string[])
{
	if (gSaving)
	{
	    strcat(gTempBuf, MakeFormattedTime());
	    strcat(gTempBuf, ": ");
		strcat(gTempBuf, string);
		strcat(gTempBuf, "\r\n");
	}
	else
	{
	    fwrite(g_fLogFile, MakeFormattedTime());
	    fwrite(g_fLogFile, ": ");
	    fwrite(g_fLogFile, string);
	    fwrite(g_fLogFile, "\r\n");
	}

	new h, m, s;
	gettime(h, m, s);
	
	h = ((h * 3600) + (m * 60) + s) * 1000;

	if (((h < gSaveDelay) && (((h + 86400000) - gLastSave) > gSaveDelay)) || ((h - gLastSave) > gSaveDelay))
	{
		saveloop();
		gLastSave = h;
	}

/*	if ((GetTickCount() - gLastSave) >= SAVE_DELAY)
	{
	    format(gTempBuf, sizeof (gTempBuf), "%s%s: Autosave\r\n", gTempBuf, MakeFormattedTime());
        saveloop();
        gLastSave += gSaveDelay;
	}*/
}

public getlasthour()
// Strictly getlasttime()
{
	new h, m, s;
	gettime(h, m, s);
	return (GetTickCount() - (((m * 60) + s) * 1000));
}

public MakeFilename()
{
	new d, m, y;
	getdate(y, m, d);
	new string[256];
	string = FormatFigures("Y_Server_Log_", d, "", m, "", y, ".txt");
	return string;
}

MakeFormattedDate()
{
	new d, m, y;
	getdate(y, m, d);
	new string[256];
	string = FormatFigures("[", d, ":", m, ":", y, "]");
	return string;
}

MakeFormattedTime()
{
	new h, m, s;
	gettime(h, m, s);
	new string[256];
	string = FormatFigures("[", h, ":", m, ":", s, "]");
	return string;
}

FormatFigures(start[], f1, sep1[], f2, sep2[], f3, end[])
{
	new string[256];
	if (f1 < 10)
	{
	    format(string, sizeof (string), "%s0%d%s", start, f1, sep1);
	}
	else
	{
	    format(string, sizeof (string), "%s%d%s", start, f1, sep1);
	}
	if (f2 < 10)
	{
	    format(string, sizeof (string), "%s0%d%s", string, f2, sep2);
	}
	else
	{
	    format(string, sizeof (string), "%s%d%s", string, f2, sep2);
	}
	if (f3 < 10)
	{
	    format(string, sizeof (string), "%s0%d%s", string, f3, end);
	}
	else
	{
	    format(string, sizeof (string), "%s%d%s", string, f3, end);
	}
	return string;
}

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

public OnPlayerRequestClass(playerid, classid)
{
	if (gRecordArray[0])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerRequestClass    (%s, %d)", ReturnPlayerIDData(playerid), classid);
		yLog(string);
	}
	return 0;
}

public OnPlayerRequestSpawn(playerid)
{
	if (gRecordArray[15])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerRequestSpawn    (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}
	return 0;
}

public OnPlayerPrivmsg(playerid, targetid, text[])
{
	if (gRecordArray[16])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerPrivmsg         (%s, %s, %s)", ReturnPlayerIDData(playerid), ReturnPlayerIDData(targetid), text);
		yLog(string);
	}
	return 1;
}

public OnFilterScriptExit()
{
	exitcode();
	return 0;
}

exitcode()
{
	new string[256];
	fwrite(g_fLogFile, "\r\n");
	yLog("======================================================");
	yLog("|                                                    |");
	yLog("| Alex \"Y_Less\" Cole's server logging system stopped |");
	yLog("|                  v0.4 - (c) 2006                   |");
	format(string, sizeof (string), "|                 Date: %s                 |", MakeFormattedDate());
	yLog(string);
	yLog("|                                                    |");
	yLog("======================================================\r\n");

	/*print("\r\n======================================================");
	print("|                                                    |");
	print("| Alex \"Y_Less\" Cole's server logging system stopped |");
	print("|                  v0.3 - (c) 2006                   |");
	print("|                                                    |");
	print("======================================================\r\n");*/

	KillTimer(gSaveTimer);
	gSaving = 1;
	fclose(g_fLogFile);
	//print("FilterScriptExit()");
}

public OnPlayerConnect(playerid)
{
    gPlayers++;
	//static started = 0;
	if (gRecordArray[1])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerConnect         (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}

	/*if (!started)
	{
		//gettime(h, m, s);
		//print("hi");
		//h = (SAVE_DELAY - (((m * 60) + s) * 1000));
		//SetTimer("savestart", 1000, 0);
		// Start it on the hour (or on the SAVE_DELAY)

		new h, m, s, u;

		gettime(h, m, s);
		u = ((3600 - (m * 60) - s) * 1000);

		while (u > gSaveDelay)
		{
	    	u -= gSaveDelay;
		}

		savestart(u);
		started = 1;
		//gLastSave = (GetTickCount() + u) - gSaveDelay;
	}*/

	return 0;
}

public OnPlayerDisconnect(playerid)
{
	if (gRecordArray[2])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerDisconnect      (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}
    gPlayers--;
    if (!gPlayers)
    {
        saveloop();
        // Autosave when all the players leave the server
    }
	return 0;
}

public OnPlayerSpawn(playerid)
{
	if (gRecordArray[3])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerSpawn           (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}
	return 0;
}

public OnPlayerDeath(playerid, killerid, reason)
{
	if (gRecordArray[4])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerDeath           (%s, %s, %d)", ReturnPlayerIDData(playerid), ReturnPlayerIDData(killerid), reason);
		yLog(string);
	}
	return 0;
}

public OnVehicleSpawn(vehicleid)
{
	if (gRecordArray[5])
	{
		new string[256];
		format(string, sizeof (string), "OnVehicleSpawn          (%d)", vehicleid);
		yLog(string);
	}
	return 0;
}

public OnVehicleDeath(vehicleid, killerid)
{
	if (gRecordArray[6])
	{
		new string[256];
		format(string, sizeof (string), "OnVehicleDeath          (%d, %d)", vehicleid, killerid);
		yLog(string);
	}
	return 0;
}

public OnPlayerText(playerid, saytext[])
{
	if (gRecordArray[7])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerText            (%s, %s)", ReturnPlayerIDData(playerid), saytext);
		yLog(string);
	}
	return 1;
}

public strtok(const string[], &index)
{
	new length = strlen(string);
	while ((index < length) && (string[index] <= ' '))
	{
		index++;
	}

	new offset = index;
	new result[32];
	while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof (result) - 1)))
	{
		result[index - offset] = string[index];
		index++;
	}
	result[index - offset] = EOS;
	return result;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
	static callbacknames[][] = {
	    "OnPlayerRequestClass",
	    "OnPlayerConnect",
	    "OnPlayerDisconnect",
	    "OnPlayerSpawn",
	    "OnPlayerDeath",
	    "OnVehicleSpawn",
	    "OnVehicleDeath",
	    "OnPlayerText",
	    "OnPlayerCommandText",
	    "OnPlayerInfoChange",
	    "OnPlayerEnterVehicle",
	    "OnPlayerExitVehicle",
	    "OnPlayerStateChange",
	    "OnPlayerEnterCheckpoint",
	    "OnPlayerLeaveCheckpoint",
	    "OnPlayerRequestSpawn",
	    "OnPlayerPrivmsg"
	};
	new index, cmd[256], retval = 0, i;
	cmd = strtok(cmdtext, index);
	if (strcmp(cmd, "/ylog", true) == 0)
	{
	    if (IsPlayerAdmin(playerid))
	    {
			cmd = strtok(cmdtext, index);
			if (strcmp(cmd, "save", true) == 0)
			{
			    saveloop(true);
			    SendClientMessage(playerid, 0xFF0000FF, "Server logs saved");
			}
			else if (strcmp(cmd, "exit", true) == 0)
			{
			    exitcode();
			    SendClientMessage(playerid, 0xFF0000FF, "Server logging stopped");
			}
			else if (strcmp(cmd, "reset", true) == 0)
			{
			    ReadConfigs();
			    SendClientMessage(playerid, 0xFF0000FF, "Log settings reloaded");
			}
			else if (strcmp(cmd, "saveset", true) == 0)
			{
			    WriteConfigs();
			    SendClientMessage(playerid, 0xFF0000FF, "Log settings saved");
			}
			else if (strcmp(cmd, "addc", true) == 0)
			{
			    if (gComCount < MAX_COMMANDS)
			    {
				    gSkipCommands[gComCount] = strtok(cmdtext, index);
				    if (gSkipCommands[gComCount][0] == '/')
				    {
					    gComCount++;
						SendClientMessage(playerid, 0xFF0000FF, "Command added to the skip command list");
						SendClientMessage(playerid, 0xFF0000FF, "Type \"/ylog saveset\" to save the settings to file");
					}
					else
					{
						SendClientMessage(playerid, 0xFF0000FF, "Error: not a command");
					}
				}
				else
				{
				    SendClientMessage(playerid, 0xFF0000FF, "Error: MAX_COMMANDS already reached, recompile to add more");
				}
			}
			else if (strcmp(cmd, "addp", true) == 0)
			{
			    if (gParCount < MAX_COMMANDS)
			    {
				    gSkipParameters[gParCount] = strtok(cmdtext, index);
				    if (gSkipParameters[gParCount][0] == '/')
				    {
					    gParCount++;
						SendClientMessage(playerid, 0xFF0000FF, "Command added to the skip parameter list");
						SendClientMessage(playerid, 0xFF0000FF, "Type \"/ylog saveset\" to save the settings to file");
					}
					else
					{
						SendClientMessage(playerid, 0xFF0000FF, "Error: not a command");
					}
				}
				else
				{
				    SendClientMessage(playerid, 0xFF0000FF, "Error: MAX_COMMANDS already reached, recompile to add more");
				}
			}
			else if (strcmp(cmd, "skipc", true) == 0)
			{
				SendClientMessage(playerid, 0xFF0000FF, "Ignored Commands:");
				cmd[0] = 0;
			    new j = 0;
			    i = 0;
			    while (i < gComCount)
			    {
					format(cmd, sizeof (cmd), "%s %s", cmd, gSkipCommands[i]);
					i++;
					j++;
					if (j == 10)
					{
						SendClientMessage(playerid, 0xFF0000FF, cmd);
						j = 0;
						cmd[0] = 0;
					}
			    }
			    if (cmd[0])
				{
				    SendClientMessage(playerid, 0xFF0000FF, cmd);
				}
			}
			else if (strcmp(cmd, "skipp", true) == 0)
			{
				SendClientMessage(playerid, 0xFF0000FF, "Ignored Parameter Commands:");
				//strdel(cmd, 0, sizeof (cmd));
				cmd[0] = 0;
			    new j = 0;
			    i = 0;
			    while (i < gParCount)
			    {
					format(cmd, sizeof (cmd), "%s %s", cmd, gSkipParameters[i]);
					i++;
					j++;
					if (j == 10)
					{
						SendClientMessage(playerid, 0xFF0000FF, cmd);
						j = 0;
						//strdel(cmd, 0, sizeof (cmd));
						cmd[0] = 0;
					}
			    }
			    if (cmd[0])
				{
				    SendClientMessage(playerid, 0xFF0000FF, cmd);
				}
			}
			else if (strcmp(cmd, "settings", true) == 0)
			{
   				SendClientMessage(playerid, 0xFF0000FF, "Callback recording:");
				cmd = "";
				new j;
			    for (i = 0, j = 0; i < sizeof (gRecordArray); i++, j++)
			    {
			        format(cmd, sizeof (cmd), "%s%s (%d) = %d, ", cmd, callbacknames[i], i, gRecordArray[i]);
			        if (j == 2)
			        {
						SendClientMessage(playerid, 0xFF0000FF, cmd);
						cmd = "";
						j = 0;
					}
			    }
			    format(cmd, sizeof (cmd), "savedelay = %d, expand = %d, dailysave = %d", gSaveDelay, gExpandParams, gDailyFiles);
   				SendClientMessage(playerid, 0xFF0000FF, cmd);
   				SendClientMessage(playerid, 0xFF0000FF, "Type \"/ylog skip1\" for ignored commands or \"/ylog skip2\" for ignored parameter commands");
   				SendClientMessage(playerid, 0xFF0000FF, "Type \"/ylog <setting>\" to toggle settings, \"/ylog callback <number>\" to toggle recording or \"/ylog savedelay <value>\" to set save delay");
			}
			else if (strcmp(cmd, "savedelay", true) == 0)
			{
				i = strval(strtok(cmdtext, index));
				if (i > 0)
				{
				    gSaveDelay = i;
				    SendClientMessage(playerid, 0xFF0000FF, "Save delay updated.  Type \"/ylog saveset\" to save the settings to file");
			    }
			    else
			    {
			        SendClientMessage(playerid, 0xFF0000FF, "Error: you must enter a positive value");
			    }
			}
			else if (strcmp(cmd, "expand", true) == 0)
			{
			    gExpandParams = 1 - gExpandParams;
			    SendClientMessage(playerid, 0xFF0000FF, "Expand option updated.  Type \"/ylog saveset\" to save the settings to file");
			}
			else if (strcmp(cmd, "dailysave", true) == 0)
			{
			    gDailyFiles = 1 - gDailyFiles;
			    SendClientMessage(playerid, 0xFF0000FF, "Daily files option updated.  Type \"/ylog saveset\" to save the settings to file");
			}
			else if (strcmp(cmd, "callback", true) == 0)
			{
			    i = strval(strtok(cmdtext, index));
			    if (i < 15)
			    {
			        gRecordArray[i] = 1 - gRecordArray[i];
			        format(cmd, sizeof (cmd), "%s (%d) = %d.  Type \"/ylog saveset\" to save the settings to file", callbacknames[i], i, gRecordArray[i]);
			        SendClientMessage(playerid, 0xFF0000FF, cmd);
			        // Toggle the value
			    }
			    else
			    {
			        SendClientMessage(playerid, 0xFF0000FF, "Valid callback number required.  Type \"ylog settings\" for a list");
			    }
			}
			else
			{
			    SendClientMessage(playerid, 0xFF0000FF, "Invalid logging command");
			}
		}
		else
		{
		    SendClientMessage(playerid, 0xFF0000FF, "yLog access required");
		}
	    retval = 1;
	}
	
	index = 0;
	cmd = strtok(cmdtext, index);
	if (gRecordArray[8])
	{
		//i = 0;
		//print("hi");
		//printf("%d", gComCount);
		for (i = gComCount; i > 0; i--)
		//while (gSkipCommands[i][0])
		{
			//printf("%s", gSkipCommands[i - 1]);
			if (strcmp(cmd, gSkipCommands[i - 1], true) == 0)
			{
			    format(cmd, sizeof (cmd), "OnPlayerCommandText     (%s, <command>)", ReturnPlayerIDData(playerid));
			    yLog(cmd);
			    return retval;
			}
		}
		//i = 0;
		//printf("%d", gParCount);
		for (i = gParCount; i > 0; i--)
		//while (gSkipParameters[i][0])
		{
			//printf("%s", gSkipParameters[i - 1]);
			if (strcmp(cmd, gSkipParameters[i - 1], true) == 0)
			{
			    format(cmd, sizeof (cmd), "OnPlayerCommandText     (%s, %s <parameters>)", ReturnPlayerIDData(playerid), cmd);
			    yLog(cmd);
			    return retval;
			}
		}
	/*	for (i = 0; i < sizeof (gSkipCommands); i++);
		{
			if (strcmp(cmd, gSkipCommands[i - 1], true) == 0)
			{
			    return retval;
			}

		}
		for (i = 0; i < sizeof (gSkipParameters); i++);
		{
			if (strcmp(cmd, gSkipParameters[i - 1], true) == 0)
			{
			    format(cmd, sizeof (cmd), "OnPlayerCommandText    (%s, %s <parameters>)", ReturnPlayerIDData(playerid), cmd);
			    yLog(cmd);
			    return retval;
			}

		}*/
		format(cmd, sizeof (cmd), "OnPlayerCommandText     (%s, %s)", ReturnPlayerIDData(playerid), cmdtext);
		yLog(cmd);
	}
	return retval;
}

public OnPlayerInfoChange(playerid)
{
	if (gRecordArray[9])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerInfoChange      (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}
	return 0;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
	if (gRecordArray[10])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerEnterVehicle    (%s, %d, %d)", ReturnPlayerIDData(playerid), vehicleid, ispassenger);
		yLog(string);
	}
	return 0;
}

public OnPlayerExitVehicle(playerid, vehicleid)
{
	if (gRecordArray[11])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerExitVehicle     (%s, %d)", ReturnPlayerIDData(playerid), vehicleid);
		yLog(string);
	}
	return 0;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
	static states[][] = {
		"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"
	};
	
	if (gRecordArray[12])
	{
		new string[256];
		if (gExpandParams)
		{
		    format(string, sizeof (string), "OnPlayerStateChange     (%d: %s, %d: %s, %d: %s)", playerid, ReturnPlayerName(playerid), newstate, states[newstate], oldstate, states[oldstate]);
		}
		else
		{
			format(string, sizeof (string), "OnPlayerStateChange     (%d, %d, %d)", playerid, newstate, oldstate);
		}

		yLog(string);
	}
	return 0;
}

public OnPlayerEnterCheckpoint(playerid)
{
	if (gRecordArray[13])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerEnterCheckpoint (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}
	return 0;
}

public OnPlayerLeaveCheckpoint(playerid)
{
	if (gRecordArray[14])
	{
		new string[256];
		format(string, sizeof (string), "OnPlayerLeaveCheckpoint (%s)", ReturnPlayerIDData(playerid));
		yLog(string);
	}
	return 0;
}

ReturnPlayerIDData(playerid)
{
	new pdat[128];
	if (playerid != INVALID_PLAYER_ID)
	{
		if (gExpandParams)
		{
		    format(pdat, sizeof (pdat), "%d: %s", playerid, ReturnPlayerName(playerid));
		}
		else
		{
		    format(pdat, sizeof (pdat), "%d", playerid);
		}
	}
	else
	{
		pdat = "<none>";
	}
	return pdat;
}

stripnl(string[])
{
	// Strip any silly newline symbols.
	new len = strlen(string);
	if (string[0] == 0)
	{
		return;
	}
	if ((string[len - 1] == '\n') || (string[len - 1] == '\r'))
	{
		string[len - 1] = 0;
		if (string[0]==0)
		{
			return;
		}
		if ((string[len - 2] == '\n') || (string[len - 2] == '\r'))
		{
			string[len - 2] = 0;
		}
	}
}