Statistics view
This commit is contained in:
parent
c5d3c90b85
commit
4bd37bdefd
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Version>1.4.0.0</Version>
|
||||
<Version>1.5.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@ -29,6 +29,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Pal.Common\Pal.Common.csproj" />
|
||||
<ProjectReference Include="..\vendor\ECommons\ECommons\ECommons.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -7,7 +7,9 @@ using Dalamud.Plugin;
|
||||
using ECommons;
|
||||
using ECommons.Schedulers;
|
||||
using ECommons.SplatoonAPI;
|
||||
using Grpc.Core;
|
||||
using ImGuiNET;
|
||||
using Pal.Client.Windows;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@ -63,6 +65,12 @@ namespace Pal.Client
|
||||
Service.WindowSystem.AddWindow(configWindow);
|
||||
}
|
||||
|
||||
var statisticsWindow = pluginInterface.Create<StatisticsWindow>();
|
||||
if (statisticsWindow is not null)
|
||||
{
|
||||
Service.WindowSystem.AddWindow(statisticsWindow);
|
||||
}
|
||||
|
||||
pluginInterface.UiBuilder.Draw += Service.WindowSystem.Draw;
|
||||
pluginInterface.UiBuilder.OpenConfigUi += OnOpenConfigUi;
|
||||
Service.Framework.Update += OnFrameworkUpdate;
|
||||
@ -93,7 +101,16 @@ namespace Pal.Client
|
||||
return;
|
||||
}
|
||||
|
||||
switch (arguments)
|
||||
{
|
||||
case "stats":
|
||||
Task.Run(async () => await FetchFloorStatistics());
|
||||
break;
|
||||
|
||||
default:
|
||||
Service.WindowSystem.GetWindow<ConfigWindow>()?.Toggle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
@ -341,6 +358,38 @@ namespace Pal.Client
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FetchFloorStatistics()
|
||||
{
|
||||
if (Service.Configuration.Mode != Configuration.EMode.Online)
|
||||
{
|
||||
Service.Chat.Print($"[Palace Pal] You can view statistics for the floor you're currently on by opening the 'Debug' tab in the configuration window.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var (success, floorStatistics) = await Service.RemoteApi.FetchStatistics();
|
||||
if (success)
|
||||
{
|
||||
var statisticsWindow = Service.WindowSystem.GetWindow<StatisticsWindow>();
|
||||
statisticsWindow.SetFloorData(floorStatistics);
|
||||
statisticsWindow.IsOpen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Service.Chat.PrintError("[Palace Pal] Unable to fetch statistics.");
|
||||
}
|
||||
}
|
||||
catch (RpcException e) when (e.StatusCode == StatusCode.PermissionDenied)
|
||||
{
|
||||
Service.Chat.Print($"[Palace Pal] You can view statistics for the floor you're currently on by opening the 'Debug' tab in the configuration window.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Service.Chat.PrintError($"[Palace Pal] {e}");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRemoteDownloads()
|
||||
{
|
||||
while (_remoteDownloads.TryDequeue(out var download))
|
||||
|
@ -20,8 +20,7 @@ namespace Pal.Client
|
||||
private const string remoteUrl = "https://pal.μ.tv";
|
||||
#endif
|
||||
private GrpcChannel _channel;
|
||||
private string _authToken;
|
||||
private DateTime _tokenExpiresAt;
|
||||
private LoginReply _lastLoginReply;
|
||||
|
||||
private async Task<bool> Connect(CancellationToken cancellationToken, bool retry = true)
|
||||
{
|
||||
@ -67,18 +66,12 @@ namespace Pal.Client
|
||||
if (string.IsNullOrEmpty(accountId))
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(_authToken) || _tokenExpiresAt < DateTime.Now)
|
||||
if (_lastLoginReply == null || string.IsNullOrEmpty(_lastLoginReply.AuthToken) || _lastLoginReply.ExpiresAt.ToDateTime().ToLocalTime() < DateTime.Now)
|
||||
{
|
||||
var loginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = accountId }, deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
||||
if (loginReply.Success)
|
||||
_lastLoginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = accountId }, deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
||||
if (!_lastLoginReply.Success)
|
||||
{
|
||||
_authToken = loginReply.AuthToken;
|
||||
_tokenExpiresAt = loginReply.ExpiresAt.ToDateTime().ToLocalTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
_authToken = null;
|
||||
if (loginReply.Error == LoginError.InvalidAccountId)
|
||||
if (_lastLoginReply.Error == LoginError.InvalidAccountId)
|
||||
{
|
||||
accountId = null;
|
||||
#if DEBUG
|
||||
@ -95,7 +88,7 @@ namespace Pal.Client
|
||||
}
|
||||
}
|
||||
|
||||
return !string.IsNullOrEmpty(_authToken);
|
||||
return !string.IsNullOrEmpty(_lastLoginReply?.AuthToken);
|
||||
}
|
||||
|
||||
public async Task<string> VerifyConnection(CancellationToken cancellationToken = default)
|
||||
@ -142,9 +135,19 @@ namespace Pal.Client
|
||||
return uploadReply.Success;
|
||||
}
|
||||
|
||||
public async Task<(bool, List<FloorStatistics>)> FetchStatistics(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (!await Connect(cancellationToken))
|
||||
return new(false, new List<FloorStatistics>());
|
||||
|
||||
var palaceClient = new PalaceService.PalaceServiceClient(_channel);
|
||||
var statisticsReply = await palaceClient.FetchStatisticsAsync(new StatisticsRequest(), headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(30), cancellationToken: cancellationToken);
|
||||
return (statisticsReply.Success, statisticsReply.FloorStatistics.ToList());
|
||||
}
|
||||
|
||||
private Metadata AuthorizedHeaders() => new Metadata
|
||||
{
|
||||
{ "Authorization", $"Bearer {_authToken}" },
|
||||
{ "Authorization", $"Bearer {_lastLoginReply?.AuthToken}" },
|
||||
};
|
||||
|
||||
public void Dispose()
|
||||
|
@ -4,7 +4,7 @@ using ECommons;
|
||||
using ImGuiNET;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Pal.Client
|
||||
namespace Pal.Client.Windows
|
||||
{
|
||||
internal class AgreementWindow : Window
|
||||
{
|
@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pal.Client
|
||||
namespace Pal.Client.Windows
|
||||
{
|
||||
internal class ConfigWindow : Window
|
||||
{
|
84
Pal.Client/Windows/StatisticsWindow.cs
Normal file
84
Pal.Client/Windows/StatisticsWindow.cs
Normal file
@ -0,0 +1,84 @@
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Pal.Common;
|
||||
using Palace;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pal.Client.Windows
|
||||
{
|
||||
internal class StatisticsWindow : Window
|
||||
{
|
||||
private SortedDictionary<ETerritoryType, TerritoryStatistics> _territoryStatistics = new();
|
||||
|
||||
public StatisticsWindow() : base("Palace Pal - Statistics###PalacePalStats")
|
||||
{
|
||||
Size = new Vector2(500, 500);
|
||||
SizeCondition = ImGuiCond.FirstUseEver;
|
||||
|
||||
foreach (ETerritoryType territory in typeof(ETerritoryType).GetEnumValues())
|
||||
{
|
||||
_territoryStatistics[territory] = new TerritoryStatistics { TerritoryName = territory.ToString() };
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (ImGui.CollapsingHeader("Discovered Traps & Coffers per Instance", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
{
|
||||
if (ImGui.BeginTable("TrapHoardStatistics", 3, ImGuiTableFlags.Borders))
|
||||
{
|
||||
ImGui.TableSetupColumn("Instance", ImGuiTableColumnFlags.WidthFixed);
|
||||
ImGui.TableSetupColumn("Traps", ImGuiTableColumnFlags.WidthFixed, 100);
|
||||
ImGui.TableSetupColumn("Hoard", ImGuiTableColumnFlags.WidthFixed, 100);
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var (territoryType, stats) in _territoryStatistics)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
if (ImGui.TableNextColumn())
|
||||
ImGui.Text(stats.TerritoryName);
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
ImGui.Text(stats.TrapCount?.ToString() ?? "-");
|
||||
|
||||
if (ImGui.TableNextColumn())
|
||||
ImGui.Text(stats.HoardCofferCount?.ToString() ?? "-");
|
||||
}
|
||||
ImGui.EndTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetFloorData(IEnumerable<FloorStatistics> floorStatistics)
|
||||
{
|
||||
foreach (var territoryStatistics in _territoryStatistics.Values)
|
||||
{
|
||||
territoryStatistics.TrapCount = null;
|
||||
territoryStatistics.HoardCofferCount = null;
|
||||
}
|
||||
|
||||
foreach (var floor in floorStatistics)
|
||||
{
|
||||
if (_territoryStatistics.TryGetValue((ETerritoryType)floor.TerritoryType, out TerritoryStatistics territoryStatistics))
|
||||
{
|
||||
territoryStatistics.TrapCount = floor.TrapCount;
|
||||
territoryStatistics.HoardCofferCount = floor.HoardCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TerritoryStatistics
|
||||
{
|
||||
public string TerritoryName { get; set; }
|
||||
public uint? TrapCount { get; set; }
|
||||
public uint? HoardCofferCount { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
37
Pal.Common/ETerritoryType.cs
Normal file
37
Pal.Common/ETerritoryType.cs
Normal file
@ -0,0 +1,37 @@
|
||||
namespace Pal.Common
|
||||
{
|
||||
public enum ETerritoryType : ushort
|
||||
{
|
||||
Palace_1_10 = 561,
|
||||
Palace_11_20,
|
||||
Palace_21_30,
|
||||
Palace_31_40,
|
||||
Palace_41_50,
|
||||
Palace_51_60 = 593,
|
||||
Palace_61_70,
|
||||
Palace_71_80,
|
||||
Palace_81_90,
|
||||
Palace_91_100,
|
||||
Palace_101_110,
|
||||
Palace_111_120,
|
||||
Palace_121_130,
|
||||
Palace_131_140,
|
||||
Palace_141_150,
|
||||
Palace_151_160,
|
||||
Palace_161_170,
|
||||
Palace_171_180,
|
||||
Palace_181_190,
|
||||
Palace_191_200,
|
||||
|
||||
HeavenOnHigh_1_10 = 770,
|
||||
HeavenOnHigh_11_20,
|
||||
HeavenOnHigh_21_30,
|
||||
HeavenOnHigh_31_40,
|
||||
HeavenOnHigh_41_50,
|
||||
HeavenOnHigh_51_60,
|
||||
HeavenOnHigh_61_70 = 782,
|
||||
HeavenOnHigh_71_80,
|
||||
HeavenOnHigh_81_90,
|
||||
HeavenOnHigh_91_100
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ package palace;
|
||||
service PalaceService {
|
||||
rpc DownloadFloors(DownloadFloorsRequest) returns (DownloadFloorsReply);
|
||||
rpc UploadFloors(UploadFloorsRequest) returns (UploadFloorsReply);
|
||||
rpc FetchStatistics(StatisticsRequest) returns (StatisticsReply);
|
||||
}
|
||||
|
||||
message DownloadFloorsRequest {
|
||||
@ -25,6 +26,20 @@ message UploadFloorsReply {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
message StatisticsRequest {
|
||||
}
|
||||
|
||||
message StatisticsReply {
|
||||
bool success = 1;
|
||||
repeated FloorStatistics floorStatistics = 2;
|
||||
}
|
||||
|
||||
message FloorStatistics {
|
||||
uint32 territoryType = 1;
|
||||
uint32 trapCount = 2;
|
||||
uint32 hoardCount = 3;
|
||||
}
|
||||
|
||||
message PalaceObject {
|
||||
ObjectType type = 1;
|
||||
float x = 2;
|
||||
|
Loading…
Reference in New Issue
Block a user