finally it is working fine

This commit is contained in:
timerix 2023-02-08 04:38:33 +06:00
parent bb282dd6a3
commit 971896cacb
8 changed files with 175 additions and 96 deletions

View File

@ -1,71 +0,0 @@
namespace ParadoxModMerger;
static class Clear
{
static ConsoleLogger logger = new($"logs", "clear");
static void Log(params string[] msg) => logger.Log(msg);
public static void ClearWorkshop(string workshopDir, string outDir)
{
string[] moddirs = Directory.GetDirectories(workshopDir);
Log("b", $"found {moddirs.Length} mod dirs");
for (int i = 0; i < moddirs.Length; i++)
{
string modarch = "";
if (Directory.GetFiles(moddirs[i], "*.zip").Length != 0)
modarch = Directory.GetFiles(moddirs[i], "*.zip")[0];
if (modarch.Length != 0)
{
Log("y", $"archive found: {modarch}");
var pr = new Process();
pr.StartInfo.CreateNoWindow = true;
pr.StartInfo.UseShellExecute = false;
pr.StartInfo.FileName = Path.Concat("7z", "7z.exe");
pr.StartInfo.Arguments = $"x -y -o _UNZIP \"{modarch}\"";
pr.Start();
pr.WaitForExit();
moddirs[i] = "_UNZIP";
Log("g", "\tfiles extracted");
}
string modname = File.ReadAllText(Path.Concat(moddirs[i], "descriptor.mod"));
modname = modname.Remove(0, modname.IndexOf("name=\"", StringComparison.Ordinal) + 6);
modname = Path.CorrectString(modname.Remove(modname.IndexOf("\"", StringComparison.Ordinal)));
Log("b", $"[{i + 1}/{moddirs.Length}] copying mod ", "c", $"{modname}");
string[] subdirs = Directory.GetDirectories(moddirs[i]);
for (sbyte n = 0; n < subdirs.Length; n++)
{
subdirs[n] = subdirs[n].Remove(0, subdirs[n].LastIndexOf(Path.Sep) + 1);
switch (subdirs[n])
{
// stellaris
case "common":
case "events":
case "flags":
case "fonts":
case "gfx":
case "interface":
case "localisation":
case "localisation_synced":
case "map":
case "music":
case "prescripted_countries":
case "sound":
// hoi4
case "history":
case "portraits":
{
Directory.Copy(Path.Concat(moddirs[i], subdirs[n]),
Path.Concat(outDir, modname, subdirs[n]),
out List<string> _conflicts, true);
Program.LogConflicts(_conflicts);
break;
}
}
}
if (Directory.Exists("_UNZIP")) Directory.Delete("_UNZIP");
}
}
}

20
Diff.cs
View File

