Skip to content

Commit bc89601

Browse files
authored
Merge pull request #4 from MrBBBaiXue/1.1.0
1.1.0
2 parents cd5ab5a + 86aa846 commit bc89601

File tree

5 files changed

+127
-40
lines changed

5 files changed

+127
-40
lines changed

RA3.Tools.Test/Program.cs

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
using RA3.Tools;
2+
using Con = System.Console;
3+
24

35
var ra3 = new RA3Instance();
6+
7+
Con.WriteLine("[Profiles]");
48
foreach (var i in ra3.Profiles)
59
{
6-
Console.WriteLine(i);
10+
Con.WriteLine(i);
711
}
8-
Console.WriteLine(ra3.GetCurrentProfile());
12+
Con.WriteLine();
13+
14+
Con.WriteLine("[Current Profile]");
15+
Con.WriteLine(ra3.GetCurrentProfile());
16+
Con.WriteLine();
17+
18+
Con.WriteLine("[RA3 Path] " + RA3.Tools.Registry.GetRA3Path());
19+
Con.WriteLine("[Registry Status] " + RA3.Tools.Registry.Status);
20+
21+
RA3.Tools.Registry.SetLanguage(RA3.Tools.Registry.GetRA3Path(), "chinese_t");
922

10-
Console.WriteLine("RA3 Path: " + RA3.Tools.Registry.GetRA3Path());
11-
Console.WriteLine("Registry Status: " + RA3.Tools.Registry.Status);
12-
Console.ReadKey();
23+
Con.ReadKey();

RA3.Tools/RA3.Tools.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
<PackageProjectUrl>https://github.com/MrBBBaiXue/RA3.Tools</PackageProjectUrl>
1212
<PackageIcon>RA3.Tools.png</PackageIcon>
1313
<RepositoryUrl>https://github.com/MrBBBaiXue/RA3.Tools</RepositoryUrl>
14-
<Version>1.0.9</Version>
14+
<Version>1.1.0</Version>
1515
<UserSecretsId>f29ab2a9-2d0a-4cd5-a893-d56121d4060a</UserSecretsId>
16-
<AssemblyVersion>1.0.9.0</AssemblyVersion>
17-
<FileVersion>1.0.9.0</FileVersion>
16+
<AssemblyVersion>1.1.0.0</AssemblyVersion>
17+
<FileVersion>1.1.0.0</FileVersion>
1818
<PackageReadmeFile>README.md</PackageReadmeFile>
1919
<PackageTags>game; red-alert-3;</PackageTags>
2020
</PropertyGroup>
2121

2222
<ItemGroup>
23-
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
23+
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
2424
<PackageReference Include="System.Diagnostics.Tools" Version="4.3.0" />
2525
</ItemGroup>
2626

RA3.Tools/RA3Instance.cs

