Add EventNotifier
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
#include <sourcemod>
|
||||
#include <multicolors>
|
||||
#include <EventNotifier>
|
||||
|
||||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
// Shortest automatic announcement interval, in seconds. Values below this are
|
||||
// raised to it; 0 or below disables the timer entirely.
|
||||
#define MIN_ANNOUNCE_INTERVAL 60.0
|
||||
|
||||
// Visible characters kept from the event name in chat.
|
||||
#define ANNOUNCE_NAME_MAX 64
|
||||
// Visible characters allowed for the map list before " +N more" is appended.
|
||||
#define ANNOUNCE_MAPS_BUDGET 120
|
||||
|
||||
ConVar g_cvInterval;
|
||||
ConVar g_cvCount;
|
||||
|
||||
Handle g_hAnnounceTimer;
|
||||
int g_iRotation;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "EventNotifier Announcements",
|
||||
author = "marisakirisame.net",
|
||||
description = "Periodically announces upcoming Unloze events in chat",
|
||||
version = PLUGIN_VERSION,
|
||||
url = "https://marisakirisame.net"
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
g_cvInterval = CreateConVar("sm_event_announce_interval", "120",
|
||||
"Seconds between event announcements in chat, -1 to disable automatic announcements (sm_event_announce still works)", _, true, -1.0);
|
||||
g_cvCount = CreateConVar("sm_event_announce_count", "3",
|
||||
"Rotate announcements through the next N upcoming events, one per announcement", _, true, 1.0, true, 20.0);
|
||||
|
||||
// CreateConVar keeps the old bounds when the cvar already exists (plugin reload),
|
||||
// so apply the lower bound explicitly.
|
||||
g_cvInterval.SetBounds(ConVarBound_Lower, true, -1.0);
|
||||
g_cvInterval.AddChangeHook(OnIntervalChanged);
|
||||
|
||||
AutoExecConfig(true, "EventNotifierAnnouncements");
|
||||
|
||||
RegAdminCmd("sm_event_announce", Command_Announce, ADMFLAG_GENERIC, "Posts the next event announcement in chat now");
|
||||
}
|
||||
|
||||
public void OnConfigsExecuted()
|
||||
{
|
||||
RestartAnnounceTimer();
|
||||
}
|
||||
|
||||
public void OnIntervalChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||
{
|
||||
RestartAnnounceTimer();
|
||||
}
|
||||
|
||||
void RestartAnnounceTimer()
|
||||
{
|
||||
delete g_hAnnounceTimer;
|
||||
|
||||
float interval = g_cvInterval.FloatValue;
|
||||
if (interval <= 0.0)
|
||||
return;
|
||||
|
||||
if (interval < MIN_ANNOUNCE_INTERVAL)
|
||||
interval = MIN_ANNOUNCE_INTERVAL;
|
||||
|
||||
g_hAnnounceTimer = CreateTimer(interval, Timer_Announce, _, TIMER_REPEAT);
|
||||
}
|
||||
|
||||
public Action Timer_Announce(Handle timer)
|
||||
{
|
||||
PostAnnouncement();
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
public Action Command_Announce(int client, int args)
|
||||
{
|
||||
if (PostAnnouncement())
|
||||
ReplyToCommand(client, "[Events] Announcement posted.");
|
||||
else
|
||||
ReplyToCommand(client, "[Events] No upcoming events to announce.");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Announcement
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Posts one event from the rotation window. Returns false when there is nothing to post.
|
||||
bool PostAnnouncement()
|
||||
{
|
||||
int count = EventNotifier_GetEventCount();
|
||||
if (count <= 0)
|
||||
return false;
|
||||
|
||||
int window = g_cvCount.IntValue;
|
||||
if (window > count)
|
||||
window = count;
|
||||
|
||||
int index = g_iRotation % window;
|
||||
g_iRotation = (index + 1) % window;
|
||||
|
||||
EventInfo ev;
|
||||
if (!EventNotifier_GetEvent(index, ev))
|
||||
return false;
|
||||
|
||||
char name[ANNOUNCE_NAME_MAX + 1];
|
||||
strcopy(name, sizeof(name), ev.name);
|
||||
if (!name[0])
|
||||
strcopy(name, sizeof(name), "Unnamed event");
|
||||
|
||||
int now = GetTime();
|
||||
char span[32];
|
||||
if (ev.start <= 0)
|
||||
{
|
||||
CPrintToChatAll("{darkorange}[Events] {yellow}#%d: {lightgreen}%s {grey}date TBA", ev.number, name);
|
||||
}
|
||||
else if (now < ev.start)
|
||||
{
|
||||
EventNotifier_FormatDuration(ev.start - now, span, sizeof(span));
|
||||
CPrintToChatAll("{darkorange}[Events] {yellow}#%d: {lightgreen}%s {lime}starts in %s", ev.number, name, span);
|
||||
}
|
||||
else
|
||||
{
|
||||
EventNotifier_FormatDuration(now - ev.start, span, sizeof(span));
|
||||
CPrintToChatAll("{darkorange}[Events] {yellow}#%d: {lightgreen}%s {orchid}started %s ago", ev.number, name, span);
|
||||
}
|
||||
|
||||
if (ev.maps[0])
|
||||
{
|
||||
char mapsLine[ANNOUNCE_MAPS_BUDGET + 132];
|
||||
int more = BuildMapsLine(ev.maps, mapsLine, sizeof(mapsLine), ANNOUNCE_MAPS_BUDGET);
|
||||
if (more > 0)
|
||||
CPrintToChatAll("{darkorange}[Events] {white}Maps: {lightgreen}%s {grey}+%d more", mapsLine, more);
|
||||
else
|
||||
CPrintToChatAll("{darkorange}[Events] {white}Maps: {lightgreen}%s", mapsLine);
|
||||
}
|
||||
|
||||
CPrintToChatAll("{darkorange}[Events] {white}Type {lime}!event %d {white}for details and the full map list.", ev.number);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copies ", "-separated items from maps into out while the visible length stays
|
||||
// within budget. Always emits at least the first item. Returns how many items
|
||||
// were left out (0 when everything fit).
|
||||
int BuildMapsLine(const char[] maps, char[] out, int maxlen, int budget)
|
||||
{
|
||||
// Count from the raw string so "+N more" is right even past the explode limit.
|
||||
int total = 1;
|
||||
for (int i = 0; maps[i]; i++)
|
||||
{
|
||||
if (maps[i] == ',' && maps[i + 1] == ' ')
|
||||
total++;
|
||||
}
|
||||
|
||||
char parts[32][128];
|
||||
int count = ExplodeString(maps, ", ", parts, sizeof(parts), sizeof(parts[]));
|
||||
|
||||
out[0] = '\0';
|
||||
int used = 0;
|
||||
int shown = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int add = strlen(parts[i]) + ((shown > 0) ? 2 : 0);
|
||||
if (shown > 0 && used + add > budget)
|
||||
break;
|
||||
|
||||
if (shown > 0)
|
||||
StrCat(out, maxlen, ", ");
|
||||
StrCat(out, maxlen, parts[i]);
|
||||
used += add;
|
||||
shown++;
|
||||
}
|
||||
|
||||
return total - shown;
|
||||
}
|
||||
Reference in New Issue
Block a user