/*
* CSB Music Player
* Copyright (C) 2026 counter-strike-boost.com
*
* An admin "DJ" plugin. Track names are read from a config file
* (addons/amxmodx/configs/csb_music.ini, one MP3 path per line). An admin opens
* a menu with /dj and plays a track to everyone via the client "mp3 play"
* command; /djstop stops it. Players can mute the DJ for themselves with
* /djmute, and a cooldown stops admins from spamming tracks.
*
* Inspired by the classic DJ / Music Menu plugins. Independent GPL
* re-implementation.
*
* 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 Music Player"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
#define ACCESS_FLAG ADMIN_LEVEL_A
#define MAX_TRACKS 32
new g_pEnabled, g_pCooldown
new g_szTracks[MAX_TRACKS][64]
new g_iTrackCount
new Float:g_fLastPlay
new bool:g_bMuted[33]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_dj_enabled", "1")
g_pCooldown = register_cvar("csb_dj_cooldown", "8")
register_clcmd("say /dj", "cmdMenu")
register_clcmd("say_team /dj", "cmdMenu")
register_clcmd("say /djstop", "cmdStop")
register_clcmd("say /djmute", "cmdMute")
loadTracks()
}
loadTracks()
{
g_iTrackCount = 0
new path[128]
get_localinfo("amxx_configsdir", path, charsmax(path))
if (!path[0])
copy(path, charsmax(path), "addons/amxmodx/configs")
add(path, charsmax(path), "/csb_music.ini")
if (!file_exists(path))
return
new line[96], len, pos = 0
while (g_iTrackCount < MAX_TRACKS && (pos = read_file(path, pos, line, charsmax(line), len)))
{
trim(line)
if (!line[0] || line[0] == ';' || line[0] == '#')
continue
copy(g_szTracks[g_iTrackCount], charsmax(g_szTracks[]), line)
g_iTrackCount++
}
}
public client_putinserver(id)
{
g_bMuted[id] = false
}
bool:hasAccess(id)
{
return (get_user_flags(id) & ACCESS_FLAG) != 0
}
public cmdMenu(id)
{
if (!get_pcvar_num(g_pEnabled))
return PLUGIN_HANDLED
if (!hasAccess(id))
{
client_print(id, print_chat, "[CSB] Only admins can use the DJ menu.")
return PLUGIN_HANDLED
}
if (g_iTrackCount == 0)
{
client_print(id, print_chat, "[CSB] No tracks in csb_music.ini.")
return PLUGIN_HANDLED
}
new menu = menu_create("\yCSB DJ^n\wPick a track:", "menuHandler")
new info[8], label[80]
for (new i = 0; i < g_iTrackCount; i++)
{
num_to_str(i, info, charsmax(info))
formatex(label, charsmax(label), "\w%s", g_szTracks[i])
menu_additem(menu, label, info, 0)
}
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL)
menu_display(id, menu, 0)
return PLUGIN_HANDLED
}
public menuHandler(id, menu, item)
{
if (item == MENU_EXIT)
{
menu_destroy(menu)
return PLUGIN_HANDLED
}
new info[8], name[80], access, callback
menu_item_getinfo(menu, item, access, info, charsmax(info), name, charsmax(name), callback)
menu_destroy(menu)
new idx = str_to_num(info)
if (idx < 0 || idx >= g_iTrackCount)
return PLUGIN_HANDLED
new Float:cd = get_pcvar_float(g_pCooldown)
if (get_gametime() - g_fLastPlay < cd)
{
client_print(id, print_chat, "[CSB] DJ is on cooldown, wait a moment.")
return PLUGIN_HANDLED
}
g_fLastPlay = get_gametime()
playToAll(g_szTracks[idx])
new admin[32]
get_user_name(id, admin, charsmax(admin))
client_print(0, print_chat, "[CSB] DJ %s is playing: %s", admin, g_szTracks[idx])
return PLUGIN_HANDLED
}
playToAll(const track[])
{
new players[32], num
get_players(players, num, "ch")
for (new i = 0; i < num; i++)
{
new pl = players[i]
if (g_bMuted[pl])
continue
client_cmd(pl, "mp3 play ^"%s^"", track)
}
}
public cmdStop(id)
{
if (!hasAccess(id))
return PLUGIN_HANDLED
new players[32], num
get_players(players, num, "ch")
for (new i = 0; i < num; i++)
client_cmd(players[i], "mp3 stop")
client_print(0, print_chat, "[CSB] The music was stopped.")
return PLUGIN_HANDLED
}
public cmdMute(id)
{
g_bMuted[id] = !g_bMuted[id]
if (g_bMuted[id])
{
client_cmd(id, "mp3 stop")
client_print(id, print_chat, "[CSB] You muted the DJ. Type /djmute again to unmute.")
}
else
{
client_print(id, print_chat, "[CSB] You unmuted the DJ.")
}
return PLUGIN_HANDLED
}