Skip to content

Commit c14378e

Browse files
authored
Merge pull request #36 from DDDDDragon/VarImprovement
[Minor] Add variable checking for AssemblyAsString actions
2 parents eeccd5e + b5af1a4 commit c14378e

2 files changed

Lines changed: 64 additions & 4 deletions

File tree

ModUtils/AsmUtils.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,31 @@ public static UndertaleInstruction.Reference<UndertaleVariable> CreateRefVariabl
168168

169169
return new UndertaleInstruction.Reference<UndertaleVariable>(variable, UndertaleInstruction.VariableType.Normal);
170170
}
171+
public static void CheckRefVariableOrCreate(string name, UndertaleInstruction.InstanceType instanceType)
172+
{
173+
try
174+
{
175+
UndertaleVariable? variable = ModLoader.Data.Variables.FirstOrDefault(t => t.Name?.Content == name);
176+
177+
if (variable == null)
178+
{
179+
CreateRefVariable(name, instanceType);
180+
}
181+
else
182+
{
183+
Log.Information(string.Format("Found variable: {0}", variable.ToString()));
184+
}
185+
186+
}
187+
catch
188+
{
189+
throw;
190+
}
191+
}
171192
public static UndertaleInstruction.Reference<UndertaleVariable> GetRefVariableOrCreate(string name, UndertaleInstruction.InstanceType instanceType)
172193
{
173-
try {
194+
try
195+
{
174196
UndertaleInstruction.Reference<UndertaleVariable> refVariable;
175197
UndertaleVariable? variable = ModLoader.Data.Variables.FirstOrDefault(t => t.Name?.Content == name);
176198

@@ -179,12 +201,12 @@ public static UndertaleInstruction.Reference<UndertaleVariable> GetRefVariableOr
179201
else
180202
refVariable = new UndertaleInstruction.Reference<UndertaleVariable>(variable, UndertaleInstruction.VariableType.Normal);
181203

182-
Log.Information(string.Format("Find variable: {0}", refVariable.ToString()));
204+
Log.Information(string.Format("Found variable: {0}", refVariable.ToString()));
183205

184206
return refVariable;
185207
}
186-
catch(Exception ex) {
187-
Log.Error(ex, "Something went wrong");
208+
catch
209+
{
188210
throw;
189211
}
190212
}

ModUtils/CodeUtils.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Runtime.CompilerServices;
66
using System.Text;
7+
using System.Text.RegularExpressions;
78
using ModShardLauncher.Resources.Codes;
89
using Serilog;
910
using UndertaleModLib;
@@ -72,13 +73,47 @@ public override string ToString()
7273
/// </summary>
7374
public class FileEnumerable<T>
7475
{
76+
private readonly Regex variableRegex = new (@"\bpop\.v\.\w\s(?<var>\w+)\.(?<name>\w+)");
7577
public readonly Header header;
7678
public readonly IEnumerable<T> ienumerable;
7779
public FileEnumerable(Header header, IEnumerable<T> ienumerable)
7880
{
7981
this.header = header;
8082
this.ienumerable = ienumerable;
8183
}
84+
/// <summary>
85+
/// Check pop variables for intructions as string and create them if needed.
86+
/// </summary>
87+
/// <param name="instructions"></param>
88+
public void CheckInstructionsVariables(string instructions)
89+
{
90+
if (header.patchingWay != PatchingWay.AssemblyAsString) return;
91+
92+
foreach (string instruction in instructions.Split('\n').Where(x => x.Contains("pop.v")))
93+
{
94+
System.Text.RegularExpressions.Match matches = variableRegex.Match(instruction);
95+
if (matches.Success)
96+
{
97+
string instanceValue = matches.Groups["var"].Value;
98+
if(instanceValue == "self")
99+
{
100+
AssemblyWrapper.CheckRefVariableOrCreate(matches.Groups["name"].Value, UndertaleInstruction.InstanceType.Self);
101+
}
102+
else if(instanceValue == "global")
103+
{
104+
AssemblyWrapper.CheckRefVariableOrCreate(matches.Groups["name"].Value, UndertaleInstruction.InstanceType.Global);
105+
}
106+
else if(instanceValue == "local")
107+
{
108+
AssemblyWrapper.CheckRefVariableOrCreate(matches.Groups["name"].Value, UndertaleInstruction.InstanceType.Local);
109+
}
110+
else
111+
{
112+
Log.Warning("Cannot infer the instance type of {0}. There is a risk it will lead to an undefined variable.", instruction);
113+
}
114+
}
115+
}
116+
}
82117
}
83118
/// <summary>
84119
/// A static class for notably IEnumerable Extensions to provide a functional-programing-like api while modding.
@@ -772,6 +807,7 @@ public static IEnumerable<string> InsertBelow(this IEnumerable<(Match, string)>
772807
/// </summary>
773808
public static FileEnumerable<string> InsertBelow(this FileEnumerable<(Match, string)> fe, string inserting)
774809
{
810+
fe.CheckInstructionsVariables(inserting);
775811
return new(fe.header, fe.ienumerable.InsertBelow(inserting.Split("\n")));
776812
}
777813
/// <summary>
@@ -820,6 +856,7 @@ public static IEnumerable<string> InsertAbove(this IEnumerable<(Match, string)>
820856
/// </summary>
821857
public static FileEnumerable<string> InsertAbove(this FileEnumerable<(Match, string)> fe, string inserting)
822858
{
859+
fe.CheckInstructionsVariables(inserting);
823860
return new(fe.header, fe.ienumerable.InsertAbove(inserting.Split("\n")));
824861
}
825862
/// <summary>
@@ -872,6 +909,7 @@ public static IEnumerable<string> ReplaceBy(this IEnumerable<(Match, string)> ie
872909
/// </summary>
873910
public static FileEnumerable<string> ReplaceBy(this FileEnumerable<(Match, string)> fe, string inserting)
874911
{
912+
fe.CheckInstructionsVariables(inserting);
875913
return new(fe.header, fe.ienumerable.ReplaceBy(inserting.Split("\n")));
876914
}
877915
/// <summary>

0 commit comments

Comments
 (0)