-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mods: Partial .txt support (Messages)
- Loading branch information
Showing
4 changed files
with
214 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using Memoria.FFPR.Configuration; | ||
using Memoria.FFPR.IL2CPP; | ||
|
||
namespace Memoria.FFPR.Core; | ||
|
||
public sealed class MessageMerger | ||
{ | ||
private const Char Separator = '\t'; | ||
private readonly OrderedDictionary<String, String> _rows = new(); | ||
|
||
public MessageMerger(String txtContent) | ||
{ | ||
if (txtContent is null) throw new ArgumentNullException(nameof(txtContent)); | ||
if (txtContent == String.Empty) throw new ArgumentException(nameof(txtContent)); | ||
|
||
using (var sr = new StringReader(txtContent)) | ||
{ | ||
while (TryReadContent(sr, out String key, out String value)) | ||
_rows.AddOrUpdate(key, value); | ||
} | ||
} | ||
|
||
public void MergeFiles(IReadOnlyList<String> filePaths) | ||
{ | ||
if (filePaths is null) throw new ArgumentNullException(nameof(filePaths)); | ||
|
||
foreach (String fullPath in filePaths) | ||
{ | ||
try | ||
{ | ||
String shortPath = ApplicationPathConverter.ReturnPlaceholders(fullPath); | ||
ModComponent.Log.LogInfo($"[Mod] Merging data from {shortPath}"); | ||
|
||
using (StreamReader sr = File.OpenText(fullPath)) | ||
MergeFile(sr); | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new ArgumentException($"Failed to merge data from {fullPath}", nameof(fullPath), ex); | ||
} | ||
} | ||
} | ||
|
||
public String BuildContent() | ||
{ | ||
using (StringWriter sw = new StringWriter()) | ||
{ | ||
foreach ((String key, String value) in _rows) | ||
sw.WriteLine($"{key}{Separator}{value}"); | ||
|
||
sw.Flush(); | ||
return sw.ToString(); | ||
} | ||
} | ||
|
||
private void MergeFile(StreamReader sr) | ||
{ | ||
while (TryReadContent(sr, out String key, out String value)) | ||
{ | ||
if (_rows.TryReplace(key, value, out var previousValue)) | ||
{ | ||
if (previousValue != value) | ||
ModComponent.Log.LogInfo($"[Mod] Changed message [{key}]: [{previousValue}] -> [{value}]"); | ||
continue; | ||
} | ||
|
||
if (_rows.TryAdd(key, value)) | ||
{ | ||
ModComponent.Log.LogInfo($"[Mod] Added new message [{key}]: [{value}]"); | ||
continue; | ||
} | ||
|
||
throw new InvalidOperationException("Collection is out of sync."); | ||
} | ||
} | ||
|
||
private Boolean TryReadContent(TextReader reader, out String key, out String value) | ||
{ | ||
while (true) | ||
{ | ||
String line = reader.ReadLine(); | ||
if (line is null) | ||
break; | ||
|
||
if (String.IsNullOrWhiteSpace(line)) | ||
continue; | ||
|
||
String[] parts = line.Split(Separator); | ||
switch (parts.Length) | ||
{ | ||
case 1: | ||
{ | ||
key = parts[0]; | ||
value = String.Empty; | ||
break; | ||
} | ||
case 2: | ||
{ | ||
key = parts[0]; | ||
value = parts[1]; | ||
break; | ||
} | ||
default: | ||
{ | ||
throw new FormatException($"Unexpected line in .txt file: {line}"); | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
key = null; | ||
value = null; | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace Memoria.FFPR.Core; | ||
|
||
public sealed class OrderedDictionary<TKey, TValue> : IEnumerable<(TKey key, TValue value)> | ||
{ | ||
private readonly Dictionary<TKey, (Int32 index, TValue value)> _set; | ||
private readonly List<(TKey key, TValue value)> _list; | ||
|
||
public OrderedDictionary() | ||
: this(EqualityComparer<TKey>.Default) | ||
{ | ||
} | ||
|
||
public OrderedDictionary(IEqualityComparer<TKey> comparer) | ||
{ | ||
_set = new Dictionary<TKey, (Int32 index, TValue value)>(comparer); | ||
_list = new List<(TKey key, TValue value)>(); | ||
} | ||
|
||
public void AddOrUpdate(TKey key, TValue value) | ||
{ | ||
if (TryAdd(key, value)) return; | ||
if (TryReplace(key, value, out _)) return; | ||
throw new InvalidOperationException("Collection is out of sync."); | ||
} | ||
|
||
public Boolean TryAdd(TKey key, TValue value) | ||
{ | ||
if (_set.ContainsKey(key)) | ||
return false; | ||
|
||
_set.Add(key, (_list.Count, value)); | ||
_list.Add((key, value)); | ||
return true; | ||
} | ||
|
||
public Boolean TryReplace(TKey key, TValue value, out TValue previousValue) | ||
{ | ||
if (!_set.TryGetValue(key, out var pair)) | ||
{ | ||
previousValue = default; | ||
return false; | ||
} | ||
|
||
previousValue = pair.value; | ||
_set[key] = (pair.index, value); | ||
_list[pair.index] = (key, value); | ||
return true; | ||
} | ||
|
||
public Boolean TryRemove(TKey key, out TValue value) | ||
{ | ||
if (!_set.TryGetValue(key, out var pair)) | ||
{ | ||
value = default; | ||
return false; | ||
} | ||
|
||
_set.Remove(key); | ||
_list.RemoveAt(pair.index); | ||
value = pair.value; | ||
return true; | ||
} | ||
|
||
public Boolean ContainsKey(TKey key) | ||
{ | ||
return _set.ContainsKey(key); | ||
} | ||
|
||
public IEnumerator<(TKey key, TValue value)> GetEnumerator() | ||
{ | ||
return _list.GetEnumerator(); | ||
} | ||
|
||
IEnumerator IEnumerable.GetEnumerator() | ||
{ | ||
return GetEnumerator(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters