fix: crash when chat is processed before init, use DI for SeString stuff

This commit is contained in:
goat 2020-06-29 23:41:33 +02:00
parent 26ad4ce74b
commit 740ccfde11
14 changed files with 110 additions and 111 deletions

View file

@ -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() {

View file

@ -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;

View file

@ -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

View file

@ -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)
}; };

View file

@ -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;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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>

View file

@ -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)
{ {

View file

@ -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;
} }
} }
} }

View file

@ -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);