Skip to content

Commit 1fad875

Browse files
authored
Merge pull request PCL-Community#54 from LaoSparrow/main
feat: Minecraft metadata file parsing
2 parents 4231839 + 13aa185 commit 1fad875

File tree

6 files changed

+538
-0
lines changed

6 files changed

+538
-0
lines changed

PCL2.Neo.Tests/GlobalUsings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
global using NUnit.Framework;
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
using PCL2.Neo.Models.Minecraft;
2+
using System.Text.Json.Nodes;
3+
4+
namespace PCL2.Neo.Tests.Models.Minecraft;
5+
6+
public class MetadataFileTest
7+
{
8+
[Test]
9+
public void MainParsingTest()
10+
{
11+
foreach (var metadataFilePath in Directory.EnumerateFiles("./MCMetadataFiles"))
12+
{
13+
var jsonObj = JsonNode.Parse(File.ReadAllText(metadataFilePath))!.AsObject();
14+
var meta = new MetadataFile(jsonObj, false);
15+
meta.Parse();
16+
Assert.That(meta.Arguments.Game, Is.Not.Empty);
17+
if (jsonObj.ContainsKey("arguments"))
18+
{
19+
Assert.That(meta.Arguments.Game.Count, Is.EqualTo(jsonObj["arguments"]!["game"]!.AsArray().Count));
20+
}
21+
22+
Assert.Multiple(() =>
23+
{
24+
Assert.That(meta.Assets, Is.Not.Empty);
25+
Assert.That(meta.AssetIndex.Id, Is.Not.Empty);
26+
Assert.That(meta.AssetIndex.Path, Is.Null);
27+
Assert.That(meta.AssetIndex.Sha1, Is.Not.Empty);
28+
Assert.That(meta.AssetIndex.Size, Is.Not.EqualTo(0));
29+
Assert.That(meta.AssetIndex.TotalSize, Is.Not.EqualTo(0));
30+
});
31+
Assert.That(meta.Downloads, Is.Not.Empty);
32+
foreach ((string id, MetadataFile.RemoteFileModel file) in meta.Downloads)
33+
{
34+
Assert.Multiple(() =>
35+
{
36+
Assert.That(id, Is.Not.Empty);
37+
Assert.That(file.Path, Is.Null);
38+
Assert.That(file.Sha1, Is.Not.Empty);
39+
Assert.That(file.Size, Is.Not.EqualTo(0));
40+
Assert.That(file.Url, Is.Not.Empty);
41+
});
42+
}
43+
44+
Assert.That(meta.Id, Is.Not.Empty);
45+
Assert.Multiple(() =>
46+
{
47+
if (meta.JavaVersion is null)
48+
return;
49+
Assert.That(meta.JavaVersion.Component, Is.Not.Empty);
50+
Assert.That(meta.JavaVersion.MajorVersion, Is.Not.EqualTo(0));
51+
});
52+
Assert.That(meta.Libraries.Count, Is.EqualTo(jsonObj["libraries"]!.AsArray().Count));
53+
Assert.Multiple(() =>
54+
{
55+
if (meta.Logging is null)
56+
return;
57+
Assert.That(meta.Logging, Is.Not.Empty);
58+
foreach ((string id, MetadataFile.LoggingModel logging) in meta.Logging)
59+
{
60+
Assert.That(id, Is.Not.Empty);
61+
Assert.That(logging.Argument, Is.Not.Empty);
62+
Assert.That(logging.File, Is.Not.Null);
63+
Assert.Multiple(() =>
64+
{
65+
Assert.That(logging.File.Id, Is.Not.Empty);
66+
Assert.That(logging.File.Path, Is.Null);
67+
Assert.That(logging.File.Sha1, Is.Not.Empty);
68+
Assert.That(logging.File.Size, Is.Not.EqualTo(0));
69+
Assert.That(logging.File.Url, Is.Not.Empty);
70+
});
71+
Assert.That(logging.Type, Is.Not.Empty);
72+
}
73+
});
74+
Assert.That(meta.MainClass, Is.Not.Empty);
75+
Assert.That(meta.MinimumLauncherVersion, Is.Not.EqualTo(0));
76+
Assert.That(meta.ReleaseTime, Is.Not.Empty);
77+
Assert.That(meta.Time, Is.Not.Empty);
78+
Assert.That(meta.Type, Is.Not.EqualTo(MetadataFile.ReleaseTypeEnum.Unknown));
79+
}
80+
}
81+
82+
[Test]
83+
public void ArgumentsParsingTest()
84+
{
85+
object[] testGameArgs =
86+
[
87+
"--username",
88+
"${auth_player_name}",
89+
"--version",
90+
"${version_name}",
91+
"--gameDir",
92+
"${game_directory}",
93+
"--assetsDir",
94+
"${assets_root}",
95+
"--assetIndex",
96+
"${assets_index_name}",
97+
"--uuid",
98+
"${auth_uuid}",
99+
"--accessToken",
100+
"${auth_access_token}",
101+
"--clientId",
102+
"${clientid}",
103+
"--xuid",
104+
"${auth_xuid}",
105+
"--userType",
106+
"${user_type}",
107+
"--versionType",
108+
"${version_type}",
109+
new MetadataFile.ConditionalArg
110+
{
111+
Rules =
112+
[
113+
new MetadataFile.Rule
114+
{
115+
Action = MetadataFile.Rule.ActionEnum.Allow,
116+
Features = new Dictionary<string, bool> { ["is_demo_user"] = true }
117+
}
118+
],
119+
Value = ["--demo"]
120+
},
121+
new MetadataFile.ConditionalArg
122+
{
123+
Rules =
124+
[
125+
new MetadataFile.Rule
126+
{
127+
Action = MetadataFile.Rule.ActionEnum.Allow,
128+
Features = new Dictionary<string, bool> { ["has_custom_resolution"] = true }
129+
}
130+
],
131+
Value =
132+
[
133+
"--width",
134+
"${resolution_width}",
135+
"--height",
136+
"${resolution_height}"
137+
]
138+
},
139+
new MetadataFile.ConditionalArg
140+
{
141+
Rules =
142+
[
143+
new MetadataFile.Rule
144+
{
145+
Action = MetadataFile.Rule.ActionEnum.Allow,
146+
Features = new Dictionary<string, bool> { ["has_quick_plays_support"] = true }
147+
}
148+
],
149+
Value =
150+
[
151+
"--quickPlayPath",
152+
"${quickPlayPath}"
153+
]
154+
},
155+
new MetadataFile.ConditionalArg
156+
{
157+
Rules =
158+
[
159+
new MetadataFile.Rule
160+
{
161+
Action = MetadataFile.Rule.ActionEnum.Allow,
162+
Features = new Dictionary<string, bool> { ["is_quick_play_singleplayer"] = true }
163+
}
164+
],
165+
Value =
166+
[
167+
"--quickPlaySingleplayer",
168+
"${quickPlaySingleplayer}"
169+
]
170+
},
171+
new MetadataFile.ConditionalArg
172+
{
173+
Rules =
174+
[
175+
new MetadataFile.Rule
176+
{
177+
Action = MetadataFile.Rule.ActionEnum.Allow,
178+
Features = new Dictionary<string, bool> { ["is_quick_play_multiplayer"] = true }
179+
}
180+
],
181+
Value =
182+
[
183+
"--quickPlayMultiplayer",
184+
"${quickPlayMultiplayer}"
185+
]
186+
},
187+
new MetadataFile.ConditionalArg
188+
{
189+
Rules =
190+
[
191+
new MetadataFile.Rule
192+
{
193+
Action = MetadataFile.Rule.ActionEnum.Allow,
194+
Features = new Dictionary<string, bool> { ["is_quick_play_realms"] = true }
195+
}
196+
],
197+
Value =
198+
[
199+
"--quickPlayRealms",
200+
"${quickPlayRealms}"
201+
]
202+
}
203+
];
204+
205+
var jsonObj = JsonNode.Parse(File.ReadAllText("./MCMetadataFiles/1.21.5.json"))!.AsObject();
206+
var meta = new MetadataFile(jsonObj, false);
207+
meta.Parse();
208+
Assert.That(meta.Arguments.Game.Count, Is.EqualTo(testGameArgs.Length));
209+
for (int i = 0; i < meta.Arguments.Game.Count; i++)
210+
{
211+
if (testGameArgs[i] is string)
212+
{
213+
Assert.That(meta.Arguments.Game[i].Value.Count, Is.EqualTo(1));
214+
Assert.That(meta.Arguments.Game[i].Value[0], Is.EqualTo(testGameArgs[i]));
215+
}
216+
else
217+
{
218+
var arg = meta.Arguments.Game[i];
219+
var testArg = (MetadataFile.ConditionalArg)testGameArgs[i];
220+
221+
Assert.That(arg.Value.SequenceEqual(testArg.Value), Is.True);
222+
Assert.That(
223+
(arg.Rules is null && testArg.Rules is null) ||
224+
(arg.Rules is not null && testArg.Rules is not null));
225+
if (arg.Rules is not null && testArg.Rules is not null)
226+
{
227+
Assert.That(arg.Rules.Count, Is.EqualTo(testArg.Rules.Count));
228+
foreach ((MetadataFile.Rule rule, MetadataFile.Rule testRule) in arg.Rules.Zip(testArg.Rules))
229+
{
230+
Assert.That(rule.Action, Is.EqualTo(testRule.Action));
231+
Assert.That((rule.Features is null && testRule.Features is null) ||
232+
(rule.Features is not null && testRule.Features is not null));
233+
if (rule.Features is not null && testRule.Features is not null)
234+
Assert.That(rule.Features.SequenceEqual(testRule.Features));
235+
Assert.That((rule.Os is null && testRule.Os is null) ||
236+
(rule.Os is not null && testRule.Os is not null));
237+
if (rule.Os is not null && testRule.Os is not null)
238+
{
239+
Assert.That(rule.Os.Arch, Is.EqualTo(testRule.Os.Arch));
240+
Assert.That(rule.Os.Name, Is.EqualTo(testRule.Os.Name));
241+
Assert.That(rule.Os.Version, Is.EqualTo(testRule.Os.Version));
242+
}
243+
}
244+
}
245+
}
246+
}
247+
}
248+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
14+
<PackageReference Include="NUnit" Version="3.13.3"/>
15+
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1"/>
16+
<PackageReference Include="NUnit.Analyzers" Version="3.6.1"/>
17+
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\PCL2.Neo\PCL2.Neo.csproj" />
22+
</ItemGroup>
23+
24+
</Project>

PCL2.Neo.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.12.35527.113
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PCL2.Neo", "PCL2.Neo\PCL2.Neo.csproj", "{AF527853-D92E-44CE-A3EB-1E308C4FBFE2}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCL2.Neo.Tests", "PCL2.Neo.Tests\PCL2.Neo.Tests.csproj", "{438856D4-C249-4E5F-8AC1-07B5EF401DC0}"
9+
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1012
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
1517
{AF527853-D92E-44CE-A3EB-1E308C4FBFE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{AF527853-D92E-44CE-A3EB-1E308C4FBFE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{AF527853-D92E-44CE-A3EB-1E308C4FBFE2}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{438856D4-C249-4E5F-8AC1-07B5EF401DC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{438856D4-C249-4E5F-8AC1-07B5EF401DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{438856D4-C249-4E5F-8AC1-07B5EF401DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{438856D4-C249-4E5F-8AC1-07B5EF401DC0}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)