@ -11,17 +11,17 @@ static class Diff
DiffMods(split[0], split[1]);
}
public static void DiffMods(string moddir0, string moddir1)
public static void DiffMods(IOPath moddir0, IOPath moddir1)
{
var hasher = new Hasher();
var diff = new Dictionary<string, byte[]>();
var diff = new Dictionary<IOPath, byte[]>();
// добавление файлов из первой папки
List<string> files = Directory.GetAllFiles(moddir0);
var mods = new List<string>();
List<IOPath> files = Directory.GetAllFiles(moddir0);
var mods = new List<IOPath>();
for (short i = 0; i < files.Count; i++)
{
byte[] hash = hasher.HashFile(files[i]);
files[i] = files[i].Replace(moddir0, "");
files[i] = files[i].ReplaceBase(moddir0, "");
diff.Add(files[i], hash);
AddMod(files[i]);
}
@ -31,17 +31,17 @@ static class Diff
for (short i = 0; i < files.Count; i++)
{
byte[] hash = hasher.HashFile(files[i]);
files[i] = files[i].Replace(moddir1, "");
files[i] = files[i].RemoveBase(moddir1);
if (diff.ContainsKey(files[i]) && diff[files[i]].HashToString() == hash.HashToString())
diff.Remove(files[i]);
else
{
diff.Add(moddir1 + files[i], hash);
diff.Add(Path.Concat(moddir1,files[i]), hash);
AddMod(files[i]);
}
}
void AddMod(string mod)
void AddMod(IOPath mod)
{
mod = mod.Remove(0, 1);
mod = mod.Remove(mod.IndexOf(Path.Sep));
@ -51,10 +51,10 @@ static class Diff
// вывод результата
StringBuilder output = new StringBuilder();
output.Append($"[{DateTime.Now}]\n\n");
foreach (string mod in mods)
foreach (var mod in mods)
{
output.Append('\n').Append(mod).Append("\n{\n");
foreach (string file in diff.Keys)
foreach (var file in diff.Keys)
{
if (file.Contains(mod))
{

View File

@ -5,13 +5,13 @@ static class Localisation
static ConsoleLogger logger = new($"logs", "autoloc");
static void Log(params string[] msg) => logger.Log(msg);
public static void GenerateRussian(string engDir, string rusDir)
public static void GenerateRussian(IOPath engDir, IOPath rusDir)
{
foreach (string enfFileName in Directory.GetAllFiles(engDir))
foreach (var enfFileName in Directory.GetAllFiles(engDir))
{
string rusFileName = enfFileName
.Replace(engDir, rusDir)
.Replace("l_english", "l_russian");
IOPath rusFileName = enfFileName
.ReplaceBase(engDir, rusDir)
.ReplaceAnywhere("l_english", "l_russian");
if (!File.Exists(rusFileName))
{
string text = File.ReadAllText(enfFileName)

View File

@ -5,20 +5,20 @@ static class Merge
static ConsoleLogger logger = new($"logs", "merge");
static void Log(params string[] msg) => logger.Log(msg);
public static void MergeAll(string[] moddirs, string outDir)
public static void MergeAll(IOPath[] moddirs, IOPath outDir)
{
Log("b", $"found {moddirs.Length} mod dirs");
for (short i = 0; i < moddirs.Length; i++)
{
Log("b", $"[{i + 1}/{moddirs.Length}] merging mod ", "c", $"{moddirs[i]}");
Directory.Copy(moddirs[i], outDir, out List<string> _conflicts, true);
Directory.Copy(moddirs[i], outDir, true, out var _conflicts);
Program.LogConflicts(_conflicts);
}
}
public static void MergeSingle(string moddir, string outDir)
public static void MergeSingle(IOPath moddir, IOPath outDir)
{
Directory.Copy(moddir, outDir, out List<string> _conflicts, true);
Directory.Copy(moddir, outDir, true, out var _conflicts);
Program.LogConflicts(_conflicts);
}
}

View File

@ -19,6 +19,9 @@ public static class Program
{
try
{
Console.OutputEncoding=Encoding.UTF8;
Console.InputEncoding=Encoding.UTF8;
string outPath = "" ;
new LaunchArgumentParser(
@ -29,7 +32,7 @@ public static class Program
0),
new LaunchArgument(new []{"clear"},
"Clear mod files and put them into separate dirs in output dir. Requires -o",
wdir=>Clear.ClearWorkshop(wdir, outPath),
wdir=>Workshop.ClearWorkshop(wdir, outPath),
"workshop_dir",
1),
new LaunchArgument(new []{"diff"},
@ -49,7 +52,10 @@ public static class Program
new LaunchArgument(new []{"gen-rus-locale"},
"Creates l_russian copy of english locale in output directory. Requires -o",
eng=>Localisation.GenerateRussian(eng, outPath),
"english_locale_path", 1)
"english_locale_path", 1),
new LaunchArgument(new []{"desc"},
"Downloads mod description from steam to new file in outDir. Requires -o",
id=>Workshop.CreateDescFile(id, outPath), "mod_id")
).ParseAndHandle(args);
}
catch (LaunchArgumentParser.ExitAfterHelpException)
@ -63,10 +69,9 @@ public static class Program
// вывод конфликтующих файлов при -merge и -clear если такие есть
public static void LogConflicts(List<string> conflicts)
public static void LogConflicts(List<IOPath> conflicts)
{
Log("w", $"found {conflicts.Count}");
if(conflicts.Count>0)
Log("w","conflicts:\n", "m", conflicts.MergeToString("\n"));
Log("y", $"conflicts found: {conflicts.Count}\n{conflicts.MergeToString("\n")}");
}
}

136
Workshop.cs Normal file
View File

@ -0,0 +1,136 @@
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using DTLib.Ben.Demystifier;
using HtmlAgilityPack;
namespace ParadoxModMerger;
using Fizzler.Systems.HtmlAgilityPack;
static class Workshop
{
static ConsoleLogger logger = new($"logs", "clear");
static void Log(params string[] msg) => logger.Log(msg);
public static void ClearWorkshop(IOPath workshopDir, IOPath outDir)
{
var moddirs = Directory.GetDirectories(workshopDir);
Log("b", $"found {moddirs.Length} mod dirs");
for (int i = 0; i < moddirs.Length; i++)
{
string modId = moddirs[i].LastName().ToString();
IOPath modZip="";
if (Directory.GetFiles(moddirs[i], "*.zip").Length != 0)
modZip = Directory.GetFiles(moddirs[i], "*.zip")[0];
if (modZip.Length != 0)
{
Log("y", $"archive found: {modZip}");
if (Directory.Exists("_UNZIP")) Directory.Delete("_UNZIP");
var pr = new Process();
pr.StartInfo.CreateNoWindow = true;
pr.StartInfo.UseShellExecute = false;
pr.StartInfo.FileName = Path.Concat("7z", "7z.exe").Str;
pr.StartInfo.Arguments = $"x -y -o_UNZIP \"{modZip}\"";
Log("h",$"{pr.StartInfo.WorkingDirectory}$: {pr.StartInfo.FileName} {pr.StartInfo.Arguments}");
pr.Start();
pr.WaitForExit();
moddirs[i] = "_UNZIP";
Log("g", "\tfiles extracted");
}
var descriptorPath = Path.Concat(moddirs[i], "descriptor.mod");
string descriptor = File.ReadAllText(descriptorPath);
string modname = descriptor.Substring(descriptor.IndexOf("name=\"", StringComparison.Ordinal) + 6);
modname = modname.Remove(modname.IndexOf("\"", StringComparison.Ordinal));
Log("b", $"[{i + 1}/{moddirs.Length}] copying mod ", "c", $"({modId}) {modname}");
IOPath outModDir=Path.Concat(outDir, Path.ReplaceRestrictedChars(modname));
File.Copy(descriptorPath, Path.Concat(outModDir, "descriptor.mod"), true);
CreateDescFile(modId, outModDir);
var subdirs = Directory.GetDirectories(moddirs[i]);
for (sbyte n = 0; n < subdirs.Length; n++)
{
subdirs[n] = subdirs[n].Remove(0, subdirs[n].LastIndexOf(Path.Sep) + 1);
switch (subdirs[n].Str)
{
// stellaris
case "common":
case "events":
case "flags":
case "fonts":
case "gfx":
case "interface":
case "localisation":
case "localisation_synced":
case "map":
case "music":
case "prescripted_countries":
case "sound":
// hoi4
case "history":
case "portraits":
{
Directory.Copy(Path.Concat(moddirs[i], subdirs[n]),
Path.Concat(outModDir, subdirs[n]),
true, out var _conflicts);
Program.LogConflicts(_conflicts);
break;
}
}
}
if (Directory.Exists("_UNZIP")) Directory.Delete("_UNZIP");
}
}
private static HttpClient http = new HttpClient();
public static async void CreateDescFile(string workshopId, IOPath outDir)
{
try
{
string desc = await DownloadModDescription(workshopId);
var file = Path.Concat(outDir, $"desc_{workshopId}.txt");
File.WriteAllText(file, desc);
Log("g", $"downloaded {workshopId} description to {file}");
}
catch (Exception e)
{
Log("r", $"mod {workshopId} error: \n"+ e.ToStringDemystified());
}
}
public static async Task<string> DownloadModDescription(string workshopId)
{
string url = "https://steamcommunity.com/sharedfiles/filedetails/?id=" + workshopId;
var b = new StringBuilder(url);
b.Append("\n\n");
string pageText = await http.GetStringAsync(url);
var page = new HtmlDocument();
page.LoadHtml(pageText);
var descNode=page.DocumentNode.QuerySelectorAll(".workshopItemDescription").FirstOrDefault();
if (descNode is null)
Log("y", $"no description found for mod {workshopId}");
else processNodes(descNode.ChildNodes);
return b.ToString().Replace("&quot;","\"");
void processNodes(IEnumerable<HtmlNode> nodes)
{
foreach (var node in nodes)
{
b.Append(
node.Name switch
{
"br" => '\n',
"a" => $"{node.InnerText} ({node.GetAttributeValue("href", "NULL_ATTRIBUTE")}) ",
_ => node.InnerText
});
}
}
}
}

View File

@ -13,7 +13,10 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DTLib" Version="1.0.4" />
<PackageReference Include="DTLib.Ben.Demystifier" Version="1.0.2" />
<PackageReference Include="Fizzler.Systems.HtmlAgilityPack" Version="1.2.1" />
<ProjectReference Include="..\DTLib\DTLib\DTLib.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
</ItemGroup>
</Project>

View File

@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution_files", "solution_
nuget.config = nuget.config
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DTLib", "..\DTLib\DTLib\DTLib.csproj", "{67E226B7-F04B-4FB1-A9AA-E4AE3A5A8A3F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|Any CPU = Release|Any CPU
@ -21,6 +23,10 @@ Global
{076BFCFF-1D3E-44FB-B434-73716B79A135}.Release|Any CPU.Build.0 = Release|Any CPU
{076BFCFF-1D3E-44FB-B434-73716B79A135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{076BFCFF-1D3E-44FB-B434-73716B79A135}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67E226B7-F04B-4FB1-A9AA-E4AE3A5A8A3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67E226B7-F04B-4FB1-A9AA-E4AE3A5A8A3F}.Release|Any CPU.Build.0 = Release|Any CPU
{67E226B7-F04B-4FB1-A9AA-E4AE3A5A8A3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67E226B7-F04B-4FB1-A9AA-E4AE3A5A8A3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE