using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json.Serialization;
using GDWeave;
using GDWeave.Godot;
using GDWeave.Godot.Variants;
using GDWeave.Modding;
using Teemaw.Calico.LexicalTransformer;
using Teemaw.Calico.Util;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
[assembly: AssemblyCompany("Atproto")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2.0+9120dafea672e86e66fa29c12a49d0e4dd746205")]
[assembly: AssemblyProduct("Atproto")]
[assembly: AssemblyTitle("Atproto")]
[assembly: AssemblyVersion("1.0.2.0")]
[module: RefSafetyRules(11)]
namespace Teemaw.Calico.Util
{
public static class ScriptTokenizer
{
private static readonly Dictionary<string, TokenType> Tokens = new Dictionary<string, TokenType>
{
{
"continue",
(TokenType)44
},
{
"return",
(TokenType)46
},
{
"break",
(TokenType)43
},
{
"match",
(TokenType)47
},
{
"while",
(TokenType)42
},
{
"elif",
(TokenType)39
},
{
"else",
(TokenType)40
},
{
"pass",
(TokenType)45
},
{
"for",
(TokenType)41
},
{
"if",
(TokenType)38
},
{
"const",
(TokenType)58
},
{
"var",
(TokenType)59
},
{
"func",
(TokenType)48
},
{
"class",
(TokenType)49
},
{
"extends",
(TokenType)51
},
{
"is",
(TokenType)52
},
{
"as",
(TokenType)60
},
{
"@onready",
(TokenType)53
},
{
"@tool",
(TokenType)54
},
{
"@export",
(TokenType)56
},
{
"yield",
(TokenType)65
},
{
"setget",
(TokenType)57
},
{
"static",
(TokenType)55
},
{
"void",
(TokenType)61
},
{
"enum",
(TokenType)62
},
{
"preload",
(TokenType)63
},
{
"assert",
(TokenType)64
},
{
"signal",
(TokenType)66
},
{
"breakpoint",
(TokenType)67
},
{
"sync",
(TokenType)69
},
{
"remote",
(TokenType)68
},
{
"master",
(TokenType)70
},
{
"slave",
(TokenType)71
},
{
"puppet",
(TokenType)72
},
{
"remotesync",
(TokenType)73
},
{
"mastersync",
(TokenType)74
},
{
"puppetsync",
(TokenType)75
},
{
"\n",
(TokenType)89
},
{
"PI",
(TokenType)90
},
{
"TAU",
(TokenType)91
},
{
"INF",
(TokenType)93
},
{
"NAN",
(TokenType)94
},
{
"error",
(TokenType)95
},
{
"cursor",
(TokenType)97
},
{
"self",
(TokenType)3
},
{
"in",
(TokenType)6
},
{
"_",
(TokenType)92
},
{
"[",
(TokenType)76
},
{
"]",
(TokenType)77
},
{
"{",
(TokenType)78
},
{
"}",
(TokenType)79
},
{
"(",
(TokenType)80
},
{
")",
(TokenType)81
},
{
",",
(TokenType)82
},
{
";",
(TokenType)83
},
{
".",
(TokenType)84
},
{
"?",
(TokenType)85
},
{
":",
(TokenType)86
},
{
"$",
(TokenType)87
},
{
"->",
(TokenType)88
},
{
">>=",
(TokenType)30
},
{
"<<=",
(TokenType)29
},
{
">>",
(TokenType)22
},
{
"<<",
(TokenType)21
},
{
"==",
(TokenType)7
},
{
"!=",
(TokenType)8
},
{
"&&",
(TokenType)13
},
{
"||",
(TokenType)14
},
{
"!",
(TokenType)15
},
{
"+=",
(TokenType)24
},
{
"-=",
(TokenType)25
},
{
"*=",
(TokenType)26
},
{
"/=",
(TokenType)27
},
{
"%=",
(TokenType)28
},
{
"&=",
(TokenType)31
},
{
"|=",
(TokenType)32
},
{
"^=",
(TokenType)33
},
{
"+",
(TokenType)16
},
{
"-",
(TokenType)17
},
{
"*",
(TokenType)18
},
{
"/",
(TokenType)19
},
{
"%",
(TokenType)20
},
{
"~",
(TokenType)37
},
{
"&",
(TokenType)34
},
{
"|",
(TokenType)35
},
{
"^",
(TokenType)36
},
{
"<=",
(TokenType)10
},
{
">=",
(TokenType)12
},
{
"<",
(TokenType)9
},
{
">",
(TokenType)11
},
{
"=",
(TokenType)23
}
};
private static readonly HashSet<string> Symbols = new HashSet<string>
{
"->", ">>=", "<<=", ">>", "<<", "==", "!=", "&&", "||", "!",
"+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "_", "[",
"]", "{", "}", "(", ")", ",", ";", ".", "?", ":",
"$", "+", "-", "*", "/", "%", "~", "&", "|", "^",
"<=", ">=", "<", ">", "="
};
private static readonly List<string> BuiltinFunctions = Enum.GetNames<BuiltinFunction>().ToList();
private static void InsertNewLine(IEnumerator<string> enumerator, uint baseIndent, List<Token> toFlush)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (enumerator.MoveNext())
{
uint num = uint.Parse(enumerator.Current);
toFlush.Add(new Token((TokenType)89, (uint?)(num + baseIndent)));
}
}
private static void BuildIdentifierName(IEnumerator<string> enumerator, List<Token> toFlush, out string? found)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
found = string.Empty;
if (enumerator.MoveNext())
{
if (enumerator.Current == ":")
{
toFlush.Add(new Token((TokenType)92, (uint?)null));
toFlush.Add(new Token((TokenType)83, (uint?)null));
}
else
{
found = "_" + enumerator.Current;
}
}
}
private static void BuildNumber(IEnumerator<string> enumerator, List<Token> toFlush, out bool foundFull)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
foundFull = true;
int num = 1;
if (enumerator.Current == "-")
{
num = -1;
if (!enumerator.MoveNext())
{
return;
}
}
if (!long.TryParse(enumerator.Current, out var result))
{
toFlush.Add(new Token((TokenType)17, (uint?)null));
foundFull = false;
}
else if (enumerator.MoveNext())
{
long result2;
if (enumerator.Current != ".")
{
toFlush.Add((Token)new ConstantToken((Variant)new IntVariant(result * num, false)));
foundFull = false;
}
else if (enumerator.MoveNext() && long.TryParse(enumerator.Current, out result2))
{
double num2 = (double)result + (double)result2 / Math.Pow(10.0, result2.ToString().Length);
toFlush.Add((Token)new ConstantToken((Variant)new RealVariant(num2 * (double)num, false)));
}
}
}
public static IEnumerable<Token> Tokenize(string gdScript, uint baseIndent = 0u)
{
List<Token> finalTokens = new List<Token>();
IEnumerable<string> enumerable = SanitizeInput(TokenizeString(gdScript + " "));
string previous = string.Empty;
string idName = string.Empty;
List<Token> toFlush = new List<Token>(2);
IEnumerator<string> enumerator = enumerable.GetEnumerator();
bool flag = false;
while (flag || enumerator.MoveNext())
{
flag = false;
TokenType value;
bool result;
if (enumerator.Current == "\n")
{
InsertNewLine(enumerator, baseIndent, toFlush);
endAndFlushId();
}
else if (enumerator.Current == "_")
{
BuildIdentifierName(enumerator, toFlush, out string found);
if (found == string.Empty)
{
endAndFlushId();
continue;
}
idName += found;
end();
}
else if (char.IsDigit(enumerator.Current[0]))
{
BuildNumber(enumerator, toFlush, out var foundFull);
flag = !foundFull;
endAndFlushId();
}
else if (BuiltinFunctions.Contains(enumerator.Current))
{
toFlush.Add(new Token((TokenType)5, (uint?)(uint)BuiltinFunctions.IndexOf(enumerator.Current)));
endAndFlushId();
}
else if (Tokens.TryGetValue(enumerator.Current, out value))
{
toFlush.Add(new Token(value, (uint?)null));
endAndFlushId();
}
else if (enumerator.Current.StartsWith('"'))
{
string current = enumerator.Current;
toFlush.Add((Token)new ConstantToken((Variant)new StringVariant(current.Substring(1, current.Length - 2))));
endAndFlushId();
}
else if (bool.TryParse(enumerator.Current, out result))
{
toFlush.Add((Token)new ConstantToken((Variant)new BoolVariant(result)));
endAndFlushId();
}
else
{
idName += enumerator.Current;
end();
}
}
foreach (Token item in finalTokens)
{
yield return item;
}
void end()
{
previous = enumerator.Current;
finalTokens.AddRange(toFlush);
toFlush.Clear();
}
void endAndFlushId()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_0353: Unknown result type (might be due to invalid IL or missing references)
//IL_035d: Expected O, but got Unknown
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0258: Expected O, but got Unknown
//IL_0253: Unknown result type (might be due to invalid IL or missing references)
//IL_025d: Expected O, but got Unknown
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Expected O, but got Unknown
//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
//IL_02f3: Expected O, but got Unknown
//IL_0239: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Expected O, but got Unknown
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
//IL_0340: Expected O, but got Unknown
//IL_0293: Unknown result type (might be due to invalid IL or missing references)
//IL_029d: Expected O, but got Unknown
//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02ba: Expected O, but got Unknown
//IL_031c: Unknown result type (might be due to invalid IL or missing references)
//IL_0326: Expected O, but got Unknown
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_030c: Expected O, but got Unknown
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_0226: Expected O, but got Unknown
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_027d: Expected O, but got Unknown
if (idName != string.Empty)
{
if (idName.Trim() == "return")
{
finalTokens.Add(new Token((TokenType)46, (uint?)null));
}
else if (idName.Trim() == "self")
{
finalTokens.Add(new Token((TokenType)3, (uint?)null));
}
else
{
switch (idName.Trim())
{
case "print":
finalTokens.Add(new Token((TokenType)5, (uint?)63u));
break;
case "min":
finalTokens.Add(new Token((TokenType)5, (uint?)52u));
break;
case "null":
finalTokens.Add((Token)new ConstantToken((Variant)new NilVariant()));
break;
case "break":
finalTokens.Add(new Token((TokenType)43, (uint?)null));
break;
case "match":
finalTokens.Add(new Token((TokenType)47, (uint?)null));
break;
case "Color":
finalTokens.Add(new Token((TokenType)4, (uint?)14u));
break;
case "Vector3":
finalTokens.Add(new Token((TokenType)4, (uint?)7u));
break;
case "lerp_angle":
finalTokens.Add(new Token((TokenType)5, (uint?)31u));
break;
case "int":
finalTokens.Add(new Token((TokenType)4, (uint?)2u));
break;
case "pow":
finalTokens.Add(new Token((TokenType)5, (uint?)19u));
break;
case "abs":
finalTokens.Add(new Token((TokenType)5, (uint?)17u));
break;
default:
finalTokens.Add((Token)new IdentifierToken(idName.Trim()));
break;
}
}
idName = string.Empty;
}
end();
}
}
private static IEnumerable<string> SanitizeInput(IEnumerable<string> tokens)
{
foreach (string token in tokens)
{
if (!(token != "\n") || !string.IsNullOrWhiteSpace(token))
{
yield return token;
}
}
}
private static IEnumerable<string> TokenizeString(string text)
{
StringBuilder builder = new StringBuilder(20);
for (int i = 0; i < text.Length; i++)
{
switch (text[i])
{
case '"':
yield return ClearBuilder();
builder.Append('"');
for (i++; i < text.Length; i++)
{
builder.Append(text[i]);
if (text[i] == '"')
{
break;
}
}
yield return ClearBuilder();
continue;
case '\n':
{
yield return ClearBuilder();
int start = i;
for (i++; i < text.Length && text[i] == '\t'; i++)
{
}
i--;
yield return "\n";
yield return $"{i - start}";
continue;
}
}
bool flag = false;
foreach (string delimiter in Symbols)
{
if (Match(text, i, delimiter))
{
yield return ClearBuilder();
yield return delimiter;
i += delimiter.Length - 1;
flag = true;
break;
}
}
if (!flag)
{
if (text[i] == ' ')
{
yield return ClearBuilder();
}
else
{
builder.Append(text[i]);
}
}
}
yield return "\n";
string ClearBuilder()
{
string result = builder.ToString();
builder.Clear();
return result;
}
}
private static bool Match(string text, int index, string match)
{
if (index + match.Length > text.Length)
{
return false;
}
for (int i = 0; i < match.Length; i++)
{
if (text[index + i] != match[i])
{
return false;
}
}
return true;
}
}
public static class TokenUtil
{
public static IEnumerable<Token> ReplaceAssignmentsAsDeferred(IEnumerable<Token> tokens, HashSet<string>? ignoredIdentifiers = null)
{
Token val = null;
bool inAssignmentStatement = false;
bool skipLine = false;
foreach (Token t in tokens)
{
if (t == null)
{
goto IL_00b8;
}
TokenType type = t.Type;
if ((int)type != 59)
{
if ((int)type != 89)
{
goto IL_00b8;
}
skipLine = false;
}
else
{
skipLine = true;
}
goto IL_01d9;
IL_00b8:
IdentifierToken identifier = (IdentifierToken)(object)((val is IdentifierToken) ? val : null);
if (identifier != null && (ignoredIdentifiers == null || !ignoredIdentifiers.Contains(identifier.Name)) && t != null && (int)t.Type == 23 && !skipLine)
{
inAssignmentStatement = true;
yield return (Token)new IdentifierToken("set_deferred");
yield return new Token((TokenType)80, (uint?)null);
yield return (Token)new ConstantToken((Variant)new StringVariant(identifier.Name));
yield return new Token((TokenType)82, (uint?)null);
val = null;
continue;
}
goto IL_01d9;
IL_01d9:
if ((int)t.Type == 89 && inAssignmentStatement)
{
inAssignmentStatement = false;
if (val != null)
{
yield return val;
}
yield return new Token((TokenType)81, (uint?)null);
yield return t;
}
else if (val != null)
{
yield return val;
}
val = (Token)((inAssignmentStatement && t != null && (int)t.Type == 1) ? ((object)StripAssociatedData(t)) : ((object)t));
}
if (val != null)
{
yield return val;
}
}
public static Token ReplaceToken(Token cursor, Token target, Token replacement)
{
if (!TokenEquals(cursor, target))
{
return cursor;
}
return replacement;
}
public static IEnumerable<Token> ReplaceTokens(IEnumerable<Token> haystack, IEnumerable<Token> needle, IEnumerable<Token> replacements)
{
List<Token> list = haystack.ToList();
List<Token> list2 = needle.ToList();
List<Token> collection = replacements.ToList();
if (list2.Count == 0)
{
return list;
}
List<Token> list3 = new List<Token>();
int num = 0;
while (num < list.Count)
{
if (IsMatch(list, list2, num))
{
list3.AddRange(collection);
num += list2.Count;
}
else
{
list3.Add(list[num]);
num++;
}
}
return list3;
}
private static bool IsMatch(List<Token> haystack, List<Token> needle, int startIndex)
{
if (startIndex + needle.Count > haystack.Count)
{
return false;
}
for (int i = 0; i < needle.Count; i++)
{
if (!TokenEquals(haystack[startIndex + i], needle[i]))
{
return false;
}
}
return true;
}
private static bool TokenEquals(Token token, Token token1)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
IdentifierToken val = (IdentifierToken)(object)((token is IdentifierToken) ? token : null);
if (val != null)
{
IdentifierToken val2 = (IdentifierToken)(object)((token1 is IdentifierToken) ? token1 : null);
if (val2 != null)
{
return val.Name == val2.Name;
}
}
ConstantToken val3 = (ConstantToken)(object)((token is ConstantToken) ? token : null);
if (val3 != null)
{
ConstantToken val4 = (ConstantToken)(object)((token1 is ConstantToken) ? token1 : null);
if (val4 != null)
{
return val3.Value.Equals(val4.Value);
}
}
if (token.Type == token1.Type)
{
return token.AssociatedData == token1.AssociatedData;
}
return false;
}
private static Token StripAssociatedData(Token token)
{
token.AssociatedData = null;
return token;
}
}
public static class WeaveUtil
{
public static bool IsModLoaded(IModInterface modInterface, string modName)
{
return modInterface.LoadedMods.Contains(modName);
}
}
}
namespace Teemaw.Calico.LexicalTransformer
{
public static class TransformationPatternFactory
{
public static Func<Token, bool>[] CreateGlobalsPattern()
{
return new Func<Token, bool>[3]
{
(Token t) => (int)t.Type == 51,
(Token t) => (int)t.Type == 1,
(Token t) => (int)t.Type == 89
};
}
public static Func<Token, bool>[] CreateFunctionDefinitionPattern(string name, string[]? args = null)
{
List<Func<Token, bool>> list = new List<Func<Token, bool>>();
list.Add((Token t) => (int)t.Type == 48);
list.Add(delegate(Token t)
{
IdentifierToken val = (IdentifierToken)(object)((t is IdentifierToken) ? t : null);
return val != null && val.Name == name;
});
list.Add((Token t) => (int)t.Type == 80);
if (args != null && args.Length > 0)
{
foreach (string arg in args)
{
list.Add(delegate(Token t)
{
IdentifierToken val = (IdentifierToken)(object)((t is IdentifierToken) ? t : null);
return val != null && val.Name == arg;
});
list.Add((Token t) => (int)t.Type == 82);
}
list.RemoveAt(list.Count - 1);
}
list.Add((Token t) => (int)t.Type == 81);
list.Add((Token t) => (int)t.Type == 86);
return list.ToArray();
}
public static Func<Token, bool>[] CreateGdSnippetPattern(string snippet, uint indent = 0u)
{
return ScriptTokenizer.Tokenize(snippet, indent).Select((Func<Token, Func<Token, bool>>)((Token snippetToken) => delegate(Token t)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if ((int)t.Type == 1)
{
Token obj = snippetToken;
IdentifierToken val = (IdentifierToken)(object)((obj is IdentifierToken) ? obj : null);
if (val != null)
{
IdentifierToken val2 = (IdentifierToken)(object)((t is IdentifierToken) ? t : null);
if (val2 != null)
{
return val.Name == val2.Name;
}
}
return false;
}
if ((int)t.Type == 2)
{
Token obj2 = snippetToken;
ConstantToken val3 = (ConstantToken)(object)((obj2 is ConstantToken) ? obj2 : null);
if (val3 != null)
{
ConstantToken val4 = (ConstantToken)(object)((t is ConstantToken) ? t : null);
if (val4 != null)
{
return val3.Value.Equals(val4.Value);
}
}
return false;
}
return t.Type == snippetToken.Type;
})).ToArray();
}
}
public enum Operation
{
None,
ReplaceAll,
ReplaceLast,
Append,
Prepend
}
public static class OperationExtensions
{
public static bool RequiresBuffer(this Operation operation)
{
if (operation == Operation.ReplaceAll || operation == Operation.Prepend)
{
return true;
}
return false;
}
public static bool YieldTokenBeforeOperation(this Operation operation)
{
if (operation == Operation.None || operation == Operation.Append)
{
return true;
}
return false;
}
public static bool YieldTokenAfterOperation(this Operation operation)
{
if (!operation.RequiresBuffer() && !operation.YieldTokenBeforeOperation())
{
return operation != Operation.ReplaceLast;
}
return false;
}
}
public record TransformationRule(string Name, Func<Token, bool>[] Pattern, Func<Token, bool>[] ScopePattern, IEnumerable<Token> Tokens, Operation Operation, uint Times, Func<bool> Predicate)
{
public MultiTokenWaiter CreateMultiTokenWaiter()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
return new MultiTokenWaiter(Pattern, false, false);
}
public MultiTokenWaiter CreateMultiTokenWaiterForScope()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
return new MultiTokenWaiter(ScopePattern, false, false);
}
}
public class TransformationRuleBuilder
{
private string? _name;
private Func<Token, bool>[]? _pattern;
private Func<Token, bool>[] _scopePattern = Array.Empty<Func<Token, bool>>();
private IEnumerable<Token>? _tokens;
private uint _times = 1u;
private Operation _operation = Operation.Append;
private Func<bool> _predicate = () => true;
public TransformationRuleBuilder Named(string name)
{
_name = name;
return this;
}
public TransformationRuleBuilder Matching(Func<Token, bool>[] pattern)
{
_pattern = pattern;
return this;
}
public TransformationRuleBuilder With(IEnumerable<Token> tokens)
{
_tokens = tokens;
return this;
}
public TransformationRuleBuilder With(Token token)
{
_tokens = new <>z__ReadOnlySingleElementList<Token>(token);
return this;
}
public TransformationRuleBuilder With(string snippet, uint indent = 0u)
{
_tokens = ScriptTokenizer.Tokenize(snippet, indent);
return this;
}
public TransformationRuleBuilder Do(Operation operation)
{
_operation = operation;
return this;
}
public TransformationRuleBuilder ExpectTimes(uint times)
{
_times = times;
return this;
}
public TransformationRuleBuilder ScopedTo(Func<Token, bool>[] scopePattern)
{
_scopePattern = scopePattern;
return this;
}
public TransformationRuleBuilder When(Func<bool> predicate)
{
_predicate = predicate;
return this;
}
public TransformationRuleBuilder When(bool eligible)
{
_predicate = () => eligible;
return this;
}
public TransformationRule Build()
{
if (string.IsNullOrEmpty(_name))
{
throw new ArgumentNullException("_name", "Name cannot be null or empty");
}
if (_pattern == null)
{
throw new ArgumentNullException("_pattern", "Pattern cannot be null");
}
if (_tokens == null)
{
throw new ArgumentNullException("_tokens", "Tokens cannot be null");
}
return new TransformationRule(_name, _pattern, _scopePattern, _tokens, _operation, _times, _predicate);
}
}
public class TransformationRuleScriptMod(IModInterface mod, string name, string scriptPath, Func<bool> predicate, TransformationRule[] rules) : IScriptMod
{
public bool ShouldRun(string path)
{
if (path != scriptPath)
{
return false;
}
if (!predicate())
{
mod.Logger.Information("[" + name + "] Predicate failed, not patching.");
return false;
}
return true;
}
public IEnumerable<Token> Modify(string path, IEnumerable<Token> tokens)
{
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Invalid comparison between Unknown and I4
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Invalid comparison between Unknown and I4
List<TransformationRule> source = rules.Where(delegate(TransformationRule rule)
{
bool num2 = rule.Predicate();
if (!num2)
{
mod.Logger.Information($"[{name}] Skipping patch {rule.Name}...");
}
return num2;
}).ToList();
List<(TransformationRule, MultiTokenWaiter, List<Token>)> list = source.Select((TransformationRule rule) => (Rule: rule, Waiter: rule.CreateMultiTokenWaiter(), Buffer: new List<Token>())).ToList();
mod.Logger.Information("[" + name + "] Patching " + path);
Dictionary<string, (int, uint)> dictionary = source.ToDictionary((TransformationRule r) => r.Name, (TransformationRule r) => (Occurred: 0, Expected: r.Times));
bool flag = true;
List<Token> list2 = new List<Token>();
list2.AddRange(tokens);
List<Token> list3 = new List<Token>();
foreach (var item in list)
{
bool flag2 = item.Item1.ScopePattern.Length != 0;
bool flag3 = !flag2;
uint? num = null;
MultiTokenWaiter val = item.Item1.CreateMultiTokenWaiterForScope();
foreach (Token item2 in list2)
{
if (flag3 && flag2)
{
if (!num.HasValue && (int)item2.Type == 89)
{
num = item2.AssociatedData.GetValueOrDefault();
}
else if (num.HasValue && (int)item2.Type == 89)
{
flag3 = item2.AssociatedData.GetValueOrDefault() >= num;
}
}
else if (flag2 && val.Check(item2))
{
val.Reset();
flag3 = true;
}
if (!flag3)
{
list3.Add(item2);
continue;
}
item.Item2.Check(item2);
if (item.Item2.Step == 0)
{
list3.AddRange(item.Item3);
item.Item3.Clear();
}
else
{
if (item.Item1.Operation.RequiresBuffer())
{
item.Item3.Add(item2);
flag = false;
}
if (item.Item2.Matched)
{
item.Item2.Reset();
if (item.Item1.Operation.YieldTokenBeforeOperation())
{
list3.Add(item2);
flag = false;
}
else
{
flag = item.Item1.Operation.YieldTokenAfterOperation();
}
switch (item.Item1.Operation)
{
case Operation.Prepend:
list3.AddRange(item.Item1.Tokens);
list3.AddRange(item.Item3);
item.Item3.Clear();
break;
case Operation.ReplaceAll:
case Operation.ReplaceLast:
case Operation.Append:
item.Item3.Clear();
list3.AddRange(item.Item1.Tokens);
break;
}
mod.Logger.Information($"[{name}] Patch {item.Item1.Name} OK!");
string name = item.Item1.Name;
(int, uint) value = dictionary[item.Item1.Name];
value.Item1 = dictionary[item.Item1.Name].Item1 + 1;
dictionary[name] = value;
}
}
if (flag)
{
list3.Add(item2);
}
else
{
flag = true;
}
}
list2.Clear();
list2.AddRange(list3);
list3.Clear();
}
foreach (KeyValuePair<string, (int, uint)> item3 in dictionary.Where<KeyValuePair<string, (int, uint)>>((KeyValuePair<string, (int Occurred, uint Expected)> result) => result.Value.Occurred != result.Value.Expected))
{
mod.Logger.Error($"[{name}] Patch {item3.Key} FAILED! Times expected={item3.Value.Item2}, actual={item3.Value.Item1}");
}
return list2;
}
}
public class TransformationRuleScriptModBuilder
{
private IModInterface? _mod;
private string? _name;
private string? _scriptPath;
private Func<bool> _predicate = () => true;
private List<TransformationRule> _rules = new List<TransformationRule>();
public TransformationRuleScriptModBuilder ForMod(IModInterface mod)
{
_mod = mod;
return this;
}
public TransformationRuleScriptModBuilder When(Func<bool> predicate)
{
_predicate = predicate;
return this;
}
public TransformationRuleScriptModBuilder Named(string name)
{
_name = name;
return this;
}
public TransformationRuleScriptModBuilder Patching(string scriptPath)
{
_scriptPath = scriptPath;
return this;
}
public TransformationRuleScriptModBuilder AddRule(TransformationRule rule)
{
if (_rules.Select((TransformationRule r) => r.Name).Contains(rule.Name))
{
throw new InvalidOperationException("Another rule with the name '" + rule.Name + "' already exists!");
}
_rules.Add(rule);
return this;
}
public TransformationRuleScriptModBuilder AddRule(TransformationRuleBuilder rule)
{
return AddRule(rule.Build());
}
public TransformationRuleScriptMod Build()
{
if (_mod == null)
{
throw new ArgumentNullException("_mod", "Mod cannot be null");
}
if (string.IsNullOrEmpty(_name))
{
throw new ArgumentNullException("_name", "Name cannot be null or empty");
}
if (string.IsNullOrEmpty(_scriptPath))
{
throw new ArgumentNullException("_scriptPath", "Script path cannot be null or empty");
}
return new TransformationRuleScriptMod(_mod, _name, _scriptPath, _predicate, _rules.ToArray());
}
}
}
namespace Atproto
{
public class AtProtoSaveFactory
{
public static IScriptMod Create(IModInterface mod)
{
return (IScriptMod)(object)new TransformationRuleScriptModBuilder().ForMod(mod).Named("AtProtoSave").Patching("res://Scenes/Singletons/UserSave/usersave.gdc")
.AddRule(new TransformationRuleBuilder().Named("ready_slot_condition").Matching(TransformationPatternFactory.CreateGdSnippetPattern("_load_save(last_loaded_slot)", 2u)).Do(Operation.ReplaceAll)
.With("var Atproto = $\"/root/Atproto\"\nif last_loaded_slot != Atproto.ATPROTO_SLOT or Atproto.config.Autoload:\n\t_load_save(last_loaded_slot)\nelse:\n\tlast_loaded_slot = -1", 2u))
.AddRule(new TransformationRuleBuilder().Named("save_file").Matching(TransformationPatternFactory.CreateGdSnippetPattern("\"locked_refs\": PlayerData.locked_refs, \n\t}\n", 2u)).Do(Operation.Append)
.With("var atproto = $\"/root/Atproto\"\nif atproto.can_save_to_atproto():\n\tatproto.AtProtoClient.save_file()\n", 1u))
.Build();
}
}
public static class CatchFishFactory
{
public static IScriptMod Create(IModInterface mod)
{
return (IScriptMod)(object)new TransformationRuleScriptModBuilder().ForMod(mod).Named("CatchFish").Patching("res://Scenes/Entities/Player/player.gdc")
.AddRule(new TransformationRuleBuilder().Named("create_fish_record").Matching(TransformationPatternFactory.CreateGdSnippetPattern("PlayerData._log_item(fish_roll, size, quality)\n", 3u)).Do(Operation.Append)
.With("$\"/root/Atproto\".AtProtoClient.catch_fish(fish_roll, size, quality)\n", 3u))
.Build();
}
}
public static class CatptureFishFactory
{
public static IScriptMod Create(IModInterface mod)
{
return (IScriptMod)(object)new TransformationRuleScriptModBuilder().ForMod(mod).Named("CaptureFish").Patching("res://Scenes/Entities/Props/fish_trap.gdc")
.AddRule(new TransformationRuleBuilder().Named("create_fish_record").Matching(TransformationPatternFactory.CreateGdSnippetPattern("PlayerData._log_item(fish_roll, size, quality)\n", 1u)).Do(Operation.Append)
.With("$\"/root/Atproto\".AtProtoClient.catch_fish(fish_roll, size, quality)\n", 1u))
.Build();
}
}
public class Config
{
[JsonInclude]
public string Handle = "";
[JsonInclude]
public string Password = "";
[JsonInclude]
public string Save = "";
[JsonInclude]
public bool Autoconnect;
[JsonInclude]
public bool Autoload;
}
public class Mod : IMod, IDisposable
{
public Config Config;
public Mod(IModInterface modInterface)
{
Config = modInterface.ReadConfig<Config>();
modInterface.RegisterScriptMod(CatchFishFactory.Create(modInterface));
modInterface.RegisterScriptMod(CatptureFishFactory.Create(modInterface));
modInterface.RegisterScriptMod(AtProtoSaveFactory.Create(modInterface));
}
public void Dispose()
{
}
}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
{
object IEnumerator.Current => _item;
T IEnumerator<T>.Current => _item;
public Enumerator(T item)
{
_item = item;
}
bool IEnumerator.MoveNext()
{
if (!_moveNextCalled)
{
return _moveNextCalled = true;
}
return false;
}
void IEnumerator.Reset()
{
_moveNextCalled = false;
}
void IDisposable.Dispose()
{
}
}
int ICollection.Count => 1;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object? IList.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => 1;
T IReadOnlyList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
}
int ICollection<T>.Count => 1;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlySingleElementList(T item)
{
_item = item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection.CopyTo(Array array, int index)
{
array.SetValue(_item, index);
}
int IList.Add(object? value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object? value)
{
return EqualityComparer<T>.Default.Equals(_item, (T)value);
}
int IList.IndexOf(object? value)
{
if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
{
return -1;
}
return 0;
}
void IList.Insert(int index, object? value)
{
throw new NotSupportedException();
}
void IList.Remove(object? value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return EqualityComparer<T>.Default.Equals(_item, item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
array[arrayIndex] = _item;
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
if (!EqualityComparer<T>.Default.Equals(_item, item))
{
return -1;
}
return 0;
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}