Skip to content

Commit

Permalink
Automatically detect story progress
Browse files Browse the repository at this point in the history
Co-Authored-By: Lincoln-LM <73306575+Lincoln-LM@users.noreply.github.com>
  • Loading branch information
LegoFigure11 and Lincoln-LM committed Dec 6, 2022
1 parent 21d5a87 commit 2d92907
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
29 changes: 29 additions & 0 deletions MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Net.Sockets;
using static RaidCrawler.Structures.Offsets;
using static SysBot.Base.SwitchButton;
using static System.Buffers.Binary.BinaryPrimitives;

namespace RaidCrawler
{
Expand Down Expand Up @@ -94,6 +95,7 @@ private async void Connect()
SwitchConnection.Connect();
ConnectionStatusText.Text = "Connected!";
IsReading = true;
ConnectionStatusText.Text = "Detecting game version...";
string id = await GetGameID(CancellationToken.None);
if (id is ScarletID)
{
Expand All @@ -110,7 +112,12 @@ private async void Connect()
IsReading = false;
}

ConnectionStatusText.Text = "Reading story progress...";
Progress.SelectedIndex = await GetStoryProgress(CancellationToken.None);

ConnectionStatusText.Text = "Reading raids...";
await ReadRaids(CancellationToken.None);

IsReading = false;
ButtonAdvanceDate.Enabled = true;
ButtonReadRaids.Enabled = true;
Expand Down Expand Up @@ -141,6 +148,28 @@ private static async void Disconnect()
}
}

private static async Task<int> GetStoryProgress(CancellationToken token)
{
int progress = 0;
for (int i = DifficultyFlags.Length - 1; i > 0 && progress == 0; i--)
{
// See https://github.com/Lincoln-LM/sv-live-map/blob/da93e0edd2fb9b89d76ec0027826c9e89acdcda5/sv_live_map_core/raid_reader.py#L59
var address = await OffsetUtil.GetPointerAddress($"{SaveBlockPointer}+{DifficultyFlags[i]:X}", token);
var key = ReadUInt32LittleEndian(await SwitchConnection.ReadBytesAbsoluteAsync(address, 4, token));
var decryptedKey = DecryptStoryProgressKey(key);
address = await OffsetUtil.GetPointerAddress($"[{SaveBlockPointer}+{DifficultyFlags[i] + 8:X}]", token);
var val = await SwitchConnection.ReadBytesAbsoluteAsync(address, 1, token);
if ((decryptedKey ^ val[0]) == 2) progress = i + 1;
}
return progress;
}

private static uint DecryptStoryProgressKey(uint key)
{
var rng = new SCXorShift32(key);
return rng.Next();
}

private void ButtonConnect_Click(object sender, EventArgs e)
{
Connect();
Expand Down
2 changes: 2 additions & 0 deletions Structures/Offsets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ internal class Offsets
public const string VioletID = "01008F6008C5E000";

public const string RaidBlockPointer = "[[main+4384B18]+180]+40";
public const string SaveBlockPointer = "[[[main+4385F30]+80]+8]"; // Thanks Lincoln-LM!
public static int[] DifficultyFlags = { 0x2BF20, 0x1F400, 0x1B640, 0x13EC0 }; // Thanks Lincoln-LM!
}

internal class OffsetUtil
Expand Down

0 comments on commit 2d92907

Please sign in to comment.