refactor and fix some shit
This commit is contained in:
143
MareSynchronos/Managers/CharacterManager.cs
Normal file
143
MareSynchronos/Managers/CharacterManager.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Logging;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using MareSynchronos.Hooks;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.Utils;
|
||||
using MareSynchronos.WebAPI;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MareSynchronos.Managers
|
||||
{
|
||||
public class CharacterManager : IDisposable
|
||||
{
|
||||
private readonly DrawHooks drawHooks;
|
||||
private readonly ClientState clientState;
|
||||
private readonly Framework framework;
|
||||
private readonly ApiController apiController;
|
||||
private readonly ObjectTable objectTable;
|
||||
private readonly IpcManager ipcManager;
|
||||
private Task? drawHookTask = null;
|
||||
|
||||
public CharacterManager(DrawHooks drawhooks, ClientState clientState, Framework framework, ApiController apiController, ObjectTable objectTable, IpcManager ipcManager)
|
||||
{
|
||||
this.drawHooks = drawhooks;
|
||||
this.clientState = clientState;
|
||||
this.framework = framework;
|
||||
this.apiController = apiController;
|
||||
this.objectTable = objectTable;
|
||||
this.ipcManager = ipcManager;
|
||||
drawHooks.StartHooks();
|
||||
clientState.TerritoryChanged += ClientState_TerritoryChanged;
|
||||
framework.Update += Framework_Update;
|
||||
drawhooks.PlayerLoadEvent += Drawhooks_PlayerLoadEvent;
|
||||
}
|
||||
|
||||
Dictionary<string, string> localPlayers = new();
|
||||
private DateTime lastCheck = DateTime.Now;
|
||||
|
||||
private unsafe void Framework_Update(Framework framework)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (clientState.LocalPlayer == null) return;
|
||||
|
||||
if (DateTime.Now < lastCheck.AddSeconds(5)) return;
|
||||
|
||||
List<string> localPlayersList = new();
|
||||
List<string> newPlayers = new();
|
||||
foreach (var obj in objectTable)
|
||||
{
|
||||
if (obj.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player) continue;
|
||||
string playerName = obj.Name.ToString();
|
||||
if (playerName == clientState.LocalPlayer.Name.ToString()) continue;
|
||||
var hashedName = Crypto.GetHash(playerName);
|
||||
}
|
||||
|
||||
foreach (var item in localPlayers.ToList())
|
||||
{
|
||||
if (!localPlayersList.Contains(item.Key))
|
||||
{
|
||||
localPlayers.Remove(item.Key);
|
||||
}
|
||||
}
|
||||
|
||||
if (newPlayers.Any())
|
||||
PluginLog.Debug("New players: " + string.Join(",", newPlayers.Select(p => p + ":" + localPlayers[p])));
|
||||
lastCheck = DateTime.Now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PluginLog.Error(ex, "error");
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientState_TerritoryChanged(object? sender, ushort e)
|
||||
{
|
||||
localPlayers.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
framework.Update -= Framework_Update;
|
||||
drawHooks.PlayerLoadEvent -= Drawhooks_PlayerLoadEvent;
|
||||
clientState.TerritoryChanged -= ClientState_TerritoryChanged;
|
||||
drawHooks?.Dispose();
|
||||
}
|
||||
|
||||
private unsafe void Drawhooks_PlayerLoadEvent(object? sender, EventArgs e)
|
||||
{
|
||||
if (sender == null) return;
|
||||
if (drawHookTask != null && !drawHookTask.IsCompleted) return;
|
||||
|
||||
var obj = (GameObject*)(IntPtr)sender;
|
||||
drawHookTask = Task.Run(() =>
|
||||
{
|
||||
PluginLog.Debug("Waiting for charater to be drawn");
|
||||
while ((obj->RenderFlags & 0b100000000000) == 0b100000000000) // 0b100000000000 is "still rendering" or something
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
PluginLog.Debug("Character finished drawing");
|
||||
|
||||
// wait one more second just in case
|
||||
Thread.Sleep(1000);
|
||||
|
||||
apiController.SendCharacterData(drawHooks.BuildCharacterCache()).RunSynchronously();
|
||||
});
|
||||
}
|
||||
|
||||
public CharacterCache GetCharacterCache() => drawHooks.BuildCharacterCache();
|
||||
|
||||
public void PrintRequestedResources() => drawHooks.PrintRequestedResources();
|
||||
|
||||
public void DebugJson()
|
||||
{
|
||||
var cache = drawHooks.BuildCharacterCache();
|
||||
cache.SetGlamourerData(ipcManager.GlamourerGetCharacterCustomization()!);
|
||||
cache.JobId = clientState.LocalPlayer!.ClassJob.Id;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (!cache.IsReady)
|
||||
{
|
||||
await Task.Delay(50);
|
||||
}
|
||||
var json = JsonConvert.SerializeObject(cache, Formatting.Indented);
|
||||
|
||||
cache.CacheHash = Crypto.GetHash(json);
|
||||
|
||||
json = JsonConvert.SerializeObject(cache, Formatting.Indented);
|
||||
PluginLog.Debug(json);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user