finally it is working fine
This commit is contained in:
parent
bb282dd6a3
commit
971896cacb
71
Clear.cs
71
Clear.cs
@ -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
20
Diff.cs
@ -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))
|
||||
{
|
||||
|
||||
@ -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)
|
||||
|
||||
8
Merge.cs
8
Merge.cs
@ -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);
|
||||
}
|
||||
}
|
||||
15
Program.cs
15
Program.cs
@ -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
136
Workshop.cs
Normal 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(""","\"");
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user