Skip to content

Commit

Permalink
LECoalesced SingleFile: Fix and support packing the localized config …
Browse files Browse the repository at this point in the history
…files so game can properly print error messages to debug logger
  • Loading branch information
Mgamerz committed Jul 14, 2024
1 parent 19d9a36 commit fea5c3c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using LegendaryExplorerCore.Gammtek.Extensions.Collections.Generic;
using LegendaryExplorerCore.Gammtek.IO;
using LegendaryExplorerCore.Misc;
using LegendaryExplorerCore.Packages;

namespace LegendaryExplorerCore.Coalesced
{
Expand All @@ -26,7 +27,7 @@ public static class CoalescedConverter
public static readonly int CoalescedMagicNumber = 1718448749;

/// <summary>
/// The list of filenames supported by this compiler
/// The list of ini filenames supported by this compiler
/// </summary>
public static readonly SortedSet<string> ProperNames =
new SortedSet<string>
Expand All @@ -44,21 +45,28 @@ public static class CoalescedConverter
"BioUI",
"BioQA",
"BioWeapon",
"Core",
"Descriptions",
"EditorTips",
"Engine",
"GFxUI",
"IpDrv",
"Launch",
"OnlineSubsystemGamespy",
"Startup",
"Subtitles",
"UnrealEd",
"WinDrv",
"XWindow"
};

/// <summary>
/// These files go in the Localizations folder and have a localized suffix. They aren't used except for some error handling messages
/// </summary>
public static readonly SortedSet<string> LocalizedFiles = new SortedSet<string>
{
"Core",
"Descriptions",
"EditorTips",
"Engine",
"GFxUI",
"IpDrv",
"Launch",
"OnlineSubsystemGamespy",
"Startup",
"Subtitles",
"UnrealEd",
"WinDrv",
"XWindow"
};

public static readonly Dictionary<string, string> SpecialCharacters =
new Dictionary<string, string>
{
Expand Down Expand Up @@ -654,13 +662,14 @@ public static CaseInsensitiveDictionary<DuplicatingIni> DecompileLE1LE2ToMemory(
/// Compiles a LE1/LE2 Coalesced file from a memory map.
/// </summary>
/// <param name="iniFileMap">Mapping of filenames to the ini object that represents the file contents.</param>
/// <param name="loc">Localization of this config file. This is important as it enables debug logger appErrorF messages.</param>
/// <returns>Memorystream of the compiled Coalesced file</returns>
public static MemoryStream CompileLE1LE2FromMemory(Dictionary<string, DuplicatingIni> iniFileMap)
public static MemoryStream CompileLE1LE2FromMemory(Dictionary<string, DuplicatingIni> iniFileMap, MELocalization loc)
{
LECoalescedBundle cb = new LECoalescedBundle("");
cb.Files.AddRange(iniFileMap);
MemoryStream ms = new MemoryStream();
cb.WriteToStream(ms);
cb.WriteToStream(ms, loc);
ms.Position = 0;
return ms;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ private ConfigAssetBundle(MEGame game, string cookedDir, string dlcFolderName)
foreach (var ini in iniFiles)
{
var fname = Path.GetFileNameWithoutExtension(ini);
if (!CoalescedConverter.ProperNames.Contains(fname, StringComparer.InvariantCultureIgnoreCase))
continue; // Not supported.
if (!CoalescedConverter.ProperNames.Contains(fname, StringComparer.OrdinalIgnoreCase))
continue; // Not supported. localization files are only supported in the main single file.
Assets[fname] = ConfigFileProxy.LoadIni(ini);
}
}
Expand Down Expand Up @@ -197,7 +197,7 @@ public CoalesceAsset GetAsset(string assetName, bool createIfNotFound = true)
/// <summary>
/// Commits this bundle to the specified single config file
/// </summary>
public void CommitAssets(string outPath)
public void CommitAssets(string outPath, MELocalization loc)
{
if (Game is MEGame.LE1 or MEGame.LE2)
{
Expand All @@ -208,7 +208,7 @@ public void CommitAssets(string outPath)
inis[asset.Key] = CoalesceAsset.ToIni(asset.Value);
}

var compiledStream = CoalescedConverter.CompileLE1LE2FromMemory(inis);
var compiledStream = CoalescedConverter.CompileLE1LE2FromMemory(inis, loc);
compiledStream.WriteToFile(outPath);
HasChanges = false;
}
Expand Down Expand Up @@ -242,7 +242,7 @@ public void CommitDLCAssets(string outPath = null)
else if (Game.IsGame3())
{
var coalFile = Path.Combine(outPath ?? CookedDir, $@"Default_{DLCFolderName}.bin");
CommitAssets(coalFile);
CommitAssets(coalFile, MELocalization.INT); // DLC does not support localization files as part of config.
HasChanges = false;
}
}
Expand Down
20 changes: 11 additions & 9 deletions LegendaryExplorer/LegendaryExplorerCore/Coalesced/LECoalesced.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Text;
using LegendaryExplorerCore.Helpers;
using LegendaryExplorerCore.Misc;
using LegendaryExplorerCore.Packages;

// Tools to unpack/repack LE1 and LE2 coalesced files.
// Originally by d00t (https://github.com/d00telemental/LECoal)
Expand Down Expand Up @@ -281,7 +282,7 @@ public void WriteToDirectory(string destinationPath)
public void WriteToFile(string destinationPath)
{
var ms = new MemoryStream();
WriteToStream(ms);
WriteToStream(ms, destinationPath.GetUnrealLocalization());
ms.WriteToFile(destinationPath);
}

Expand Down Expand Up @@ -309,13 +310,13 @@ internal List<string> splitValue(string val)
return splitVal;
}

