diff --git a/NHSE.Injection/NHSE.Injection.csproj b/NHSE.Injection/NHSE.Injection.csproj
index 477e3a3..45ec128 100644
--- a/NHSE.Injection/NHSE.Injection.csproj
+++ b/NHSE.Injection/NHSE.Injection.csproj
@@ -6,6 +6,10 @@
enable
+
+
+
+
diff --git a/NHSE.Injection/SysBot/SwitchCommand.cs b/NHSE.Injection/SysBot/SwitchCommand.cs
index ea1acdf..ddd4f3b 100644
--- a/NHSE.Injection/SysBot/SwitchCommand.cs
+++ b/NHSE.Injection/SysBot/SwitchCommand.cs
@@ -9,7 +9,7 @@ namespace NHSE.Injection
public static class SwitchCommand
{
private static readonly Encoding Encoder = Encoding.UTF8;
- private static byte[] Encode(string command) => Encoder.GetBytes(command + "\r\n");
+ private static byte[] Encode(string command, bool addrn = true) => Encoder.GetBytes(addrn ? command + "\r\n" : command);
///
/// Removes the virtual controller from the bot. Allows physical controllers to control manually.
@@ -66,5 +66,13 @@ public static class SwitchCommand
/// Data to write
/// Encoded command bytes
public static byte[] Poke(uint offset, byte[] data) => Encode($"poke 0x{offset:X8} 0x{string.Concat(data.Select(z => $"{z:X2}"))}");
+
+ ///
+ /// (Without return) Requests the Bot to send bytes from .
+ ///
+ /// Address of the data
+ /// Amount of bytes
+ /// Encoded command bytes
+ public static byte[] PeekRaw(uint offset, int count) => Encode($"peek 0x{offset:X8} {count}", false);
}
}
\ No newline at end of file
diff --git a/NHSE.Injection/SysBot/USBBot.cs b/NHSE.Injection/SysBot/USBBot.cs
new file mode 100644
index 0000000..e59b918
--- /dev/null
+++ b/NHSE.Injection/SysBot/USBBot.cs
@@ -0,0 +1,164 @@
+using System;
+using System.Threading;
+using LibUsbDotNet;
+using LibUsbDotNet.Main;
+
+namespace NHSE.Injection
+{
+ public class USBBot : IRAMReadWriter
+ {
+ private UsbDevice? SwDevice;
+ private UsbEndpointReader? reader;
+ private UsbEndpointWriter? writer;
+
+ public bool Connected { get; private set; }
+
+ private readonly object _sync = new object();
+
+ public bool Connect()
+ {
+ lock (_sync)
+ {
+ // Find and open the usb device.
+ //SwDevice = UsbDevice.OpenUsbDevice(SwFinder);
+ foreach (UsbRegistry ur in UsbDevice.AllDevices)
+ {
+ if (ur.Vid == 1406 && ur.Pid == 12288)
+ SwDevice = ur.Device;
+ }
+ //SwDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
+
+ // If the device is open and ready
+ if (SwDevice == null)
+ {
+ throw new Exception("Device Not Found.");
+ }
+
+ if (SwDevice.IsOpen)
+ SwDevice.Close();
+ SwDevice.Open();
+
+ if (SwDevice is IUsbDevice wholeUsbDevice)
+ {
+ // This is a "whole" USB device. Before it can be used,
+ // the desired configuration and interface must be selected.
+
+ // Select config #1
+ wholeUsbDevice.SetConfiguration(1);
+
+ // Claim interface #0.
+ bool resagain = wholeUsbDevice.ClaimInterface(0);
+ if (!resagain)
+ {
+ wholeUsbDevice.ReleaseInterface(0);
+ wholeUsbDevice.ClaimInterface(0);
+ }
+ }
+ else
+ {
+ Disconnect();
+ throw new Exception("Device is using WinUSB driver. Use libusbK and create a filter");
+ }
+
+ // open read write endpoints 1.
+ reader = SwDevice.OpenEndpointReader(ReadEndpointID.Ep01);
+ writer = SwDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
+
+ Connected = true;
+ return true;
+ }
+ }
+
+ public void Disconnect()
+ {
+ lock (_sync)
+ {
+ if (SwDevice != null)
+ {
+ if (SwDevice.IsOpen)
+ {
+ IUsbDevice? wholeUsbDevice = SwDevice as IUsbDevice;
+ wholeUsbDevice?.ReleaseInterface(0);
+ SwDevice.Close();
+ }
+ }
+
+ reader?.Dispose();
+ writer?.Dispose();
+ Connected = false;
+ }
+ }
+
+ private int ReadInternal(byte[] buffer)
+ {
+ byte[] sizeOfReturn = new byte[4];
+
+ //read size, no error checking as of yet, should be the required 368 bytes
+ if (reader == null)
+ throw new Exception("USB writer is null, you may have disconnected the device during previous function");
+
+ reader.Read(sizeOfReturn, 5000, out _);
+
+ //read stack
+ reader.Read(buffer, 5000, out var lenVal);
+ return lenVal;
+ }
+
+ private int SendInternal(byte[] buffer)
+ {
+ if (writer == null)
+ throw new Exception("USB writer is null, you may have disconnected the device during previous function");
+
+ uint pack = (uint)buffer.Length + 2;
+ var ec = writer.Write(BitConverter.GetBytes(pack), 2000, out _);
+ if (ec != ErrorCode.None)
+ {
+ Disconnect();
+ throw new Exception(UsbDevice.LastErrorString);
+ }
+ ec = writer.Write(buffer, 2000, out var l);
+ if (ec != ErrorCode.None)
+ {
+ Disconnect();
+ throw new Exception(UsbDevice.LastErrorString);
+ }
+ return l;
+ }
+
+ public int Read(byte[] buffer)
+ {
+ lock (_sync)
+ {
+ return ReadInternal(buffer);
+ }
+ }
+
+ public byte[] ReadBytes(uint offset, int length)
+ {
+ lock (_sync)
+ {
+ var cmd = SwitchCommand.PeekRaw(offset, length);
+ SendInternal(cmd);
+
+ // give it time to push data back
+ Thread.Sleep((length / 256) + 100);
+
+ var buffer = new byte[length];
+ var _ = ReadInternal(buffer);
+ //return Decoder.ConvertHexByteStringToBytes(buffer);
+ return buffer;
+ }
+ }
+
+ public void WriteBytes(byte[] data, uint offset)
+ {
+ lock (_sync)
+ {
+ SendInternal(SwitchCommand.Poke(offset, data));
+
+ // give it time to push data back
+ Thread.Sleep((data.Length / 256) + 100);
+ }
+ }
+ }
+}
diff --git a/NHSE.Sprites/Item/ItemSprite.cs b/NHSE.Sprites/Item/ItemSprite.cs
index cd8b0fc..c351d37 100644
--- a/NHSE.Sprites/Item/ItemSprite.cs
+++ b/NHSE.Sprites/Item/ItemSprite.cs
@@ -20,6 +20,10 @@ public static void Initialize(string path, string[] itemNames)
ItemNames = itemNames;
+ //create items folder if not exist
+ if (!Directory.Exists(path))
+ Directory.CreateDirectory(path);
+
var files = Directory.EnumerateFiles(path, "*.png", SearchOption.AllDirectories);
foreach (var f in files)
{
diff --git a/NHSE.Sprites/NHSE.Sprites.csproj b/NHSE.Sprites/NHSE.Sprites.csproj
index 48068af..b9d5bc0 100644
--- a/NHSE.Sprites/NHSE.Sprites.csproj
+++ b/NHSE.Sprites/NHSE.Sprites.csproj
@@ -1,4 +1,4 @@
-
+
net46;netcoreapp3.1
diff --git a/NHSE.WinForms/Subforms/PlayerItemEditor.cs b/NHSE.WinForms/Subforms/PlayerItemEditor.cs
index 45e4f42..2d58b86 100644
--- a/NHSE.WinForms/Subforms/PlayerItemEditor.cs
+++ b/NHSE.WinForms/Subforms/PlayerItemEditor.cs
@@ -111,9 +111,12 @@ static void AfterWrite(InjectionResult r)
var sb = new SysBotController(InjectionType.Pouch);
var pockInject = new PocketInjector(ItemArray.Items, sb.Bot);
var ai = new AutoInjector(pockInject, AfterRead, AfterWrite);
+ var ub = new USBBotController();
+ var pockInjectUSB = new PocketInjector(ItemArray.Items, ub.Bot);
+ var aiUSB = new AutoInjector(pockInjectUSB, AfterRead, AfterWrite);
ItemGrid.ItemChanged = () => ai.Write();
- var sysbot = new SysBotUI(ai, sb);
+ var sysbot = new SysBotUI(ai, sb, aiUSB, ub);
sysbot.Show();
}
}
diff --git a/NHSE.WinForms/Subforms/SysBot/SysBotUI.Designer.cs b/NHSE.WinForms/Subforms/SysBot/SysBotUI.Designer.cs
index f0cd19d..da3287f 100644
--- a/NHSE.WinForms/Subforms/SysBot/SysBotUI.Designer.cs
+++ b/NHSE.WinForms/Subforms/SysBot/SysBotUI.Designer.cs
@@ -43,7 +43,13 @@ private void InitializeComponent()
this.B_ReadCurrent = new System.Windows.Forms.Button();
this.B_WriteCurrent = new System.Windows.Forms.Button();
this.TIM_Interval = new System.Windows.Forms.Timer(this.components);
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.ReadUSB = new System.Windows.Forms.Button();
+ this.WriteUSB = new System.Windows.Forms.Button();
+ this.L_OffsetUSB = new System.Windows.Forms.Label();
+ this.RamOffsetUSB = new System.Windows.Forms.TextBox();
this.GB_Inject.SuspendLayout();
+ this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// B_Connect
@@ -188,11 +194,65 @@ private void InitializeComponent()
//
this.TIM_Interval.Interval = 5000;
//
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.RamOffsetUSB);
+ this.groupBox1.Controls.Add(this.L_OffsetUSB);
+ this.groupBox1.Controls.Add(this.WriteUSB);
+ this.groupBox1.Controls.Add(this.ReadUSB);
+ this.groupBox1.Location = new System.Drawing.Point(16, 191);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(149, 75);
+ this.groupBox1.TabIndex = 14;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "USB";
+ //
+ // ReadUSB
+ //
+ this.ReadUSB.Location = new System.Drawing.Point(6, 46);
+ this.ReadUSB.Name = "ReadUSB";
+ this.ReadUSB.Size = new System.Drawing.Size(68, 23);
+ this.ReadUSB.TabIndex = 0;
+ this.ReadUSB.Text = "Read USB";
+ this.ReadUSB.UseVisualStyleBackColor = true;
+ this.ReadUSB.Click += new System.EventHandler(this.ReadUSB_Click);
+ //
+ // WriteUSB
+ //
+ this.WriteUSB.Location = new System.Drawing.Point(74, 46);
+ this.WriteUSB.Name = "WriteUSB";
+ this.WriteUSB.Size = new System.Drawing.Size(69, 23);
+ this.WriteUSB.TabIndex = 1;
+ this.WriteUSB.Text = "Write USB";
+ this.WriteUSB.UseVisualStyleBackColor = true;
+ this.WriteUSB.Click += new System.EventHandler(this.WriteUSB_Click);
+ //
+ // L_OffsetUSB
+ //
+ this.L_OffsetUSB.Location = new System.Drawing.Point(3, 24);
+ this.L_OffsetUSB.Name = "L_OffsetUSB";
+ this.L_OffsetUSB.Size = new System.Drawing.Size(63, 20);
+ this.L_OffsetUSB.TabIndex = 20;
+ this.L_OffsetUSB.Text = "Offset:";
+ this.L_OffsetUSB.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // RamOffsetUSB
+ //
+ this.RamOffsetUSB.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.RamOffsetUSB.Location = new System.Drawing.Point(72, 24);
+ this.RamOffsetUSB.MaxLength = 8;
+ this.RamOffsetUSB.Name = "RamOffsetUSB";
+ this.RamOffsetUSB.Size = new System.Drawing.Size(63, 20);
+ this.RamOffsetUSB.TabIndex = 24;
+ this.RamOffsetUSB.Text = "AC4723D0";
+ this.RamOffsetUSB.TextChanged += new System.EventHandler(this.RamOffsetUSB_TextChanged);
+ //
// SysBotUI
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(184, 197);
+ this.ClientSize = new System.Drawing.Size(184, 278);
+ this.Controls.Add(this.groupBox1);
this.Controls.Add(this.GB_Inject);
this.Controls.Add(this.B_Connect);
this.Controls.Add(this.L_Port);
@@ -209,6 +269,8 @@ private void InitializeComponent()
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SysBotUI_FormClosing);
this.GB_Inject.ResumeLayout(false);
this.GB_Inject.PerformLayout();
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
@@ -230,5 +292,10 @@ private void InitializeComponent()
private System.Windows.Forms.CheckBox CHK_AutoRead;
private System.Windows.Forms.Timer TIM_Interval;
private System.Windows.Forms.CheckBox CHK_Validate;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button ReadUSB;
+ private System.Windows.Forms.Button WriteUSB;
+ private System.Windows.Forms.TextBox RamOffsetUSB;
+ private System.Windows.Forms.Label L_OffsetUSB;
}
}
\ No newline at end of file
diff --git a/NHSE.WinForms/Subforms/SysBot/SysBotUI.cs b/NHSE.WinForms/Subforms/SysBot/SysBotUI.cs
index 80ed7d3..c4a709c 100644
--- a/NHSE.WinForms/Subforms/SysBot/SysBotUI.cs
+++ b/NHSE.WinForms/Subforms/SysBot/SysBotUI.cs
@@ -9,13 +9,17 @@ public partial class SysBotUI : Form
{
private readonly AutoInjector Injector;
private readonly SysBotController Bot;
+ private readonly AutoInjector InjectorUSB;
+ private readonly USBBotController BotUSB;
- public SysBotUI(AutoInjector injector, SysBotController c)
+ public SysBotUI(AutoInjector injector, SysBotController c, AutoInjector injectorUSB, USBBotController b)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Bot = c;
Injector = injector;
+ BotUSB = b;
+ InjectorUSB = injectorUSB;
var offset = Bot.GetDefaultOffset();
Injector.SetWriteOffset(offset);
@@ -122,5 +126,79 @@ private void RamOffset_TextChanged(object sender, EventArgs e)
Injector.SetWriteOffset(offset);
}
+
+ private void ReadUSB_Click(object sender, EventArgs e)
+ {
+ if (!BotUSB.Connect())
+ return;
+
+ var offset = StringUtil.GetHexValue(RamOffsetUSB.Text);
+ if (offset == 0)
+ {
+ WinFormsUtil.Error(MessageStrings.MsgInvalidHexValue);
+ return;
+ }
+
+ InjectorUSB.SetWriteOffset(offset);
+
+ try
+ {
+ var result = InjectorUSB.Read(true);
+ if (result == InjectionResult.Success)
+ return;
+ WinFormsUtil.Alert(result.ToString());
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ WinFormsUtil.Error(ex.Message);
+ }
+
+ BotUSB.Disconnect();
+ }
+
+ private void WriteUSB_Click(object sender, EventArgs e)
+ {
+ if (!BotUSB.Connect())
+ return;
+
+ var offset = StringUtil.GetHexValue(RamOffsetUSB.Text);
+ if (offset == 0)
+ {
+ WinFormsUtil.Error(MessageStrings.MsgInvalidHexValue);
+ return;
+ }
+
+ InjectorUSB.SetWriteOffset(offset);
+
+ try
+ {
+ var result = InjectorUSB.Write(true);
+ if (result == InjectionResult.Success)
+ return;
+ WinFormsUtil.Alert(result.ToString());
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ WinFormsUtil.Error(ex.Message);
+ }
+
+ BotUSB.Disconnect();
+ }
+
+ private void RamOffsetUSB_TextChanged(object sender, EventArgs e)
+ {
+ var offset = StringUtil.GetHexValue(RamOffsetUSB.Text);
+ if (offset == 0)
+ {
+ WinFormsUtil.Error(MessageStrings.MsgInvalidHexValue);
+ return;
+ }
+
+ Injector.SetWriteOffset(offset);
+ }
}
}
diff --git a/NHSE.WinForms/Subforms/SysBot/USBBotController.cs b/NHSE.WinForms/Subforms/SysBot/USBBotController.cs
new file mode 100644
index 0000000..0c8b2ee
--- /dev/null
+++ b/NHSE.WinForms/Subforms/SysBot/USBBotController.cs
@@ -0,0 +1,53 @@
+using System;
+using NHSE.Injection;
+
+namespace NHSE.WinForms
+{
+ public class USBBotController
+ {
+ public readonly USBBot Bot = new USBBot();
+
+ public bool Connect()
+ {
+ try
+ {
+ return Bot.Connect();
+ }
+#pragma warning disable CA1031 // Do not catch general exception types
+ catch (Exception ex)
+#pragma warning restore CA1031 // Do not catch general exception types
+ {
+ WinFormsUtil.Error(ex.Message);
+ return false;
+ }
+ }
+
+ public void Disconnect()
+ {
+ Bot.Disconnect();
+ }
+
+ //todo: this
+ //public uint GetDefaultOffset()
+ //{
+ // return Settings.Default.SysBotPouchOffset;
+ //}
+
+ //public void PopPrompt()
+ //{
+ //}
+
+ public void WriteBytes(byte[] data, uint offset)
+ {
+ Bot.WriteBytes(data, offset);
+ //SetOffset(offset);
+ }
+
+ public byte[] ReadBytes(uint offset, int length)
+ {
+ var result = Bot.ReadBytes(offset, length);
+ //SetOffset(offset);
+ return result;
+ }
+ }
+}