mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-24 01:19:18 +01:00
fix: crash when chat is processed before init, use DI for SeString stuff
This commit is contained in:
parent
26ad4ce74b
commit
740ccfde11
14 changed files with 110 additions and 111 deletions
|
|
@ -61,6 +61,8 @@ namespace Dalamud {
|
||||||
|
|
||||||
public DataManager Data { get; private set; }
|
public DataManager Data { get; private set; }
|
||||||
|
|
||||||
|
internal SeStringManager SeStringManager { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
internal Localization LocalizationManager;
|
internal Localization LocalizationManager;
|
||||||
|
|
||||||
|
|
@ -122,8 +124,7 @@ namespace Dalamud {
|
||||||
this.Data = new DataManager(this.StartInfo.Language);
|
this.Data = new DataManager(this.StartInfo.Language);
|
||||||
await this.Data.Initialize(this.baseDirectory);
|
await this.Data.Initialize(this.baseDirectory);
|
||||||
|
|
||||||
// TODO: better way to do this? basically for lumina injection
|
SeStringManager = new SeStringManager(Data);
|
||||||
SeString.Dalamud = this;
|
|
||||||
|
|
||||||
this.NetworkHandlers = new NetworkHandlers(this, this.Configuration.OptOutMbCollection);
|
this.NetworkHandlers = new NetworkHandlers(this, this.Configuration.OptOutMbCollection);
|
||||||
|
|
||||||
|
|
@ -145,6 +146,9 @@ namespace Dalamud {
|
||||||
Log.Error(ex, "Plugin load failed.");
|
Log.Error(ex, "Plugin load failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.Framework.Enable();
|
||||||
|
this.ClientState.Enable();
|
||||||
|
|
||||||
IsReady = true;
|
IsReady = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -153,9 +157,6 @@ namespace Dalamud {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
ReplaceExceptionHandler();
|
ReplaceExceptionHandler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.Framework.Enable();
|
|
||||||
this.ClientState.Enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unload() {
|
public void Unload() {
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,10 @@ namespace Dalamud.DiscordBot {
|
||||||
await channel.SendMessageAsync(embed: embedBuilder.Build());
|
await channel.SendMessageAsync(embed: embedBuilder.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ProcessChatMessage(XivChatType type, StdString message, StdString sender) {
|
public async Task ProcessChatMessage(XivChatType type, SeString message, SeString sender) {
|
||||||
|
if (this.dalamud.SeStringManager == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Special case for outgoing tells, these should be sent under Incoming tells
|
// Special case for outgoing tells, these should be sent under Incoming tells
|
||||||
var wasOutgoingTell = false;
|
var wasOutgoingTell = false;
|
||||||
if (type == XivChatType.TellOutgoing) {
|
if (type == XivChatType.TellOutgoing) {
|
||||||
|
|
@ -180,8 +183,7 @@ namespace Dalamud.DiscordBot {
|
||||||
var channels = chatTypeConfigs.Select(c => GetChannel(c.Channel).GetAwaiter().GetResult());
|
var channels = chatTypeConfigs.Select(c => GetChannel(c.Channel).GetAwaiter().GetResult());
|
||||||
|
|
||||||
|
|
||||||
var parsedSender = SeString.Parse(sender.RawData);
|
var playerLink = sender.Payloads.FirstOrDefault(x => x.Type == PayloadType.Player) as PlayerPayload;
|
||||||
var playerLink = parsedSender.Payloads.FirstOrDefault(x => x.Type == PayloadType.Player) as PlayerPayload;
|
|
||||||
|
|
||||||
string senderName;
|
string senderName;
|
||||||
string senderWorld;
|
string senderWorld;
|
||||||
|
|
@ -192,15 +194,15 @@ namespace Dalamud.DiscordBot {
|
||||||
|
|
||||||
// Special case 2 - When the local player talks in party/alliance, the name comes through as raw text,
|
// Special case 2 - When the local player talks in party/alliance, the name comes through as raw text,
|
||||||
// but prefixed by their position number in the party (which for local player may always be 1)
|
// but prefixed by their position number in the party (which for local player may always be 1)
|
||||||
if (parsedSender.TextValue.EndsWith(this.dalamud.ClientState.LocalPlayer.Name))
|
if (sender.TextValue.EndsWith(this.dalamud.ClientState.LocalPlayer.Name))
|
||||||
{
|
{
|
||||||
senderName = this.dalamud.ClientState.LocalPlayer.Name;
|
senderName = this.dalamud.ClientState.LocalPlayer.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error("playerLink was null. Sender: {0}", BitConverter.ToString(sender.RawData));
|
Log.Error("playerLink was null. Sender: {0}", BitConverter.ToString(sender.Encode()));
|
||||||
|
|
||||||
senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : parsedSender.TextValue;
|
senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : sender.TextValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.GameData.Name;
|
senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.GameData.Name;
|
||||||
|
|
@ -209,7 +211,7 @@ namespace Dalamud.DiscordBot {
|
||||||
senderWorld = playerLink.World.Name;
|
senderWorld = playerLink.World.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawMessage = SeString.Parse(message.RawData).TextValue;
|
var rawMessage = message.TextValue;
|
||||||
|
|
||||||
var avatarUrl = string.Empty;
|
var avatarUrl = string.Empty;
|
||||||
var lodestoneId = string.Empty;
|
var lodestoneId = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -51,22 +51,12 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Lumina instance to use for any necessary data lookups.
|
/// The Lumina instance to use for any necessary data lookups.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected DataManager dataResolver;
|
protected DataManager DataResolver;
|
||||||
|
|
||||||
// private for now, since subclasses shouldn't interact with this
|
// private for now, since subclasses shouldn't interact with this
|
||||||
// To force-invalidate it, Dirty can be set to true
|
// To force-invalidate it, Dirty can be set to true
|
||||||
private byte[] encodedData;
|
private byte[] encodedData;
|
||||||
|
|
||||||
protected Payload()
|
|
||||||
{
|
|
||||||
// this is not a good way to do this, but I don't want to have to include a dalamud
|
|
||||||
// reference on multiple methods in every payload class
|
|
||||||
// We could also just directly reference this static where we use it, but this at least
|
|
||||||
// allows for more easily changing how this is injected later, without affecting code
|
|
||||||
// that makes use of it
|
|
||||||
this.dataResolver = SeString.Dalamud.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Encode this payload object into a byte[] useable in-game for things like the chat log.
|
/// Encode this payload object into a byte[] useable in-game for things like the chat log.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -88,7 +78,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">A reader positioned at the start of the payload, and containing at least one entire payload.</param>
|
/// <param name="reader">A reader positioned at the start of the payload, and containing at least one entire payload.</param>
|
||||||
/// <returns>The constructed Payload-derived object that was decoded from the binary data.</returns>
|
/// <returns>The constructed Payload-derived object that was decoded from the binary data.</returns>
|
||||||
public static Payload Decode(BinaryReader reader)
|
public static Payload Decode(BinaryReader reader, DataManager data)
|
||||||
{
|
{
|
||||||
var payloadStartPos = reader.BaseStream.Position;
|
var payloadStartPos = reader.BaseStream.Position;
|
||||||
|
|
||||||
|
|
@ -105,6 +95,8 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
payload = DecodeChunk(reader);
|
payload = DecodeChunk(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payload.DataResolver = data;
|
||||||
|
|
||||||
// for now, cache off the actual binary data for this payload, so we don't have to
|
// for now, cache off the actual binary data for this payload, so we don't have to
|
||||||
// regenerate it if the payload isn't modified
|
// regenerate it if the payload isn't modified
|
||||||
// TODO: probably better ways to handle this
|
// TODO: probably better ways to handle this
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
string value = null;
|
string value = null;
|
||||||
|
|
||||||
var sheet = this.dataResolver.GetExcelSheet<Completion>();
|
var sheet = this.DataResolver.GetExcelSheet<Completion>();
|
||||||
|
|
||||||
Completion row = null;
|
Completion row = null;
|
||||||
try
|
try
|
||||||
|
|
@ -119,24 +119,24 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
|
|
||||||
var name = actualTableName switch
|
var name = actualTableName switch
|
||||||
{
|
{
|
||||||
"Action" => this.dataResolver.GetExcelSheet<Lumina.Excel.GeneratedSheets.Action>().GetRow(this.key).Name,
|
"Action" => this.DataResolver.GetExcelSheet<Lumina.Excel.GeneratedSheets.Action>().GetRow(this.key).Name,
|
||||||
"ActionComboRoute" => this.dataResolver.GetExcelSheet<ActionComboRoute>().GetRow(this.key).Name,
|
"ActionComboRoute" => this.DataResolver.GetExcelSheet<ActionComboRoute>().GetRow(this.key).Name,
|
||||||
"BuddyAction" => this.dataResolver.GetExcelSheet<BuddyAction>().GetRow(this.key).Name,
|
"BuddyAction" => this.DataResolver.GetExcelSheet<BuddyAction>().GetRow(this.key).Name,
|
||||||
"ClassJob" => this.dataResolver.GetExcelSheet<ClassJob>().GetRow(this.key).Name,
|
"ClassJob" => this.DataResolver.GetExcelSheet<ClassJob>().GetRow(this.key).Name,
|
||||||
"Companion" => this.dataResolver.GetExcelSheet<Companion>().GetRow(this.key).Singular,
|
"Companion" => this.DataResolver.GetExcelSheet<Companion>().GetRow(this.key).Singular,
|
||||||
"CraftAction" => this.dataResolver.GetExcelSheet<CraftAction>().GetRow(this.key).Name,
|
"CraftAction" => this.DataResolver.GetExcelSheet<CraftAction>().GetRow(this.key).Name,
|
||||||
"GeneralAction" => this.dataResolver.GetExcelSheet<GeneralAction>().GetRow(this.key).Name,
|
"GeneralAction" => this.DataResolver.GetExcelSheet<GeneralAction>().GetRow(this.key).Name,
|
||||||
"GuardianDeity" => this.dataResolver.GetExcelSheet<GuardianDeity>().GetRow(this.key).Name,
|
"GuardianDeity" => this.DataResolver.GetExcelSheet<GuardianDeity>().GetRow(this.key).Name,
|
||||||
"MainCommand" => this.dataResolver.GetExcelSheet<MainCommand>().GetRow(this.key).Name,
|
"MainCommand" => this.DataResolver.GetExcelSheet<MainCommand>().GetRow(this.key).Name,
|
||||||
"Mount" => this.dataResolver.GetExcelSheet<Mount>().GetRow(this.key).Singular,
|
"Mount" => this.DataResolver.GetExcelSheet<Mount>().GetRow(this.key).Singular,
|
||||||
"Pet" => this.dataResolver.GetExcelSheet<Pet>().GetRow(this.key).Name,
|
"Pet" => this.DataResolver.GetExcelSheet<Pet>().GetRow(this.key).Name,
|
||||||
"PetAction" => this.dataResolver.GetExcelSheet<PetAction>().GetRow(this.key).Name,
|
"PetAction" => this.DataResolver.GetExcelSheet<PetAction>().GetRow(this.key).Name,
|
||||||
"PetMirage" => this.dataResolver.GetExcelSheet<PetMirage>().GetRow(this.key).Name,
|
"PetMirage" => this.DataResolver.GetExcelSheet<PetMirage>().GetRow(this.key).Name,
|
||||||
"PlaceName" => this.dataResolver.GetExcelSheet<PlaceName>().GetRow(this.key).Name,
|
"PlaceName" => this.DataResolver.GetExcelSheet<PlaceName>().GetRow(this.key).Name,
|
||||||
"Race" => this.dataResolver.GetExcelSheet<Race>().GetRow(this.key).Masculine,
|
"Race" => this.DataResolver.GetExcelSheet<Race>().GetRow(this.key).Masculine,
|
||||||
"TextCommand" => this.dataResolver.GetExcelSheet<TextCommand>().GetRow(this.key).Command,
|
"TextCommand" => this.DataResolver.GetExcelSheet<TextCommand>().GetRow(this.key).Command,
|
||||||
"Tribe" => this.dataResolver.GetExcelSheet<Tribe>().GetRow(this.key).Masculine,
|
"Tribe" => this.DataResolver.GetExcelSheet<Tribe>().GetRow(this.key).Masculine,
|
||||||
"Weather" => this.dataResolver.GetExcelSheet<Weather>().GetRow(this.key).Name,
|
"Weather" => this.DataResolver.GetExcelSheet<Weather>().GetRow(this.key).Name,
|
||||||
_ => throw new Exception(actualTableName)
|
_ => throw new Exception(actualTableName)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.item ??= this.dataResolver.GetExcelSheet<Item>().GetRow(this.itemId);
|
this.item ??= this.DataResolver.GetExcelSheet<Item>().GetRow(this.itemId);
|
||||||
return this.item;
|
return this.item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.map ??= this.dataResolver.GetExcelSheet<Map>().GetRow(this.mapId);
|
this.map ??= this.DataResolver.GetExcelSheet<Map>().GetRow(this.mapId);
|
||||||
return this.map;
|
return this.map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.territoryType ??= this.dataResolver.GetExcelSheet<TerritoryType>().GetRow(this.territoryTypeId);
|
this.territoryType ??= this.DataResolver.GetExcelSheet<TerritoryType>().GetRow(this.territoryTypeId);
|
||||||
return this.territoryType;
|
return this.territoryType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.world ??= this.dataResolver.GetExcelSheet<World>().GetRow(this.serverId);
|
this.world ??= this.DataResolver.GetExcelSheet<World>().GetRow(this.serverId);
|
||||||
return this.world;
|
return this.world;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
status ??= this.dataResolver.GetExcelSheet<Status>().GetRow(this.statusId);
|
status ??= this.DataResolver.GetExcelSheet<Status>().GetRow(this.statusId);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.color ??= this.dataResolver.GetExcelSheet<UIColor>().GetRow(this.colorKey);
|
this.color ??= this.DataResolver.GetExcelSheet<UIColor>().GetRow(this.colorKey);
|
||||||
return this.color;
|
return this.color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
this.color ??= this.dataResolver.GetExcelSheet<UIColor>().GetRow(this.colorKey);
|
this.color ??= this.DataResolver.GetExcelSheet<UIColor>().GetRow(this.colorKey);
|
||||||
return this.color;
|
return this.color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Dalamud.Game.Chat.SeStringHandling.Payloads;
|
||||||
|
|
||||||
namespace Dalamud.Game.Chat.SeStringHandling
|
namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
{
|
{
|
||||||
|
|
@ -11,9 +12,6 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SeString
|
public class SeString
|
||||||
{
|
{
|
||||||
// TODO: probably change how this is done/where it comes from
|
|
||||||
internal static Dalamud Dalamud { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The ordered list of payloads included in this SeString.
|
/// The ordered list of payloads included in this SeString.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -36,29 +34,6 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Parse a binary game message into an SeString.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Binary message payload data in SE's internal format.</param>
|
|
||||||
/// <returns>An SeString containing parsed Payload objects for each payload in the data.</returns>
|
|
||||||
public static SeString Parse(byte[] bytes)
|
|
||||||
{
|
|
||||||
var payloads = new List<Payload>();
|
|
||||||
|
|
||||||
using (var stream = new MemoryStream(bytes))
|
|
||||||
using (var reader = new BinaryReader(stream))
|
|
||||||
{
|
|
||||||
while (stream.Position < bytes.Length)
|
|
||||||
{
|
|
||||||
var payload = Payload.Decode(reader);
|
|
||||||
if (payload != null)
|
|
||||||
payloads.Add(payload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SeString(payloads);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new SeString from an ordered list of payloads.
|
/// Creates a new SeString from an ordered list of payloads.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,47 @@
|
||||||
using Dalamud.Game.Chat.SeStringHandling.Payloads;
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Dalamud.Data;
|
||||||
|
using Dalamud.Game.Chat.SeStringHandling.Payloads;
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.Chat.SeStringHandling
|
namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
{
|
{
|
||||||
/// <summary>
|
class SeStringManager
|
||||||
/// A utility class for working with common SeString variants.
|
|
||||||
/// </summary>
|
|
||||||
public static class SeStringUtils
|
|
||||||
{
|
{
|
||||||
|
private readonly DataManager data;
|
||||||
|
|
||||||
|
public SeStringManager(DataManager Data) {
|
||||||
|
this.data = Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse a binary game message into an SeString.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bytes">Binary message payload data in SE's internal format.</param>
|
||||||
|
/// <returns>An SeString containing parsed Payload objects for each payload in the data.</returns>
|
||||||
|
public SeString Parse(byte[] bytes)
|
||||||
|
{
|
||||||
|
var payloads = new List<Payload>();
|
||||||
|
|
||||||
|
using (var stream = new MemoryStream(bytes))
|
||||||
|
using (var reader = new BinaryReader(stream))
|
||||||
|
{
|
||||||
|
while (stream.Position < bytes.Length)
|
||||||
|
{
|
||||||
|
var payload = Payload.Decode(reader, this.data);
|
||||||
|
if (payload != null)
|
||||||
|
payloads.Add(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SeString(payloads);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an SeString representing an entire Payload chain that can be used to link an item in the chat log.
|
/// Creates an SeString representing an entire Payload chain that can be used to link an item in the chat log.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -18,9 +49,9 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// <param name="isHQ">Whether to link the high-quality variant of the item.</param>
|
/// <param name="isHQ">Whether to link the high-quality variant of the item.</param>
|
||||||
/// <param name="displayNameOverride">An optional name override to display, instead of the actual item name.</param>
|
/// <param name="displayNameOverride">An optional name override to display, instead of the actual item name.</param>
|
||||||
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
|
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
|
||||||
public static SeString CreateItemLink(uint itemId, bool isHQ, string displayNameOverride = null)
|
public SeString CreateItemLink(uint itemId, bool isHQ, string displayNameOverride = null)
|
||||||
{
|
{
|
||||||
string displayName = displayNameOverride ?? SeString.Dalamud.Data.GetExcelSheet<Item>().GetRow(itemId).Name;
|
string displayName = displayNameOverride ?? this.data.GetExcelSheet<Item>().GetRow(itemId).Name;
|
||||||
if (isHQ)
|
if (isHQ)
|
||||||
{
|
{
|
||||||
displayName += $" {(char)SeIconChar.HighQuality}";
|
displayName += $" {(char)SeIconChar.HighQuality}";
|
||||||
|
|
@ -50,12 +81,12 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// <param name="isHQ">Whether to link the high-quality variant of the item.</param>
|
/// <param name="isHQ">Whether to link the high-quality variant of the item.</param>
|
||||||
/// <param name="displayNameOverride">An optional name override to display, instead of the actual item name.</param>
|
/// <param name="displayNameOverride">An optional name override to display, instead of the actual item name.</param>
|
||||||
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
|
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
|
||||||
public static SeString CreateItemLink(Item item, bool isHQ, string displayNameOverride = null)
|
public SeString CreateItemLink(Item item, bool isHQ, string displayNameOverride = null)
|
||||||
{
|
{
|
||||||
return CreateItemLink((uint)item.RowId, isHQ, displayNameOverride ?? item.Name);
|
return CreateItemLink((uint)item.RowId, isHQ, displayNameOverride ?? item.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SeString CreateMapLink(uint territoryId, uint mapId, int rawX, int rawY)
|
public SeString CreateMapLink(uint territoryId, uint mapId, int rawX, int rawY)
|
||||||
{
|
{
|
||||||
var mapPayload = new MapLinkPayload(territoryId, mapId, rawX, rawY);
|
var mapPayload = new MapLinkPayload(territoryId, mapId, rawX, rawY);
|
||||||
var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}";
|
var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}";
|
||||||
|
|
@ -81,7 +112,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// <param name="yCoord">The human-readable y-coordinate for this link.</param>
|
/// <param name="yCoord">The human-readable y-coordinate for this link.</param>
|
||||||
/// <param name="fudgeFactor">An optional offset to account for rounding and truncation errors; it is best to leave this untouched in most cases.</param>
|
/// <param name="fudgeFactor">An optional offset to account for rounding and truncation errors; it is best to leave this untouched in most cases.</param>
|
||||||
/// <returns>An SeString containing all of the payloads necessary to display a map link in the chat log.</returns>
|
/// <returns>An SeString containing all of the payloads necessary to display a map link in the chat log.</returns>
|
||||||
public static SeString CreateMapLink(uint territoryId, uint mapId, float xCoord, float yCoord, float fudgeFactor = 0.05f)
|
public SeString CreateMapLink(uint territoryId, uint mapId, float xCoord, float yCoord, float fudgeFactor = 0.05f)
|
||||||
{
|
{
|
||||||
var mapPayload = new MapLinkPayload(territoryId, mapId, xCoord, yCoord, fudgeFactor);
|
var mapPayload = new MapLinkPayload(territoryId, mapId, xCoord, yCoord, fudgeFactor);
|
||||||
var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}";
|
var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}";
|
||||||
|
|
@ -106,13 +137,13 @@ namespace Dalamud.Game.Chat.SeStringHandling
|
||||||
/// <param name="yCoord">The human-readable y-coordinate for this link.</param>
|
/// <param name="yCoord">The human-readable y-coordinate for this link.</param>
|
||||||
/// <param name="fudgeFactor">An optional offset to account for rounding and truncation errors; it is best to leave this untouched in most cases.</param>
|
/// <param name="fudgeFactor">An optional offset to account for rounding and truncation errors; it is best to leave this untouched in most cases.</param>
|
||||||
/// <returns>An SeString containing all of the payloads necessary to display a map link in the chat log.</returns>
|
/// <returns>An SeString containing all of the payloads necessary to display a map link in the chat log.</returns>
|
||||||
public static SeString CreateMapLink(string placeName, float xCoord, float yCoord, float fudgeFactor = 0.05f)
|
public SeString CreateMapLink(string placeName, float xCoord, float yCoord, float fudgeFactor = 0.05f)
|
||||||
{
|
{
|
||||||
var mapSheet = SeString.Dalamud.Data.GetExcelSheet<Map>();
|
var mapSheet = this.data.GetExcelSheet<Map>();
|
||||||
|
|
||||||
var matches = SeString.Dalamud.Data.GetExcelSheet<PlaceName>().GetRows()
|
var matches = this.data.GetExcelSheet<PlaceName>().GetRows()
|
||||||
.Where(row => row.Name.ToLowerInvariant() == placeName.ToLowerInvariant())
|
.Where(row => row.Name.ToLowerInvariant() == placeName.ToLowerInvariant())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
foreach (var place in matches)
|
foreach (var place in matches)
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +93,7 @@ namespace Dalamud.Game {
|
||||||
this.dalamud = dalamud;
|
this.dalamud = dalamud;
|
||||||
|
|
||||||
dalamud.Framework.Gui.Chat.OnCheckMessageHandled += OnCheckMessageHandled;
|
dalamud.Framework.Gui.Chat.OnCheckMessageHandled += OnCheckMessageHandled;
|
||||||
dalamud.Framework.Gui.Chat.OnChatMessageRaw += OnChatMessage;
|
dalamud.Framework.Gui.Chat.OnChatMessage += OnChatMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCheckMessageHandled(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool isHandled) {
|
private void OnCheckMessageHandled(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool isHandled) {
|
||||||
|
|
@ -121,8 +121,8 @@ namespace Dalamud.Game {
|
||||||
|
|
||||||
public string LastLink { get; private set; }
|
public string LastLink { get; private set; }
|
||||||
|
|
||||||
private void OnChatMessage(XivChatType type, uint senderId, ref StdString sender,
|
private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender,
|
||||||
ref StdString message, ref bool isHandled) {
|
ref SeString message, ref bool isHandled) {
|
||||||
|
|
||||||
if (type == XivChatType.Notice && !this.hasSeenLoadingMsg)
|
if (type == XivChatType.Notice && !this.hasSeenLoadingMsg)
|
||||||
PrintWelcomeMessage();
|
PrintWelcomeMessage();
|
||||||
|
|
@ -136,14 +136,11 @@ namespace Dalamud.Game {
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var messageVal = message.Value;
|
|
||||||
var senderVal = sender.Value;
|
|
||||||
|
|
||||||
if (type == XivChatType.RetainerSale)
|
if (type == XivChatType.RetainerSale)
|
||||||
{
|
{
|
||||||
foreach (var regex in retainerSaleRegexes[dalamud.StartInfo.Language])
|
foreach (var regex in retainerSaleRegexes[dalamud.StartInfo.Language])
|
||||||
{
|
{
|
||||||
var matchInfo = regex.Match(message.Value);
|
var matchInfo = regex.Match(message.TextValue);
|
||||||
|
|
||||||
// we no longer really need to do/validate the item matching since we read the id from the byte array
|
// we no longer really need to do/validate the item matching since we read the id from the byte array
|
||||||
// but we'd be checking the main match anyway
|
// but we'd be checking the main match anyway
|
||||||
|
|
@ -152,10 +149,10 @@ namespace Dalamud.Game {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var itemLink =
|
var itemLink =
|
||||||
SeString.Parse(message.RawData).Payloads.First(x => x.Type == PayloadType.Item) as ItemPayload;
|
message.Payloads.First(x => x.Type == PayloadType.Item) as ItemPayload;
|
||||||
|
|
||||||
if (itemLink == null) {
|
if (itemLink == null) {
|
||||||
Log.Error("itemLink was null. Msg: {0}", BitConverter.ToString(message.RawData));
|
Log.Error("itemLink was null. Msg: {0}", BitConverter.ToString(message.Encode()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,12 +173,13 @@ namespace Dalamud.Game {
|
||||||
Task.Run(() => this.dalamud.BotManager.ProcessChatMessage(type, messageCopy, senderCopy));
|
Task.Run(() => this.dalamud.BotManager.ProcessChatMessage(type, messageCopy, senderCopy));
|
||||||
|
|
||||||
// Handle all of this with SeString some day
|
// Handle all of this with SeString some day
|
||||||
|
/*
|
||||||
if ((this.HandledChatTypeColors.ContainsKey(type) || type == XivChatType.Say || type == XivChatType.Shout ||
|
if ((this.HandledChatTypeColors.ContainsKey(type) || type == XivChatType.Say || type == XivChatType.Shout ||
|
||||||
type == XivChatType.Alliance || type == XivChatType.TellOutgoing || type == XivChatType.Yell) && !message.Value.Contains((char)0x02)) {
|
type == XivChatType.Alliance || type == XivChatType.TellOutgoing || type == XivChatType.Yell)) {
|
||||||
var italicsStart = message.Value.IndexOf("*");
|
var italicsStart = message.TextValue.IndexOf("*", StringComparison.InvariantCulture);
|
||||||
var italicsEnd = message.Value.IndexOf("*", italicsStart + 1);
|
var italicsEnd = message.TextValue.IndexOf("*", italicsStart + 1, StringComparison.InvariantCulture);
|
||||||
|
|
||||||
var messageString = message.Value;
|
var messageString = message.TextValue;
|
||||||
|
|
||||||
while (italicsEnd != -1) {
|
while (italicsEnd != -1) {
|
||||||
var it = MakeItalics(
|
var it = MakeItalics(
|
||||||
|
|
@ -194,9 +192,9 @@ namespace Dalamud.Game {
|
||||||
|
|
||||||
message.RawData = Encoding.UTF8.GetBytes(messageString);
|
message.RawData = Encoding.UTF8.GetBytes(messageString);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var linkMatch = this.urlRegex.Match(message.TextValue);
|
||||||
var linkMatch = this.urlRegex.Match(message.Value);
|
|
||||||
if (linkMatch.Value.Length > 0)
|
if (linkMatch.Value.Length > 0)
|
||||||
LastLink = linkMatch.Value;
|
LastLink = linkMatch.Value;
|
||||||
}
|
}
|
||||||
|
|
@ -244,7 +242,7 @@ namespace Dalamud.Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string MakeItalics(string text) {
|
private static SeString MakeItalics(string text) {
|
||||||
// TODO: when the above code is switched to SeString, this can be a straight insertion of the
|
// TODO: when the above code is switched to SeString, this can be a straight insertion of the
|
||||||
// italics payloads only, and be a lot cleaner
|
// italics payloads only, and be a lot cleaner
|
||||||
var italicString = new SeString(new List<Payload>(new Payload[]
|
var italicString = new SeString(new List<Payload>(new Payload[]
|
||||||
|
|
@ -254,7 +252,7 @@ namespace Dalamud.Game {
|
||||||
EmphasisItalicPayload.ItalicsOff
|
EmphasisItalicPayload.ItalicsOff
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(italicString.Encode());
|
return italicString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,8 +116,8 @@ namespace Dalamud.Game.Internal.Gui {
|
||||||
var sender = StdString.ReadFromPointer(pSenderName);
|
var sender = StdString.ReadFromPointer(pSenderName);
|
||||||
var message = StdString.ReadFromPointer(pMessage);
|
var message = StdString.ReadFromPointer(pMessage);
|
||||||
|
|
||||||
var parsedSender = SeString.Parse(sender.RawData);
|
var parsedSender = this.dalamud.SeStringManager.Parse(sender.RawData);
|
||||||
var parsedMessage = SeString.Parse(message.RawData);
|
var parsedMessage = this.dalamud.SeStringManager.Parse(message.RawData);
|
||||||
|
|
||||||
Log.Verbose("[CHATGUI][{0}][{1}]", parsedSender.TextValue, parsedMessage.TextValue);
|
Log.Verbose("[CHATGUI][{0}][{1}]", parsedSender.TextValue, parsedMessage.TextValue);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue