Browse Source

commit: Update for 1.12.2 support with YUR; Add CutPerSecond; Code cleanup;

HOME 3 years ago
parent
commit
f861605b84

+ 4 - 0
BsWidget/BaseForm.cs

@@ -5,6 +5,10 @@ using System.Drawing.Imaging;
 using System.Runtime.InteropServices;
 using System.Windows.Forms;
 
+// ReSharper disable UnusedMember.Local
+// ReSharper disable IdentifierTypo
+// ReSharper disable MemberCanBePrivate.Global
+
 namespace BsWidget
 {
     public abstract partial class BaseForm : Form

+ 4 - 5
BsWidget/BeatSaberHttpStatus/BeatSaberHttpStatusClient.cs

@@ -1,11 +1,10 @@
-using System;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
 using WebSocketSharp;
 
 namespace BsWidget.BeatSaberHttpStatus
 {
-    internal class BeatSaberHttpStatusClient
+    internal sealed class BeatSaberHttpStatusClient
     {
         private bool _isRunning;
         private WebSocket _webSocket;
@@ -45,6 +44,6 @@ namespace BsWidget.BeatSaberHttpStatus
             OnEvent(evt);
         }
 
-        protected virtual void OnEvent(BeatSaberStatusEventArgs e) => Event?.Invoke(this, e);
+        private void OnEvent(BeatSaberStatusEventArgs e) => Event?.Invoke(this, e);
     }
 }

+ 5 - 1
BsWidget/BeatSaberHttpStatus/BeatSaberStatusEventArgs.cs

