Skip to content

Commit 398b1b2

Browse files
committed
[Parser] Improve upstream parser compatibility
1 parent 33f87b4 commit 398b1b2

File tree

6 files changed

+63
-20
lines changed

6 files changed

+63
-20
lines changed

Libraries/ProtoZeroGenerator/ProtobufSourceGenerator.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ public override object VisitMessageDef(Protobuf3Parser.MessageDefContext context
217217
var fieldType = Parse(fieldTypeStr);
218218
var packedOption = field.fieldOptions()?.fieldOption()?.FirstOrDefault(o =>
219219
string.Equals(o.optionName().GetText(), "packed", StringComparison.OrdinalIgnoreCase));
220+
var asWellKnownWrapperOption = field.fieldOptions()?.fieldOption().FirstOrDefault(o =>
221+
string.Equals(o.optionName().GetText(), "AsWellKnownWrapper", StringComparison.OrdinalIgnoreCase));
220222
message.Fields.Add(new FieldDefinition
221223
{
222224
Name = GetUniqueFieldName(message.Name, field.fieldName().GetText().ToTitleCase()),
@@ -228,6 +230,9 @@ public override object VisitMessageDef(Protobuf3Parser.MessageDefContext context
228230
? string.Equals(packedOption.constant().GetText(), "true",
229231
StringComparison.OrdinalIgnoreCase)
230232
: fieldType.IsPackedByDefault(),
233+
AsWellKnownWrapper = asWellKnownWrapperOption != null &&
234+
string.Equals(asWellKnownWrapperOption.constant().GetText(), "true",
235+
StringComparison.OrdinalIgnoreCase),
231236
});
232237
}
233238
else if (element.oneof() is { } oneof)
@@ -590,6 +595,10 @@ string ReadType(ProtoType type, string reader)
590595
codeGenerator.OpenBlock($"case FieldIds.{field.Name}:");
591596
if (field.IsRepeated)
592597
{
598+
if (field.AsWellKnownWrapper)
599+
{
600+
throw new NotImplementedException("I didn't implement repeated well known wrappers yet");
601+
}
593602
if (field.IsPacked)
594603
{
595604
if (!field.Type.IsScalar)
@@ -644,7 +653,17 @@ string ReadType(ProtoType type, string reader)
644653
}
645654
else
646655
{
647-
codeGenerator.AppendLine($"{field.Name} = {ReadType(field.Type, "reader")};");
656+
if (field.AsWellKnownWrapper)
657+
{
658+
codeGenerator.AppendLine("var subReader = reader.ReadMessage();");
659+
codeGenerator.AppendLine("if (!subReader.Next()) break; ");
660+
codeGenerator.AppendLine("if (subReader.Tag != 1) { throw new InvalidOperationException(\"Can't read well known wrapper, because of an invalid tag\"); }");
661+
codeGenerator.AppendLine($"{field.Name} = {ReadType(field.Type, "subReader")};");
662+
}
663+
else
664+
{
665+
codeGenerator.AppendLine($"{field.Name} = {ReadType(field.Type, "reader")};");
666+
}
648667
}
649668
}
650669

@@ -841,6 +860,7 @@ public class FieldDefinition
841860
public bool IsOptional { get; set; }
842861
public bool IsOptionalPointer { get; set; } = true;
843862
public bool IsPacked { get; set; }
863+
public bool AsWellKnownWrapper { get; set; }
844864
}
845865

846866
public class EnumDefinition

