/* * CSB HLTV Auto Record * Copyright (C) 2026 counter-strike-boost.com * * Automatically starts and stops a demo recording on the connected HLTV proxy * at match start / end. The proxy joins as a client, so the plugin locates it * with is_user_hltv() and drives it with client_cmd(hltv, "record "). * Demos are named with the map and a date/time stamp, and players are told the * match is being recorded. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. It is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See for details. */ #include #include new const PLUGIN[] = "CSB HLTV Auto Record" new const VERSION[] = "1.0.0" new const AUTHOR[] = "counter-strike-boost.com" new g_pEnabled, g_pPrefix, g_pAnnounce new bool:g_bRecording new g_szDemo[64] public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR) g_pEnabled = register_cvar("csb_hltv_enabled", "1") g_pPrefix = register_cvar("csb_hltv_prefix", "csb") g_pAnnounce = register_cvar("csb_hltv_announce", "1") register_logevent("evGameCommencing", 2, "1=Game_Commencing") register_concmd("amx_record", "cmdRecord", ADMIN_BAN, "- start HLTV demo recording now") register_concmd("amx_stoprecord", "cmdStopRecord", ADMIN_BAN, "- stop HLTV demo recording") } findHltv() { new max = get_maxplayers() for (new i = 1; i <= max; i++) { if (is_user_connected(i) && is_user_hltv(i)) return i } return 0 } buildDemoName(out[], len) { new prefix[16], mapname[32], stamp[32] get_pcvar_string(g_pPrefix, prefix, charsmax(prefix)) get_mapname(mapname, charsmax(mapname)) get_time("%Y%m%d-%H%M", stamp, charsmax(stamp)) if (!prefix[0]) copy(prefix, charsmax(prefix), "csb") formatex(out, len, "%s_%s_%s", prefix, mapname, stamp) } announce(const msg[]) { if (get_pcvar_num(g_pAnnounce)) client_print(0, print_chat, "[CSB HLTV] %s", msg) } startRecording() { new hltv = findHltv() if (!hltv) { announce("No HLTV proxy is connected - nothing to record.") return 0 } buildDemoName(g_szDemo, charsmax(g_szDemo)) client_cmd(hltv, "record %s", g_szDemo) g_bRecording = true new msg[128] formatex(msg, charsmax(msg), "Recording this match as %s", g_szDemo) announce(msg) log_amx("[CSB HLTV] recording started: %s", g_szDemo) return 1 } stopRecording() { new hltv = findHltv() if (hltv) client_cmd(hltv, "stop") if (g_bRecording) { announce("Match recording stopped.") log_amx("[CSB HLTV] recording stopped: %s", g_szDemo) } g_bRecording = false return 1 } public evGameCommencing() { if (!get_pcvar_num(g_pEnabled)) return /* a fresh game is starting: restart the demo cleanly */ if (g_bRecording) stopRecording() set_task(1.5, "taskAutoStart") } public taskAutoStart() { if (get_pcvar_num(g_pEnabled) && !g_bRecording) startRecording() } public cmdRecord(id, level, cid) { if (!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED if (g_bRecording) { console_print(id, "[CSB HLTV] Already recording (%s).", g_szDemo) return PLUGIN_HANDLED } if (startRecording()) console_print(id, "[CSB HLTV] Recording started: %s", g_szDemo) else console_print(id, "[CSB HLTV] No HLTV proxy connected.") return PLUGIN_HANDLED } public cmdStopRecord(id, level, cid) { if (!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED stopRecording() console_print(id, "[CSB HLTV] Recording stopped.") return PLUGIN_HANDLED }