Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
6cbe54ff73 | |||
6fd5bbc582 | |||
262182cfaf | |||
007b391dc2 | |||
9918c7d559 | |||
2bf8d9018d | |||
8eaf94f634 | |||
20adf93d39 | |||
fd3e5f61cb | |||
e617c3852b | |||
9f013bed38 | |||
916afb2348 | |||
6eb892151c | |||
6a9e4978aa |
@ -35,10 +35,10 @@ public class Cartographics : Transaction {
|
||||
/* add multi sell and normal ones together */
|
||||
long total =
|
||||
Entries.OfType<MultiSellExplorationDataEntry>()
|
||||
.Sum(x => x.TotalEarnings)
|
||||
.Sum(x => x.Total)
|
||||
+
|
||||
Entries.OfType<SellExplorationDataEntry>()
|
||||
.Sum(x => x.TotalEarnings)
|
||||
.Sum(x => x.Total)
|
||||
;
|
||||
return total;
|
||||
}
|
||||
|
17
EDPlayerJournal/BGS/Parsers/CommanderParser.cs
Normal file
17
EDPlayerJournal/BGS/Parsers/CommanderParser.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using EDPlayerJournal.BGS;
|
||||
using EDPlayerJournal.Entries;
|
||||
|
||||
internal class CommanderParser : ITransactionParserPart {
|
||||
public void Parse(Entry entry, TransactionParserContext context, TransactionParserOptions options, TransactionList transactions) {
|
||||
CommanderEntry commanderEntry = (CommanderEntry)entry;
|
||||
if (commanderEntry != null && !string.IsNullOrEmpty(commanderEntry.FullName)) {
|
||||
if (!context.Commanders.Contains(commanderEntry.FullName)) {
|
||||
context.Commanders.Add(commanderEntry.FullName);
|
||||
}
|
||||
}
|
||||
// A commander entry happens when you log out, and log back in again
|
||||
// for example when switching from Open, to Solo or PG.
|
||||
context.DiscernCombatZone(transactions, entry);
|
||||
context.ResetCombatZone();
|
||||
}
|
||||
}
|
@ -602,15 +602,6 @@ internal class DropshipDeployParser : ITransactionParserPart {
|
||||
}
|
||||
}
|
||||
|
||||
internal class CommanderParser : ITransactionParserPart {
|
||||
public void Parse(Entry entry, TransactionParserContext context, TransactionParserOptions options, TransactionList transactions) {
|
||||
// A commander entry happens when you log out, and log back in again
|
||||
// for example when switching from Open, to Solo or PG.
|
||||
context.DiscernCombatZone(transactions, entry);
|
||||
context.ResetCombatZone();
|
||||
}
|
||||
}
|
||||
|
||||
public class TransactionParser {
|
||||
private static Dictionary<string, ITransactionParserPart> ParserParts { get; } = new()
|
||||
{
|
||||
@ -669,6 +660,11 @@ public class TransactionParser {
|
||||
return Parse(entries, defaultOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of commanders seen during parsing.
|
||||
/// </summary>
|
||||
public List<string> Commanders { get; set; } = new();
|
||||
|
||||
public List<Transaction>? Parse(IEnumerable<Entry> entries, TransactionParserOptions options) {
|
||||
TransactionList transactions = new();
|
||||
TransactionParserContext context = new();
|
||||
@ -686,6 +682,9 @@ public class TransactionParser {
|
||||
transactionParserPart.Parse(entry, context, options, transactions);
|
||||
}
|
||||
|
||||
// Copy out list of commanders seen
|
||||
Commanders = context.Commanders;
|
||||
|
||||
return transactions.ToList();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,11 @@
|
||||
namespace EDPlayerJournal.BGS;
|
||||
|
||||
internal class TransactionParserContext {
|
||||
/// <summary>
|
||||
/// List of commander names seen in the logs. May be empty.
|
||||
/// </summary>
|
||||
public List<string> Commanders { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Name of the current system the player is in.
|
||||
/// </summary>
|
||||
|
@ -8,4 +8,13 @@ public class CommanderEntry : Entry {
|
||||
Name = JSON.Value<string>("Name") ?? "";
|
||||
FID = JSON.Value<string>("FID") ?? "";
|
||||
}
|
||||
|
||||
public string FullName {
|
||||
get {
|
||||
if (string.IsNullOrEmpty(Name)) {
|
||||
return string.Empty;
|
||||
}
|
||||
return "CMDR " + Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,23 @@
|
||||
namespace EDPlayerJournal.Entries;
|
||||
namespace EDPlayerJournal.Entries;
|
||||
|
||||
public class MultiSellExplorationDataEntry : Entry {
|
||||
protected override void Initialise() {
|
||||
TotalEarnings = (JSON.Value<int?>("TotalEarnings") ?? 0);
|
||||
TotalEarnings = JSON.Value<long?>("TotalEarnings") ?? 0;
|
||||
BaseValue = JSON.Value<long?>("BaseValue") ?? 0;
|
||||
Bonus = JSON.Value<long?>("Bonus") ?? 0;
|
||||
}
|
||||
|
||||
public int TotalEarnings { get; set; } = 0;
|
||||
public long Total {
|
||||
get { return BaseValue + Bonus; }
|
||||
}
|
||||
|
||||
public long BaseValue { get; set; } = 0;
|
||||
|
||||
public long Bonus { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Total Earnings are the actual earnings without bonus. So this
|
||||
/// value is BaseValue minus any percent a crew pilot takes.
|
||||
/// </summary>
|
||||
public long TotalEarnings { get; set; } = 0;
|
||||
}
|
||||
|
@ -6,8 +6,17 @@ namespace EDPlayerJournal.Entries;
|
||||
public class SellExplorationDataEntry : Entry {
|
||||
public long BaseValue { get; set; }
|
||||
public long Bonus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total Earnings are the actual earnings without bonus. So this
|
||||
/// value is BaseValue minus any percent a crew pilot takes.
|
||||
/// </summary>
|
||||
public long TotalEarnings { get; set; }
|
||||
|
||||
public long Total {
|
||||
get { return BaseValue + Bonus; }
|
||||
}
|
||||
|
||||
public List<string> Systems { get; set; } = new List<string>();
|
||||
public List<string> Discovered { get; set; } = new List<string>();
|
||||
|
||||
|
@ -1,5 +1,15 @@
|
||||
# EliteBGS changelog
|
||||
|
||||
## 0.4.3 on 18.09.2024
|
||||
|
||||
* Add possibility to post log reports to Discord webhooks.
|
||||
Logs are automatically split to fit discord length, and you can choose the
|
||||
name of the Commander to post it as. There are some restrictions, so for
|
||||
ultra long logs the one line log format might be necessary.
|
||||
* Fix cartographics data value by igonring `TotalEarnings`. Total earnings
|
||||
is the same as `BaseValue`, except any percentages taken by crew members
|
||||
is deducted. Actual total value is `BaseValue` plus `Bonus`.
|
||||
|
||||
## 0.4.2 on 02.05.2024
|
||||
|
||||
* Add a bot header for all generated logs that shows the tool version, as
|
||||
|
@ -198,4 +198,65 @@ public class DiscordLogGenerator {
|
||||
|
||||
return log.ToString().Trim();
|
||||
}
|
||||
|
||||
public virtual string[] SplitLog(string log, int maxcount = 2000) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected string[] SplitLogWithHeader(string log, string header, int maxcount = 2000) {
|
||||
string[] lines = log.Split("\n");
|
||||
List<string> chunks = new();
|
||||
string chunk = string.Empty;
|
||||
|
||||
// Optimisation
|
||||
if (log.Length <= maxcount) {
|
||||
return new string[] { log };
|
||||
}
|
||||
|
||||
// First split the log into its headers
|
||||
// skip first bot header line
|
||||
for (int i = 1; i < lines.Length; i++) {
|
||||
string line = lines[i];
|
||||
|
||||
if (line.StartsWith(header) && !string.IsNullOrEmpty(chunk)) {
|
||||
chunks.Add(chunk.Trim());
|
||||
chunk = string.Empty;
|
||||
}
|
||||
|
||||
chunk = chunk + "\n" + line;
|
||||
}
|
||||
|
||||
int curchunk = 0;
|
||||
string botheader = BotHeader().Trim() + "\n";
|
||||
// Leave room for botheader and some leeway
|
||||
int maxlength = (2000 - botheader.Length - 10);
|
||||
|
||||
// Then try to collate chunks
|
||||
for (curchunk = 0; curchunk < chunks.Count; ++curchunk) {
|
||||
int count = chunks[curchunk].Length;
|
||||
while (count < maxlength && (curchunk+1) < chunks.Count) {
|
||||
count += chunks[curchunk + 1].Length + 2;
|
||||
if (count < maxlength) {
|
||||
chunks[curchunk] += "\n";
|
||||
chunks[curchunk] += chunks[curchunk + 1];
|
||||
chunks.RemoveAt(curchunk + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Readd bott headers
|
||||
for (int i = 0; i < chunks.Count; i++) {
|
||||
chunks[i] = chunks[i].Insert(0, botheader);
|
||||
}
|
||||
|
||||
// Now finally check if any one chunk is bigger than max length
|
||||
for (int i = 0; i < chunks.Count; i++) {
|
||||
if (chunks[i].Length > maxcount) {
|
||||
throw new ApplicationException(
|
||||
string.Format("a chunk turned out bigger than {0}", maxcount));
|
||||
}
|
||||
}
|
||||
|
||||
return chunks.ToArray();
|
||||
}
|
||||
}
|
||||
|
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, string username = "EDBGS") {
|
||||
JsonObject obj = new();
|
||||
obj.Add("content", log);
|
||||
obj.Add("username", username);
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<Version>0.4.2</Version>
|
||||
<Version>0.4.3</Version>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>true</UseWPF>
|
||||
|
@ -1,4 +1,7 @@
|
||||
namespace EliteBGS;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Documents;
|
||||
|
||||
namespace EliteBGS;
|
||||
|
||||
public class GenericDiscordLog : DiscordLogGenerator {
|
||||
public override string ToString() {
|
||||
@ -8,4 +11,8 @@ public class GenericDiscordLog : DiscordLogGenerator {
|
||||
public override string Name {
|
||||
get { return "Generic"; }
|
||||
}
|
||||
|
||||
public override string[] SplitLog(string log, int maxcount = 2000) {
|
||||
return SplitLogWithHeader(log, "**Date:**", maxcount);
|
||||
}
|
||||
}
|
||||
|
@ -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,11 @@
|
||||
<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 />
|
||||
<Label Content="Post log as" VerticalAlignment="Center" Margin="0,3,0,3" />
|
||||
<ComboBox x:Name="Commanders" VerticalAlignment="Stretch" Margin="0,3,0,3" Width="180" />
|
||||
<Label Content="to" VerticalAlignment="Center" Margin="0,3,0,3" />
|
||||
<mah:DropDownButton x:Name="PostToDiscord" Content="Discord" />
|
||||
</ToolBar>
|
||||
<TreeView CheckBox.Checked="TreeView_CheckBox_Updated"
|
||||
CheckBox.Unchecked="TreeView_CheckBox_Updated"
|
||||
@ -189,6 +215,7 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
@ -244,6 +271,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);
|
||||
}
|
||||
@ -182,6 +185,11 @@ public partial class MainWindow : MetroWindow {
|
||||
|
||||
List<Transaction> transactions = parser.Parse(entries, options);
|
||||
|
||||
Commanders.ItemsSource = parser.Commanders;
|
||||
if (Commanders.Items.Count > 0) {
|
||||
Commanders.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
// Filter the transactions down to the given time frame
|
||||
transactions = transactions
|
||||
.Where(t => t.CompletedAtDateTime >= start && t.CompletedAtDateTime <= end)
|
||||
@ -580,4 +588,129 @@ 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 = "All";
|
||||
menu.Click += PostToAll_Click;
|
||||
PostToDiscord.Items.Add(menu);
|
||||
}
|
||||
}
|
||||
|
||||
private void PostToDiscordWebhook(IEnumerable<DiscordWebhook> hooks) {
|
||||
if (string.IsNullOrEmpty(DiscordLog.Text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DiscordLogGenerator discord = LogType.SelectedItem as DiscordLogGenerator;
|
||||
string[] chunks;
|
||||
|
||||
try {
|
||||
chunks = discord.SplitLog(DiscordLog.Text);
|
||||
} catch (Exception) {
|
||||
MessageBox.Show(
|
||||
"The log could not be split into discord appropriate length.\n" +
|
||||
"This happens with the bigger logs formats if you do lots of things in one system.\n" +
|
||||
"Try posting the log in the OneLine format.",
|
||||
"Sorry!", MessageBoxButton.OK, MessageBoxImage.Error
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
string commander = "EDBGS";
|
||||
if (Commanders.SelectedIndex >= 0) {
|
||||
commander = Commanders.SelectedItem.ToString();
|
||||
}
|
||||
|
||||
foreach (var hook in hooks) {
|
||||
try {
|
||||
foreach (var chunk in chunks) {
|
||||
DiscordPoster.PostToDiscord(hook, chunk, commander);
|
||||
}
|
||||
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;
|
||||
}
|
||||
PostToDiscordWebhook(new DiscordWebhook[] { hook });
|
||||
}
|
||||
|
||||
private void PostToAll_Click(object sender, RoutedEventArgs e) {
|
||||
PostToDiscordWebhook(Config.Global.Webhooks);
|
||||
}
|
||||
}
|
||||
|
@ -91,4 +91,8 @@ public class NonaDiscordLog : DiscordLogGenerator {
|
||||
public override string Name {
|
||||
get { return "NovaNavy"; }
|
||||
}
|
||||
|
||||
public override string[] SplitLog(string log, int maxcount = 2000) {
|
||||
return SplitLogWithHeader(log, ":clock2: `Date:`", maxcount);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
using EliteBGS.LogGenerator;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Documents;
|
||||
|
||||
namespace EliteBGS;
|
||||
|
||||
@ -25,6 +28,30 @@ public class OneLineDiscordLog : DiscordLogGenerator {
|
||||
return "";
|
||||
}
|
||||
|
||||
public override string[] SplitLog(string log, int maxcount = 2000) {
|
||||
string[] lines = log.Split('\n');
|
||||
List<string> chunks = new();
|
||||
string chunk = string.Empty;
|
||||
|
||||
// Optimisation
|
||||
if (log.Length <= maxcount) {
|
||||
return new string[] { log };
|
||||
}
|
||||
|
||||
for (int i = 0; i < lines.Length; i++) {
|
||||
string line = lines[i];
|
||||
if ((chunk.Length + line.Length) > maxcount || i == lines.Length - 1) {
|
||||
chunks.Add(chunk.Trim());
|
||||
chunk = string.Empty;
|
||||
chunk = chunk.Insert(0, BotHeader()).Trim();
|
||||
} else {
|
||||
chunk = chunk + "\n" + line;
|
||||
}
|
||||
}
|
||||
|
||||
return chunks.ToArray();
|
||||
}
|
||||
|
||||
public override string GenerateDiscordLog(Report report) {
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
|
@ -49,5 +49,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.4.2.0")]
|
||||
[assembly: AssemblyFileVersion("0.4.2.0")]
|
||||
[assembly: AssemblyVersion("0.4.3.0")]
|
||||
[assembly: AssemblyFileVersion("0.4.3.0")]
|
||||
|
@ -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…
x
Reference in New Issue
Block a user