Skip to content

Commit af55ced

Browse files
committed
Generate project files for multi-version projects correctly.
1 parent 7a34c5b commit af55ced

27 files changed

+640
-104
lines changed

UnityModStudio.Build/Tasks/AddGameToRegistry.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public override bool Execute()
4848
GameExecutableFileName = gameInformation.GameExecutableFile.Name,
4949
Architecture = gameInformation.Architecture.ToString(),
5050
UnityVersion = gameInformation.UnityVersion,
51+
TargetFrameworkMoniker = gameInformation.TargetFrameworkMoniker,
5152
MonoProfile = gameInformation.GetMonoProfileString(),
5253
};
5354
if (TryParseEnum(ModDeploymentMode, nameof(ModDeploymentMode), out ModDeploymentMode modDeploymentMode))

UnityModStudio.Build/Tasks/UpdateGameRegistry.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public override bool Execute()
6161
match.Game.GameExecutableFileName = gameInformation.GameExecutableFile.Name;
6262
match.Game.Architecture = gameInformation.Architecture.ToString();
6363
match.Game.UnityVersion = gameInformation.UnityVersion;
64+
match.Game.TargetFrameworkMoniker = gameInformation.TargetFrameworkMoniker;
6465
match.Game.MonoProfile = gameInformation.GetMonoProfileString();
6566
}
6667
}

UnityModStudio.Build/Tasks/UpdateProjectFile.cs

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Xml.Linq;
1010
using Microsoft.Build.Framework;
1111
using Microsoft.Build.Utilities;
12+
using UnityModStudio.Common;
1213

