Skip to content

Commit

Permalink
v1.1.0 - Added Discord notifications for kicks, more toggles, automat…
Browse files Browse the repository at this point in the history
…ic build scripting, etc etc.
  • Loading branch information
Shigbeard committed Nov 23, 2024
1 parent 825f63d commit 361c92d
Show file tree
Hide file tree
Showing 12 changed files with 1,285 additions and 16 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Demo Check Autobuild
# shamelessly stolen from https://github.com/sapphonie/StAC-tf2/blob/master/.github/workflows/blank.yml - thanks sapph!

on:
push:
tags:
- 'v*'

jobs:
run:
name: Run action
runs-on: ubuntu-latest

# skip build on '[ci skip]'
if: "!contains(github.event.head_commit.message, '[ci skip]')"
# this angers the ~linter~

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Setup SourcePawn Compiler
uses: rumblefrog/setup-sp@master
with:
version: '1.12.x'

- name: Compile Plugins
run: |
cd ./scripting
pwd
spcomp -i"./include/" demo_check.sp -o ../plugins/demo_check.smx
ls -la
- name: Zip packages
run: |
mkdir build
7za a -r build/demo_check.zip scripting/ plugins/ extensions/ translations/
ls -la
pwd
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
./build/demo_check.zip
fail_on_unmatched_files: true
generate_release_notes: true
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
plugins
# ignore my ide
.vscode
demo_check.zip
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This plugin is used to check if players are recording demos or not.

## Compiling

