feat: use Lumina for client state resolvers

This commit is contained in:
goat 2020-03-24 03:16:49 +09:00
parent 7de63374ea
commit db474652ee
13 changed files with 58 additions and 30 deletions

View file

@ -85,7 +85,7 @@ namespace Dalamud {
this.Data = new DataManager(this.StartInfo.Language);
this.Data.Initialize();
this.ClientState = new ClientState(this, info, this.SigScanner, this.targetModule);
this.ClientState = new ClientState(this, info, this.SigScanner);
this.BotManager = new DiscordBotManager(this, this.Configuration.DiscordFeatureConfig);

View file

@ -119,7 +119,7 @@ namespace Dalamud.DiscordBot {
var world = string.Empty;
if (this.dalamud.ClientState.Actors.Length > 0)
world = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Name;
world = this.dalamud.ClientState.LocalPlayer.CurrentWorld.GameData.Name;
var embedBuilder = new EmbedBuilder
{
@ -144,7 +144,7 @@ namespace Dalamud.DiscordBot {
dynamic item = XivApi.GetItem(itemId).GetAwaiter().GetResult();
var character = this.dalamud.ClientState.LocalPlayer;
var characterInfo = await GetCharacterInfo(character.Name, character.HomeWorld.Name);
var characterInfo = await GetCharacterInfo(character.Name, character.HomeWorld.GameData.Name);
var embedBuilder = new EmbedBuilder {
Title = (isHq ? "<:hq:593406013651156994> " : "") + item.Name,
@ -203,7 +203,7 @@ namespace Dalamud.DiscordBot {
senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : parsedSender.TextValue;
}
senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.Name;
senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.GameData.Name;
} else {
playerLink.Resolve();

View file

@ -11,13 +11,15 @@ namespace Dalamud.Game.ClientState.Actors {
/// </summary>
public class ActorTable : ICollection {
private ClientStateAddressResolver Address { get; }
private Dalamud dalamud;
/// <summary>
/// Set up the actor table collection.
/// </summary>
/// <param name="addressResolver">Client state address resolver.</param>
public ActorTable(ClientStateAddressResolver addressResolver) {
public ActorTable(Dalamud dalamud, ClientStateAddressResolver addressResolver) {
Address = addressResolver;
this.dalamud = dalamud;
Log.Verbose("Actor table address {ActorTable}", Address.ActorTable);
}
@ -50,9 +52,9 @@ namespace Dalamud.Game.ClientState.Actors {
switch (actorStruct.ObjectKind)
{
case ObjectKind.Player: return new PlayerCharacter(actorStruct);
case ObjectKind.BattleNpc: return new BattleNpc(actorStruct);
default: return new Actor(actorStruct);
case ObjectKind.Player: return new PlayerCharacter(actorStruct, this.dalamud);
case ObjectKind.BattleNpc: return new BattleNpc(actorStruct, this.dalamud);
default: return new Actor(actorStruct, this.dalamud);
}
} catch (AccessViolationException) {
return null;

View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Dalamud.Game.ClientState.Actors.Resolvers
{
public abstract class BaseResolver {
protected Dalamud dalamud;
public BaseResolver(Dalamud dalamud) {
this.dalamud = dalamud;
}
}
}

View file

@ -9,22 +9,23 @@ namespace Dalamud.Game.ClientState.Actors.Resolvers
/// <summary>
/// This object represents a class or job.
/// </summary>
public class ClassJob {
public class ClassJob : BaseResolver {
/// <summary>
/// ID of the ClassJob.
/// </summary>
public readonly int Id;
/// <summary>
/// Name of the ClassJob.
/// GameData linked to this ClassJob.
/// </summary>
public string Name => (string) XivApi.GetClassJob(this.Id).GetAwaiter().GetResult()["Name"];
public Lumina.Excel.GeneratedSheets.ClassJob GameData =>
this.dalamud.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.ClassJob>().GetRow(this.Id);
/// <summary>
/// Set up the ClassJob resolver with the provided ID.
/// </summary>
/// <param name="id">The ID of the world.</param>
public ClassJob(byte id) {
public ClassJob(byte id, Dalamud dalamud) : base(dalamud) {
this.Id = id;
}
}

View file

@ -9,22 +9,23 @@ namespace Dalamud.Game.ClientState.Actors.Resolvers
/// <summary>
/// This object represents a world a character can reside on.
/// </summary>
public class World {
public class World : BaseResolver {
/// <summary>
/// ID of the world.
/// </summary>
public readonly int Id;
/// <summary>
/// Name of the world.
/// GameData linked to this world.
/// </summary>
public string Name => (string) XivApi.GetWorld(this.Id).GetAwaiter().GetResult()["Name"];
public Lumina.Excel.GeneratedSheets.World GameData =>
this.dalamud.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.World>().GetRow(this.Id);
/// <summary>
/// Set up the world resolver with the provided ID.
/// </summary>
/// <param name="id">The ID of the world.</param>
public World(byte id) {
public World(byte id, Dalamud dalamud) : base(dalamud) {
this.Id = id;
}
}

View file

@ -8,12 +8,16 @@ namespace Dalamud.Game.ClientState.Actors.Types {
/// </summary>
protected Structs.Actor actorStruct;
protected Dalamud dalamud;
/// <summary>
/// Initialize a representation of a basic FFXIV actor.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public Actor(Structs.Actor actorStruct) {
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
public Actor(Structs.Actor actorStruct, Dalamud dalamud) {
this.actorStruct = actorStruct;
this.dalamud = dalamud;
}
/// <summary>

View file

@ -9,7 +9,8 @@ namespace Dalamud.Game.ClientState.Actors.Types {
/// Set up a new Chara with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public Chara(Structs.Actor actorStruct) : base(actorStruct) { }
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
protected Chara(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
/// <summary>
/// The level of this Chara.
@ -19,7 +20,7 @@ namespace Dalamud.Game.ClientState.Actors.Types {
/// <summary>
/// The ClassJob of this Chara.
/// </summary>
public ClassJob ClassJob => new ClassJob(this.actorStruct.ClassJob);
public ClassJob ClassJob => new ClassJob(this.actorStruct.ClassJob, this.dalamud);
/// <summary>
/// The current HP of this Chara.

View file

@ -7,7 +7,8 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
/// Set up a new BattleNpc with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public BattleNpc(Structs.Actor actorStruct) : base(actorStruct) { }
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
public BattleNpc(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
/// <summary>
/// The BattleNpc <see cref="BattleNpcSubKind" /> of this BattleNpc.

View file

@ -7,7 +7,8 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
/// Set up a new NPC with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public Npc(Structs.Actor actorStruct) : base(actorStruct) { }
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
protected Npc(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
/// <summary>
/// The data ID of the NPC linking to their respective game data.

View file

@ -9,16 +9,17 @@ namespace Dalamud.Game.ClientState.Actors.Types {
/// Set up a new player character with the provided memory representation.
/// </summary>
/// <param name="actorStruct">The memory representation of the base actor.</param>
public PlayerCharacter(Structs.Actor actorStruct) : base(actorStruct) { }
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
public PlayerCharacter(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
/// <summary>
/// The current <see cref="World">world</see> of the character.
/// </summary>
public World CurrentWorld => new World(this.actorStruct.CurrentWorld);
public World CurrentWorld => new World(this.actorStruct.CurrentWorld, this.dalamud);
/// <summary>
/// The home <see cref="World">world</see> of the character.
/// </summary>
public World HomeWorld => new World(this.actorStruct.HomeWorld);
public World HomeWorld => new World(this.actorStruct.HomeWorld, this.dalamud);
}
}

View file

@ -61,8 +61,7 @@ namespace Dalamud.Game.ClientState
/// <param name="dalamud">Dalamud instance</param>
/// /// <param name="startInfo">StartInfo of the current Dalamud launch</param>
/// <param name="scanner">Sig scanner</param>
/// <param name="targetModule">Game process module</param>
public ClientState(Dalamud dalamud, DalamudStartInfo startInfo, SigScanner scanner, ProcessModule targetModule) {
public ClientState(Dalamud dalamud, DalamudStartInfo startInfo, SigScanner scanner) {
Address = new ClientStateAddressResolver();
Address.Setup(scanner);
@ -70,7 +69,7 @@ namespace Dalamud.Game.ClientState
this.ClientLanguage = startInfo.Language;
this.Actors = new ActorTable(Address);
this.Actors = new ActorTable(dalamud, Address);
this.JobGauges = new JobGauges(Address);

View file

@ -69,8 +69,8 @@ namespace Dalamud.Interface
stateString += $"ActorTableLen: {this.dalamud.ClientState.Actors.Length}\n";
stateString += $"LocalPlayerName: {this.dalamud.ClientState.LocalPlayer.Name}\n";
stateString += $"CurrentWorldName: {this.dalamud.ClientState.LocalPlayer.CurrentWorld.Name}\n";
stateString += $"HomeWorldName: {this.dalamud.ClientState.LocalPlayer.HomeWorld.Name}\n";
stateString += $"CurrentWorldName: {this.dalamud.ClientState.LocalPlayer.CurrentWorld.GameData.Name}\n";
stateString += $"HomeWorldName: {this.dalamud.ClientState.LocalPlayer.HomeWorld.GameData.Name}\n";
stateString += $"LocalCID: {this.dalamud.ClientState.LocalContentId:X}\n";
stateString += $"LastLinkedItem: {this.dalamud.Framework.Gui.Chat.LastLinkedItemId.ToString()}\n";
@ -85,7 +85,7 @@ namespace Dalamud.Interface
if (actor is Chara chara)
stateString +=
$" Level: {chara.Level} ClassJob: {chara.ClassJob.Name} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n";
$" Level: {chara.Level} ClassJob: {chara.ClassJob.GameData.Name} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n";
;
}