1314
namespace UnityModStudio.Build.Tasks
1415
{
@@ -77,7 +78,7 @@ public override bool Execute()
7778
{
7879
inputStream.Position = 0;
7980
outputStream.Position = 0;
80-
if (AreStreamsDifferent(inputStream, outputStream))
81+
if (!Utils.AreStreamsEqual(inputStream, outputStream))
8182
{
8283
inputStream.Close();
8384

@@ -227,59 +228,6 @@ private static void SetComment(XElement element, string comment)
227228
commentNode.Value = comment;
228229
}
229230

230-
// Inspired by https://dev.to/emrahsungu/how-to-compare-two-files-using-net-really-really-fast-2pd9
231-
private static bool AreStreamsDifferent(Stream streamA, Stream streamB)
232-
{
233-
if (streamA.Length != streamB.Length)
234-
return true;
235-
236-
const int bufferLength = 4096 * 32;
237-
var bufferA = ArrayPool<byte>.Shared.Rent(bufferLength);
238-
var bufferB = ArrayPool<byte>.Shared.Rent(bufferLength);
239-
try
240-
{
241-
while (true)
242-
{
243-
var bytesReadA = ReadIntoBuffer(streamA, bufferA);
244-
var bytesReadB = ReadIntoBuffer(streamB, bufferB);
245-
246-
if (bytesReadA != bytesReadB)
247-
return true;
248-
249-
if (bytesReadA == 0)
250-
return false;
251-
252-
var totalProcessed = 0;
253-
while (totalProcessed < bufferA.Length)
254-
{
255-
if (!Vector.EqualsAll(new Vector<byte>(bufferA, totalProcessed), new Vector<byte>(bufferB, totalProcessed)))
256-
return true;
257-
258-
totalProcessed += Vector<byte>.Count;
259-
}
260-
}
261-
}
262-
finally
263-
{
264-
ArrayPool<byte>.Shared.Return(bufferA);
265-
ArrayPool<byte>.Shared.Return(bufferB);
266-
}
267-
268-
static int ReadIntoBuffer(Stream stream, byte[] buffer)
269-
{
270-
var totalBytesRead = 0;
271-
while (totalBytesRead < buffer.Length)
272-
{
273-
var bytesRead = stream.Read(buffer, totalBytesRead, buffer.Length - totalBytesRead);
274-
if (bytesRead == 0)
275-
return totalBytesRead;
276-
277-
totalBytesRead += bytesRead;
278-
}
279-
return totalBytesRead;
280-
}
281-
}
282-
283231

284232
[SuppressMessage("ReSharper", "UnusedMember.Local")]
285233
private enum ItemAction

UnityModStudio.Common.Tests/GameRegistryTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public async Task WhenLoadedFromValidFile_FillWithGames()
8686
Assert.AreEqual("Game1.exe", game1.GameExecutableFileName);
8787
Assert.AreEqual("X64", game1.Architecture);
8888
Assert.AreEqual("2022.3.22f1", game1.UnityVersion);
89+
Assert.IsNull(game1.TargetFrameworkMoniker);
8990
Assert.AreEqual(".NET Standard 2.1", game1.MonoProfile);
9091

9192
var game2 = gameRegistry.Games.ElementAt(1);
@@ -102,6 +103,7 @@ public async Task WhenLoadedFromValidFile_FillWithGames()
102103
Assert.AreEqual("Game2.exe", game2.GameExecutableFileName);
103104
Assert.AreEqual("X64", game2.Architecture);
104105
Assert.AreEqual("2018.4.36f1", game2.UnityVersion);
106+
Assert.IsNull(game2.TargetFrameworkMoniker);
105107
Assert.AreEqual(".NET 4.6", game2.MonoProfile);
106108

107109
var game3 = gameRegistry.Games.ElementAt(2);
@@ -118,6 +120,7 @@ public async Task WhenLoadedFromValidFile_FillWithGames()
118120
Assert.AreEqual("Game2.exe", game3.GameExecutableFileName);
119121
Assert.AreEqual("X64", game3.Architecture);
120122
Assert.AreEqual("2018.4.36f1", game3.UnityVersion);
123+
Assert.AreEqual("net46", game3.TargetFrameworkMoniker);
121124
Assert.AreEqual(".NET 4.6", game3.MonoProfile);
122125

123126
Assert.IsFalse(gameRegistry.WatchForChanges);
@@ -139,6 +142,28 @@ public async Task WhenSavingGame_WriteJson()
139142
VerifyGameResistryEquals("GameRegistry_SingleGameSaved.json");
140143
}
141144

145+
[TestMethod]
146+
public void WhenEnsureAllGamePropertiesInvoked_ResolveAllProperties()
147+
{
148+
IGameRegistry gameRegistry = new GameRegistry(_gameRegistryPath);
149+
var game = new Game
150+
{
151+
DisplayName = "Game 1",
152+
Path = Path.Combine(SampleGameInfo.DownloadPath, "2018-net4-v1.0"),
153+
GameName = "Unity2018Test",
154+
};
155+
gameRegistry.AddGame(game);
156+
157+
gameRegistry.EnsureAllGameProperties(game);
158+
159+
Assert.AreEqual("Unity2018Test", game.GameName);
160+
Assert.AreEqual("Unity2018Test.exe", game.GameExecutableFileName);
161+
Assert.AreEqual("X64", game.Architecture);
162+
Assert.AreEqual("2018.4.36f1", game.UnityVersion);
163+
Assert.AreEqual("net46", game.TargetFrameworkMoniker);
164+
Assert.AreEqual(".NET 4.6", game.MonoProfile);
165+
}
166+
142167
[TestMethod]
143168
public void WhenAddingGame_AddToGames()
144169
{

UnityModStudio.Common.Tests/Resources/GameRegistry_Initial.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"GameExecutableFileName": "Game2.exe",
4646
"Architecture": "X64",
4747
"UnityVersion": "2018.4.36f1",
48+
"TargetFrameworkMoniker": "net46",
4849
"MonoProfile": ".NET 4.6"
4950
}
5051
]

UnityModStudio.Common/Options/Game.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class Game
2323
public string? GameExecutableFileName { get; set; }
2424
public string? Architecture { get; set; }
2525
public string? UnityVersion { get; set; }
26+
public string? TargetFrameworkMoniker { get; set; }
2627
public string? MonoProfile { get; set; }
2728
}
2829
}

UnityModStudio.Common/Options/GameRegistry.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public interface IGameRegistry
1919

2020
void AddGame(Game game);
2121
void RemoveGame(Game game);
22+
void EnsureAllGameProperties(Game game);
2223
Game? FindGameById(Guid id);
2324
Game? FindGameByDisplayName(string name);
2425
GameMatchResult FindGameByProperties(IReadOnlyDictionary<string, string> properties, bool strictMatch);
@@ -79,6 +80,22 @@ private async void OnStoreChanged(object sender, FileSystemEventArgs e)
7980

8081
public void RemoveGame(Game game) => _games.Remove(game.Id);
8182

