Initial commit

This commit is contained in:
goat 2019-09-21 22:29:38 +09:00
commit ac838687f8
157 changed files with 27905 additions and 0 deletions

View file

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Dalamud.Game.Chat {
// TODO: This class does not work - it's a hack, needs a revamp and better handling for payloads used in player chat
public class SeString {
public enum PlayerLinkType {
ItemLink = 0x03
}
public enum SeStringPayloadType {
PlayerLink = 0x27
}
private const int START_BYTE = 0x02;
private const int END_BYTE = 0x03;
public static (string Output, List<SeStringPayloadContainer> Payloads) Parse(string input) {
var output = new List<byte>();
var payloads = new List<SeStringPayloadContainer>();
var bytes = Encoding.UTF8.GetBytes(input);
using (var stream = new MemoryStream(bytes))
using (var reader = new BinaryReader(stream)) {
while (stream.Position < bytes.Length) {
var b = stream.ReadByte();
if (b == START_BYTE)
ProcessPacket(reader, output, payloads);
else
output.Add((byte) b);
}
}
return (Encoding.UTF8.GetString(output.ToArray()), payloads);
}
private static void ProcessPacket(BinaryReader reader, List<byte> output,
List<SeStringPayloadContainer> payloads) {
var type = reader.ReadByte();
var payloadSize = GetInteger(reader);
var payload = new byte[payloadSize];
reader.Read(payload, 0, payloadSize);
var orphanByte = reader.Read();
// If the end of the tag isn't what we predicted, let's ignore it for now
while (orphanByte != END_BYTE) orphanByte = reader.Read();
//output.AddRange(Encoding.UTF8.GetBytes($"<{type.ToString("X")}:{BitConverter.ToString(payload)}>"));
switch ((SeStringPayloadType) type) {
case SeStringPayloadType.PlayerLink:
if (payload[0] == (byte) PlayerLinkType.ItemLink)
payloads.Add(new SeStringPayloadContainer {
Type = SeStringPayloadType.PlayerLink,
Param1 = BitConverter.ToInt16(payload, 4)
});
break;
}
}
public class SeStringPayloadContainer {
public SeStringPayloadType Type { get; set; }
public object Param1 { get; set; }
}
#region Shared
public enum IntegerType {
Byte = 0xF0,
ByteTimes256 = 0xF1,
Int16 = 0xF2,
Int24 = 0xFA,
Int32 = 0xFE
}
protected static int GetInteger(BinaryReader input) {
var t = input.ReadByte();
var type = (IntegerType) t;
return GetInteger(input, type);
}
protected static int GetInteger(BinaryReader input, IntegerType type) {
const byte ByteLengthCutoff = 0xF0;
var t = (byte) type;
if (t < ByteLengthCutoff)
return t - 1;
switch (type) {
case IntegerType.Byte:
return input.ReadByte();
case IntegerType.ByteTimes256:
return input.ReadByte() * 256;
case IntegerType.Int16: {
var v = 0;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
}
case IntegerType.Int24: {
var v = 0;
v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
}
case IntegerType.Int32: {
var v = 0;
v |= input.ReadByte() << 24;
v |= input.ReadByte() << 16;
v |= input.ReadByte() << 8;
v |= input.ReadByte();
return v;
}
default:
throw new NotSupportedException();
}
}
#endregion
}
}

View file