WDE.PacketViewer/PacketParserIntegration/PacketParserService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ public async Task RunParser(string input, ParserConfiguration config, DumpFormat
183183
processStartInfo.WorkingDirectory = Path.GetDirectoryName(path)!;
184184
processStartInfo.UseShellExecute = false;
185185
processStartInfo.RedirectStandardOutput = true;
186+
processStartInfo.RedirectStandardError = true;
186187
processStartInfo.CreateNoWindow = true;
187188

188189
Process process = new Process();
@@ -192,11 +193,17 @@ public async Task RunParser(string input, ParserConfiguration config, DumpFormat
192193
if (float.TryParse(data.Data, out var p))
193194
progress.Report(p);
194195
};
196+
process.ErrorDataReceived += (sender, data) =>
197+
{
198+
if (data.Data != null)
199+
LOG.LogWarning(data.Data);
200+
};
195201

196202
if (!process.Start())
197203
throw new CouldNotRunParserException();
198204

199205
process.BeginOutputReadLine();
206+
process.BeginErrorReadLine();
200207
try
201208
{
202209
await process.WaitForExitAsync(token);

WDE.PacketViewer/PacketParserIntegration/SniffLoader.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
using WowPacketParser.PacketStructures;
1111
using WowPacketParser.Proto;
1212

13-
//using WowPacketParser.PacketStructures;
14-
1513
namespace WDE.PacketViewer.PacketParserIntegration
1614
{
1715
[AutoRegister]
@@ -59,9 +57,9 @@ public async Task<Packets> LoadSniff(RefCountedArena allocator, string path, int
5957
{
6058
var versionType = await GetVersionAndDump(parsedPath);
6159
runParser = !versionType.HasValue ||
62-
versionType.Value.Item1 != StructureVersion.ProtobufStructureVersion ||
63-
(versionType.Value.Item2 == DumpFormatType.UniversalProto && withText) ||
64-
(versionType.Value.Item2 == DumpFormatType.UniversalProtoWithSeparateText && !File.Exists(parsedTextPath));
60+
!ParserVersionCompatible(versionType.Value.Version) ||
61+
(versionType.Value.Format == DumpFormatType.UniversalProto && withText) ||
62+
(versionType.Value.Format == DumpFormatType.UniversalProtoWithSeparateText && !File.Exists(parsedTextPath));
6563
}
6664

6765
if (runParser)
@@ -74,15 +72,26 @@ public async Task<Packets> LoadSniff(RefCountedArena allocator, string path, int
7472
}
7573
}
7674
path = parsedPath;
75+
var versionType2 = await GetVersionAndDump(path);
76+
if (!versionType2.HasValue)
77+
{
78+
throw new ParserException("Parser didn't generate the output file. Aborting. Open debug console (Help->Open Debug Console) and report the issue on github.");
79+
}
80+
81+
if (!ParserVersionCompatible(versionType2.Value.Version))
82+
{
83+
throw new ParserException(
84+
$"Your parser generated an output file in a different format ({versionType2.Value.Item1}) than expected (>= {StructureVersion.MinProtobufStructureVersion} and <= {StructureVersion.MaxProtobufStructureVersion}). Aborting. If you downloaded the parser from the internet, make sure you have the latest version.");
85+
}
7786
}
7887
else if (extension == ".dat")
7988
{
8089
var parsedTextPath = Path.ChangeExtension(path, "txt");
8190
var versionType = await GetVersionAndDump(path);
8291
bool runParser = !versionType.HasValue ||
83-
versionType.Value.Item1 != StructureVersion.ProtobufStructureVersion ||
84-
(versionType.Value.Item2 == DumpFormatType.UniversalProto && withText) ||
85-
(versionType.Value.Item2 == DumpFormatType.UniversalProtoWithSeparateText && !File.Exists(parsedTextPath));
92+
!ParserVersionCompatible(versionType.Value.Version) ||
93+
(versionType.Value.Format == DumpFormatType.UniversalProto && withText) ||
94+
(versionType.Value.Format == DumpFormatType.UniversalProtoWithSeparateText && !File.Exists(parsedTextPath));
8695

8796
if (runParser)
8897
{
@@ -124,6 +133,12 @@ public async Task<Packets> LoadSniff(RefCountedArena allocator, string path, int
124133
return packets;
125134
}
126135

136+
private bool ParserVersionCompatible(ulong version)
137+
{
138+
return version >= StructureVersion.MinProtobufStructureVersion &&
139+
version <= StructureVersion.MaxProtobufStructureVersion;
140+
}
141+
127142
private bool IsFileInUse(string path)
128143
{
129144
if (!File.Exists(path))
@@ -141,7 +156,7 @@ private bool IsFileInUse(string path)
141156
return false;
142157
}
143158

144-
public unsafe Task<(ulong, DumpFormatType)?> GetVersionAndDump(string path)
159+
public unsafe Task<(ulong Version, DumpFormatType Format)?> GetVersionAndDump(string path)
145160
{
146161
using var input = File.OpenRead(path);
147162
var firstBytes = new byte[100]; // enough for the header

WDE.PacketViewer/PacketStructures/StructureVersion.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public class StructureVersion
66
* Everytime you change structures.proto, please increment this version
77
* so that user could know if one needs to reparse the sniff
88
*/
9-
public static readonly ulong ProtobufStructureVersion = 21;
9+
public static readonly ulong MinProtobufStructureVersion = 20;
10+
public static readonly ulong MaxProtobufStructureVersion = 21;
1011
}
1112
}

WDE.PacketViewer/PacketStructures/structures.proto

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ message PacketBase {
2828
string opcode = 2;
2929
google.protobuf.Timestamp time = 3;
3030
string stringData = 4;
31-
optional int64 textStartOffset = 5;
32-
int32 textLength = 6;
31+
optional int64 textStartOffset = 5 [AsWellKnownWrapper = true];
32+
int32 textLength = 6 [AsWellKnownWrapper = true];
3333
optional int64 headerTextStartOffset = 900;
3434
int32 headerTextLength = 901;
3535
bool isFirstPacketWithThisHeader = 902;
@@ -709,23 +709,23 @@ message CreateObject {
709709
optional StationaryPositionData stationary = 6;
710710
optional VehicleCreate vehicle = 7;
711711
optional Quat rotation = 8;
712-
optional int32 textStartOffset = 9;
713-
optional int32 textLength = 10;
712+
optional int32 textStartOffset = 9 [AsWellKnownWrapper = true];
713+
optional int32 textLength = 10 [AsWellKnownWrapper = true];
714714
optional string text = 11;
715715
}
716716

717717
message UpdateObject {
718718
UniversalGuid guid = 1;
719719
UpdateValues values = 2;
720-
optional int32 textStartOffset = 3;
721-
optional int32 textLength = 4;
720+
optional int32 textStartOffset = 3 [AsWellKnownWrapper = true];
721+
optional int32 textLength = 4 [AsWellKnownWrapper = true];
722722
optional string text = 5;
723723
}
724724

725725
message DestroyedObject {
726726
UniversalGuid guid = 1;
727-
optional int32 textStartOffset = 2;
728-
optional int32 textLength = 3;
727+
optional int32 textStartOffset = 2 [AsWellKnownWrapper = true];
728+
optional int32 textLength = 3 [AsWellKnownWrapper = true];
729729
optional string text = 4;
730730
}
731731

WoWPacketParser

Submodule WoWPacketParser updated 181 files

0 commit comments

Comments
 (0)