diff --git a/RetainerTrack/.editorconfig b/RetainerTrack/.editorconfig index 89b3328..66a9314 100644 --- a/RetainerTrack/.editorconfig +++ b/RetainerTrack/.editorconfig @@ -990,7 +990,7 @@ csharp_space_around_binary_operators = before_and_after csharp_using_directive_placement = outside_namespace:silent csharp_prefer_simple_using_statement = true:suggestion csharp_prefer_braces = true:silent -csharp_style_namespace_declarations = block_scoped:silent +csharp_style_namespace_declarations = file_scoped:suggestion csharp_style_prefer_method_group_conversion = true:silent csharp_style_prefer_top_level_statements = true:silent csharp_style_prefer_primary_constructors = true:suggestion diff --git a/RetainerTrack/Commands/AccountIdCommand.cs b/RetainerTrack/Commands/AccountIdCommand.cs new file mode 100644 index 0000000..bd4e848 --- /dev/null +++ b/RetainerTrack/Commands/AccountIdCommand.cs @@ -0,0 +1,62 @@ +using System; +using Dalamud.Game.ClientState.Objects; +using Dalamud.Game.ClientState.Objects.Enums; +using Dalamud.Game.ClientState.Objects.Types; +using Dalamud.Game.Command; +using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Client.Game.Character; +using RetainerTrack.Handlers; + +namespace RetainerTrack.Commands +{ + internal sealed class AccountIdCommand : IDisposable + { + private readonly ICommandManager _commandManager; + private readonly IClientState _clientState; + private readonly ITargetManager _targetManager; + private readonly IChatGui _chatGui; + private readonly PersistenceContext _persistenceContext; + + public AccountIdCommand(ICommandManager commandManager, IClientState clientState, ITargetManager targetManager, + IChatGui chatGui, PersistenceContext persistenceContext) + { + _commandManager = commandManager; + _clientState = clientState; + _targetManager = targetManager; + _chatGui = chatGui; + _persistenceContext = persistenceContext; + + _commandManager.AddHandler("/accountid", new CommandInfo(ProcessCommand) + { + HelpMessage = "Shows the accountid of your target (or if no target, yourself)" + }); + } + + private void ProcessCommand(string command, string arguments) + { + IGameObject? character = _targetManager.Target ?? _clientState.LocalPlayer; + if (character == null || character.ObjectKind != ObjectKind.Player) + return; + + unsafe + { + var bc = (BattleChara*)character.Address; + _chatGui.Print($"{character.Name} has Account Id: {bc->AccountId}, Content Id: {bc->ContentId}"); + + _persistenceContext.HandleContentIdMapping([ + new PlayerMapping + { + ContentId = bc->ContentId, + AccountId = bc->AccountId, + PlayerName = bc->NameString, + } + ]); + } + } + + public void Dispose() + { + _commandManager.RemoveHandler("/accountid"); + } + } +} diff --git a/RetainerTrack/Handlers/ObjectTableHandler.cs b/RetainerTrack/Handlers/ObjectTableHandler.cs index a3b0ea0..1a25038 100644 --- a/RetainerTrack/Handlers/ObjectTableHandler.cs +++ b/RetainerTrack/Handlers/ObjectTableHandler.cs @@ -46,15 +46,13 @@ internal sealed class ObjectTableHandler : IDisposable if (obj.ObjectKind == ObjectKind.Player) { var bc = (BattleChara*)obj.Address; - var ep = (ExtendedPlayer*)obj.Address; - - if (ep->ContentId == 0 || ep->AccountId == 0) + if (bc->ContentId == 0 || bc->AccountId == 0) continue; playerMappings.Add(new PlayerMapping { - ContentId = ep->ContentId, - AccountId = ep->AccountId, + ContentId = bc->ContentId, + AccountId = bc->AccountId, PlayerName = bc->NameString, }); } @@ -70,11 +68,4 @@ internal sealed class ObjectTableHandler : IDisposable { _framework.Update -= FrameworkUpdate; } - - [StructLayout(LayoutKind.Explicit, Size = 0x2280)] - public struct ExtendedPlayer - { - [FieldOffset(0x2258)] public ulong AccountId; - [FieldOffset(0x2260)] public ulong ContentId; - } } diff --git a/RetainerTrack/RetainerTrack.csproj b/RetainerTrack/RetainerTrack.csproj index 3e18e9e..fa5bbab 100644 --- a/RetainerTrack/RetainerTrack.csproj +++ b/RetainerTrack/RetainerTrack.csproj @@ -1,6 +1,6 @@ - 4.1 + 4.2 win-x64 none dist diff --git a/RetainerTrack/RetainerTrackPlugin.cs b/RetainerTrack/RetainerTrackPlugin.cs index 052d1fe..e8e0589 100644 --- a/RetainerTrack/RetainerTrackPlugin.cs +++ b/RetainerTrack/RetainerTrackPlugin.cs @@ -58,24 +58,24 @@ internal sealed class RetainerTrackPlugin : IDalamudPlugin serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - _sqliteConnectionString = - $"Data Source={Path.Join(pluginInterface.GetPluginConfigDirectory(), DatabaseFileName)}"; - serviceCollection.AddDbContext(o => o - .UseSqlite(_sqliteConnectionString) - .UseModel(RetainerTrackContextModel.Instance)); - + _sqliteConnectionString = PrepareSqliteDb(serviceCollection, pluginInterface.GetPluginConfigDirectory()); _serviceProvider = serviceCollection.BuildServiceProvider(); RunMigrations(_serviceProvider); + InitializeRequiredServices(_serviceProvider); + } - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); - _serviceProvider.GetRequiredService(); + private static string PrepareSqliteDb(IServiceCollection serviceCollection, string getPluginConfigDirectory) + { + string connectionString = $"Data Source={Path.Join(getPluginConfigDirectory, DatabaseFileName)}"; + serviceCollection.AddDbContext(o => o + .UseSqlite(connectionString) + .UseModel(RetainerTrackContextModel.Instance)); + return connectionString; } private static void RunMigrations(IServiceProvider serviceProvider) @@ -85,6 +85,16 @@ internal sealed class RetainerTrackPlugin : IDalamudPlugin dbContext.Database.Migrate(); } + private static void InitializeRequiredServices(ServiceProvider serviceProvider) + { + serviceProvider.GetRequiredService(); + serviceProvider.GetRequiredService(); + serviceProvider.GetRequiredService(); + serviceProvider.GetRequiredService(); + serviceProvider.GetRequiredService(); + serviceProvider.GetRequiredService(); + } + public void Dispose() { _serviceProvider?.Dispose();