|
4 | 4 | using System.Linq; |
5 | 5 | using System.Runtime.CompilerServices; |
6 | 6 | using System.Text; |
| 7 | +using System.Text.RegularExpressions; |
7 | 8 | using ModShardLauncher.Resources.Codes; |
8 | 9 | using Serilog; |
9 | 10 | using UndertaleModLib; |
@@ -72,13 +73,47 @@ public override string ToString() |
72 | 73 | /// </summary> |
73 | 74 | public class FileEnumerable<T> |
74 | 75 | { |
| 76 | + private readonly Regex variableRegex = new (@"\bpop\.v\.\w\s(?<var>\w+)\.(?<name>\w+)"); |
75 | 77 | public readonly Header header; |
76 | 78 | public readonly IEnumerable<T> ienumerable; |
77 | 79 | public FileEnumerable(Header header, IEnumerable<T> ienumerable) |
78 | 80 | { |
79 | 81 | this.header = header; |
80 | 82 | this.ienumerable = ienumerable; |
81 | 83 | } |
| 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 | + } |
82 | 117 | } |
83 | 118 | /// <summary> |
84 | 119 | /// 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)> |
772 | 807 | /// </summary> |
773 | 808 | public static FileEnumerable<string> InsertBelow(this FileEnumerable<(Match, string)> fe, string inserting) |
774 | 809 | { |
| 810 | + fe.CheckInstructionsVariables(inserting); |
775 | 811 | return new(fe.header, fe.ienumerable.InsertBelow(inserting.Split("\n"))); |
776 | 812 | } |
777 | 813 | /// <summary> |
@@ -820,6 +856,7 @@ public static IEnumerable<string> InsertAbove(this IEnumerable<(Match, string)> |
820 | 856 | /// </summary> |
821 | 857 | public static FileEnumerable<string> InsertAbove(this FileEnumerable<(Match, string)> fe, string inserting) |
822 | 858 | { |
| 859 | + fe.CheckInstructionsVariables(inserting); |
823 | 860 | return new(fe.header, fe.ienumerable.InsertAbove(inserting.Split("\n"))); |
824 | 861 | } |
825 | 862 | /// <summary> |
@@ -872,6 +909,7 @@ public static IEnumerable<string> ReplaceBy(this IEnumerable<(Match, string)> ie |
872 | 909 | /// </summary> |
873 | 910 | public static FileEnumerable<string> ReplaceBy(this FileEnumerable<(Match, string)> fe, string inserting) |
874 | 911 | { |
| 912 | + fe.CheckInstructionsVariables(inserting); |
875 | 913 | return new(fe.header, fe.ienumerable.ReplaceBy(inserting.Split("\n"))); |
876 | 914 | } |
877 | 915 | /// <summary> |
|
0 commit comments