/* plugin_cavey_adminlog.sma version 1.3, By Caveman ICQ# 70710878 Please read the readme Also available from http://gosh.ex.ac.uk/~py99jan/ */ #include <core> #include <console> #include <string> #include <admin> #include <adminlib> #include <cavey> #include <cavey> #if _cavey_included < 1 /*This will cause a nice error if you need to update the cavey.inc*/ Update_Your_Cavey_Inc() #endinput #endif /*Version of AdminMod this was designed for*/ new STRING_VERSION[MAX_DATA_LENGTH] = "2.50.42"; /*Any further compatibility is by accident, not by design*/ #define MAX_IPADDRESS MAX_AUTHID_LENGTH new UserIP[MAX_PLAYERS][MAX_IPADDRESS]; new Silence; new log_type; new filter_admin; new Tell_admin; new ACCESS_TELL_ADMIN; new ACCESS_ADMINLOG; new multiple_servers; new LOG_EVERYTHING; new log_to_file; public plugin_init() { new Command[MAX_DATA_LENGTH]; /*Set global variables from vault*/ /*Controls silence setting*/ cavey_vault_init("ADMINLOG_SILENCE", 0, Silence); /*Controls multiple server support*/ cavey_vault_init("ADMINLOG_MULTIPLE_SERVERS", 0, multiple_servers); /*Controls what style of log to produce*/ cavey_vault_init("ADMINLOG_LOGTYPE", 1, log_type); /*Controls whether to filter admin console commands*/ cavey_vault_init("ADMINLOG_FILTERCONSOLE", 1, filter_admin); /*Who has access to change adminlog settings*/ cavey_vault_init("ADMINLOG_ACCESSADMINLOG", ACCESS_RCON, ACCESS_ADMINLOG); if (ACCESS_ADMINLOG == 0){ /*You may NOT set this to 0!*/ ACCESS_ADMINLOG = ACCESS_RCON; } /*Controls whether to even bother telling an admin*/ cavey_vault_init("ADMINLOG_TELLADMIN", 0, Tell_admin); /*Controls whether to even bother telling an admin*/ cavey_vault_init("ADMINLOG_LOGTOFILE", 1, log_to_file); /*Controls who has access to hear the admin alerts*/ cavey_vault_init("ADMINLOG_ACCESSADMINALERT", ACCESS_RCON, ACCESS_TELL_ADMIN); /*Controls whether the plugin logs everything 0 = off 1 = All but says 2 = Everything */ cavey_vault_init("ADMINLOG_LOGEVERYTHING", 0, LOG_EVERYTHING); /*Find out if the settings are correct, if not dont even bother......*/ if ( getvar("file_access_read") == 0 || getvar("file_access_write") == 0 ){ plugin_registerinfo("Cavey's adminlog (Disabled)","Please set file_access_read and file_access_write to 1",STRING_VERSION); return PLUGIN_CONTINUE; } else if (!fileexists("adminlogs/loggedcmds.ini") && LOG_EVERYTHING == 0){ plugin_registerinfo("Cavey's adminlog (Disabled)","Please create the adminlogs directory containing the loggedcmds.ini",STRING_VERSION); return PLUGIN_CONTINUE; } /*Configure plugin*/ if (LOG_EVERYTHING == 0){ new Count; new FileSize = filesize("adminlogs/loggedcmds.ini"); snprintf(Command, MAX_DATA_LENGTH, "Adding commands"); say(Command); for(Count=1;Count<=FileSize;Count++) { readfile("adminlogs/loggedcmds.ini",Command,Count,MAX_DATA_LENGTH); plugin_registercmd(Command,"LogCommand",ACCESS_ALL,""); } snprintf(Command, MAX_DATA_LENGTH, "%d commands added",Count); say(Command); snprintf(Command, MAX_DATA_LENGTH, "Logs admin use and abuse of %d commands",Count); } else { snprintf(Command, MAX_DATA_LENGTH, "Logs admin use and abuse of all server commands"); } if ( Silence == 0 ){ plugin_registerinfo("Cavey's adminlog",Command,STRING_VERSION); plugin_registercmd("admin_adminlog","admin_adminlog",ACCESS_ALL,"admin_adminlog : Allows admins to change the adminlog settings. Run ^"admin_adminlog^" for details."); } else { plugin_registerinfo("Cavey's Fun Plugin","Fun plugin for adminmod (Disabled)",STRING_VERSION); plugin_registercmd("admin_adminlog","admin_adminlog",ACCESS_ALL,""); /*Yes, that is right as this way we can HIDE it*/ } return PLUGIN_CONTINUE; } public LogCommand(HLCommand, HLData, HLUserName, UserIndex){ if (LOG_EVERYTHING != 0){ return PLUGIN_CONTINUE; } new Command[MAX_COMMAND_LENGTH]; new UserName[MAX_NAME_LENGTH]; new Data[MAX_DATA_LENGTH]; convert_string(HLUserName, UserName, MAX_NAME_LENGTH); convert_string(HLCommand,Command,MAX_COMMAND_LENGTH); convert_string(HLData,Data,MAX_DATA_LENGTH); return act_on_command(Command, Data, UserName, UserIndex); } public plugin_command(HLCommand, HLData, HLUserName, UserIndex){ new Command[MAX_COMMAND_LENGTH]; convert_string(HLCommand,Command,MAX_COMMAND_LENGTH); if (LOG_EVERYTHING == 0){ return PLUGIN_CONTINUE; } else if ((LOG_EVERYTHING == 1) && (strncmp(Command, "admin_", 3) != 0) ){ return PLUGIN_CONTINUE; /*In state 1, dont log anything which does not start with "admin_")*/ } new UserName[MAX_NAME_LENGTH]; new Data[MAX_DATA_LENGTH]; convert_string(HLUserName, UserName, MAX_NAME_LENGTH); convert_string(HLData,Data,MAX_DATA_LENGTH); return act_on_command(Command, Data, UserName, UserIndex); } act_on_command(Command[], Data[], UserName[], UserIndex){ /*If it is from the console, are we meant to ignore them?*/ if ( (UserIndex == 0) && (filter_admin != 0) ){ return PLUGIN_CONTINUE; } new Target[MAX_NAME_LENGTH]; new Reason[MAX_DATA_LENGTH]; new UserIdentifier[MAX_IPADDRESS]; new TargetName[MAX_NAME_LENGTH]; new TargetIdentifier[MAX_IPADDRESS]; new text[MAX_DATA_LENGTH]; new FileName[MAX_DATA_LENGTH]; new CurMonth[MAX_NUMBER_LENGTH]; new CurDate[MAX_NUMBER_LENGTH]; new CurTime[MAX_NUMBER_LENGTH]; servertime(CurMonth, MAX_NUMBER_LENGTH, "%B"); servertime(CurDate, MAX_NUMBER_LENGTH, "%d"); servertime(CurTime, MAX_NUMBER_LENGTH, "%H:%M"); /*Get the users information*/ if ( getvar("sv_lan") == 1 ){ strtok(UserIP[UserIndex], ":", UserIdentifier, MAX_IPADDRESS); } else { new SessionID,Team,Dead; plrinfo(UserIndex,UserName,MAX_NAME_LENGTH,SessionID,UserIdentifier,Team,Dead); } strbreak(Data,Target,Reason, MAX_DATA_LENGTH); /*What is going in the log then?*/ if (check_user(Target)==1){ /*We have a target, so prepare the information*/ new TargetIndex; get_userindex(Target, TargetIndex); if ( getvar("sv_lan") == 1 ){ get_username(Target,TargetName,MAX_NAME_LENGTH); strtok(UserIP[TargetIndex], ":", TargetIdentifier, MAX_IPADDRESS); } else { new SessionID,Team,Dead; plrinfo(TargetIndex,TargetName,MAX_NAME_LENGTH,SessionID,TargetIdentifier,Team,Dead); } snprintf(text, MAX_DATA_LENGTH, "%s^t%s^t%s^t%s(%s)^t%s^t%s(%s)^t%s", CurMonth, CurDate, CurTime, UserName, UserIdentifier, Command, TargetName, TargetIdentifier, Reason); } else { snprintf(text, MAX_DATA_LENGTH, "%s^t%s^t%s^t%s(%s)^t%s^t%s^t%s", CurMonth, CurDate, CurTime, UserName, UserIdentifier, Command, Target, Reason); } if (log_to_file != 0){ /*So where are we going to stick it?*/ if ( log_type == 0 ){ /*One big file*/ snprintf(FileName, MAX_DATA_LENGTH, "adminlogs/admin_command"); } else if ( log_type == 1 ) { /*One file per day*/ snprintf(FileName, MAX_DATA_LENGTH, "adminlogs/%s-%s", CurDate, CurMonth); } else if ( log_type ==2 || log_type == 3 || log_type == 4 || log_type == 5){ /*One file per user either by Name or by Identifier Identifier is already set to WonID, IP or SteamID*/ new SafeName[MAX_AUTHID_LENGTH]; if ( log_type ==2 || log_type == 3){ strcpy(SafeName,UserName,MAX_NAME_LENGTH); } else if (log_type == 4 || log_type == 5){ strcpy(SafeName,UserIdentifier,MAX_AUTHID_LENGTH); } /* Whatever it is, make sure it is safe.....*/ for (new i=0;i<strlen(SafeName);i++){ if ( (SafeName[i]>='0') && (SafeName[i]<='9') ){ } else if ( (SafeName[i]>='A') && (SafeName[i]<='Z') ){ } else if ( (SafeName[i]>='a') && (SafeName[i]<='z') ){ } else { SafeName[i] = 65; /*Replace any non-safe characters with an 'A'*/ } } if ( log_type == 2 || log_type == 4){ snprintf(FileName, MAX_DATA_LENGTH, "adminlogs/%s", SafeName); } else if ( log_type == 3 || log_type == 5){ snprintf(FileName, MAX_DATA_LENGTH, "adminlogs/%s-%s-%s", SafeName, CurDate, CurMonth); } } /*Add on the server port IF required*/ if (multiple_servers != 0) { snprintf(text,MAX_TEXT_LENGTH,"%d",getvar("port")); strcat(FileName,text,MAX_DATA_LENGTH); } /*End the file name*/ strcat(FileName,".log",MAX_DATA_LENGTH); writefile(FileName,text,-1); } /*Now do we tell the admins?*/ if ( (Tell_admin != 0) ){ /*What do we tell them?*/ if (check_user(Target)==1){ snprintf(text, MAX_DATA_LENGTH, "%s(%s) used %s against %s(%s) Reason: %s", UserName, UserIdentifier, Command, TargetName, TargetIdentifier, Reason); } else { snprintf(text, MAX_DATA_LENGTH, "%s(%s) used %s %s %s", UserName, UserIdentifier, Command, Target, Reason); } /*Find the admins and tell them*/ for( new i=1; i<=maxplayercount(); i++) { strinit(UserName); new SessionID; new AuthID[MAX_AUTHID_LENGTH]; new Team; new Dead; if(plrinfo(i,UserName,MAX_NAME_LENGTH,SessionID,AuthID,Team,Dead)==1) { if(access(ACCESS_TELL_ADMIN,UserName)!=0) { messageex(UserName, text, print_chat); } } } } return PLUGIN_CONTINUE; } public plugin_connect(HLUserName, HLIP, UserIndex) { if (UserIndex >= 1 && UserIndex <= MAX_PLAYERS) { strinit(UserIP[UserIndex]); convert_string(HLIP, UserIP[UserIndex], MAX_IPADDRESS); } return PLUGIN_CONTINUE; } public plugin_disconnect(HLUserName, UserIndex) { if (UserIndex >= 1 && UserIndex <= MAX_PLAYERS) { strinit(UserIP[UserIndex]); } return PLUGIN_CONTINUE; } public admin_adminlog(HLCommand, HLData, HLUserName, UserIndex){ new Command[MAX_COMMAND_LENGTH]; new Data[MAX_DATA_LENGTH]; new UserName[MAX_NAME_LENGTH]; convert_string(HLUserName, UserName, MAX_NAME_LENGTH); convert_string(HLCommand,Command,MAX_COMMAND_LENGTH); convert_string(HLData,Data,MAX_DATA_LENGTH); if ( access(ACCESS_ADMINLOG, UserName)==0 ){ return PLUGIN_CONTINUE; /*Command hidden from those without access*/ } if ( strlen(Data) == 0 ){ /*Give general instructions*/ messageex(UserName, "Information sent to console" ,print_chat); selfmessage("-------- Adminlog Function -------------------------------------------------------"); selfmessage(" admin_adminlog console - Effects whether commands from the console are logged."); selfmessage(" admin_adminlog logtype - Effects how the logs are stored on your server."); selfmessage(" admin_adminlog servers - Effects whether mutltiple server support is enabled."); selfmessage(" admin_adminlog silence - Effects whether the users can see the adminlog plugin."); selfmessage(" admin_adminlog telladmin - Effects whether commands are anounced to authorised users."); selfmessage(" admin_adminlog whoadmin - Defines who is considered as an authorised user for ^"telladmin^"."); selfmessage(" admin_adminlog allcmds - Defines whether to log ALL server commands or not."); selfmessage(" "); selfmessage(" Type in one of the strings to see details on that section"); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else { new Section[MAX_DATA_LENGTH]; new Value[MAX_DATA_LENGTH]; strbreak(Data,Section,Value, MAX_DATA_LENGTH); new iValue = strtonum(Value); if (strcasestr(Section, "silence") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Silence -------------------------------------------"); selfmessage(" admin_adminlog silence <value>"); selfmessage(" - 0 disables silence and allows it to show"); selfmessage(" - 1 hides the description, help and disguises"); selfmessage(" admin_adminlog to make the plugin vanish"); selfmessage(" NB This requires a map change for settings to take effect"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 0", filter_admin); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue == 0 || iValue == 1 ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Silence setting set to %s", Value); selfmessage(Data); snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Changes will take effect on map change"); selfmessage(Data); set_vaultdata("ADMINLOG_SILENCE",Value); } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Silence^" to %s", Value); selfmessage(Data); } } else if ( (strcasestr(Section, "logtype") != -1) || (strcasestr(Section, "log-type") != -1) ){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Log-Type ------------------------------------------"); selfmessage(" admin_adminlog logtype <value>"); selfmessage(" - 0 logs ALL commands to ONE file"); selfmessage(" - 1 logs all commands to a different file each day"); selfmessage(" - 2 logs all commands to a different file per user"); selfmessage(" - 3 logs all commands to a different file per user per day"); selfmessage(" - 4 logs all commands to a different file per WonID or IP"); selfmessage(" - 5 logs all commands to a different file per WonID or IP per day"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 1", log_type); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue >= 0 && iValue <= 3 ) { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Log-type setting set to %s", Value); selfmessage(Data); set_vaultdata("ADMINLOG_LOGTYPE",Value); log_type = iValue; } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Log-Type^" to %s", Value); selfmessage(Data); } } else if (strcasestr(Section, "console") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Console -------------------------------------------"); selfmessage(" admin_adminlog console <value>"); selfmessage(" - 0 logs EVERYTHING"); selfmessage(" - 1 ignores any commands from the HL console"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 1", filter_admin); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue == 0 || iValue == 1 ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Console-Filter setting set to %s", Value); selfmessage(Data); set_vaultdata("ADMINLOG_FILTERADMIN",Value); filter_admin = iValue; } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Console^" to %s", Value); selfmessage(Data); } } else if (strcasestr(Section, "telladmin") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Tell Admin -------------------------------------------"); selfmessage(" admin_adminlog telladmin <value>"); selfmessage(" - 0 disables the function"); selfmessage(" - 1 anounces all logged commands to admins"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 0", Tell_admin); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue == 0 || iValue == 1 ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] telladmin setting set to %s", Value); selfmessage(Data); set_vaultdata("ADMINLOG_TELLADMIN",Value); Tell_admin = iValue; } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Tell-Admin^" to %s", Value); selfmessage(Data); } } else if (strcasestr(Section, "logtofile") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Log To File -------------------------------------------"); selfmessage(" admin_adminlog logtofile <value>"); selfmessage(" - 0 disables logging to a file"); selfmessage(" - 1 enables logging to a file"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 1", log_to_file); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue == 0 || iValue == 1 ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] logtofile setting set to %s", Value); selfmessage(Data); set_vaultdata("ADMINLOG_LOGTOFILE",Value); log_to_file = iValue; } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Log To File^" to %s", Value); selfmessage(Data); } } else if (strcasestr(Section, "servers") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Multiple Servers -------------------------------------------"); selfmessage(" admin_adminlog servers <value>"); selfmessage(" - 0 disables the function"); selfmessage(" - 1 Allows different log files per server/port"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 0", multiple_servers); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue == 0 || iValue == 1 ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Multiple server support setting set to %s", Value); selfmessage(Data); set_vaultdata("ADMINLOG_MULTIPLE_SERVERS",Value); multiple_servers = iValue; } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Multiple Servers^" to %s", Value); selfmessage(Data); } } else if (strcasestr(Section, "whoadmin") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Tell Admin -------------------------------------------"); selfmessage(" admin_adminlog telladmin <value>"); snprintf(Data, MAX_DATA_LENGTH, " - %d ACCESS_CHAT",ACCESS_CHAT); selfmessage(Data); snprintf(Data, MAX_DATA_LENGTH, " - %d ACCESS_KICK",ACCESS_KICK); selfmessage(Data); snprintf(Data, MAX_DATA_LENGTH, " - %d ACCESS_BAN",ACCESS_BAN); selfmessage(Data); snprintf(Data, MAX_DATA_LENGTH, " - %d ACCESS_IMMUNITY",ACCESS_IMMUNITY); selfmessage(Data); snprintf(Data, MAX_DATA_LENGTH, " - %d ACCESS_RCON",ACCESS_RCON); selfmessage(Data); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 65536", ACCESS_TELL_ADMIN); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue == ACCESS_CHAT || iValue == ACCESS_KICK || iValue == ACCESS_BAN || iValue == ACCESS_IMMUNITY || iValue == ACCESS_RCON ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] ACCESS_TELLADMIN setting set to %s", Value); selfmessage(Data); set_vaultdata("ADMINLOG_ACCESSADMINALERT",Value); ACCESS_TELL_ADMIN = iValue; } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Who-Admin^" to %s", Value); selfmessage(Data); } } else if (strcasestr(Section, "allcmds") != -1){ if ( strlen(Value) == 0 ){ /*Section instructions*/ selfmessage("-------- Adminlog Function -- Logged Commands -------------------------------------------"); selfmessage(" admin_adminlog allcmds <value>"); selfmessage(" - 0 leaves the server only logging the commands in loggedcmds.ini"); selfmessage(" - 1 the server will log all except the say commands"); selfmessage(" - 2 the server will log EVERYTHING"); selfmessage(" "); selfmessage(" NB This requires a map change for settings to take effect"); selfmessage(" "); snprintf(Data, MAX_DATA_LENGTH, " Setting currently %d - default is 0", LOG_EVERYTHING); selfmessage(Data); selfmessage("-------- End adminlog -----------------------------------------------------------"); } else if ( iValue >= 0 && iValue <= 2 ){ snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Server ^"Logged Commands^" set to %s", Value); selfmessage(Data); selfmessage("[ADMINLOG]Settings will take effect when the server changes map"); set_vaultdata("ADMINLOG_LOGEVERYTHING",Value); } else { snprintf(Data, MAX_DATA_LENGTH, "[ADMINLOG] Unable to set ^"Logged Commands^" to %s", Value); selfmessage(Data); } } else { /*Error*/ } } if (LOG_EVERYTHING != 0){ return PLUGIN_HANDLED; } else { convert_string(HLData,Data,MAX_DATA_LENGTH); act_on_command(Command, Data, UserName, UserIndex); return PLUGIN_HANDLED; } return PLUGIN_HANDLED; }