Skip to content

Commit 2c9abca

Browse files
committed
Added icon to exe and switched build action to Windows until dotnet/runtime#3828 and dotnet/sdk#3943 are fixed.
Re-wrote bond voucher parsing to use a map with updated credit values, resolves #1 Added caching of previous state for massive performance gains (AppData json). Added detection when not run from command line to wait for input before closing.
1 parent b0ae4f1 commit 2c9abca

File tree

5 files changed

+121
-32
lines changed

5 files changed

+121
-32
lines changed

.github/workflows/dotnet.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,21 @@ on: [push]
88

99
jobs:
1010
build:
11-
12-
runs-on: ubuntu-latest
13-
11+
runs-on: windows-latest
1412
steps:
1513
- uses: actions/checkout@v2
1614
- name: Setup .NET
1715
uses: actions/setup-dotnet@v1
1816
with:
1917
dotnet-version: 5.0.x
2018
- name: Restore dependencies
21-
run: dotnet restore
19+
run: dotnet restore --runtime win-x64
2220
- name: Build
23-
#run: dotnet build --no-restore
24-
run: dotnet publish -c Release -r win-x64 -p:PublishSingleFile=true --self-contained true
21+
run: dotnet build --no-restore --runtime win-x64 -c Release TCS.csproj
2522
#- name: Test
2623
# run: dotnet test --no-build --verbosity normal
24+
- name: Publish
25+
run: dotnet publish --no-build --runtime win-x64 -c Release -p:PublishSingleFile=true --self-contained true TCS.csproj
2726
- name: Release
2827
uses: softprops/action-gh-release@v1
2928
if: startsWith(github.ref, 'refs/tags/')

Program.cs

Lines changed: 102 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,50 @@ public class Program {
3030
[DllImport("shell32.dll")]
3131
extern static int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid folderId, uint flags, IntPtr token, [MarshalAs(UnmanagedType.LPWStr)] out string pszPath);
3232

