Add project files.
This commit is contained in:
38
BGS/Cartographics.cs
Normal file
38
BGS/Cartographics.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class Cartographics : LogEntry {
|
||||
public Cartographics(MultiSellExplorationDataEntry e, string current_system, string current_station) {
|
||||
this.Entries.Add(e);
|
||||
this.System = current_system;
|
||||
this.Station = current_station;
|
||||
}
|
||||
|
||||
public int TotalSum {
|
||||
get {
|
||||
return (from entry in Entries
|
||||
where entry.Is(Events.MultiSellExplorationData)
|
||||
select (entry as MultiSellExplorationDataEntry).TotalEarnings)
|
||||
.Sum()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.AppendFormat("Sold {0} CR worth of Cartographics Data", TotalSum);
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cartographics only help the controlling faction.
|
||||
/// </summary>
|
||||
public override bool OnlyControllingFaction => true;
|
||||
}
|
||||
}
|
||||
11
BGS/CombatZone.cs
Normal file
11
BGS/CombatZone.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class CombatZone {
|
||||
private int level;
|
||||
}
|
||||
}
|
||||
11
BGS/DiscordLogGenerator.cs
Normal file
11
BGS/DiscordLogGenerator.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public interface IDiscordLogGenerator {
|
||||
string GenerateDiscordLog(Report report);
|
||||
}
|
||||
}
|
||||
24
BGS/LogEntry.cs
Normal file
24
BGS/LogEntry.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class LogEntry {
|
||||
private List<Entry> entries = new List<Entry>();
|
||||
|
||||
public List<Entry> Entries => entries;
|
||||
public string Station { get; set; }
|
||||
public string System { get; set; }
|
||||
public string Faction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this entry only benefits the controlling faction or not, default: no
|
||||
/// </summary>
|
||||
public virtual bool OnlyControllingFaction {
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
42
BGS/MissionCompleted.cs
Normal file
42
BGS/MissionCompleted.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class MissionCompleted : LogEntry {
|
||||
public MissionCompleted(MissionCompletedEntry e, string system, string station) {
|
||||
this.Entries.Add(e);
|
||||
this.Faction = e.JSON.GetValue("Faction").ToString();
|
||||
this.System = system;
|
||||
this.Station = station;
|
||||
}
|
||||
|
||||
public string MissionName {
|
||||
get { return (Entries[0] as MissionCompletedEntry).HumanReadableName; }
|
||||
}
|
||||
|
||||
public string Influence {
|
||||
get { return (Entries[0] as MissionCompletedEntry).GetInfluenceForFaction(Faction); }
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
if (Entries.Count <= 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
var entry = Entries[0] as MissionCompletedEntry;
|
||||
var influence = entry.GetInfluenceForFaction(Faction);
|
||||
|
||||
builder.AppendFormat("{0}", entry.HumanReadableName);
|
||||
if (influence != "") {
|
||||
builder.AppendFormat(", Influence: {0}", influence);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
158
BGS/NonaDiscordLog.cs
Normal file
158
BGS/NonaDiscordLog.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class NonaDiscordLog : IDiscordLogGenerator {
|
||||
private string FormatDate() {
|
||||
StringBuilder date = new StringBuilder();
|
||||
DateTime today = DateTime.Now;
|
||||
string suffix;
|
||||
|
||||
if (today.Day == 1 || today.Day == 21 || today.Day == 31) {
|
||||
suffix = "st";
|
||||
} else if (today.Day == 2 || today.Day == 22) {
|
||||
suffix = "nd";
|
||||
} else {
|
||||
suffix = "th";
|
||||
}
|
||||
|
||||
date.AppendFormat("{0} {1}{2}, {3}",
|
||||
today.ToString("MMMM"), today.Day, suffix,
|
||||
today.Year + EliteDangerous.YearOffset
|
||||
);
|
||||
|
||||
return date.ToString();
|
||||
}
|
||||
|
||||
private string BuildCartoGraphics(Objective objective) {
|
||||
var total = from entries in objective.LogEntries
|
||||
where entries.GetType() == typeof(Cartographics)
|
||||
select entries
|
||||
;
|
||||
var pages = total.Count();
|
||||
var sum = total.Sum(x => (x as Cartographics).TotalSum);
|
||||
|
||||
if (pages <= 0 || sum <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return string.Format("Sold {0} page(s) worth of universal cartographics\n" +
|
||||
"(Total value: {1} CR)\n", pages, sum);
|
||||
}
|
||||
|
||||
private string BuildMicroResourcesSold(Objective objective) {
|
||||
var total = from entries in objective.LogEntries
|
||||
where entries.GetType() == typeof(SellMicroResources)
|
||||
select entries
|
||||
;
|
||||
var sum = total.Sum(x => (x as SellMicroResources).TotalSum);
|
||||
|
||||
if (sum <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return string.Format("Sold {0} CR worth of Micro Resources\n", sum);
|
||||
}
|
||||
|
||||
private string BuildVouchers(Objective objective) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
var missions = from entries in objective.LogEntries
|
||||
where entries.GetType() == typeof(Vouchers)
|
||||
select entries
|
||||
;
|
||||
|
||||
if (missions == null || missions.Count() <= 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
foreach (var mission in missions) {
|
||||
var m = mission as Vouchers;
|
||||
builder.AppendFormat("Handed in {0} vouchers for {1}\n", m.Type, m.Faction);
|
||||
builder.AppendFormat("(Total value: {0} CR)\n", m.TotalSum);
|
||||
builder.AppendFormat("\n");
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private string BuildMissionList(Objective objective) {
|
||||
Dictionary<string, Dictionary<string, int>> collated = new Dictionary<string, Dictionary<string, int>>();
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
||||
var missions = from entries in objective.LogEntries
|
||||
where entries.GetType() == typeof(MissionCompleted)
|
||||
select entries
|
||||
;
|
||||
|
||||
if (missions == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
foreach (MissionCompleted m in missions) {
|
||||
if (!collated.ContainsKey(m.MissionName)) {
|
||||
collated[m.MissionName] = new Dictionary<string, int>();
|
||||
}
|
||||
if (!collated[m.MissionName].ContainsKey(m.Influence)) {
|
||||
collated[m.MissionName][m.Influence] = 0;
|
||||
}
|
||||
|
||||
++collated[m.MissionName][m.Influence];
|
||||
}
|
||||
|
||||
foreach (var mission in collated) {
|
||||
if (objective.Faction != null) {
|
||||
output.AppendFormat("{0} for {1}\n", mission.Key, objective.Faction);
|
||||
} else {
|
||||
output.AppendFormat("{0}\n", mission.Key);
|
||||
}
|
||||
output.Append("(");
|
||||
foreach (var influence in mission.Value.OrderBy(x => x.Key.Length)) {
|
||||
output.AppendFormat("Inf{0} x{1}, ", influence.Key, influence.Value);
|
||||
}
|
||||
output.Remove(output.Length - 2, 2); // remove last ", "
|
||||
output.Append(")\n\n");
|
||||
}
|
||||
|
||||
return output.ToString();
|
||||
}
|
||||
|
||||
public string GenerateDiscordLog(Report report) {
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
log.AppendFormat(":clock2: `Date:` {0}\n", FormatDate());
|
||||
foreach (var objective in report.Objectives) {
|
||||
if (objective.LogEntries.Count <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
log.AppendFormat(":globe_with_meridians: `Location:` {0}\n", objective.ToShortString());
|
||||
log.Append(":clipboard: `Conducted:`\n");
|
||||
log.Append("```\n");
|
||||
|
||||
StringBuilder entries = new StringBuilder();
|
||||
|
||||
var missions = BuildMissionList(objective);
|
||||
entries.Append(missions);
|
||||
|
||||
var vouchers = BuildVouchers(objective);
|
||||
entries.Append(vouchers);
|
||||
|
||||
var carto = BuildCartoGraphics(objective);
|
||||
entries.Append(carto);
|
||||
|
||||
var micro = BuildMicroResourcesSold(objective);
|
||||
entries.Append(micro);
|
||||
|
||||
log.Append(entries.ToString().Trim());
|
||||
log.Append("\n```\n");
|
||||
}
|
||||
|
||||
return log.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
103
BGS/Objective.cs
Normal file
103
BGS/Objective.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class Objective {
|
||||
private string system;
|
||||
private string station;
|
||||
private string faction;
|
||||
|
||||
private List<LogEntry> entries = new List<LogEntry>();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<LogEntry> LogEntries {
|
||||
get => entries;
|
||||
set => entries = value;
|
||||
}
|
||||
|
||||
public int Matches(LogEntry e) {
|
||||
int match_count = 0;
|
||||
|
||||
if (e.OnlyControllingFaction) {
|
||||
if (Faction == null || (e.Faction != Faction)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.System != null && system != null &&
|
||||
e.System == system) {
|
||||
++match_count;
|
||||
}
|
||||
|
||||
if (e.Station != null && station != null &&
|
||||
e.Station == station) {
|
||||
++match_count;
|
||||
}
|
||||
|
||||
if (e.Faction != null && faction != null &&
|
||||
e.Faction == faction) {
|
||||
++match_count;
|
||||
}
|
||||
|
||||
return match_count;
|
||||
}
|
||||
|
||||
public int CompareTo(Objective other) {
|
||||
return (other.System == System &&
|
||||
other.Station == Station &&
|
||||
other.Faction == Faction) ? 0 : -1;
|
||||
}
|
||||
|
||||
public bool IsValid => System != null && Faction != null;
|
||||
|
||||
public string System {
|
||||
get { return system; }
|
||||
set { system = value; }
|
||||
}
|
||||
|
||||
public string Station {
|
||||
get { return station; }
|
||||
set { station = value; }
|
||||
}
|
||||
|
||||
public string Faction {
|
||||
get { return faction; }
|
||||
set { faction = value; }
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (system != null && system.Length > 0) {
|
||||
str.AppendFormat("System: {0}", system);
|
||||
}
|
||||
if (station != null && station.Length > 0) {
|
||||
if (str.Length > 0) {
|
||||
str.Append(", ");
|
||||
}
|
||||
str.AppendFormat("Station: {0}", station);
|
||||
}
|
||||
if (faction != null && faction.Length > 0) {
|
||||
if (str.Length > 0) {
|
||||
str.Append(", ");
|
||||
}
|
||||
str.AppendFormat("Faction: {0}", faction);
|
||||
}
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
public string ToShortString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (system != null && system.Length > 0) {
|
||||
str.AppendFormat("{0}", system);
|
||||
}
|
||||
if (station != null && station.Length > 0) {
|
||||
if (str.Length > 0) {
|
||||
str.Append(", ");
|
||||
}
|
||||
str.AppendFormat("{0}", station);
|
||||
}
|
||||
return str.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
121
BGS/Report.cs
Normal file
121
BGS/Report.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class Report {
|
||||
private List<Objective> objectives = new List<Objective>();
|
||||
|
||||
public delegate void OnLogDelegate(string log);
|
||||
|
||||
public event OnLogDelegate OnLog;
|
||||
|
||||
public List<Objective> Objectives {
|
||||
get { return objectives; }
|
||||
set { objectives = value; }
|
||||
}
|
||||
|
||||
public bool AddObjective(Objective objective) {
|
||||
var found = objectives.Find(x => x == objective);
|
||||
bool added = false;
|
||||
|
||||
if (found == null) {
|
||||
objectives.Add(objective);
|
||||
added = true;
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
private bool IsRelevant(Entry e) {
|
||||
return e.Is(Events.MissionCompleted) ||
|
||||
e.Is(Events.Docked) ||
|
||||
e.Is(Events.FSDJump) ||
|
||||
e.Is(Events.MultiSellExplorationData) ||
|
||||
e.Is(Events.SellMicroResources) ||
|
||||
e.Is(Events.RedeemVoucher)
|
||||
;
|
||||
}
|
||||
|
||||
public void Scan(PlayerJournal journal, DateTime start, DateTime end) {
|
||||
var entries = from file in journal.Files
|
||||
where file.NormalisedTimestamp >= start && file.NormalisedTimestamp <= end
|
||||
select file.Entries
|
||||
;
|
||||
var relevant = from log in entries.SelectMany(array => array)
|
||||
where IsRelevant(log)
|
||||
select log
|
||||
;
|
||||
|
||||
string current_system = null;
|
||||
string current_station = null;
|
||||
string controlling_faction = null;
|
||||
|
||||
this.objectives.ForEach(x => x.LogEntries.Clear());
|
||||
|
||||
foreach (var e in relevant) {
|
||||
LogEntry entry = null;
|
||||
|
||||
if (e.Is(Events.Docked)) {
|
||||
/* gleem the current station from this message
|
||||
*/
|
||||
current_station = (e as DockedEntry).StationName;
|
||||
} else if (e.Is(Events.FSDJump)) {
|
||||
current_system = (e as FSDJumpEntry).StarSystem;
|
||||
controlling_faction = (e as FSDJumpEntry).SystemFaction;
|
||||
} else if (e.Is(Events.MissionCompleted)) {
|
||||
var completed = e as MissionCompletedEntry;
|
||||
entry = new MissionCompleted(completed, current_system, current_station);
|
||||
if (completed.HumanReadableNameWasGenerated) {
|
||||
OnLog?.Invoke("Human readable name for mission \"" +
|
||||
completed.Name +
|
||||
"\" was generated, please report this.");
|
||||
}
|
||||
} else if (e.Is(Events.MultiSellExplorationData)) {
|
||||
entry = new Cartographics(e as MultiSellExplorationDataEntry, current_system, current_station);
|
||||
entry.Faction = controlling_faction;
|
||||
} else if (e.Is(Events.RedeemVoucher)) {
|
||||
entry = new Vouchers();
|
||||
entry.Entries.Add(e);
|
||||
entry.System = current_system;
|
||||
entry.Station = current_station;
|
||||
entry.Faction = controlling_faction;
|
||||
} else if (e.Is(Events.SellMicroResources)) {
|
||||
entry = new SellMicroResources(current_system, current_station);
|
||||
entry.Entries.Add(e);
|
||||
}
|
||||
|
||||
if (entry == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var matches = objectives
|
||||
.Where(x => x.Matches(entry) > 0)
|
||||
.OrderBy(x => x.Matches(entry))
|
||||
;
|
||||
if (matches == null || matches.Count() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var objective = matches
|
||||
.OrderBy(x => x.Matches(entry))
|
||||
.Reverse()
|
||||
.First()
|
||||
;
|
||||
|
||||
if (objective != null) {
|
||||
objective.LogEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Scan(PlayerJournal journal) {
|
||||
Scan(journal, DateTime.Now, DateTime.Now);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
BGS/SellMicroResources.cs
Normal file
28
BGS/SellMicroResources.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class SellMicroResources : LogEntry {
|
||||
public SellMicroResources(string system, string station) {
|
||||
System = system;
|
||||
Station = Station;
|
||||
}
|
||||
|
||||
public int TotalSum {
|
||||
get {
|
||||
return Entries
|
||||
.Where(x => x.GetType() == typeof(SellMicroResourcesEntry))
|
||||
.Sum(x => (x as SellMicroResourcesEntry).Price)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format("Sell Micro Resources: {0} CR", TotalSum);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
BGS/Vouchers.cs
Normal file
44
BGS/Vouchers.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NonaBGS.Journal;
|
||||
|
||||
namespace NonaBGS.BGS {
|
||||
public class Vouchers : LogEntry {
|
||||
|
||||
public int TotalSum {
|
||||
get {
|
||||
return Entries
|
||||
.Where(x => x.GetType() == typeof(RedeemVoucherEntry))
|
||||
.Sum(x => (x as RedeemVoucherEntry).Amount)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public string Type {
|
||||
get {
|
||||
string v = Entries
|
||||
.Where(x => x.GetType() == typeof(RedeemVoucherEntry))
|
||||
.GroupBy(x => (x as RedeemVoucherEntry).Type)
|
||||
.Select(x => x.Key)
|
||||
.First();
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.AppendFormat("{0} Vouchers: {1} CR", TotalSum, Type);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vouchers only help the controlling faction
|
||||
/// </summary>
|
||||
public override bool OnlyControllingFaction => true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user