83+
public void EnsureAllGameProperties(Game game)
84+
{
85+
if (game is { GameName: not null, GameExecutableFileName: not null, Architecture: not null, UnityVersion: not null, TargetFrameworkMoniker: not null, MonoProfile: not null })
86+
return;
87+
88+
if (!GameInformationResolver.TryGetGameInformation(game.Path, out var gameInformation, out _))
89+
return;
90+
91+
game.GameName = gameInformation!.Name;
92+
game.GameExecutableFileName = gameInformation.GameExecutableFile.Name;
93+
game.Architecture = gameInformation.Architecture.ToString();
94+
game.UnityVersion = gameInformation.UnityVersion;
95+
game.TargetFrameworkMoniker = gameInformation.TargetFrameworkMoniker;
96+
game.MonoProfile = gameInformation.GetMonoProfileString();
97+
}
98+
8299
public Game? FindGameById(Guid id) => _games.TryGetValue(id, out var game) ? game : null;
83100

84101
public Game? FindGameByDisplayName(string name) => FindGamesByDisplayName(name).FirstOrDefault();

UnityModStudio.Common/Utils.cs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.IO;
1+
using System.Buffers;
2+
using System.IO;
3+
using System.Numerics;
24
using System.Text;
35

46
namespace UnityModStudio.Common
@@ -36,5 +38,58 @@ public static string AppendTrailingSlash(string path) =>
3638
sb[i] = '_';
3739
return sb.ToString();
3840
}
41+
42+
// Inspired by https://dev.to/emrahsungu/how-to-compare-two-files-using-net-really-really-fast-2pd9
43+
public static bool AreStreamsEqual(Stream streamA, Stream streamB)
44+
{
45+
if (streamA.Length != streamB.Length)
46+
return false;
47+
48+
const int bufferLength = 4096 * 32;
49+
var bufferA = ArrayPool<byte>.Shared.Rent(bufferLength);
50+
var bufferB = ArrayPool<byte>.Shared.Rent(bufferLength);
51+
try
52+
{
53+
while (true)
54+
{
55+
var bytesReadA = ReadIntoBuffer(streamA, bufferA);
56+
var bytesReadB = ReadIntoBuffer(streamB, bufferB);
57+
58+
if (bytesReadA != bytesReadB)
59+
return false;
60+
61+
if (bytesReadA == 0)
62+
return true;
63+
64+
var totalProcessed = 0;
65+
while (totalProcessed < bufferA.Length)
66+
{
67+
if (!Vector.EqualsAll(new Vector<byte>(bufferA, totalProcessed), new Vector<byte>(bufferB, totalProcessed)))
68+
return false;
69+
70+
totalProcessed += Vector<byte>.Count;
71+
}
72+
}
73+
}
74+
finally
75+
{
76+
ArrayPool<byte>.Shared.Return(bufferA);
77+
ArrayPool<byte>.Shared.Return(bufferB);
78+
}
79+
80+
static int ReadIntoBuffer(Stream stream, byte[] buffer)
81+
{
82+
var totalBytesRead = 0;
83+
while (totalBytesRead < buffer.Length)
84+
{
85+
var bytesRead = stream.Read(buffer, totalBytesRead, buffer.Length - totalBytesRead);
86+
if (bytesRead == 0)
87+
return totalBytesRead;
88+
89+
totalBytesRead += bytesRead;
90+
}
91+
return totalBytesRead;
92+
}
93+
}
3994
}
4095
}

UnityModStudio.Options/AddGamesViewModelBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ private IEnumerable<Game> GetGames()
106106
GameExecutableFileName = gameInformation.GameExecutableFile.Name,
107107
Architecture = gameInformation.Architecture.ToString(),
108108
UnityVersion = gameInformation.UnityVersion,
109+
TargetFrameworkMoniker = gameInformation.TargetFrameworkMoniker,
109110
MonoProfile = gameInformation.GetMonoProfileString(),
110111
};
111112
}

UnityModStudio.Options/GamePropertiesViewModelBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ protected virtual void OnConfirm()
204204
Game.GameExecutableFileName = GameExecutableFileName;
205205
Game.Architecture = Architecture;
206206
Game.UnityVersion = UnityVersion;
207+
Game.TargetFrameworkMoniker = TargetFrameworkMoniker;
207208
Game.MonoProfile = MonoProfile;
208209
}
209210
}

0 commit comments

Comments
 (0)