Skip to content

Commit d2205f1

Browse files
authored
Add command line argument that allows going straight to the host window (#708)
* Add command line argument that allows going straight to the host window * SaveFileReader: Switch from Jetbrains.Annotations to #nullable enable
1 parent 788c2e2 commit d2205f1

File tree

4 files changed

+92
-69
lines changed

4 files changed

+92
-69
lines changed

Source/Client/MultiplayerStatic.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public static class MultiplayerStatic
4242
public static readonly Texture2D GiftModeIcon = ContentFinder<Texture2D>.Get("UI/Buttons/GiftMode");
4343
public static readonly Texture2D TradeModeIcon = ContentFinder<Texture2D>.Get("UI/Buttons/TradeMode");
4444

45+
public const string MpHostReplayCmdLineArg = "mphostreplay";
46+
4547
static MultiplayerStatic()
4648
{
4749
Native.InitLmfPtr(
@@ -263,6 +265,11 @@ void TickBatch()
263265
DirectXmlSaver.SaveDataObject(new SyncContainer(), "SyncHandlers.xml");
264266
ExtendDirectXmlSaver.extend = false;
265267
}
268+
269+
if (GenCommandLine.TryGetCommandLineArg(MpHostReplayCmdLineArg, out var path))
270+
{
271+
DoubleLongEvent(() => HostWindow.VerifyAndOpen(path), "Loading");
272+
}
266273
}
267274

268275
public class SyncContainer

Source/Client/Windows/HostWindow.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using RimWorld;
33
using System;
44
using System.Collections.Generic;
5+
using System.IO;
56
using System.Linq;
67
using UnityEngine;
78
using Verse;
@@ -34,6 +35,16 @@ enum Tab
3435

3536
private ServerSettings serverSettings;
3637

38+
public static void VerifyAndOpen(string path)
39+
{
40+
FileInfo fileInfo = new(path);
41+
var saveFile = SaveFile.ReadMpSave(fileInfo);
42+
ServerBrowser.CheckGameVersionAndMods(
43+
saveFile,
44+
() => { Find.WindowStack.Add(new HostWindow(saveFile) { returnToServerBrowser = false }); }
45+
);
46+
}
47+
3748
public HostWindow(SaveFile file = null)
3849
{
3950
closeOnAccept = false;
Lines changed: 73 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#nullable enable
12
using Multiplayer.Common;
23
using RimWorld;
34
using System;
@@ -14,17 +15,17 @@ namespace Multiplayer.Client
1415
{
1516
public class SaveFileReader
1617
{
17-
public List<FileInfo> SpSaves { get; private set; }
18-
public List<FileInfo> MpSaves { get; private set; }
18+
public List<FileInfo> SpSaves { get; private set; } = [];
19+
public List<FileInfo> MpSaves { get; private set; } = [];
1920

2021
private ConcurrentDictionary<FileInfo, SaveFile> data = new();
21-
private Task spTask, mpTask;
22+
private Task? spTask, mpTask;
2223

2324
public void StartReading()
2425
{
2526
SpSaves = GenFilePaths.AllSavedGameFiles.OrderByDescending(f => f.LastWriteTime).ToList();
2627

27-
var replaysDir = new DirectoryInfo(GenFilePaths.FolderUnderSaveData("MpReplays"));
28+
var replaysDir = new DirectoryInfo(Multiplayer.ReplaysDir);
2829
var toRead = replaysDir.GetFiles("*.zip", MpVersion.IsDebug ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
2930
MpSaves = toRead.OrderByDescending(f => f.LastWriteTime).ToList();
3031

@@ -37,18 +38,15 @@ public void StartReading()
3738

3839
public void WaitTasks()
3940
{
40-
spTask.Wait();
41-
mpTask.Wait();
41+
spTask?.Wait();
42+
mpTask?.Wait();
4243
}
4344

4445
private void ReadSpSave(FileInfo file)
4546
{
4647
try
4748
{
48-
var saveFile = new SaveFile(Path.GetFileNameWithoutExtension(file.Name), false, file);
49-
using var stream = file.OpenRead();
50-
ReadSaveInfo(stream, saveFile);
51-
data[file] = saveFile;
49+
data[file] = SaveFile.ReadSpSave(file);
5250
}
5351
catch (Exception ex)
5452
{
@@ -60,58 +58,16 @@ private void ReadMpSave(FileInfo file)
6058
{
6159
try
6260
{
63-
var displayName = Path.ChangeExtension(Path.GetRelativePath(Multiplayer.ReplaysDir, file.FullName), null);
64-
var saveFile = new SaveFile(displayName, true, file);
65-
66-
var replay = Replay.ForLoading(file);
67-
if (!replay.LoadInfo()) return;
68-
69-
saveFile.gameName = replay.info.name;
70-
saveFile.protocol = replay.info.protocol;
71-
saveFile.replaySections = replay.info.sections.Count;
72-
73-
if (!replay.info.rwVersion.NullOrEmpty())
74-
{
75-
saveFile.rwVersion = replay.info.rwVersion;
76-
saveFile.modIds = replay.info.modIds.ToArray();
77-
saveFile.modNames = replay.info.modNames.ToArray();
78-
saveFile.asyncTime = replay.info.asyncTime;
79-
saveFile.multifaction = replay.info.multifaction;
80-
}
81-
else
82-
{
83-
using var zip = replay.OpenZipRead();
84-
using var stream = zip.GetEntry("world/000_save")!.Open();
85-
ReadSaveInfo(stream, saveFile);
86-
}
87-
88-
data[file] = saveFile;
61+
var saveFile = SaveFile.ReadMpSave(file);
62+
if (saveFile != null) data[file] = saveFile;
8963
}
9064
catch (Exception ex)
9165
{
9266
Log.Warning($"Exception loading replay info of {file.Name}: {ex}");
9367
}
9468
}
9569

96-
private void ReadSaveInfo(Stream stream, SaveFile save)
97-
{
98-
using var reader = new XmlTextReader(stream);
99-
reader.ReadToNextElement(); // savedGame
100-
reader.ReadToNextElement(); // meta
101-
102-
if (reader.Name != "meta") return;
103-
104-
reader.ReadToDescendant("gameVersion");
105-
save.rwVersion = VersionControl.VersionStringWithoutRev(reader.ReadString());
106-
107-
reader.ReadToNextSibling("modIds");
108-
save.modIds = reader.ReadStrings();
109-
110-
reader.ReadToNextSibling("modNames");
111-
save.modNames = reader.ReadStrings();
112-
}
113-
114-
public SaveFile GetData(FileInfo file)
70+
public SaveFile? GetData(FileInfo file)
11571
{
11672
data.TryGetValue(file, out var saveFile);
11773
return saveFile;
@@ -124,26 +80,26 @@ public void RemoveFile(FileInfo info)
12480
}
12581
}
12682

127-
public class SaveFile
83+
public class SaveFile(string displayName, bool replay, FileInfo file)
12884
{
129-
public string displayName;
130-
public bool replay;
85+
public string displayName = displayName;
86+
public bool replay = replay;
13187
public int replaySections;
132-
public FileInfo file;
88+
public FileInfo file = file;
13389

134-
public string gameName;
90+
public string? gameName;
13591

136-
public string rwVersion;
137-
public string[] modNames = Array.Empty<string>();
138-
public string[] modIds = Array.Empty<string>();
92+
public string? rwVersion;
93+
public string[] modNames = [];
94+
public string[] modIds = [];
13995

14096
public int protocol;
14197
public bool asyncTime;
14298
public bool multifaction;
14399

144100
public bool HasRwVersion => rwVersion != null;
145101

146-
public bool MajorAndMinorVerEqualToCurrent =>
102+
public bool MajorAndMinorVerEqualToCurrent => rwVersion != null &&
147103
VersionControl.MajorFromVersionString(rwVersion) == VersionControl.CurrentMajor &&
148104
VersionControl.MinorFromVersionString(rwVersion) == VersionControl.CurrentMinor;
149105

@@ -164,11 +120,60 @@ public Color VersionColor
164120
}
165121
}
166122

167-
public SaveFile(string displayName, bool replay, FileInfo file)
123+
public static SaveFile ReadSpSave(FileInfo file)
124+
{
125+
var saveFile = new SaveFile(Path.GetFileNameWithoutExtension(file.Name), false, file);
126+
using var stream = file.OpenRead();
127+
ReadSaveInfo(stream, saveFile);
128+
return saveFile;
129+
}
130+
131+
public static SaveFile? ReadMpSave(FileInfo file)
168132
{
169-
this.displayName = displayName;
170-
this.replay = replay;
171-
this.file = file;
133+
var displayName = Path.ChangeExtension(Path.GetRelativePath(Multiplayer.ReplaysDir, file.FullName), null);
134+
var saveFile = new SaveFile(displayName, true, file);
135+
136+
var replay = Replay.ForLoading(file);
137+
if (!replay.LoadInfo()) return null;
138+
139+
saveFile.gameName = replay.info.name;
140+
saveFile.protocol = replay.info.protocol;
141+
saveFile.replaySections = replay.info.sections.Count;
142+
143+
if (!replay.info.rwVersion.NullOrEmpty())
144+
{
145+
saveFile.rwVersion = replay.info.rwVersion;
146+
saveFile.modIds = replay.info.modIds.ToArray();
147+
saveFile.modNames = replay.info.modNames.ToArray();
148+
saveFile.asyncTime = replay.info.asyncTime;
149+
saveFile.multifaction = replay.info.multifaction;
150+
}
151+
else
152+
{
153+
using var zip = replay.OpenZipRead();
154+
using var stream = zip.GetEntry("world/000_save")!.Open();
155+
ReadSaveInfo(stream, saveFile);
156+
}
157+
158+
return saveFile;
159+
}
160+
161+
private static void ReadSaveInfo(Stream stream, SaveFile save)
162+
{
163+
using var reader = new XmlTextReader(stream);
164+
reader.ReadToNextElement(); // savedGame
165+
reader.ReadToNextElement(); // meta
166+
167+
if (reader.Name != "meta") return;
168+
169+
reader.ReadToDescendant("gameVersion");
170+
save.rwVersion = VersionControl.VersionStringWithoutRev(reader.ReadString());
171+
172+
reader.ReadToNextSibling("modIds");
173+
save.modIds = reader.ReadStrings();
174+
175+
reader.ReadToNextSibling("modNames");
176+
save.modNames = reader.ReadStrings();
172177
}
173178
}
174179
}

Source/Client/Windows/ServerBrowser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ private void DrawFileButtons(SaveFile file, ref float width)
271271
width += 120;
272272
}
273273

274-
private static void CheckGameVersionAndMods(SaveFile file, Action action)
274+
public static void CheckGameVersionAndMods(SaveFile file, Action action)
275275
{
276276
ScribeMetaHeaderUtility.lastMode = ScribeMetaHeaderUtility.ScribeHeaderMode.Map;
277277
ScribeMetaHeaderUtility.loadedGameVersion = file.rwVersion;

0 commit comments

Comments
 (0)