+63-28
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,43 @@ namespace RA3.Tools
1010
{
1111
public class RA3Instance
1212
{
13+
/// <summary>
14+
/// Private pre-defined name of QuickLoader.
15+
/// </summary>
16+
/// TODO: Download to AppData automatically.
1317
private static readonly string _quickLoaderPath = "RA3.QuickLoader.exe";
14-
//
18+
19+
/// <summary>
20+
/// Game install folder.
21+
/// </summary>
1522
public string GamePath;
23+
24+
/// <summary>
25+
/// Parameter passes to game.
26+
/// </summary>
1627
public string LaunchParamter;
28+
29+
/// <summary>
30+
/// Whether to use RA3BarLauncher to launch game.
31+
/// </summary>
1732
public bool UseBarLauncher;
33+
34+
/// <summary>
35+
/// Avaliable profiles of game user.
36+
/// </summary>
1837
public List<string> Profiles
1938
{
2039
get { return GetProfilesList(); }
2140
}
22-
//
23-
public readonly ResourceFolder ModFolder = new ResourceFolder(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Red Alert 3\\Mods\\");
24-
public readonly ResourceFolder ReplayFolder = new ResourceFolder(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Red Alert 3\\Replays\\");
25-
public readonly ResourceFolder MapFolder = new ResourceFolder(Environment.GetEnvironmentVariable("appdata") + "\\Red Alert 3\\Maps\\");
26-
public readonly ResourceFolder ProfileFolder = new ResourceFolder(Environment.GetEnvironmentVariable("appdata") + "\\Red Alert 3\\Profiles\\");
41+
public readonly ResourceFolder ModFolder = new ResourceFolder(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Red Alert 3", "Mods"));
42+
public readonly ResourceFolder ReplayFolder = new ResourceFolder(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Red Alert 3", "Replays"));
43+
public readonly ResourceFolder MapFolder = new ResourceFolder(Path.Combine(Environment.GetEnvironmentVariable("appdata"), "Red Alert 3", "Maps"));
44+
public readonly ResourceFolder ProfileFolder = new ResourceFolder(Path.Combine(Environment.GetEnvironmentVariable("appdata"), "Red Alert 3", "Profiles"));
45+
2746
/// <summary>
28-
/// 红警3进程实例
47+
/// Red-Alert 3 Game Instance.
2948
/// </summary>
30-
/// <param name="gamePath">游戏路径(可选,为空则从注册表读取)</param>
49+
/// <param name="gamePath">Game install folder. Will Read from Registry if empty.</param>
3150
public RA3Instance(string gamePath = "")
3251
{
3352
//Read GamePath
@@ -39,8 +58,8 @@ public RA3Instance(string gamePath = "")
3958
{
4059
GamePath = gamePath;
4160
}
42-
//Check RA3.QuickLoader
43-
if (File.Exists($".\\{_quickLoaderPath}"))
61+
//Check if RA3.QuickLoader is avaliable.
62+
if (File.Exists(Path.GetFullPath(_quickLoaderPath)))
4463
{
4564
UseBarLauncher = true;
4665
}
@@ -51,33 +70,42 @@ public bool IsRA3PathValid()
5170
{
5271
try
5372
{
54-
return Directory.EnumerateFiles(GamePath, "RA3_*_1.12.SkuDef").Any();
73+
return Directory.EnumerateFiles(GamePath, "*.skudef").Any();
5574
}
5675
catch (Exception) { }
5776
return false;
5877
}
5978

6079
public bool IsRA3FileValid()
6180
{
62-
return false;
81+
throw new NotImplementedException();
6382
}
6483
#endregion
6584

6685
#region Launch & Register
86+
/// <summary>
87+
/// launch game using skudef file directly.
88+
/// </summary>
89+
/// <param name="executablePath">e.g. ra3_1.12.game</param>
90+
/// <param name="skudefPath">e.g. RA3_chinese_t_1.12.skudef</param>
91+
public static void LaunchUsingSkudef(string executablePath, string skudefPath)
92+
{
93+
if (!File.Exists(executablePath))
94+
throw new ArgumentException("Game not found.", nameof(executablePath));
95+
if (!File.Exists(skudefPath))
96+
throw new ArgumentException("Skudef not found.");
97+
var startInfo = new ProcessStartInfo(executablePath, $"-config {skudefPath}");
98+
Process.Start(startInfo);
99+
}
100+
// TODO: 与Launch合并
101+
67102
public void Register()
68103
{
69-
//ToDo : 需要直接写入,而不是依赖RA3.reg
70-
try
104+
if (IsRA3PathValid() && Registry.Status != Registry.RegistryStatus.Correct)
71105
{
72-
if (File.Exists("RA3.reg"))
73-
{
74-
string regPath = Path.GetFullPath("RA3.reg");
75-
regPath = @"""" + regPath + @"""";
76-
Process.Start("regedit", string.Format(" /s {0}", regPath));
77-
}
78-
//write registion here.
106+
Registry.SetRA3Path(GamePath);
107+
Registry.EnableMapSync();
79108
}
80-
catch (Exception) { }
81109
}
82110

83111
public void Launch()
@@ -100,7 +128,7 @@ public void Launch()
100128
#endregion
101129

102130
#region Steam & Origin Version detection.
103-
//From @BSG-75 (https://github.com/BSG-75)
131+
//From @lanyizi (https://github.com/lanyizi)
104132
public bool DoesRA3NeedSteamAppID()
105133
{
106134
var ra3Path = GamePath;
@@ -132,7 +160,7 @@ public void GenerateSteamAppID()
132160
}
133161

134162
//Abandoned
135-
public void GeneratePatchedParFile()
163+
public void _GeneratePatchedParFile()
136164
{
137165
var tucParPath = Path.Combine(GamePath, "Data", "ra3_1.12.par");
138166
var oldFileId = 0;
@@ -147,7 +175,11 @@ public void GeneratePatchedParFile()
147175
#endregion
148176

149177
#region Profile Operations
150-
// Parse string encoded by EA similar to UTF-8 in directory.ini
178+
/// <summary>
179+
/// Parse string encoded by EA similar to UTF-8 in directory.ini
180+
/// </summary>
181+
/// <param name="s">string</param>
182+
/// <returns></returns>
151183
private string ParseDirectoryString(string s)
152184
{
153185
var bytes = new List<byte>();
@@ -168,7 +200,10 @@ private string ParseDirectoryString(string s)
168200
}
169201
return Encoding.Unicode.GetString(bytes.ToArray());
170202
}
171-
203+
/// <summary>
204+
/// Get list of avaliable profiles list.
205+
/// </summary>
206+
/// <returns>List of avaliable game profiles.</returns>
172207
private List<string> GetProfilesList()
173208
{
174209
var original = ParseDirectoryString(File.ReadAllLines($"{ProfileFolder.Path}\\directory.ini")[0]);
@@ -216,7 +251,7 @@ public void DeleteAllSkirmishINI()
216251
}
217252
#endregion
218253

219-
//ToDo:1.完善检测文件完整的函数
220-
//ToDo:8.软链接修改Mod,Map,Replay的位置(在ResourceFolder类中)
254+
//ToDo: 1.完善检测文件完整的函数
255+
//ToDo: 8.软链接修改Mod,Map,Replay的位置(在ResourceFolder类中)
221256
}
222257
}

RA3.Tools/Registry.cs

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Microsoft.Win32;
2+
using System.IO;
23

34
namespace RA3.Tools
45
{
@@ -9,7 +10,8 @@ public enum RegistryStatus
910
Correct,
1011
NotExist,
1112
MissingPath,
12-
MissingMapSync
13+
MissingMapSync,
14+
MissingLanguage,
1315
}
1416

1517
public static RegistryStatus Status
@@ -34,6 +36,13 @@ private static RegistryStatus IsRegistryValid()
3436
{
3537
return RegistryStatus.MissingMapSync;
3638
}
39+
40+
using var viewUser = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default);
41+
using var languageRa3 = view32.OpenSubKey("Software\\Electronic Arts\\Electronic Arts\\Red Alert 3", writable: true);
42+
if (languageRa3 == null || languageRa3.GetValue("Language") == null)
43+
{
44+
return RegistryStatus.MissingLanguage;
45+
}
3746
return RegistryStatus.Correct;
3847
}
3948

@@ -57,6 +66,37 @@ public static void SetRA3Path(string path)
5766
ra3.SetValue("Install Dir", path, RegistryValueKind.String);
5867
}
5968

69+
/// <summary>
70+
///
71+
/// </summary>
72+
/// <param name="gamePath">Game install folder.</param>
73+
/// <param name="value">Language string.</param>
74+
/// <returns>true if succeed. false if failed (language not find in game folder).</returns>
75+
public static bool SetLanguage(string gamePath, string value)
76+
{
77+
try
78+
{
79+
// verify if v1.12 skudef file of this value exists.
80+
var isTargetSkudefExists = File.Exists(Path.Combine(gamePath, $"RA3_{value}_1.12.skudef"));
81+
var isTargetCsfExists = File.Exists(Path.Combine(gamePath, "Launcher", $"{value}.csf"));
82+
if (isTargetSkudefExists && isTargetCsfExists)
83+
{
84+
using var view32 = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default);
85+
using var ra3 = view32.OpenSubKey("Software\\Electronic Arts\\Electronic Arts\\Red Alert 3", writable: true);
86+
if (ra3 == null)
87+
{
88+
using var newRa3 = view32.CreateSubKey("Software\\Electronic Arts\\Electronic Arts\\Red Alert 3", writable: true);
89+
newRa3.SetValue("Language", value, RegistryValueKind.String);
90+
return true;
91+
}
92+
ra3.SetValue("Language", value, RegistryValueKind.String);
93+
return true;
94+
}
95+
}
96+
catch { }
97+
return false;
98+
}
99+
60100
public static void EnableMapSync()
61101
{
62102
using var view32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);

RA3.Tools/Utility.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace RA3.Tools
1212
{
1313
public static class Utility
1414
{
15-
//From CSDN. (From https://github.com/MrBBBaiXue/CoronaLauncher/)
15+
// From https://github.com/RA3CoronaDevelopers/CoronaLauncher/
1616
private static long GetDirectoryLength(string directoryPath)
1717
{
1818
if (!Directory.Exists(directoryPath))
@@ -105,6 +105,7 @@ public void OpenInExplorer()
105105
}
106106
public string GetSize()
107107
{
108+
// TODO: Don't return "ERROR" only!
108109
try { return Utility.GetDirectorySize(Path); }
109110
catch (Exception) { return "ERROR"; }
110111
}
@@ -158,7 +159,7 @@ public void AddBig(string bigPath)
158159
_addedBigs.Add(bigPath);
159160
}
160161

161-
//private methods.
162+
// Private methods.
162163
private List<string> TryRead()
163164
{
164165
string[] skudefCommands = File.ReadAllLines(Path);

0 commit comments

Comments
 (0)