add possibility to post logs to discord webhooks
This commit is contained in:
parent
0203008202
commit
6a9e4978aa
32
EliteBGS/DiscordPoster.cs
Normal file
32
EliteBGS/DiscordPoster.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using EliteBGS.Util;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace EliteBGS;
|
||||
|
||||
public class DiscordPoster {
|
||||
public static readonly int DiscordLimit = 2000;
|
||||
|
||||
public static void PostToDiscord(DiscordWebhook webhook, string log) {
|
||||
JsonObject obj = new();
|
||||
obj.Add("content", log);
|
||||
obj.Add("username", "EDBGS");
|
||||
|
||||
using (var client = new HttpClient()) {
|
||||
var content = new StringContent(obj.ToString(), Encoding.UTF8, "application/json");
|
||||
var response = client.PostAsync(webhook.Webhook, content);
|
||||
if (response == null) {
|
||||
throw new Exception("failed to post content to Discord webhook");
|
||||
}
|
||||
response.Wait();
|
||||
var resp = response.Result;
|
||||
if (!resp.IsSuccessStatusCode) {
|
||||
throw new Exception(string.Format(
|
||||
"failed to post content to webhook {0}: {1} / {2}",
|
||||
webhook.Name, resp.StatusCode, resp.Content.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ public partial class LoadEntriesWindow : Window {
|
||||
dialog.DefaultExt = ".log";
|
||||
dialog.Filter = "Log files (*.log)|*.log|All files (*.*)|*";
|
||||
|
||||
var location = config.Global.DefaultJournalLocation;
|
||||
var location = AppConfig.DefaultJournalLocation;
|
||||
if (Directory.Exists(location)) {
|
||||
dialog.InitialDirectory = location;
|
||||
}
|
||||
|
@ -5,9 +5,13 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:EliteBGS"
|
||||
xmlns:Util="clr-namespace:EliteBGS.Util" d:DataContext="{d:DesignInstance Type=Util:AppConfig}" x:Name="window" x:Class="EliteBGS.MainWindow"
|
||||
xmlns:Util="clr-namespace:EliteBGS.Util"
|
||||
d:DataContext="{d:DesignInstance Type=Util:AppConfig}"
|
||||
x:Name="window"
|
||||
x:Class="EliteBGS.MainWindow"
|
||||
mc:Ignorable="d"
|
||||
Title="Elite: Dangerous BGS Helper" Height="520" Width="950" Icon="Salus.ico" Closing="window_Closing">
|
||||
Title="Elite: Dangerous BGS Helper" Height="620" Width="950" Icon="Salus.ico" Closing="window_Closing"
|
||||
>
|
||||
<Window.Resources>
|
||||
<local:MinusFortyFiveConverter x:Key="MinusFortyFiveConverter" />
|
||||
<Style x:Key="StretchingTreeViewStyle" TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
|
||||
@ -15,6 +19,23 @@
|
||||
</Style>
|
||||
|
||||
<local:Report x:Key="ObjectivesBasedOnSystem" />
|
||||
<Util:Config x:Key="Config" />
|
||||
|
||||
<DataTemplate DataType="{x:Type Util:DiscordWebhook}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Name: " Grid.Column="0" Margin="2,0,0,0"/>
|
||||
<TextBox Text="{Binding Name}" Grid.Column="1"/>
|
||||
|
||||
<TextBlock Text="Webhook URL: " Grid.Column="2" Margin="2,0,0,0"/>
|
||||
<TextBox Text="{Binding Webhook}" Grid.Column="3"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<HierarchicalDataTemplate DataType="{x:Type local:SystemObjectives}" ItemsSource="{Binding Path=Objectives}">
|
||||
<Grid
|
||||
@ -162,6 +183,8 @@
|
||||
<ComboBox x:Name="LogType" VerticalAlignment="Stretch" Margin="0,3,0,3" Width="140" SelectionChanged="LogType_SelectionChanged" />
|
||||
<Separator />
|
||||
<CheckBox x:Name="SelectAll" Content="Select All" IsChecked="True" Click="SelectAll_Click"/>
|
||||
<Separator />
|
||||
<mah:DropDownButton x:Name="PostToDiscord" Content="Post to Discord" />
|
||||
</ToolBar>
|
||||
<TreeView CheckBox.Checked="TreeView_CheckBox_Updated"
|
||||
CheckBox.Unchecked="TreeView_CheckBox_Updated"
|
||||
@ -189,6 +212,7 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -244,6 +268,35 @@
|
||||
<mah:ToggleSwitch x:Name="NoFleetCarrier" Grid.Row="2" Grid.ColumnSpan="2" Content="Ignore transactions done on a Fleet Carrier" Toggled="NoFleetCarrier_Toggled" />
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Discord Webhooks" Grid.Row="3" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="3" Margin="0,5,0,0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<DataGrid x:Name="Webhooks"
|
||||
Grid.Row="0"
|
||||
ItemsSource="{Binding Webhooks}"
|
||||
AutoGenerateColumns="False"
|
||||
ScrollViewer.CanContentScroll="True"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
MaxHeight="100"
|
||||
MinHeight="100"
|
||||
KeyUp="Webhooks_KeyUp"
|
||||
CellEditEnding="Webhooks_CellEditEnding"
|
||||
>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
|
||||
<DataGridTextColumn Header="Webhook URL" Binding="{Binding Webhook}" Width="*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Left" Margin="5,10,5,0">
|
||||
<Button x:Name="AddWebHook" Content="Add" Click="AddWebHook_Click"/>
|
||||
<Button x:Name="RemoveWebHook" Content="Remove" Click="RemoveWebHook_Click" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Event Log">
|
||||
|
@ -46,6 +46,9 @@ public partial class MainWindow : MetroWindow {
|
||||
/* ignored */
|
||||
}
|
||||
|
||||
Webhooks.ItemsSource = Config.Global.Webhooks;
|
||||
RefreshPostMenu();
|
||||
|
||||
foreach (DiscordLogGenerator type in logtypes) {
|
||||
LogType.Items.Add(type);
|
||||
}
|
||||
@ -580,4 +583,128 @@ public partial class MainWindow : MetroWindow {
|
||||
}
|
||||
report.SystemObjectives.ForEach(t => { t.IsEnabled = (bool)SelectAll.IsChecked; });
|
||||
}
|
||||
|
||||
private void AddWebHook_Click(object sender, RoutedEventArgs e) {
|
||||
Config.Global.Webhooks.Add(new DiscordWebhook {
|
||||
Name = "Discord Server Name",
|
||||
Webhook = "..."
|
||||
});
|
||||
Webhooks.Items.Refresh();
|
||||
RefreshPostMenu();
|
||||
}
|
||||
|
||||
private void RemoveWebHook_Click(object sender, RoutedEventArgs e) {
|
||||
if (Webhooks.SelectedItems.Count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selection = Webhooks.SelectedItems
|
||||
.OfType<DiscordWebhook>()
|
||||
.ToList()
|
||||
;
|
||||
foreach (var item in selection) {
|
||||
Config.Global.Webhooks.Remove(item);
|
||||
}
|
||||
Webhooks.Items.Refresh();
|
||||
RefreshPostMenu();
|
||||
}
|
||||
|
||||
private void Webhooks_KeyUp(object sender, KeyEventArgs e) {
|
||||
DataGridCell cell = e.OriginalSource as DataGridCell;
|
||||
/* We also get keypresses from DataGridCells that are currently
|
||||
* editing their content. Filter those out. We don't want to delete
|
||||
* the row when the user presses DEL while editing the cells content
|
||||
*/
|
||||
if (cell == null || cell.IsEditing) {
|
||||
return;
|
||||
}
|
||||
if (e.Key == Key.Delete) {
|
||||
RemoveWebHook_Click(this, new RoutedEventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
private void Webhooks_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) {
|
||||
try {
|
||||
Config.SaveGlobal();
|
||||
} catch (Exception) { }
|
||||
e.Cancel = false;
|
||||
RefreshPostMenu();
|
||||
}
|
||||
|
||||
private void RefreshPostMenu() {
|
||||
MenuItem menu;
|
||||
PostToDiscord.Items.Clear();
|
||||
if (Config.Global.Webhooks.Count <= 0) {
|
||||
PostToDiscord.IsEnabled = false;
|
||||
} else {
|
||||
PostToDiscord.IsEnabled = true;
|
||||
foreach (var item in Config.Global.Webhooks) {
|
||||
menu = new MenuItem();
|
||||
menu.Header = item.Name;
|
||||
menu.Click += DiscordWebhook_Click;
|
||||
PostToDiscord.Items.Add(menu);
|
||||
}
|
||||
PostToDiscord.Items.Add(new Separator());
|
||||
|
||||
menu = new MenuItem();
|
||||
menu.Header = "Post To All";
|
||||
menu.Click += PostToAll_Click;
|
||||
PostToDiscord.Items.Add(menu);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckDiscordPostMessageLength() {
|
||||
var content = DiscordLog.Text;
|
||||
if (string.IsNullOrEmpty(content)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (content.Length >= DiscordPoster.DiscordLimit) {
|
||||
MessageBox.Show("The log is too long for discord posting (limit of 2000 characters).",
|
||||
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void PostToDiscordWebhook(DiscordWebhook hook) {
|
||||
if (string.IsNullOrEmpty(DiscordLog.Text)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
DiscordPoster.PostToDiscord(hook, DiscordLog.Text);
|
||||
Log(string.Format("successfully posted to discord webhook {0}",
|
||||
hook.Name));
|
||||
} catch (Exception ex) {
|
||||
Log(string.Format("failed to post to discord webhook {0}: {1}",
|
||||
hook.Name, ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
private void DiscordWebhook_Click(object sender, RoutedEventArgs e) {
|
||||
MenuItem item = sender as MenuItem;
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
DiscordWebhook hook = Config.Global.Webhooks
|
||||
.Find(x => string.Compare(x.Name, item.Header.ToString()) == 0)
|
||||
;
|
||||
if (hook == null) {
|
||||
return;
|
||||
}
|
||||
if (!CheckDiscordPostMessageLength()) {
|
||||
return;
|
||||
}
|
||||
PostToDiscordWebhook(hook);
|
||||
}
|
||||
|
||||
private void PostToAll_Click(object sender, RoutedEventArgs e) {
|
||||
if (!CheckDiscordPostMessageLength()) {
|
||||
return;
|
||||
}
|
||||
foreach (DiscordWebhook hook in Config.Global.Webhooks) {
|
||||
PostToDiscordWebhook(hook);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,71 +1,79 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace EliteBGS.Util {
|
||||
public class AppConfig {
|
||||
private static readonly string default_journal_location = "%UserProfile%\\Saved Games\\Frontier Developments\\Elite Dangerous";
|
||||
private string journal_location = default_journal_location;
|
||||
public string DefaultJournalLocation => default_journal_location;
|
||||
private string colour = "Amber";
|
||||
private string theme = "Dark";
|
||||
namespace EliteBGS.Util;
|
||||
|
||||
public string LastUsedDiscordTemplate { get; set; }
|
||||
public class AppConfig {
|
||||
private static readonly string default_journal_location = "%UserProfile%\\Saved Games\\Frontier Developments\\Elite Dangerous";
|
||||
private string journal_location = default_journal_location;
|
||||
private string colour = "Amber";
|
||||
private string theme = "Dark";
|
||||
|
||||
public string JournalLocation {
|
||||
get {
|
||||
if (journal_location == null) {
|
||||
return DefaultJournalLocation;
|
||||
}
|
||||
return journal_location;
|
||||
}
|
||||
set {
|
||||
journal_location = value;
|
||||
public static string DefaultJournalLocation => default_journal_location;
|
||||
|
||||
public string LastUsedDiscordTemplate { get; set; }
|
||||
|
||||
public string JournalLocation {
|
||||
get {
|
||||
if (journal_location == null) {
|
||||
return DefaultJournalLocation;
|
||||
}
|
||||
return journal_location;
|
||||
}
|
||||
|
||||
public string Theme {
|
||||
get {
|
||||
return theme;
|
||||
}
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
theme = "Dark";
|
||||
} else {
|
||||
theme = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Colour {
|
||||
get {
|
||||
return colour;
|
||||
}
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
colour = "Blue";
|
||||
} else {
|
||||
colour = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether we ignore influence support scenarios form parsing.
|
||||
/// </summary>
|
||||
public bool IgnoreInfluenceSupport { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we ignore market buy entries during parsing.
|
||||
/// </summary>
|
||||
public bool IgnoreMarketBuy { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to ignore fleet carrier stuff when parsing.
|
||||
/// </summary>
|
||||
public bool IgnoreFleetCarrier { get; set; } = true;
|
||||
|
||||
[JsonIgnore]
|
||||
public string FullTheme {
|
||||
get { return Theme + "." + Colour; }
|
||||
set {
|
||||
journal_location = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Theme {
|
||||
get {
|
||||
return theme;
|
||||
}
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
theme = "Dark";
|
||||
} else {
|
||||
theme = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Colour {
|
||||
get {
|
||||
return colour;
|
||||
}
|
||||
set {
|
||||
if (string.IsNullOrEmpty(value)) {
|
||||
colour = "Blue";
|
||||
} else {
|
||||
colour = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether we ignore influence support scenarios form parsing.
|
||||
/// </summary>
|
||||
public bool IgnoreInfluenceSupport { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we ignore market buy entries during parsing.
|
||||
/// </summary>
|
||||
public bool IgnoreMarketBuy { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to ignore fleet carrier stuff when parsing.
|
||||
/// </summary>
|
||||
public bool IgnoreFleetCarrier { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// List of Webhooks configured
|
||||
/// </summary>
|
||||
public List<DiscordWebhook> Webhooks { get; set; } = new List<DiscordWebhook>();
|
||||
|
||||
[JsonIgnore]
|
||||
public string FullTheme {
|
||||
get { return Theme + "." + Colour; }
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace EliteBGS.Util {
|
||||
public class Config {
|
||||
|
13
EliteBGS/Util/DiscordWebhook.cs
Normal file
13
EliteBGS/Util/DiscordWebhook.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace EliteBGS.Util;
|
||||
|
||||
public class DiscordWebhook {
|
||||
/// <summary>
|
||||
/// Webhook URL
|
||||
/// </summary>
|
||||
public string Webhook { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Human readable name for easier identification
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
Loading…
Reference in New Issue
Block a user