Requires [morecolors.inc](https://github.com/DoctorMcKay/sourcemod-plugins/blob/master/scripting/include/morecolors.inc)
All includes and extensions are bundled with this repository. Special thanks to [Dr. McKay](https://github.com/DoctorMcKay/sourcemod-plugins/blob/master/scripting/include/morecolors.inc) and [Sapphonie](https://github.com/sapphonie/StAC-tf2) from whom I shamelessly stole morecolors.inc and SteamWorks.inc/discord.inc (plus extensions) from.

## Installation

Expand All @@ -19,12 +19,37 @@ The plugin has a few cvars that can be configured:

- `sm_democheck_enabled <0/1>` - Enable or disable the plugin. Default: `1`
- `sm_democheck_onreadyup <0/1>` - Performs an additional check at ready up. Requires SoapDM to be running. Default: `0`
- `sm_democheck_warn <0/1>` - Set the plugin into warning only mode. Default: `0`. If enabled, players will be warned if they are not recording demos, but will not be kicked.

Additionally if your use case requires different languages or links to documentation, you can modify the `demo_check.phrases.txt` file in the `translations` directory. Currently only English is supported, and existing documentation links are for ozfortress.

We've also included Discord Webhook support! Starting from version 1.1.0, you can now configure the plugin to send a message to a Discord webhook when a player is kicked for not recording demos. To enable this feature, you will need to set the following cvars:

- `sm_democheck_announce_discord <0/1>` - Enable or disable the Discord webhook feature. Default: `0`

Additionally, modify `/tf/addons/sourcemod/configs/discord.cfg` with the following:

```cfg
"Discord"
{
"democheck"
{
"url" "discord webhook url"
}
}
```

Trust me, it'll be a riot to watch. We don't set the avatar by the way, just the message. Set the avatar and username in the webhook settings on Discord.

Starting from 1.1.0, we've also enabled silencing of the check messages. This is useful if you want to run the plugin in the background without notifying players. To enable this feature, you will need to set the following cvars:

- `sm_democheck_announce <0/1>` - Enable or disable the announce feature. Default: `1` (enabled)

Players will still be told they're being kicked, and why. But they won't be alerted if the check passed.

## Commands

All commands are server side only.
All commands are server side only. Yes, they can be used with RCON, and honestly it'd be funnier that way.

- `sm_democheck <#userid>` - Check if a given player is recording demos.
- `sm_democheck_all` - Check if all players are recording demos.
Expand All @@ -45,3 +70,5 @@ At this stage, the plugin only performs this check when manually triggered, when
## License

This project is licensed under the GNU GPL 3.0 License - see the [LICENSE](LICENSE) file for details.

Parts of this project may be licensed under different licenses. See their sources for more information.
Binary file added extensions/SteamWorks.ext.dll
Binary file not shown.
Binary file added extensions/SteamWorks.ext.so
Binary file not shown.
Binary file added plugins/demo_check.smx
Binary file not shown.
Binary file added plugins/discord.smx
Binary file not shown.
114 changes: 102 additions & 12 deletions scripting/demo_check.sp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <sourcemod>
#include <sdktools>
#include <morecolors>
#include <SteamWorks>
#include <discord>

#define DEMOCHECK_TAG "{lime}[{red}Demo Check{lime}]{white} "

Expand All @@ -25,12 +27,17 @@ public Plugin:myinfo =
name = "Demo Check",
author = "Shigbeard",
description = "Checks if a player is recording a demo",
version = "1.0.1",
version = "1.1.0",
url = "https://ozfortress.com/"
};

ConVar g_bDemoCheckEnabled;
ConVar g_bDemoCheckOnReadyUp; // Requires SoapDM
ConVar g_bDemoCheckWarn;
ConVar g_bDemoCheckAnnounce;
ConVar g_bDemoCheckAnnounceDiscord; // Requires Discord
ConVar g_HostName;
ConVar g_HostPort;

public void OnPluginStart()
{
Expand All @@ -39,13 +46,19 @@ public void OnPluginStart()
g_bDemoCheckEnabled = CreateConVar("sm_democheck_enabled", "1", "Enable demo check", FCVAR_NOTIFY, true, 0.0, true, 1.0);
g_bDemoCheckOnReadyUp = CreateConVar("sm_democheck_onreadyup", "0", "Check if all players are recording a demo when both teams ready up - requires SoapDM", FCVAR_NOTIFY, true, 0.0, true, 1.0);

g_bDemoCheckWarn = CreateConVar("sm_democheck_warn", "0", " Set the plugin into warning only mode.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
g_bDemoCheckAnnounce = CreateConVar("sm_democheck_announce", "1", "Announce passed demo checks to chat", FCVAR_NOTIFY, true, 0.0, true, 1.0);
g_bDemoCheckAnnounceDiscord = CreateConVar("sm_democheck_announce_discord", "0", "Announce failed demo checks to discord", FCVAR_NOTIFY, true, 0.0, true, 1.0);

RegServerCmd("sm_democheck", Cmd_DemoCheck_Console, "Check if a player is recording a demo", 0);
RegServerCmd("sm_democheck_enable", Cmd_DemoCheckEnable_Console, "Enable demo check", 0);
RegServerCmd("sm_democheck_disable", Cmd_DemoCheckDisable_Console, "Disable demo check", 0);
RegServerCmd("sm_democheck_all", Cmd_DemoCheckAll_Console, "Check if all players are recording a demo", 0);

HookConVarChange(g_bDemoCheckEnabled, OnDemoCheckEnabledChange)

g_HostName = FindConVar("hostname");
g_HostPort = FindConVar("hostport");
}

public void SOAP_StopDeathMatching()
Expand Down Expand Up @@ -77,7 +90,10 @@ public void OnDemoCheckEnabledChange(ConVar convar, const char[] oldValue, const
{
if (GetConVarBool(g_bDemoCheckEnabled))
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "enabled");
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "enabled");
}
for (int i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i))
Expand All @@ -88,7 +104,10 @@ public void OnDemoCheckEnabledChange(ConVar convar, const char[] oldValue, const
}
else
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "disabled");
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "disabled");
}
}
}