public void WriteToStream(Stream ms)
public void WriteToStream(Stream ms, MELocalization lang)
{
var writer = new BinaryWriter(ms);
writer.Write(Files.Count);
foreach (var file in Files)
{
writer.WriteCoalescedString(GetIniFullPath(file.Key));
writer.WriteCoalescedString(GetIniFullPath(file.Key, lang));
writer.Write(file.Value.Sections.Count);

foreach (var section in file.Value.Sections)
Expand All @@ -337,23 +338,24 @@ public void WriteToStream(Stream ms)
}
}

private string GetIniFullPath(string filename)
private string GetIniFullPath(string filename, MELocalization localization)
{
var extension = Path.GetExtension(filename).ToLower();
var fNameNoExt = Path.GetFileNameWithoutExtension(filename); // strip this off to ensure we don't double them up
switch (extension)
{
case ".int":
case ".ita":
case ".deu":
case ".pol":
case ".fra":
return $@"..\..\Localization\{extension.Substring(1).ToUpper()}\{filename}";
case "" when CoalescedConverter.LocalizedFiles.Contains(fNameNoExt, StringComparer.OrdinalIgnoreCase): // No extension, may have been stripped
return $@"..\..\Localization\{localization.ToString().ToUpper()}\{fNameNoExt}.{localization.ToString().ToLower()}";
case ".ini":
return $@"..\..\BIOGame\Config\{filename}";
case "" when CoalescedConverter.ProperNames.Contains(filename, StringComparer.InvariantCultureIgnoreCase): // No extension, may have been stripped
return $@"..\..\BIOGame\Config\{filename}.ini";
case "":
return $@"..\..\BIOGame\Config\{filename}.int"; // It's one of those localization files. Just set it to int. These are never used anyways.
case "" when CoalescedConverter.ProperNames.Contains(fNameNoExt, StringComparer.OrdinalIgnoreCase): // No extension, may have been stripped
return $@"..\..\BIOGame\Config\{fNameNoExt}.ini";

}
throw new Exception($"Filename '{filename}' has invalid file extension for LE1/LE2 Coalesced filename");
}
Expand Down

1 comment on commit fea5c3c

@Mgamerz
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Narrator: It didn't fix it.

Going to write up some tests for this

Please sign in to comment.