@ -0,0 +1,15 @@
using System;
namespace Dalamud.Game.Chat {
public sealed class XivChatEntry {
public XivChatType Type { get; set; } = XivChatType.Debug;
public uint SenderId { get; set; }
public string Name { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
public IntPtr Parameters { get; set; }
}
}

View file

@ -0,0 +1,132 @@
using System;
using System.Linq;
namespace Dalamud.Game.Chat {
/// <summary>
/// The FFXIV chat types as seen in the LogKind ex table.
/// </summary>
public enum XivChatType : ushort {
None = 0,
Debug = 1,
[XivChatTypeInfo("Urgent", null, 0xFF9400D3)]
Urgent = 2,
[XivChatTypeInfo("Notice", null, 0xFF9400D3)]
Notice = 3,
[XivChatTypeInfo("Say", "s", 0xFFFFFFFF)]
Say = 10,
[XivChatTypeInfo("Shout", "shout", 0xFFFF4500)]
Shout = 11,
TellOutgoing = 12,
[XivChatTypeInfo("Tell", "tell", 0xFFFF69B4)]
TellIncoming = 13,
[XivChatTypeInfo("Party", "p", 0xFF1E90FF)]
Party = 14,
[XivChatTypeInfo("Alliance", "a", 0xFFFF4500)]
Alliance = 15,
[XivChatTypeInfo("Linkshell 1", "ls1", 0xFF228B22)]
Ls1 = 16,
[XivChatTypeInfo("Linkshell 2", "ls2", 0xFF228B22)]
Ls2 = 17,
[XivChatTypeInfo("Linkshell 3", "ls3", 0xFF228B22)]
Ls3 = 18,
[XivChatTypeInfo("Linkshell 4", "ls4", 0xFF228B22)]
Ls4 = 19,
[XivChatTypeInfo("Linkshell 5", "ls5", 0xFF228B22)]
Ls5 = 20,
[XivChatTypeInfo("Linkshell 6", "ls6", 0xFF228B22)]
Ls6 = 21,
[XivChatTypeInfo("Linkshell 7", "ls7", 0xFF228B22)]
Ls7 = 22,
[XivChatTypeInfo("Linkshell 8", "ls8", 0xFF228B22)]
Ls8 = 23,
[XivChatTypeInfo("Free Company", "fc", 0xFF00BFFF)]
FreeCompany = 24,
[XivChatTypeInfo("Novice Network", "nn", 0xFF8B4513)]
NoviceNetwork = 27,
[XivChatTypeInfo("Yell", "y", 0xFFFFFF00)]
Yell = 30,
[XivChatTypeInfo("Party", "p", 0xFF1E90FF)]
CrossParty = 32,
[XivChatTypeInfo("PvP Team", "pvp", 0xFFF4A460)]
PvPTeam = 36,
[XivChatTypeInfo("Crossworld Linkshell 1", "cw1", 0xFF1E90FF)]
CrossLinkShell1 = 37,
[XivChatTypeInfo("Echo", null, 0xFF808080)]
Echo = 56,
SystemError = 58,
GatheringSystemMessage = 60,
[XivChatTypeInfo("Crossworld Linkshell 2", "cw2", 0xFF1E90FF)]
CrossLinkShell2 = 101,
[XivChatTypeInfo("Crossworld Linkshell 3", "cw3", 0xFF1E90FF)]
CrossLinkShell3 = 102,
[XivChatTypeInfo("Crossworld Linkshell 4", "cw4", 0xFF1E90FF)]
CrossLinkShell4 = 103,
[XivChatTypeInfo("Crossworld Linkshell 5", "cw5", 0xFF1E90FF)]
CrossLinkShell5 = 104,
[XivChatTypeInfo("Crossworld Linkshell 6", "cw6", 0xFF1E90FF)]
CrossLinkShell6 = 105,
[XivChatTypeInfo("Crossworld Linkshell 7", "cw7", 0xFF1E90FF)]
CrossLinkShell7 = 106,
[XivChatTypeInfo("Crossworld Linkshell 8", "cw8", 0xFF1E90FF)]
CrossLinkShell8 = 107
}
public static class XivChatTypeExtensions {
public static XivChatTypeInfoAttribute GetDetails(this XivChatType p) {
return p.GetAttribute<XivChatTypeInfoAttribute>();
}
}
public class XivChatTypeInfoAttribute : Attribute {
internal XivChatTypeInfoAttribute(string fancyName, string slug, uint defaultColor) {
FancyName = fancyName;
Slug = slug;
DefaultColor = defaultColor;
}
public string FancyName { get; }
public string Slug { get; }
public uint DefaultColor { get; }
}
public static class EnumExtensions {
public static TAttribute GetAttribute<TAttribute>(this Enum value)
where TAttribute : Attribute {
var type = value.GetType();
var name = Enum.GetName(type, value);
return type.GetField(name) // I prefer to get attributes this way
.GetCustomAttributes(false)
.OfType<TAttribute>()
.SingleOrDefault();
}
}
}