Expand Down Expand Up @@ -171,25 +190,44 @@ public void OnDSEnableCheck(QueryCookie cookie, int client, ConVarQueryResult re
{
if (StrEqual(value, "3"))
{
CPrintToChat(client, DEMOCHECK_TAG ... "%t", "ds_enabled 3");
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChat(client, DEMOCHECK_TAG ... "%t", "ds_enabled 3");
}
}
else if(StrEqual(value, "0"))
{
PrintToConsole(client, "[Demo Check] %t", "ds_enabled 1 or 2");
PrintToConsole(client, "[Demo Check] %t", "docs");
char sName[64];
GetClientName(client, sName, sizeof(sName));
CreateTimer(2.0, Timer_KickClient, client);
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce", sName);

if (GetConVarBool(g_bDemoCheckWarn))
{
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce_disabled", sName);
}
} else {
CreateTimer(2.0, Timer_KickClient, client);
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce", sName);
}
}
else
{
PrintToConsole(client, "[Demo Check] %t", "ds_enabled 0");
PrintToConsole(client, "[Demo Check] %t", "docs");
char sName[64];
GetClientName(client, sName, sizeof(sName));
CreateTimer(2.0, Timer_KickClient, client);
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce", sName);
if (GetConVarBool(g_bDemoCheckWarn))
{
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce_disabled", sName);
}
} else {
CreateTimer(2.0, Timer_KickClient, client);
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce", sName);
}
}
}

Expand All @@ -201,17 +239,69 @@ public void OnDSAutoDeleteCheck(QueryCookie cookie, int client, ConVarQueryResul
PrintToConsole(client, "[Demo Check] %t", "docs");
char sName[64];
GetClientName(client, sName, sizeof(sName));
CreateTimer(2.0, Timer_KickClient, client);
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce", sName);
if (GetConVarBool(g_bDemoCheckWarn))
{
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce_disabled", sName);
}
} else {
CreateTimer(2.0, Timer_KickClient, client);
CPrintToChatAll(DEMOCHECK_TAG ... "%t", "kicked_announce", sName);
}
}
else
{
CPrintToChat(client, DEMOCHECK_TAG ... "%t", "ds_autodelete 0");
if (GetConVarBool(g_bDemoCheckAnnounce))
{
CPrintToChat(client, DEMOCHECK_TAG ... "%t", "ds_autodelete 0");
}
}
}

public Action Timer_KickClient(Handle timer, int client)
{
if (!IsClientInGame(client))
{
return Plugin_Stop;
}
if (GetConVarBool(g_bDemoCheckAnnounceDiscord))
{
char sName[64];
char sSteamID[64];
char sProfileURL[64];
char sServerName[64];
int iServerIP[4];
int iServerPort;
char sServerIP[64];
GetClientName(client, sName, sizeof(sName));
GetClientAuthId(client, AuthId_Steam2, sSteamID, sizeof(sSteamID));
GetClientAuthId(client, AuthId_SteamID64, sProfileURL, sizeof(sProfileURL));
Format(sProfileURL, sizeof(sProfileURL), "https://steamcommunity.com/profiles/%s", sProfileURL);
char sMsg[512];
if (g_HostName == INVALID_HANDLE)
{
g_HostName = FindConVar("hostname");
if (g_HostName == INVALID_HANDLE)
{
Format(sServerName, sizeof(sServerName), "Unknown Server");
}
}
if (g_HostPort == INVALID_HANDLE)
{
g_HostPort = FindConVar("hostport");
if (g_HostPort == INVALID_HANDLE)
{
iServerPort = 27015;
}
}
GetConVarString(g_HostName, sServerName, sizeof(sServerName));
iServerPort = GetConVarInt(g_HostPort);
SteamWorks_GetPublicIP(iServerIP);
Format(sServerIP, sizeof(sServerIP), "%i.%i.%i.%i:%i", iServerIP[0], iServerIP[1], iServerIP[2], iServerIP[3], iServerPort);
Format(sMsg, sizeof(sMsg), "[Demo Check] %t", "discord_democheck", sName, sSteamID, sProfileURL, sServerName, sServerIP);
Discord_SendMessage("democheck", sMsg);
}
KickClient(client, "[Demo Check] %t", "kicked");
return Plugin_Stop;
}
Loading

0 comments on commit 361c92d

Please sign in to comment.