Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: post global chat messages to discord #24

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Bloodstone.API;
using Bloodstone.Hooks;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using UnityEngine;
using v_rising_discord_bot_companion.chat;
using v_rising_discord_bot_companion.query;

namespace v_rising_discord_bot_companion;
Expand All @@ -24,6 +26,9 @@ public class Plugin : BasePlugin {

private PluginConfig? _pluginConfig;
private ConfigEntry<string> _basicAuthUsers;
private ConfigEntry<string?> _discordWebhookUrl;
private ConfigEntry<string> _discordWebhookUsername;
private ConfigEntry<string> _discordWebhookAvatarUrl;

public Plugin() {

Expand All @@ -36,6 +41,24 @@ public Plugin() {
"",
"A list of comma separated username:password entries that are allowed to query the HTTP API."
);
_discordWebhookUrl = Config.Bind<string?>(
"Discord",
"WebhookUrl",
null,
"The discord webhook url to post chat messages to."
);
_discordWebhookUsername = Config.Bind<string>(
"Discord",
"WebhookUsername",
"Jarvis",
"The username to use when posting messages to discord."
);
_discordWebhookAvatarUrl = Config.Bind(
"Discord",
"WebhookAvatarUrl",
"https://raw.githubusercontent.com/DarkAtra/v-rising-discord-bot/main/docs/assets/icon.png",
"The url to the avatar image for the discord webhook."
);
}

public override void Load() {
Expand All @@ -45,7 +68,6 @@ public override void Load() {
return;
}


// Plugin startup logic
Log.LogInfo($"Plugin {MyPluginInfo.PLUGIN_GUID} version {MyPluginInfo.PLUGIN_VERSION} is loaded!");

Expand All @@ -56,9 +78,17 @@ public override void Load() {
// Harmony patching
_harmony = new Harmony(MyPluginInfo.PLUGIN_GUID);
_harmony.PatchAll(Assembly.GetExecutingAssembly());

if (GetPluginConfig().DiscordWebhookUrl != null) {
Logger.LogInfo("Configuring DiscordChatSystem.");
Chat.OnChatMessage += DiscordChatSystem.HandleChatEvent;
}
}

public override bool Unload() {
if (_pluginConfig?.DiscordWebhookUrl != null) {
Chat.OnChatMessage -= DiscordChatSystem.HandleChatEvent;
}
_harmony?.UnpatchSelf();
if (_queryDispatcher != null) {
Object.Destroy(_queryDispatcher);
Expand Down Expand Up @@ -88,7 +118,10 @@ private PluginConfig ParsePluginConfig() {
}

return new PluginConfig(
BasicAuthUsers: basicAuthUsers
BasicAuthUsers: basicAuthUsers,
DiscordWebhookUrl: _discordWebhookUrl.Value,
DiscordWebhookUsername: _discordWebhookUsername.Value,
DiscordWebhookAvatarUrl: _discordWebhookAvatarUrl.Value
);
}
}
5 changes: 4 additions & 1 deletion PluginConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
namespace v_rising_discord_bot_companion;

public readonly record struct PluginConfig(
List<BasicAuthUser> BasicAuthUsers
List<BasicAuthUser> BasicAuthUsers,
string? DiscordWebhookUrl,
string DiscordWebhookUsername,
string DiscordWebhookAvatarUrl
);

public readonly record struct BasicAuthUser(
Expand Down
54 changes: 54 additions & 0 deletions chat/DiscordChatSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Bloodstone.Hooks;
using ProjectM.Network;

namespace v_rising_discord_bot_companion.chat;

public class DiscordChatSystem {

private static readonly int MAX_MESSAGE_LENGTH = 2000;

private static readonly HttpClient _httpClient = new();
private static readonly JsonSerializerOptions _serializeOptions = new() {
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
Copy link
Owner Author

@DarkAtra DarkAtra Jun 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsonNamingPolicy.SnakeCaseLower does not exist in .net6 - see https://github.com/DarkAtra/v-rising-discord-bot-companion/pull/24/files#r1657375255

};

public static void HandleChatEvent(VChatEvent vChatEvent) {

var pluginConfig = Plugin.Instance.GetPluginConfig();
var discordWebhookUrl = pluginConfig.DiscordWebhookUrl;
if (discordWebhookUrl == null || vChatEvent.Type != ChatMessageType.Global) {
return;
}

try {

var webhookRequestPayload = new DiscordWebhookRequestPayload(
Username: pluginConfig.DiscordWebhookUsername,
AvatarUrl: pluginConfig.DiscordWebhookAvatarUrl,
Content: $"{vChatEvent.User.CharacterName}: {vChatEvent.Message.Substring(0, Math.Min(vChatEvent.Message.Length, MAX_MESSAGE_LENGTH - vChatEvent.User.CharacterName.Length))}"
);

var webhookRequest = new HttpRequestMessage(HttpMethod.Post, discordWebhookUrl) {
Content = new StringContent(
JsonSerializer.Serialize(webhookRequestPayload, _serializeOptions),
Encoding.UTF8,
"application/json"
)
};

var response = _httpClient.Send(webhookRequest);
if (response.StatusCode != HttpStatusCode.NoContent) {
Plugin.Logger.LogError($"Discord webhook responded with unexpected status code '{response.StatusCode}' - please check your configuration");
}
} catch (Exception e) {
Plugin.Logger.LogError($"Exception calling discord webhook: {e.Message}");
}
}
}
7 changes: 7 additions & 0 deletions chat/DiscordWebhookRequestPayload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace v_rising_discord_bot_companion.chat;

public readonly record struct DiscordWebhookRequestPayload(
string Username,
string Content,
string AvatarUrl
);
10 changes: 10 additions & 0 deletions http-requests.http
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ POST http://localhost:25570/api/save/v1
Content-Type: application/json

{}

### Discord Webhook
POST https://discord.com/api/webhooks/xxx/xxx
Content-Type: application/json

{
"username": "Jarvis",
"avatar_url": "https://raw.githubusercontent.com/DarkAtra/v-rising-discord-bot/main/docs/assets/icon.png",
"content": "Atra: Test"
}
2 changes: 1 addition & 1 deletion v-rising-discord-bot-companion.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Description>A companion mod for DarkAtra/v-rising-discord-bot.</Description>
<Version>0.4.1</Version>

<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likely has to be reverted - the game uses .net6 and i'm not sure if using a different .net version would cause unexpected issues, so it's safer to stay on the same version as the game for now.

<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
Expand Down
Loading