private static Payload DecodeChunk(BinaryReader reader) { Payload payload = null; reader.ReadByte(); // START_BYTE var chunkType = (SeStringChunkType)reader.ReadByte(); var chunkLen = GetInteger(reader); var packetStart = reader.BaseStream.Position; // any unhandled payload types will be turned into a RawPayload with the exact same binary data switch (chunkType) { case SeStringChunkType.EmphasisItalic: payload = new EmphasisItalicPayload(); break; case SeStringChunkType.SeHyphen: payload = SeHyphenPayload.Payload; break; case SeStringChunkType.Interactable: { var subType = (EmbeddedInfoType)reader.ReadByte(); switch (subType) { case EmbeddedInfoType.PlayerName: payload = new PlayerPayload(); break; case EmbeddedInfoType.ItemLink: payload = new ItemPayload(); break; case EmbeddedInfoType.MapPositionLink: payload = new MapLinkPayload(); break; case EmbeddedInfoType.Status: payload = new StatusPayload(); break; case EmbeddedInfoType.QuestLink: payload = new QuestPayload(); break; case EmbeddedInfoType.DalamudLink: payload = new DalamudLinkPayload(); break; case EmbeddedInfoType.LinkTerminator: // this has no custom handling and so needs to fallthrough to ensure it is captured default: // but I'm also tired of this log if (subType != EmbeddedInfoType.LinkTerminator) { Log.Verbose("Unhandled EmbeddedInfoType: {0}", subType); } // rewind so we capture the Interactable byte in the raw data reader.BaseStream.Seek(-1, SeekOrigin.Current); break; } } break; case SeStringChunkType.AutoTranslateKey: payload = new AutoTranslatePayload(); break; case SeStringChunkType.UIForeground: payload = new UIForegroundPayload(); break; case SeStringChunkType.UIGlow: payload = new UIGlowPayload(); break; case SeStringChunkType.Icon: payload = new IconPayload(); break; default: Log.Verbose("Unhandled SeStringChunkType: {0}", chunkType); break; } payload ??= new RawPayload((byte)chunkType); payload.DecodeImpl(reader, reader.BaseStream.Position + chunkLen - 1); // read through the rest of the packet var readBytes = (uint)(reader.BaseStream.Position - packetStart); reader.ReadBytes((int)(chunkLen - readBytes + 1)); // +1 for the END_BYTE marker return(payload); }
private static Payload ProcessChunk(BinaryReader reader) { Payload payload = null; reader.ReadByte(); // START_BYTE var chunkType = (SeStringChunkType)reader.ReadByte(); var chunkLen = GetInteger(reader); var packetStart = reader.BaseStream.Position; switch (chunkType) { case SeStringChunkType.Interactable: { var subType = (EmbeddedInfoType)reader.ReadByte(); switch (subType) { case EmbeddedInfoType.PlayerName: payload = new PlayerPayload(); break; case EmbeddedInfoType.ItemLink: payload = new ItemPayload(); break; case EmbeddedInfoType.MapPositionLink: payload = new MapLinkPayload(); break; case EmbeddedInfoType.Status: payload = new StatusPayload(); break; case EmbeddedInfoType.LinkTerminator: // this has no custom handling and so needs to fallthrough to ensure it is captured default: Log.Verbose("Unhandled EmbeddedInfoType: {0}", subType); // rewind so we capture the Interactable byte in the raw data reader.BaseStream.Seek(-1, SeekOrigin.Current); payload = new RawPayload((byte)chunkType); break; } } break; case SeStringChunkType.AutoTranslateKey: payload = new AutoTranslatePayload(); break; case SeStringChunkType.UIForeground: payload = new UIForegroundPayload(); break; case SeStringChunkType.UIGlow: payload = new UIGlowPayload(); break; default: Log.Verbose("Unhandled SeStringChunkType: {0}", chunkType); payload = new RawPayload((byte)chunkType); break; } payload?.ProcessChunkImpl(reader, reader.BaseStream.Position + chunkLen - 1); // read through the rest of the packet var readBytes = (uint)(reader.BaseStream.Position - packetStart); reader.ReadBytes((int)(chunkLen - readBytes + 1)); // +1 for the END_BYTE marker return(payload); }