@@ -1,4 +1,8 @@
-namespace BsWidget.BeatSaberHttpStatus
+// ReSharper disable InconsistentNaming
+// ReSharper disable ClassNeverInstantiated.Global
+// ReSharper disable IdentifierTypo
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+namespace BsWidget.BeatSaberHttpStatus
 {
     internal class BeatSaberStatusEventArgs
     {

+ 1 - 1
BsWidget/GdiPlusExt.cs

@@ -78,7 +78,7 @@ namespace BsWidget
             var arc = new RectangleF(bounds.Location, size);
             var path = new GraphicsPath();
 
-            if (radius == 0)
+            if (Math.Abs(radius) < 0.00001)
             {
                 path.AddRectangle(bounds);
                 return path;

+ 63 - 38
BsWidget/MainForm.cs

@@ -51,6 +51,7 @@ namespace BsWidget
         public int CurrentCombo { get; set; } = 120;
         public string CurrentRank { get; set; } = "XX";
         public int CurrentMaxScore { get; set; }
+        public int CurrentCutPerSecond { get; set; }
 
         public float? CpuUsage { get; set; } = 12.3f;
         public float? CpuGhz { get; set; } = 2.333f;
@@ -63,9 +64,12 @@ namespace BsWidget
 
         public class HistoryModel
         {
+            public DateTime Time { get; set; }
+
             public int CutScore { get; set; }
             public int CurrentCombo { get; set; }
             public float Percent { get; set; }
+            public int CutsPerSecond { get; set; }
             public float HeartRate { get; set; }
             public float KcalPerMin { get; set; }
         }
@@ -90,7 +94,6 @@ namespace BsWidget
             _computer.RAMEnabled = false;
             _computer.Open();
 
-            Text = "Beat Saber Status Widget";
             _queue = new BlockingCollection<UpdateFlags>();
             CutHistory = new List<HistoryModel>();
 
@@ -103,6 +106,7 @@ namespace BsWidget
 
         protected override void OnLoad(EventArgs e)
         {
+            Text = "Beat Saber Status Widget";
             base.OnLoad(e);
             Font = new Font("", 30, FontStyle.Bold, GraphicsUnit.Pixel);
             TopMost = false;
@@ -150,11 +154,6 @@ namespace BsWidget
 
         private void BeatSaber_Event(object sender, BeatSaberStatusEventArgs e)
         {
-            if (e.Event == "noteMissed")
-            {
-                var bp = 0;
-            }
-
             var flags = (UpdateFlags)0;
 
             if (e.Event == "menu" && CutHistory.Count > 0)
@@ -201,11 +200,16 @@ namespace BsWidget
             {
                 lock (CutHistory)
                 {
+                    var now = DateTime.Now;
+                    var preNow = now.AddSeconds(-1);
+                    CurrentCutPerSecond = CutHistory.Count(p => p.Time > preNow);
                     CutHistory.Add(new HistoryModel
                     {
+                        Time = now,
                         CutScore = e.NoteCut.FinalScore.Value,
                         CurrentCombo = CurrentCombo,
                         Percent = (float)CurrentScore / CurrentMaxScore,
+                        CutsPerSecond = CurrentCutPerSecond,
                         HeartRate = YurStatus.HeartRate,
                         KcalPerMin = YurStatus.KcalPerMin,
                     });
@@ -215,7 +219,6 @@ namespace BsWidget
 
             if (flags == 0)
             {
-                var bp = 0;
             }
             else
             {
@@ -229,16 +232,20 @@ namespace BsWidget
         {
             try
             {
-                foreach (var hardware in _computer.Hardware.Where(p => p.HardwareType == HardwareType.CPU))
+                foreach (var hardware in _computer.Hardware.Where(p => p.HardwareType == HardwareType.CPU || p.HardwareType == HardwareType.GpuNvidia))
                 {
                     hardware.Update();
                 }
+            }
+            catch (Exception)
+            {
+                return;
+            }
 
-                CpuUsage = _computer.Hardware.Where(p => p.HardwareType == HardwareType.CPU).SelectMany(p => p.Sensors)
-                    .Where(p => p.SensorType == SensorType.Load && p.Name=="CPU Total").Select(p => p.Value).Max();
-
+            try
+            {
                 var mhz = _computer.Hardware.Where(p => p.HardwareType == HardwareType.CPU).SelectMany(p => p.Sensors)
-                    .Where(p => p.SensorType == SensorType.Clock).Select(p => p.Value).Max();
+                                   .Where(p => p.SensorType == SensorType.Clock).Select(p => p.Value).Max();
 
                 if (mhz.HasValue)
                 {
@@ -251,17 +258,21 @@ namespace BsWidget
             }
             catch
             {
-                CpuUsage = null;
                 CpuGhz = null;
             }
 
             try
             {
-                foreach (var hardware in _computer.Hardware.Where(p => p.HardwareType == HardwareType.GpuNvidia))
-                {
-                    hardware.Update();
-                }
+                CpuUsage = _computer.Hardware.Where(p => p.HardwareType == HardwareType.CPU).SelectMany(p => p.Sensors)
+                    .Where(p => p.SensorType == SensorType.Load && p.Name == "CPU Total").Select(p => p.Value).Max();
+            }
+            catch
+            {
+                CpuUsage = null;
+            }
 
+            try
+            {
                 GpuUsage = _computer.Hardware.Where(p => p.HardwareType == HardwareType.GpuNvidia).SelectMany(p => p.Sensors)
                     .Where(p => p.SensorType == SensorType.Load && p.Name == "GPU Core").Select(p => p.Value).Max();
             }
@@ -282,8 +293,8 @@ namespace BsWidget
         protected override void RenderGraphic(Graphics g)
         {
             const int margin = 10;
-            var ChWidth = ViewSize.Width - margin * 2;
-            var ChHeight = 64;
+            const int chHeight = 64;
+            var chWidth = ViewSize.Width - margin * 2;
 
             if (_queue.Count == 0) return;
 
@@ -293,40 +304,39 @@ namespace BsWidget
 
             g.SetHighQuality();
 
-            float nextY = 0;
-
             if (flags.HasFlag(UpdateFlags.NoteFullyCut) || flags.HasFlag(UpdateFlags.RefreshAll))
             {
-                var ChLeft = margin;
-                var ChTop = margin;
+                const int chLeft = margin;
+                const int chTop = margin;
 
-                var ChBottom = ChTop + ChHeight;
+                var chBottom = chTop + chHeight;
 
                 float RecordPixel = 2.5f;
                 var LineWidth = 1.5f;
 
-                var DisplayCount = (int)(ChWidth / RecordPixel);
+                var displayCount = (int)(chWidth / RecordPixel);
 
                 using var scorePen = new Pen(Color.FromArgb(200, 255, 0, 0), LineWidth) { LineJoin = LineJoin.Round };
                 using var comboPen = new Pen(Color.FromArgb(200, 0, 0, 255), LineWidth) { LineJoin = LineJoin.Round };
                 using var percentPen = new Pen(Color.FromArgb(200, Color.Green), LineWidth) { LineJoin = LineJoin.Round };
+                using var cpsPen = new Pen(Color.Yellow, LineWidth) { LineJoin = LineJoin.Round };
                 using var heartPen = new Pen(Color.FromArgb(200, Color.White), LineWidth) { LineJoin = LineJoin.Round };
                 using var calPen = new Pen(Color.FromArgb(200, Color.Lime), LineWidth) { LineJoin = LineJoin.Round };
 
                 //clear region 0,210 Wx200
-                g.ClearRect(Color.Transparent, 0, ChTop - 3, ViewSize.Width, ChHeight + 6 + 20);
+                g.ClearRect(Color.Transparent, 0, chTop - 3, ViewSize.Width, chHeight + 6 + 20);
 
                 //draw chart
                 using var bgBrush = new SolidBrush(Color.FromArgb(90, 255, 255, 255));
-                g.FillRectangle(bgBrush, ChLeft, ChTop, ChWidth, ChHeight);
-                g.DrawRectangle(Pens.White, ChLeft - 1, ChTop - 1, ChWidth + 2, ChHeight + 2);
+                g.FillRectangle(bgBrush, chLeft, chTop, chWidth, chHeight);
+                g.DrawRectangle(Pens.White, chLeft - 1, chTop - 1, chWidth + 2, chHeight + 2);
 
                 if (CutHistory.Count > 1)
                 {
                     HistoryModel[] items;
                     lock (CutHistory)
                     {
-                        var skip = CutHistory.Count > DisplayCount ? CutHistory.Count - DisplayCount : 0;
+                        var skip = CutHistory.Count > displayCount ? CutHistory.Count - displayCount : 0;
 
                         items = CutHistory.Skip(skip).ToArray();
                     }
@@ -353,39 +363,45 @@ namespace BsWidget
                         var rngCal = maxCal - minCal;
                         if (rngCal < 1) rngCal = 1;
 
-                        var x = ChWidth - items.Length * RecordPixel + ChLeft + 1;
+                        var minCps = items.Select(p => p.CutsPerSecond).Min();
+                        var maxCps = items.Select(p => p.CutsPerSecond).Max();
+                        var rngCps = maxCps - minCps;
+                        if (rngCps < 1) rngCps = 1;
+
+                        var x = chWidth - items.Length * RecordPixel + chLeft + 1;
 
                         var scorePts = new List<PointF>();
                         var comboPts = new List<PointF>();
                         var percentPts = new List<PointF>();
                         var heaPts = new List<PointF>();
                         var calPts = new List<PointF>();
+                        var cpsPts = new List<PointF>();
 
                         for (var i = 0; i < items.Length; i++)
                         {
                             var item = items[i];
-                            scorePts.Add(new PointF(x + RecordPixel * i, (ChBottom - 1) - (ChHeight - 2) * ((float)(item.CutScore - minScore) / rngScore)));
-                            comboPts.Add(new PointF(x + RecordPixel * i, (ChBottom - 1) - (ChHeight - 2) * ((float)(item.CurrentCombo - minCombo) / rngCombo)));
-                            percentPts.Add(new PointF(x + RecordPixel * i, (ChBottom - 1) - (ChHeight - 2) * item.Percent));
-                            heaPts.Add(new PointF(x + RecordPixel * i, (ChBottom - 1) - (ChHeight - 2) * ((item.HeartRate - minHea) / rngHea)));
-                            calPts.Add(new PointF(x + RecordPixel * i, (ChBottom - 1) - (ChHeight - 2) * ((item.KcalPerMin - minCal) / rngCal)));
+                            scorePts.Add(new PointF(x + RecordPixel * i, (chBottom - 1) - (chHeight - 2) * ((float)(item.CutScore - minScore) / rngScore)));
+                            comboPts.Add(new PointF(x + RecordPixel * i, (chBottom - 1) - (chHeight - 2) * ((float)(item.CurrentCombo - minCombo) / rngCombo)));
+                            percentPts.Add(new PointF(x + RecordPixel * i, (chBottom - 1) - (chHeight - 2) * item.Percent));
+                            cpsPts.Add(new PointF(x + RecordPixel * i, (chBottom - 1) - (chHeight - 2) * ((float)(item.CutsPerSecond - minCps) / rngCps)));
+                            heaPts.Add(new PointF(x + RecordPixel * i, (chBottom - 1) - (chHeight - 2) * ((item.HeartRate - minHea) / rngHea)));
+                            calPts.Add(new PointF(x + RecordPixel * i, (chBottom - 1) - (chHeight - 2) * ((item.KcalPerMin - minCal) / rngCal)));
                         }
 
                         g.DrawLines(scorePen, scorePts.ToArray());
                         g.DrawLines(comboPen, comboPts.ToArray());
                         g.DrawLines(percentPen, percentPts.ToArray());
+                        g.DrawLines(cpsPen, cpsPts.ToArray());
                         g.DrawLines(heartPen, heaPts.ToArray());
                         g.DrawLines(calPen, calPts.ToArray());
                     }
                 }
-
-                nextY = ChHeight + margin * 2;
             }
 
             if (flags.HasFlag(UpdateFlags.Performance) || flags.HasFlag(UpdateFlags.RefreshAll))
             {
                 float x = margin;
-                float y = ChHeight + margin * 2;
+                float y = chHeight + margin * 2;
 
                 //clear region 0,180 Wx180
                 g.ClearRect(Color.Transparent, 0, y, ViewSize.Width, 50);
@@ -412,6 +428,13 @@ namespace BsWidget
                     Brushes.Green, 2.5f);
                 x += sz.Width + margin * 2;
 
+                sz = g.DrawStringWithOutline($"{CurrentCutPerSecond}", Font, x, y, Color.Black, Color.White);
+                x += sz.Width + margin * 2;
+
+                sz = g.DrawStringWithRoundedRect("CUT / SEC", _smallFont, x, y + margin * 1.5f, Brushes.Black,
+                    Brushes.Yellow, 2.5f);
+                x += sz.Width + margin * 2;
+
                 sz = g.DrawStringWithOutline($"{YurStatus.HeartRate:N1}", Font, x, y, Color.Black, Color.White);
                 x += sz.Width + margin * 2;
 
@@ -422,6 +445,7 @@ namespace BsWidget
                 sz = g.DrawStringWithOutline($"{YurStatus.KcalPerMin:N1}", Font, x, y, Color.Black, Color.White);
                 x += sz.Width + margin * 2;
 
+                // ReSharper disable once RedundantAssignment
                 sz = g.DrawStringWithRoundedRect("KCAL / MIN", _smallFont, x, y + margin * 1.5f, Brushes.Black,
                     Brushes.Lime, 2.5f);
             }
@@ -459,6 +483,7 @@ namespace BsWidget
                     sz = g.DrawStringWithOutline($"{SongNjs}", Font, x, y, Color.Black, Color.White);
                     x += sz.Width + margin * 2;
 
+                    // ReSharper disable once RedundantAssignment
                     sz = g.DrawStringWithRoundedRect("NJS", _smallFont, x, y + margin * 1.5f, Brushes.Black, Brushes.White, 2.5f);
                 }
 

+ 1 - 2
BsWidget/Properties/AssemblyInfo.cs

@@ -1,5 +1,4 @@
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 // 有关程序集的一般信息由以下
@@ -22,7 +21,7 @@ using System.Runtime.InteropServices;
 // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
 [assembly: Guid("2d981a37-94d5-442d-a945-0d0f777345bc")]
 
-// 程序集的版本信息由下列四个值组成: 
+// 程序集的版本信息由下列四个值组成:
 //
 //      主版本
 //      次版本

+ 35 - 0
BsYurHttpStatus/AccessHelper.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Linq;
+using YUR.Fit.Core.Models;
+
+namespace BsYurHttpStatus
+{
+    internal static class AccessHelper
+    {
+        public static float SuckFloatProperty(this OverlayStatusUpdate instance, string propertyName)
+        {
+            Type t;
+            try
+            {
+                t = instance.CalculationMetrics.GetType();
+            }
+            catch
+            {
+                return -1;
+            }
+
+            var propertyInfos = t.GetProperties();
+            var i = propertyInfos.FirstOrDefault(x => x.Name == propertyName && x.PropertyType == typeof(float));
+            if (i == null) return -2;
+
+            try
+            {
+                return (float)i.GetValue(instance.CalculationMetrics);
+            }
+            catch
+            {
+                return -3;
+            }
+        }
+    }
+}

+ 11 - 3
BsYurHttpStatus/BsYurHttpStatus.csproj

@@ -5,15 +5,23 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <Reference Include="IllusionPlugin">
-      <HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\IllusionPlugin.dll</HintPath>
-    </Reference>
+    <None Remove="manifest.json" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="manifest.json" />
+  </ItemGroup>
+
+  <ItemGroup>
     <Reference Include="websocket-sharp">
       <HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\websocket-sharp.dll</HintPath>
     </Reference>
     <Reference Include="0Harmony">
       <HintPath>$(BeatSaberDir)\Libs\0Harmony.dll</HintPath>
     </Reference>
+    <Reference Include="IPA.Loader">
+      <HintPath>$(BeatSaberDir)\Beat Saber_Data\Managed\IPA.Loader.dll</HintPath>
+    </Reference>
     <Reference Include="Newtonsoft.Json">
       <HintPath>$(BeatSaberDir)\Libs\Newtonsoft.Json.dll</HintPath>
     </Reference>

+ 11 - 11
BsYurHttpStatus/HttpStatusServer.cs

@@ -1,7 +1,7 @@
-using System;
-using System.Text;
-using BsWidgetShareCodes;
+using BsWidgetShareCodes;
 using Newtonsoft.Json;
+using System;
+using System.Text;
 using WebSocketSharp;
 using WebSocketSharp.Server;
 using YUR.Fit.Core.Models;
@@ -16,29 +16,29 @@ namespace BsYurHttpStatus
 
         internal event EventHandler StatusChanged;
 
-        private HttpServer server;
+        private HttpServer _server;
 
         public void Start()
         {
-            server = new HttpServer(ServerPort);
+            _server = new HttpServer(ServerPort);
 
-            server.OnGet += (sender, e) =>
+            _server.OnGet += (sender, e) =>
             {
                 OnHTTPGet(e);
             };
 
-            server.AddWebSocketService<StatusBroadcastBehavior>("/socket", behavior => behavior.SetParent(this));
+            _server.AddWebSocketService<StatusBroadcastBehavior>("/socket", behavior => behavior.SetParent(this));
 
             Plugin.Log("Starting HTTP server on port " + ServerPort);
-            server.Start();
+            _server.Start();
         }
 
-        public void Stop() => server.Stop();
+        public void Stop() => _server.Stop();
 
         public void Update(OverlayStatusUpdate input)
         {
-            Status.HeartRate = input.HeartRate ?? input.CalculationMetrics.EstHeartRate;
-            Status.KcalPerMin = input.CalculationMetrics.BurnRate;
+            Status.HeartRate = input.HeartRate ?? input.SuckFloatProperty("EstHeartRate");
+            Status.KcalPerMin = input.SuckFloatProperty("BurnRate");
 
             StatusChanged?.Invoke(this, EventArgs.Empty);
         }

+ 8 - 5
BsYurHttpStatus/Plugin.cs

@@ -1,14 +1,15 @@
 using HarmonyLib;
-using IllusionPlugin;
 using System;
 using System.Diagnostics;
 using System.Reflection;
+using IPA;
 using YUR.Fit.Core.Models;
 using YUR.ViewControllers;
 
 namespace BsYurHttpStatus
 {
-    public sealed class Plugin : IPlugin
+    [Plugin(RuntimeOptions.SingleStartInit)]
+    public class Plugin //: IPlugin
     {
         [Conditional("DEBUG")]
         internal static void Log(string text) => Debug.Print($"BsYurHttpStatus {text}");
@@ -22,6 +23,7 @@ namespace BsYurHttpStatus
         public string Name => "YUR Http Status";
         public string Version => "0.0.0.1";
 
+        [OnStart]
         public void OnApplicationStart()
         {
             Log("OnApplicationStart");
@@ -32,7 +34,7 @@ namespace BsYurHttpStatus
                 var original = AccessTools.Method(typeof(ActivityViewController), "OverlayUpdateAction");
                 var method = GetType().GetMethod(nameof(PatchMethod), BindingFlags.Static | BindingFlags.NonPublic);
                 _harmony = new Harmony(Name);
-                _harmony.Patch(original, postfix:new HarmonyMethod(method));
+                _harmony.Patch(original, postfix: new HarmonyMethod(method));
                 _isPatched = true;
                 Log("Patch success");
             }
@@ -58,6 +60,7 @@ namespace BsYurHttpStatus
             }
         }
 
+        [OnExit]
         public void OnApplicationQuit()
         {
             Log("OnApplicationQuit");
@@ -95,9 +98,9 @@ namespace BsYurHttpStatus
 
         private static void PatchMethod(ref OverlayStatusUpdate status)
         {
-            _statusServer?.Update(status);
+            Log("Update:"+status.SuckFloatProperty("EstHeartRate"));
 
-            Log("YUR.(Est)HeartRate:" + (status.HeartRate ?? status.CalculationMetrics.EstHeartRate));
+            _statusServer?.Update(status);
         }
 
         public void OnLevelWasLoaded(int level)

+ 16 - 0
BsYurHttpStatus/manifest.json

@@ -0,0 +1,16 @@
+{
+  "$schema": "https://raw.githubusercontent.com/bsmg/BSIPA-MetadataFileSchema/master/Schema.json",
+  "author": "Coder",
+  "description": "A plugin for provide YUR status via HTTP in Beat Saber.",
+  "gameVersion": "1.12.2",
+  "id": "BsYurHttpStatus",
+  "name": "BsYurHttpStatus",
+  "version": "1.0.0",
+  "dependsOn": {
+    "BSIPA": "^4.1.3",
+    "YUR Fit Calorie Tracker": "^2.6.0"
+  },
+  "links": {
+    "project-source": "https://topcl.net/gogs/coder/BeatWidget"
+  }
+}