////////////////////////////// // COMMAND RECORDER // // by Sir Drink a lot // // for Counter-Strike // // // // Logs all commands used // // by players on server. // // // // - This plugin must the // // first one in plugin.ini. // // - file_access_read and // // file_access_write // // must be enabled!!!! // // // // v.85: added option <n/i> // // in admin_bbox_who // // v.84: added search <ID> // // in admin_bbox_who // // v.83: optimized code of // // admin_bbox_who // // v.82: added // // admin_bbox_who // // v.81: specmode for adding// // /check steam_id // ////////////////////////////// #include <string> #include <admin> #include <adminlib> new STRING_VERSION[10]="0.85"; new g_plugin; new g_MainDir[MAX_TEXT_LENGTH]="addons/adminmod/config/blackbox"; new g_LogFiles[3][]={ "say_cmds.log", "retribution_cmds.log", "admin_cmds.log" }; #define MAX_ENTRIES 500 new g_STEAM_ID[MAX_ENTRIES][MAX_AUTHID_LENGTH]; new g_Names[MAX_ENTRIES][MAX_NAME_LENGTH]; new g_loaded; #define MAX_RETR_CMDS 20 new g_Retribution_Cmds[MAX_RETR_CMDS][]={ "slap", "slay", "kick", "ban", "bury", "unbury", "gag", "ungag", "llama", "unllama", "slayteam", "ct", "t", "vote_kick", "execclient", "execall", "execteam", "restrict", "unrestrict", "unban" }; new g_User[MAX_PLAYERS]; public plugin_init() { new iread; new iwrite; iread = getvar("file_access_read"); iwrite = getvar("file_access_write"); if(iwrite & iread){ plugin_registerinfo("Server Black Box","Logs all STEAM_IDs, say/say_team and admin_ commands in special logfiles",STRING_VERSION); plugin_registercmd("admin_bbox","admin_bbox",ACCESS_CONFIG,"admin_bbox <on/off>: turns plugin on/off"); plugin_registercmd("admin_bbox_read","admin_bbox_read",ACCESS_CONFIG,"admin_bbox_read <user> <last entries>: searches for last commands executed by <user>"); plugin_registercmd("admin_bbox_who","admin_bbox_who",ACCESS_CONFIG,"admin_bbox_who <option='n' or 'i'> <'n'=user/steam-id - 'i'=database_id>: searches for nicknames/steamid or displays database_id!"); plugin_registercmd("specmode","specmode",ACCESS_ALL); if(!get_vaultnumdata("BLACK_BOX",g_plugin)){ set_vaultnumdata("BLACK_BOX",1); g_plugin=1; } read_index_file(); }else{ plugin_registerinfo("COMMAND RECORDER","PLUGIN DISABLED, because file_access_write is not set to 1 in adminmod.cfg",STRING_VERSION); selfmessage("[BLACK BOX] Plugin is disabled, because file_access_write is not set to 1 in adminmod.cfg"); } return PLUGIN_CONTINUE; } //load index.log for fast search for Nickname or Steam_ID, if player is not available on server. read_index_file(){ new Data[MAX_DATA_LENGTH]; new File[MAX_TEXT_LENGTH]; new iFileSize; new i; snprintf(File,MAX_TEXT_LENGTH,"%s/index.log",g_MainDir); if(fileexists(File)){ iFileSize = filesize(File); if(iFileSize>=MAX_ENTRIES){ iFileSize=MAX_ENTRIES-1; selfmessage("[BLACK-BOX] To many entries in index.log! Increase MAX_ENTRIES in plugin_sdal_blackbox.sma and recompile!"); } for(i=1;i<=iFileSize;i++){ readfile(File,Data,i,MAX_DATA_LENGTH); strsplit(Data,"®",g_STEAM_ID[g_loaded],MAX_AUTHID_LENGTH,g_Names[g_loaded],MAX_NAME_LENGTH); g_loaded++; } g_loaded--; } } public specmode(HLCommand,HLData,HLUserName,UserIndex) { if(!g_User[UserIndex]){ new AuthID[MAX_AUTHID_LENGTH]; new User[MAX_NAME_LENGTH]; convert_string(HLUserName,User,MAX_NAME_LENGTH); get_userAuthID(User,AuthID,MAX_AUTHID_LENGTH); g_User[UserIndex]=1; check_index(AuthID,User); } return PLUGIN_CONTINUE; } check_index(AuthID[],User[]){ new Data[MAX_TEXT_LENGTH]; new File[MAX_TEXT_LENGTH]; new i; new found; for(i=0;i<=g_loaded;i++){ if(strcmp(AuthID,g_STEAM_ID[i])==0){ if(strcmp(User,g_Names[i])==0){ found=1; break; } } } if(!found){ snprintf(Data,MAX_TEXT_LENGTH,"%s®%s",AuthID,User); snprintf(File,MAX_TEXT_LENGTH,"%s/index.log",g_MainDir); writefile(File,Data,-1); g_loaded++; strcpy(g_STEAM_ID[g_loaded],AuthID,MAX_AUTHID_LENGTH); strcpy(g_Names[g_loaded],User,MAX_NAME_LENGTH); } } public plugin_command(HLCommand,HLData,HLUserName,UserIndex){ if(g_plugin){ new Data[MAX_DATA_LENGTH]; new Command[MAX_COMMAND_LENGTH]; new i; convert_string(HLData,Data,MAX_DATA_LENGTH); convert_string(HLCommand,Command,MAX_COMMAND_LENGTH); if(strcmp(Command,"say")==0 || strcmp(Command,"say_team")==0){ strstripquotes(Data); record_file(UserIndex,Command,Data,0); return PLUGIN_CONTINUE; }else if(strncmp(Command,"admin_",6)==0){ for(i=0;i<=MAX_RETR_CMDS;i++){ if(strcmp(Command[6],g_Retribution_Cmds[i])==0){ record_file(UserIndex,Command,Data,1); return PLUGIN_CONTINUE; break; } } record_file(UserIndex,Command,Data,2); } } return PLUGIN_CONTINUE; } record_file(UserIndex,Command[],Data[],iLogFile){ new Text[MAX_TEXT_LENGTH]; new File[MAX_TEXT_LENGTH]; new ST[MAX_DATA_LENGTH]; new User[MAX_NAME_LENGTH]; new AuthID[MAX_AUTHID_LENGTH]; new sTeam[MAX_NAME_LENGTH]; new iSession; new iTeam; if(UserIndex!=0){ playerinfo(UserIndex,User,MAX_NAME_LENGTH,iSession,_,iTeam,_,AuthID); if(iTeam==1){ snprintf(sTeam,MAX_NAME_LENGTH,"TERRORIST"); }else if (iTeam==2){ snprintf(sTeam,MAX_NAME_LENGTH,"CT"); }else{ snprintf(sTeam,MAX_NAME_LENGTH,"SPECTATOR"); } }else{ strcpy(User,"RCON/ADMIN",MAX_NAME_LENGTH); strcpy(AuthID,"---",MAX_AUTHID_LENGTH); strcpy(sTeam,"NONE",MAX_NAME_LENGTH); } snprintf(File,MAX_TEXT_LENGTH,"%s/%s",g_MainDir,g_LogFiles[iLogFile]); servertime(ST, MAX_DATA_LENGTH, "L %m/%d/%y - %H:%M:%S:"); //write data to global log files snprintf(Text,MAX_TEXT_LENGTH,"%s ^"%s<%i><%s><%s>^" %s ^"%s^"",ST,User,iSession,AuthID,sTeam,Command,Data); writefile(File,Text,-1); if(UserIndex!=0){ //create an index entry, if player with this steam_id AND his nickname does not exist in index.log check_index(AuthID,User); //write data to users own log file strsubst(AuthID,":","_",MAX_AUTHID_LENGTH); snprintf(File,MAX_TEXT_LENGTH,"%s/database/%s.log",g_MainDir,AuthID); writefile(File,Text,-1); } } public plugin_disconnect(HLUserName,UserIndex) { g_User[UserIndex]=0; return PLUGIN_CONTINUE; } public plugin_connect(HLUserName,HLIP, UserIndex) { g_User[UserIndex]=0; return PLUGIN_CONTINUE; } ////////////////////// // ADMIN COMMANDS // ////////////////////// //turn plugin on/off public admin_bbox(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; convert_string(HLData,Data,MAX_DATA_LENGTH); if(strlen(Data)){ g_plugin=check_param(Data); set_vaultnumdata("BLACK_BOX",g_plugin); } snprintf(Data,MAX_DATA_LENGTH,"[BLACK BOX] Plugin is set to %i",g_plugin); selfmessage(Data); return PLUGIN_HANDLED; } public admin_bbox_who(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; new sOption[1]; new iData; convert_string(HLData,Data,MAX_DATA_LENGTH); strsep(Data," ",sOption,1,Data,MAX_DATA_LENGTH); if(sOption[0]!='i' || sOption[0]!='n'){ snprintf(Data,MAX_DATA_LENGTH,"%s%s",sOption,Data); } if(sOption[0]=='i'){ iData=strtonum(Data); read_users(Data,0,iData); }else{ read_users(Data,0,0); } return PLUGIN_HANDLED; } //read log entries of player public admin_bbox_read(HLCommand,HLData,HLUserName,UserIndex) { new Data[MAX_DATA_LENGTH]; new Text[MAX_TEXT_LENGTH]; new Target[MAX_NAME_LENGTH]; new RealPlayer[MAX_NAME_LENGTH]; new LastEntries[MAX_NUMBER_LENGTH]; new AuthID[MAX_AUTHID_LENGTH]; new ilast; new found; new read; convert_string(HLData,Data,MAX_DATA_LENGTH); strsep(Data," ",Target,MAX_NAME_LENGTH,LastEntries,MAX_NUMBER_LENGTH); ilast=strtonum(LastEntries); if(!ilast){ ilast=10; } selfmessage("* SERVER BLACK BOX *"); //check, if player is available on server if(!strlen(Target)){ selfmessage("* No valid data for target! Please use admin_bbox_read <user> <last entries>"); }else{ if (check_user(Target)==1) { get_username(Target,RealPlayer,MAX_NAME_LENGTH); get_userAuthID(Target,AuthID,MAX_AUTHID_LENGTH); snprintf(Text,MAX_TEXT_LENGTH,"* Reading last %i log entries of %s",ilast,RealPlayer); selfmessage(Text); read_user_file(AuthID,ilast); }else{ //not available...now we need to check index.log arrays and perform a search in database snprintf(Text,MAX_TEXT_LENGTH,"* Player '%s' is not available on server or is not unique.",Target); selfmessage(Text); read=read_users(Target,found,0); if(found==0){ selfmessage("* Sorry! No entry found in database correspondig to this player."); }else if (found>1){ selfmessage("* Sorry! Too many entries found in database. Please specify search!"); }else{ read_user_file(g_STEAM_ID[read],ilast); } } } return PLUGIN_HANDLED; } read_users(Data[],found=0,ID){ new Text[MAX_TEXT_LENGTH]; new i; new read; selfmessage("* Start searching in database"); selfmessage("* Player(s) found:"); if(ID!=0){ snprintf(Text,MAX_TEXT_LENGTH,"* Searching for %s:",g_STEAM_ID[ID]); selfmessage(Text); }else{ snprintf(Text,MAX_TEXT_LENGTH,"* ID. - STEAM - PLAYER",g_STEAM_ID[ID]); selfmessage(Text); } for(i=0;i<=g_loaded;i++){ if(ID!=0){ if(strcmp(g_STEAM_ID[ID],g_STEAM_ID[i])==0){ snprintf(Text,MAX_TEXT_LENGTH,"* - %s",g_Names[i]); found++; read=i; selfmessage(Text); strinit(Text); } }else if(strstrx(g_STEAM_ID[i],Data)!=-1 || strstrx(g_Names[i],Data)!=-1){ snprintf(Text,MAX_TEXT_LENGTH,"* %i. %s - %s",i,g_STEAM_ID[i],g_Names[i]); found++; read=i; selfmessage(Text); strinit(Text); } if(found>10){ selfmessage("* Stopped search. Too many entries found!"); break; } } return read; } read_user_file(AuthID[],iLast){ new Data[MAX_DATA_LENGTH]; new File[MAX_TEXT_LENGTH]; new iFileSize; new i; strsubst(AuthID,":","_",MAX_AUTHID_LENGTH); snprintf(File,MAX_TEXT_LENGTH,"%s/database/%s.log",g_MainDir,AuthID); selfmessage("* Players last log entries:"); if(fileexists(File)){ iFileSize=filesize(File); for(i=iFileSize;i>iFileSize-iLast;i--){ readfile(File,Data,i,MAX_DATA_LENGTH); if(!strlen(Data)){ break; } selfmessage(Data); strinit(Data); } }else{ selfmessage("* No log entries available for this player."); } }