33+
[DllImport("kernel32.dll", SetLastError = true)]
34+
static extern uint GetConsoleProcessList(uint[] processList, uint processCount);
35+
// https://stackoverflow.com/a/50244207
36+
// https://devblogs.microsoft.com/oldnewthing/20160125-00/?p=92922
37+
private static bool ConsoleWillBeDestroyed() {
38+
var processList = new uint[1];
39+
var processCount = GetConsoleProcessList(processList, 1);
40+
return processCount == 1;
41+
}
42+
3343
public static void Main(string[] args) {
44+
Console.Title = "Thargoid Combat Statistics";
3445
if (SHGetKnownFolderPath(SavedGames, 0, IntPtr.Zero, out string path) != 0) {
3546
throw new DirectoryNotFoundException("Saved Games folder not found");
3647
}
3748
string logs = Path.GetFullPath(Path.Combine(path, "Frontier Developments/Elite Dangerous"));
3849

39-
var counts = Enum.GetValues<ThargoidRewards>().ToDictionary<ThargoidRewards, ThargoidRewards, uint>(s => s, s => 0);
40-
int missionRewards = 0;
41-
50+
Cache state = new Cache();
51+
string cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".json");
52+
if (File.Exists(cachePath)) {
53+
try {
54+
var json = File.ReadAllText(cachePath);
55+
state = JsonSerializer.Deserialize<Cache>(json);
56+
}
57+
catch (UnauthorizedAccessException e) {
58+
Console.Error.WriteLine("Unable to read cache from {0}", cachePath);
59+
}
60+
}
61+
DateTimeOffset curr = DateTimeOffset.MinValue;
62+
4263
foreach (var log in Directory.GetFiles(logs, "Journal.*.log").OrderBy(s => s)) {
64+
Console.SetCursorPosition(0, Console.CursorTop);
65+
66+
var ts = log.Split('.').Skip(1).First();
67+
// Journal.200619124437.01.log
68+
curr = DateTimeOffset.ParseExact(ts, "yyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat);
69+
if (curr <= state.Last) {
70+
Console.Write("Skipping " + log);
71+
continue;
72+
}
73+
Console.Write(("Analysing " + log)/*.PadRight(Console.BufferWidth - 1)*/);
74+
4375
var fs = new FileStream(log, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
4476
var sr = new StreamReader(fs);
45-
Console.SetCursorPosition(0, Console.CursorTop);
46-
Console.Write("Analysing " + log);
4777

4878
var lines = sr.ReadToEnd();
4979
if (!lines.Contains("Thargoid")) continue;
@@ -60,43 +90,92 @@ public static void Main(string[] args) {
6090
if (!string.IsNullOrEmpty(evt.VictimFaction) && evt.VictimFaction.Contains("$faction_Thargoid")) {
6191
//Console.WriteLine("{0} {1} {2} => {3}", evt.Timestamp, evt.VictimFaction, evt.Reward, (ThargoidRewards)evt.Reward);
6292

63-
if (!Enum.IsDefined(typeof(ThargoidRewards), evt.Reward)) {
64-
Console.WriteLine("Unknown reward value {0}", evt.Reward);
93+
if (!Map.ContainsKey(evt.Reward)) {
94+
if (Console.GetCursorPosition().Left > 0)
95+
Console.Error.WriteLine();
96+
Console.Error.WriteLine("Unknown reward value {0}", evt.Reward);
97+
continue;
6598
}
66-
counts[ (ThargoidRewards)evt.Reward ]++;
99+
state.Counts[ Map[evt.Reward] ]++;
67100
}
68101
}
69102
else if (evt.Event == "MissionCompleted") {
70103
if (evt.Name == "Mission_MassacreThargoid_name") {
71-
missionRewards += evt.Reward;
104+
state.MissionRewards += evt.Reward;
72105
}
73106
}
74107
}
75108
}
76109
Console.SetCursorPosition(0, Console.CursorTop);
110+
Console.Write(new string(' ', Console.BufferWidth - 1));
111+
Console.SetCursorPosition(0, Console.CursorTop);
112+
113+
state.Last = curr/*DateTimeOffset.Now*/;
114+
try {
115+
File.WriteAllText(cachePath, JsonSerializer.Serialize(state, new JsonSerializerOptions { WriteIndented = true }));
116+
}
117+
catch (UnauthorizedAccessException e) {
118+
Console.Error.WriteLine("Unable to write cache to {0}", cachePath);
119+
}
120+
77121
Console.WriteLine("--------------------------------------------");
78122
Console.WriteLine(" THARGOID COMBAT STATS ");
79123
Console.WriteLine("--------------------------------------------");
80-
Console.WriteLine(" Thargoid Scouts killed: {0,4}", counts[ThargoidRewards.Scout]);
81-
Console.WriteLine(" Cyclops Variant Interceptors killed: {0,4}", counts[ThargoidRewards.Cyclops]);
82-
Console.WriteLine(" Basilisk Variant Interceptors killed: {0,4}", counts[ThargoidRewards.Basilisk]);
83-
Console.WriteLine(" Medusa Variant Interceptors killed: {0,4}", counts[ThargoidRewards.Medusa]);
84-
Console.WriteLine(" Hydra Variant Interceptors killed: {0,4}", counts[ThargoidRewards.Hydra]);
124+
Console.WriteLine(" Thargoid Scouts killed: {0,4}", state.Counts[Thargoids.Scout]);
125+
Console.WriteLine(" Cyclops Variant Interceptors killed: {0,4}", state.Counts[Thargoids.Cyclops]);
126+
Console.WriteLine(" Basilisk Variant Interceptors killed: {0,4}", state.Counts[Thargoids.Basilisk]);
127+
Console.WriteLine(" Medusa Variant Interceptors killed: {0,4}", state.Counts[Thargoids.Medusa]);
128+
Console.WriteLine(" Hydra Variant Interceptors killed: {0,4}", state.Counts[Thargoids.Hydra]);
85129
Console.WriteLine("--------------------------------------------");
86-
Console.WriteLine(" Total Thargoids killed: {0,4}", counts.Sum(s => s.Value));
130+
Console.WriteLine(" Total Thargoids killed: {0,4}", state.Counts.Sum(s => s.Value));
87131
Console.WriteLine();
88-
Console.WriteLine(" Total Thargoid mission payouts: {0,10:n0}", missionRewards);
132+
Console.WriteLine(" Total Thargoid mission payouts: {0,11:n0}", state.MissionRewards);
133+
134+
if (ConsoleWillBeDestroyed()) {
135+
Console.WriteLine();
136+
Console.WriteLine("Press any key to continue . . . ");
137+
Console.ReadKey();
138+
}
89139
}
90140

91-
enum ThargoidRewards {
92-
// Logs still have the pre-Dec 2020 values
93-
Scout = 10000,
94-
Cyclops = 2000000,
95-
Basilisk = 6000000,
96-
Medusa = 10000000,
97-
Hydra = 15000000,
141+
public enum Thargoids {
142+
Scout,
143+
Cyclops,
144+
Basilisk,
145+
Medusa,
146+
Hydra,
98147
}
99148

149+
public readonly static Dictionary<int, Thargoids> Map = new Dictionary<int, Thargoids> {
150+
// Logs with pre-Dec 2020 values:
151+
{ 10000, Thargoids.Scout },
152+
{ 2000000, Thargoids.Cyclops },
153+
{ 6000000, Thargoids.Basilisk },
154+
{ 10000000, Thargoids.Medusa },
155+
{ 15000000, Thargoids.Hydra },
156+
// Logs ≈post-Sep 2021:
157+
{ 80000, Thargoids.Scout },
158+
{ 8000000, Thargoids.Cyclops },
159+
{ 24000000, Thargoids.Basilisk },
160+
{ 40000000, Thargoids.Medusa },
161+
{ 60000000, Thargoids.Hydra },
162+
{ 80000000, Thargoids.Hydra },
163+
};
164+
165+
public class Cache {
166+
public DateTimeOffset Last { get; set; }
167+
public Dictionary<Thargoids, uint> Counts { get; set; }
168+
//public uint[] Counts { get; set; }
169+
public int MissionRewards { get; set; }
170+
171+
public Cache() {
172+
Last = DateTimeOffset.MinValue;
173+
Counts = Enum.GetValues<Thargoids>().ToDictionary<Thargoids, Thargoids, uint>(s => s, s => 0);
174+
//Counts = new uint[ (int)Enum.GetValues<Thargoids>().Max() ];
175+
MissionRewards = 0;
176+
}
177+
};
178+
100179
public class LogEvent {
101180
public DateTime Timestamp { get; set; }
102181
public string Event { get; set; }

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ GNU General Public License for more details.
2626

2727
You should have received a copy of the GNU General Public License
2828
along with this program. If not, see <http://www.gnu.org/licenses/>.
29+
30+
# Acknowledgements
31+
32+
Icon based on [a GIF](https://www.reddit.com/r/EliteDangerous/comments/ezc3a6/i_made_a_thargoid_bonk_gif_emoji_for_discord/) by CMDR Arburich.

TCS.csproj

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,25 @@
99
<PublishTrimmed>true</PublishTrimmed>
1010
<PlatformTarget>x64</PlatformTarget>
1111
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
12-
<Version>1.0.1</Version>
12+
<Version>1.0.2</Version>
1313
<Copyright>Copyright © 2021 Sebastian Southen</Copyright>
1414
<PackageLicenseExpression>GPLv3</PackageLicenseExpression>
1515
<PackageProjectUrl>https://github.com/Southen/tcs</PackageProjectUrl>
1616
<RepositoryUrl>https://github.com/Southen/tcs</RepositoryUrl>
17-
<AssemblyVersion>1.0.1</AssemblyVersion>
18-
<FileVersion>1.0.1</FileVersion>
17+
<AssemblyVersion>1.0.2</AssemblyVersion>
18+
<FileVersion>1.0.2</FileVersion>
1919
<Product>Thargoid Combat Statistics</Product>
20+
<PackageIcon>thargbonk.ico</PackageIcon>
21+
<ApplicationIcon>thargbonk.ico</ApplicationIcon>
22+
<PackageTags>elite-dangerous</PackageTags>
2023
</PropertyGroup>
2124

2225
<ItemGroup>
2326
<None Include=".github\workflows\dotnet.yml" />
27+
<None Include="thargbonk.ico">
28+
<Pack>True</Pack>
29+
<PackagePath></PackagePath>
30+
</None>
2431
</ItemGroup>
2532

2633
</Project>

thargbonk.ico

14.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)