Skip to content

Instantly share code, notes, and snippets.

@lynn
Last active April 1, 2022 11:28
Show Gist options
  • Save lynn/7b326938e2fbe15e0498dc3e9046c637 to your computer and use it in GitHub Desktop.
Save lynn/7b326938e2fbe15e0498dc3e9046c637 to your computer and use it in GitHub Desktop.
Deltarune code extraction script for UndertaleModTool
// Maybe you need to tweak this DLL path for your .NET framework version.
#r "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Text.RegularExpressions.dll"
using System.Text.RegularExpressions;
EnsureDataLoaded();
static var Lang = new Dictionary<string, string>();
public static class Operands {
public static IEnumerable<string> Or(Match m) {
yield return m.Groups[1].Value;
foreach (Capture c in m.Groups[2].Captures) yield return c.Value;
yield return m.Groups[3].Value;
}
public static IEnumerable<string> And(Match m) {
foreach (Capture c in m.Groups[1].Captures) yield return c.Value;
yield return m.Groups[2].Value;
yield return m.Groups[3].Value;
}
}
{
foreach (string line in File.ReadLines(@"C:\Program Files (x86)\SURVEY_PROGRAM\lang\lang_en.json")) {
Regex r1 = new Regex(" \"(\\w+)\": (.*),$");
Match m = r1.Match(line);
if (m.Success) Lang.Add(m.Groups[1].Value, m.Groups[2].Value);
}
using (StreamWriter log = new StreamWriter("__log.txt")) {
foreach (UndertaleCode c in Data.Code) {
log.WriteLine("//// " + c.ToString());
string deco = Decompiler.Decompile(c);
Regex rLoc = new Regex("scr_84_get_lang_string\\(\"([A-Za-z_0-9]+)\"@\\d+\\)");
deco = rLoc.Replace(deco, m => {
string translation = "\"???(Not found)???\"";
Lang.TryGetValue(m.Groups[1].Value, out translation);
return translation;
});
Regex rSpace = new Regex("^[ ]+", RegexOptions.Multiline);
deco = rSpace.Replace(deco, m => new String(' ', Math.Min(m.Length / 4, 10)));
// This whole mess changes constructions like:
//
// if (x) {
// if (y)
// _temp_local_var_52 = z
// else
// _temp_local_var_52 = 0
// }
// else
// _temp_local_var_52 = 0
// if _temp_local_var_52
//
// into:
//
// if (x && y && z)
//
// (Frankly, it's the decompiler that ought to do a better job, but hey.)
//
Regex rAnd = new Regex(@"
(?'g'
if[ ](.+) \n[ ]*
{ \n[ ]*
)*
if[ ](.+) \n[ ]*
(?<v>_temp_local_var_\d+)[ ]=[ ](.+) \n[ ]*
else \n[ ]*
\k<v>[ ]=[ ]0 \n[ ]*
(?'-g'
} \n[ ]*
else \n[ ]*
\k<v>[ ]=[ ]0 \n[ ]*
)*
if[ ]\k<v>
(?(g)(?!))
", RegexOptions.IgnorePatternWhitespace);
deco = rAnd.Replace(deco, m => "if (" + String.Join(" && ", Operands.And(m)) + ")");
Regex rOr = new Regex(@"
if[ ](.+) \n[ ]*
(?'v'_temp_local_var_\d+)[ ]=[ ]1 \n[ ]*
else \n[ ]*
(?'g'
{ \n[ ]*
if[ ](.+) \n[ ]*
\k<v>[ ]=[ ]1 \n[ ]*
else \n[ ]*
)*
\k<v>[ ]=[ ](.+) \n[ ]*
(?'-g'
} \n[ ]*
)*
if[ ]\k<v>
(?(g)(?!))
", RegexOptions.IgnorePatternWhitespace);
deco = rOr.Replace(deco, m => "if (" + String.Join(" || ", Operands.Or(m)) + ")");
log.WriteLine(deco);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment