I've searched around on these forums, none of the current plugins does this job.
- after 15sec upon connection start recording.
- showing it in chat for user only a message that we are recording.
- after 20sec print a line in chat with his/her nick - steamid.
- query for "stop" command, when stop = kick. (Reason: Do not stop recording during League Play)
the use for this is as we all know client demos can leave traces of cheat use. spectating or a hltv demo does not.
This would be ideal for our league.
this is what we currently got. Code
Code:
/*
* AMX Mod X Script
*
* Auto Demo Recorder
*
* Authors: MoHApX, F4RR3LL
*
* Credits: Pr4yer
*
* Original Menu code by Fysiks
*
* Complex rebuild by MoHApX
*
*/
#include <amxmodx>
#include <amxmisc>
#define PLUGIN "Auto Demo Recorder"
#define VERSION "3.0c"
#define AUTHOR "MoHApX/F4RR3LL"
/* You may change this value to any admin access flag you want */
#define ADR_ACCESS_LEVEL ADMIN_KICK
/* Uncomment the line below to turn on logging every recorded demo */
//#define ADR_ADVANCED_LOGGING
#define ADR_TASKID_MENU 1250
#define ADR_TASKID_CHECK 2452
#define ADR_TASKID_INFO1 3654
#define ADR_TASKID_INFO2 4856
#define ADR_TASKID_INFO3 5058
#define ADR_TASKID_INFO4 6250
new
g_rec_mode,
g_rec_delay,
g_rec_info,
g_prefix,
g_message_delay,
g_menu,
g_demo_name,
g_request_info,
g_upload_url,
g_obey_immunity,
g_self_record
new RecChoiceMenu[] = "Demo Menu"
new RecAdminMenu[] = "Recorder Menu"
new LogFile[128]
new bool:ButtonPressed[33] = { false, ... }
new bool:FirstMessage[33] = { true, ... }
new
g_sayText,
g_showActivity,
g_menuPosition[33],
g_menuPlayers[33][32],
g_menuPlayersNum[33]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_cvar("adr_version", VERSION, FCVAR_SERVER|FCVAR_UNLOGGED|FCVAR_SPONLY)
register_clcmd("say /record", "MotdWindow", ADMIN_ALL, " - Shows Auto Demo Recorder info")
register_clcmd("say_team /record", "MotdWindow", ADMIN_ALL, " - Shows Auto Demo Recorder info")
register_concmd("amx_record", "cmdRec", ADMIN_ALL, "<name or #userid> - Force POV demo record on player")
register_clcmd("amx_recordmenu", "cmdRecMenu", ADR_ACCESS_LEVEL, " - Displays Demo Recorder Menu")
register_menucmd(register_menuid(RecAdminMenu), 1023, "AdminRecMenu")
register_menucmd(register_menuid(RecChoiceMenu), MENU_KEY_1|MENU_KEY_2, "AutoRecMenu")
register_dictionary("auto_demo_recorder.txt")
g_sayText = get_user_msgid("SayText")
g_showActivity = get_cvar_pointer("amx_show_activity")
g_rec_mode = register_cvar("adr_rec_mode", "2")
g_rec_delay = register_cvar("adr_rec_delay", "15")
g_rec_info = register_cvar("adr_rec_info", "1")
g_prefix = register_cvar("adr_prefix", "adr")
g_message_delay = register_cvar("adr_message_delay", "60")
g_menu = register_cvar("adr_menu", "1")
g_demo_name = register_cvar("adr_demo_name", "1")
g_request_info = register_cvar("adr_request_info", "2")
g_upload_url = register_cvar("adr_upload_url", "Ask server administrator for URL!")
g_obey_immunity = register_cvar("adr_obey_immunity", "1")
g_self_record = register_cvar("adr_self_record", "1")
}
public plugin_cfg()
{
if(!get_pcvar_num(g_rec_mode))
return PLUGIN_HANDLED
static AmxxLogsDir[96], LogFilesDir[112], LogFileName[12]
get_localinfo("amxx_logs", AmxxLogsDir, charsmax(AmxxLogsDir))
formatex(LogFilesDir, charsmax(LogFilesDir), "%s/auto_demo_recorder", AmxxLogsDir)
if(!dir_exists(LogFilesDir))
mkdir(LogFilesDir)
get_time("adr%m%d.log", LogFileName, charsmax(LogFile))
formatex(LogFile, charsmax(LogFile), "%s/%s", LogFilesDir, LogFileName)
if(get_pcvar_num(g_rec_delay) < 15)
set_pcvar_num(g_rec_delay, 15)
if(get_pcvar_num(g_rec_delay) > 150)
set_pcvar_num(g_rec_delay, 150)
if(get_pcvar_num(g_message_delay) && get_pcvar_num(g_message_delay) < 30)
set_pcvar_num(g_message_delay, 30)
if(get_pcvar_num(g_message_delay) > 300)
set_pcvar_num(g_message_delay, 300)
return PLUGIN_HANDLED
}
public MotdWindow(id)
{
if(get_pcvar_num(g_rec_mode))
show_motd(id, "motd_adr_info.txt", "Auto Demo Recorder")
}
public ShowStartInfo(id)
{
id = id - ADR_TASKID_INFO1
if(is_user_connected(id))
client_print(id, print_chat, "%L", id, "ADR_START_INFO")
}
public ShowChatInfo(tempid[])
{
new id = tempid[0]
if(!is_user_connected(id))
return PLUGIN_HANDLED
if(FirstMessage[id])
{
client_printc(id, "!g[INFO]!y -------------------------------------", id)
client_printc(id, "!g[INFO]!t %L", id, "ADR_INFO1_STRING1")
client_printc(id, "!g[INFO]!t %L", id, "ADR_INFO1_STRING2")
client_printc(id, "!g[INFO]!y -------------------------------------", id)
FirstMessage[id] = false
}
else
{
client_printc(id, "!g[INFO]!y --------------------------------------------", id)
client_printc(id, "!g[INFO]!t %L !g/record", id, "ADR_INFO2_STRING1")
client_printc(id, "!g[INFO]!t %L !gAuto Demo Recorder", id, "ADR_INFO2_STRING2")
client_printc(id, "!g[INFO]!y --------------------------------------------", id)
}
return PLUGIN_HANDLED
}
public ShowRequestInfo(tempid[])
{
new id = tempid[0]
new adminid = tempid[1]
if(!is_user_connected(id))
return PLUGIN_HANDLED
new adminname[32]
get_user_name(adminid, adminname, 31)
static UploadURL[128]
get_pcvar_string(g_upload_url, UploadURL, charsmax(UploadURL))
//replace_all(UploadURL, charsmax(UploadURL), "http://", "")
if(get_pcvar_num(g_request_info) == 1)
{
client_printc(id, "!g[INFO]!y --------------------------------------------", id)
client_printc(id, "!g[INFO]!t %L", id, "ADR_INFO_REQUEST1")
client_printc(id, "!g[INFO]!t %L", id, "ADR_INFO_REQUEST2")
client_printc(id, "!g[INFO]!t %s", UploadURL)
}
else if(get_pcvar_num(g_request_info) != 0 && get_pcvar_num(g_request_info) != 1)
{
new message[256]
formatex(message, charsmax(message), "%L^n%s", id, "ADR_INFO_HUD", UploadURL)
set_hudmessage(225, 0, 0, 0.02, 0.18, 0, 6.0, 8.0, 0.0, 0.05)
show_hudmessage(id, message)
}
switch(get_pcvar_num(g_showActivity))
{
case 1:
{
console_print(id, "Server admin requested your demo!")
console_print(id, "Upload it to URL: %s", UploadURL)
}
case 2:
{
console_print(id, "Server admin %s requested your demo!", adminname)
console_print(id, "Upload it to URL: %s", UploadURL)
}
}
if(get_pcvar_num(g_message_delay))
{
FirstMessage[id] = true
remove_task(id + ADR_TASKID_INFO2)
set_task(get_pcvar_float(g_message_delay), "ShowChatInfo", id + ADR_TASKID_INFO2, tempid, 1)
remove_task(id + ADR_TASKID_INFO3)
set_task(get_pcvar_float(g_message_delay)*2, "ShowChatInfo", id + ADR_TASKID_INFO3, tempid, 1)
}
return PLUGIN_HANDLED
}
public realplayer(id)
{
if(!is_user_bot(id) && !is_user_hltv(id))
return true
return false
}
public client_disconnect(id)
{
remove_task(id + ADR_TASKID_MENU)
remove_task(id + ADR_TASKID_CHECK)
remove_task(id + ADR_TASKID_INFO1)
remove_task(id + ADR_TASKID_INFO2)
remove_task(id + ADR_TASKID_INFO3)
remove_task(id + ADR_TASKID_INFO4)
}
public client_putinserver(id)
{
if(!get_pcvar_num(g_rec_mode) || !realplayer(id))
return PLUGIN_HANDLED
if(get_pcvar_num(g_self_record))
set_task(20.0, "ShowStartInfo", id + ADR_TASKID_INFO1)
if(get_pcvar_num(g_rec_mode) == 1)
{
ButtonPressed[id] = false
new tempid[1]
tempid[0] = id
remove_task(id + ADR_TASKID_MENU)
set_task(get_pcvar_float(g_rec_delay), "BeforeDemoRec", id + ADR_TASKID_MENU, tempid, 1)
}
return PLUGIN_HANDLED
}
public BeforeDemoRec(tempid[])
{
new id = tempid[0]
if(!is_user_connected(id))
return PLUGIN_HANDLED
if(!get_pcvar_num(g_menu))
{
DemoRec(id, 0, 0)
}
else
{
new RecMenuBody[256], pLen = formatex(RecMenuBody, charsmax(RecMenuBody), "\y%L^n^n", id, "ADR_MENU1")
pLen += formatex(RecMenuBody[pLen], charsmax(RecMenuBody) - pLen, "%L^n", id, "ADR_MENU2")
pLen += formatex(RecMenuBody[pLen], charsmax(RecMenuBody) - pLen, "\w1. \r%L^n", id, "ADR_YES")
pLen += formatex(RecMenuBody[pLen], charsmax(RecMenuBody) - pLen, "\w2. \r%L", id, "ADR_NO")
pLen += formatex(RecMenuBody[pLen], charsmax(RecMenuBody) - pLen, " (%L)", id, "ADR_MENU_WARNING")
show_menu(id, (MENU_KEY_1|MENU_KEY_2), RecMenuBody, 10, RecChoiceMenu)
remove_task(id + ADR_TASKID_CHECK)
set_task(11.0, "ButtonPressedCheck", id + ADR_TASKID_CHECK, tempid, 1)
}
return PLUGIN_HANDLED
}
public ButtonPressedCheck(tempid[])
{
new id = tempid[0]
if(!is_user_connected(id))
return PLUGIN_HANDLED
if(!ButtonPressed[id])
DemoRec(id, 0, 0)
return PLUGIN_HANDLED
}
public AutoRecMenu(id, key)
{
key++
switch(key)
{
case 1: DemoRec(id, 0, 0)
case 2: DemoRec(id, 1, 0)
}
}
public cmdRec(id)
{
if(!get_pcvar_num(g_rec_mode))
return PLUGIN_HANDLED
if(read_argc() < 2)
{
if(!get_pcvar_num(g_self_record))
{
client_print(id, print_chat, "%L", id, "ADR_SELFREC_DISABLED")
console_print(id, "This function is disabled on the server")
}
else
DemoRec(id, 0, id)
return PLUGIN_HANDLED
}
static target[32]
read_argv(1, target, 31)
new player = cmd_target(id, target, 2)
if(!player)
return PLUGIN_HANDLED
if(!realplayer(player) || !access(id, ADR_ACCESS_LEVEL) || (get_pcvar_num(g_obey_immunity) && access(player, ADMIN_IMMUNITY) && player != id))
{
new playername[32]
get_user_name(player, playername, 31)
client_print(id, print_chat, "%L", id, "ADR_REQUEST_FAIL", playername)
console_print(id, "It's impossible to request demo on player %s!", playername)
}
else
DemoRec(player, 0, id)
return PLUGIN_HANDLED
}
public cmdRecMenu(id, level, cid)
{
if(!get_pcvar_num(g_rec_mode) || !cmd_access(id, level, cid, 1))
return PLUGIN_HANDLED
displayMenu(id, g_menuPosition[id] = 0)
return PLUGIN_HANDLED
}
displayMenu(id, pos)
{
if(pos < 0)
return PLUGIN_HANDLED
get_players(g_menuPlayers[id], g_menuPlayersNum[id])
new menuBody[512]
new b = 0
new z
new name[32]
new start = pos * 8, aLen
if(start >= g_menuPlayersNum[id])
start = pos = g_menuPosition[id] = 0
aLen = formatex(menuBody, 511, "\y%L\R%d/%d^n\w^n", id, "ADR_ADMIN_MENU", pos + 1, (g_menuPlayersNum[id] / 8 + ((g_menuPlayersNum[id] % 8) ? 1 : 0)))
new end = start + 8
new keys = MENU_KEY_0
if(end > g_menuPlayersNum[id])
end = g_menuPlayersNum[id]
for(new a = start; a < end; ++a)
{
z = g_menuPlayers[id][a]
get_user_name(z, name, 31)
if(!realplayer(z) || (get_pcvar_num(g_obey_immunity) && access(z, ADMIN_IMMUNITY) && z != id))
{
++b
aLen += formatex(menuBody[aLen], 511-aLen, "\d%d. %s^n\w", b, name)
}
else
{
keys |= (1<<b)
if (is_user_admin(z))
aLen += formatex(menuBody[aLen], 511-aLen, "%d. %s \r*^n\w", ++b, name)
else
aLen += formatex(menuBody[aLen], 511-aLen, "%d. %s^n", ++b, name)
}
}
if (end != g_menuPlayersNum[id])
{
formatex(menuBody[aLen], 511-aLen, "^n9. %L...^n0. %L", id, "MORE", id, pos ? "BACK" : "EXIT")
keys |= MENU_KEY_9
}
else
formatex(menuBody[aLen], 511-aLen, "^n0. %L", id, pos ? "BACK" : "EXIT")
show_menu(id, keys, menuBody, -1, RecAdminMenu)
return PLUGIN_HANDLED
}
public AdminRecMenu(id, key)
{
switch(key)
{
case 8: displayMenu(id, ++g_menuPosition[id])
case 9: displayMenu(id, --g_menuPosition[id])
default:
{
new player = g_menuPlayers[id][g_menuPosition[id] * 8 + key]
DemoRec(player, 0, id)
}
}
}
public DemoRec(id, choice, adminid)
{
if(!is_user_connected(id))
return PLUGIN_HANDLED
static nickname[32], ip[16], steamid[20], prefix[16]
get_user_name(id, nickname, charsmax(nickname))
get_user_ip(id, ip, charsmax(ip), 1)
get_user_authid(id, steamid, charsmax(steamid))
get_pcvar_string(g_prefix, prefix, charsmax(prefix))
ButtonPressed[id] = true
if(choice == 1 && (get_pcvar_num(g_obey_immunity) && access(id, ADMIN_IMMUNITY)))
{
#if defined ADR_ADVANCED_LOGGING
log_to_file(LogFile, "Player [ %s | %s | %s ] with immunity refused to record demo.", nickname, steamid, ip)
#endif
return PLUGIN_HANDLED
}
else if(choice == 1)
{
#if defined ADR_ADVANCED_LOGGING
log_to_file(LogFile, "Player [ %s | %s | %s ] refused to record demo and was kicked from the server.", nickname, steamid, ip)
#endif
remove_task(id + ADR_TASKID_MENU)
remove_task(id + ADR_TASKID_CHECK)
server_cmd("kick #%d You can't play on this server without recording POV demo!", get_user_userid(id))
return PLUGIN_HANDLED
}
static DemoName[128], MapName[32], NameType
get_mapname(MapName, charsmax(MapName))
NameType = get_pcvar_num(g_demo_name)
if(adminid && adminid != id)
NameType = 3
else if(adminid == id)
{
NameType = 2
adminid = 0
}
switch(NameType)
{
case 0: formatex(DemoName, charsmax(DemoName), "_%s_autorecorded_demo", prefix)
case 1: formatex(DemoName, charsmax(DemoName), "_%s_%s_autorecorded_demo", prefix, MapName)
default:
{
static CurrentTime[9], CurrentDate[11]
get_time("%H:%M:%S", CurrentTime, charsmax(CurrentTime))
get_time("%d-%m-%Y", CurrentDate, charsmax(CurrentDate))
if(NameType == 3)
{
static Hash[34]
md5(DemoName, Hash)
formatex(DemoName, charsmax(DemoName), "_%s_%s_%s_%s_MD5-%s", prefix, MapName, CurrentTime, CurrentDate, Hash)
}
else
formatex(DemoName, charsmax(DemoName), "_%s_%s_%s_%s", prefix, MapName, CurrentTime, CurrentDate)
}
}
replace_all(DemoName, charsmax(DemoName), ".", "-")
replace_all(DemoName, charsmax(DemoName), "/", "-")
replace_all(DemoName, charsmax(DemoName), "\", "-")
replace_all(DemoName, charsmax(DemoName), ":", "-")
replace_all(DemoName, charsmax(DemoName), "*", "-")
replace_all(DemoName, charsmax(DemoName), "?", "-")
replace_all(DemoName, charsmax(DemoName), "<", "-")
replace_all(DemoName, charsmax(DemoName), ">", "-")
replace_all(DemoName, charsmax(DemoName), "|", "-")
replace_all(DemoName, charsmax(DemoName), " ", "-")
client_cmd(id, "stop; record ^"%s^"", DemoName)
formatex(DemoName, charsmax(DemoName), "%s.dem", DemoName)
if(get_pcvar_num(g_rec_info) == 1)
{
client_printc(id, "!g[INFO]!y --------------------------------------------", id)
client_printc(id, "!g[INFO]!t %L", id, "ADR_REC_FILE")
client_printc(id, "!g[INFO]!t %s", DemoName)
client_printc(id, "!g[INFO]!y --------------------------------------------", id)
}
else if(get_pcvar_num(g_rec_info) != 0 && get_pcvar_num(g_rec_info) != 1)
{
new message[256]
formatex(message, charsmax(message), "%L^n^n%s", id, "ADR_REC_FILE", DemoName)
set_hudmessage(225, 0, 0, 0.02, 0.18, 0, 6.0, 6.0, 0.0, 0.05)
show_hudmessage(id, message)
}
new tempid[2]
tempid[0] = id
tempid[1] = adminid
if(!adminid)
{
#if defined ADR_ADVANCED_LOGGING
log_to_file(LogFile, "Demo filename: %s. Player [ %s | %s | %s ].", DemoName, nickname, steamid, ip)
#endif
if(get_pcvar_num(g_message_delay))
{
FirstMessage[id] = true
remove_task(id + ADR_TASKID_INFO2)
set_task(get_pcvar_float(g_message_delay), "ShowChatInfo", id + ADR_TASKID_INFO2, tempid, 1)
remove_task(id + ADR_TASKID_INFO3)
set_task(get_pcvar_float(g_message_delay)*2, "ShowChatInfo", id + ADR_TASKID_INFO3, tempid, 1)
}
}
else
{
new adminname[32], playername[32], adminsteamid[20]
get_user_name(adminid, adminname, 31)
get_user_authid(adminid, adminsteamid, charsmax(adminsteamid))
get_user_name(id, playername, 31)
log_to_file(LogFile, "%s [ %s ] requested POV demo on player [ %s | %s | %s ]. Demo filename: %s.", adminname, adminsteamid, nickname, steamid, ip, DemoName)
client_print(adminid, print_chat, "%L", adminid, "ADR_REQUEST_SUCCESS", playername)
console_print(adminid, "Demo request on player %s was successfully send!", playername)
remove_task(id + ADR_TASKID_INFO4)
set_task(15.0, "ShowRequestInfo", id + ADR_TASKID_INFO4, tempid, 2)
}
return PLUGIN_HANDLED
}
stock client_printc(const id, const string[], {Float, Sql, Resul,_}:...) {
new msg[191], players[32], count = 1
vformat(msg, charsmax(msg), string, 3)
replace_all(msg,190,"!g","^4")
replace_all(msg,190,"!y","^1")
replace_all(msg,190,"!t","^3")
if(id)
players[0] = id
else
get_players(players, count, "ch")
for (new i = 0 ; i < count ; i++)
{
if(is_user_connected(players[i]))
{
message_begin(MSG_ONE_UNRELIABLE, g_sayText,_, players[i])
write_byte(players[i])
write_string(msg)
message_end()
}
}
}
incase you where wondering about slow hacking.
the players that play in our league sign an agreement to these rules upon registering.
the numberofrecording.dem would need to go in rotation.
that way there is a HD size limit of the league recordings and enough time to request the demo.
without having to put up with excuses of "my demo got overwritten".