-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParserCode.cs
160 lines (144 loc) · 5.99 KB
/
ParserCode.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace SignatureBuilder
{
public abstract class ParserCode
{
public static readonly Regex regexFrag = new Regex(@"\+?\s?Fragment\[(\S+)\]", RegexOptions.Compiled | RegexOptions.Singleline);
public static readonly Regex regexPkt = new Regex(@"Packet\[(.+?)\]:(([0-9A-Fa-f]{2})+)", RegexOptions.Compiled | RegexOptions.Singleline);
/// <summary>
/// [1]: Desc, [3]: Actual Hex-Byte
/// </summary>
public static readonly Regex regexSubcate = new Regex(@"SubCate\[(.+?)\](:([0-9A-Fa-f]{2})+)?", RegexOptions.Compiled | RegexOptions.Singleline);
public static readonly Regex regexSign = new Regex(@"(\$[124]|([A-Fa-f0-9]{2})+|64\$4|73\$4\$gbk|\$gbk|param){1}", RegexOptions.Compiled | RegexOptions.Singleline);
/// <summary>
/// original line number : sanitized code from that line
/// </summary>
protected readonly Dictionary</*ori line num*/int, /*line code*/string> Lines = new Dictionary<int, string>();
public void AddLine(int lineNum, string code)
{
if (!Lines.TryAdd(lineNum, code))
Program.Log(LogLevel.ERR | LogLevel.EXIT, "Failed to add code line with same line number"); // this will never happen..
}
public abstract void BuildSignature();
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <param name="line"></param>
/// <returns>(Signature, JObject)</returns>
public (string, JObject) ParseSignatureLine(string line)
{
dynamic paramInfo = new JObject();
if (line.StartsWith("pad-"))
{
string retn = "";
// build for padding bytes
for (int i = 0; i < int.Parse(line[4..].Trim()); i++)
retn += "00";
paramInfo.name = "Padding";
return (retn, paramInfo);
}
if (!line.Contains(":") || line.StartsWith("SubCate["))
return (null, null);
// ignore comment "//" after argument signature
var args = line.Split(":");
paramInfo.name = args[0];
// args[1] validation
if (!regexSign.Match(args[1]).Success)
{
Program.Log(LogLevel.ERR | LogLevel.EXIT,
"Invalid Signature.",
"Args[1]: [" + args[1] + "]",
"Raw: " + line
);
}
// parse special information
string curr = "";
for (int i = 2; i < args.Length; i++)
{
curr = args[i].Split("//")[0].TrimEnd();
if (curr.StartsWith("R["))
{
// Reference
// remove "R[" & "]":
var arr = new JArray();
paramInfo["func"] = arr;
foreach (var str in (args[i][2..^1]).Split(","))
arr.Add(str);
switch (arr[0].ToString().ToUpper())
{
case "SKILL":
arr[0] = "db_Skill";
break;
case "NPC":
paramInfo["func"][0] = "db_NPC";
break;
case "MAP":
paramInfo["func"][0] = "db_Map";
break;
case "FS":
paramInfo["func"][0] = "db_FormatString";
break;
case "ITEM":
paramInfo["func"][0] = "db_Item";
break;
default:
Program.Log(LogLevel.WARN,
@"Failed to parse ""R"" option",
"Unknown Reference Database: [" + arr[0] + "]",
"Raw: " + curr
);
continue;
}
}
else if (curr.StartsWith("Fn["))
{
// Function
// remove "Fn[" & "]" before split:
paramInfo["func"] = new JArray(curr[3..^1].Split(","));
}
else if (curr.StartsWith("T"))
{
// Force Data Type
var m = Regex.Match(curr, @"T\[(byte|short|ushort|int|uint)\].*", RegexOptions.Compiled).Groups;
if (m[1].Value == " ")
{
Program.Log(LogLevel.WARN,
@"Failed to parse ""T"" option",
"Captured: [" + string.Join(", ", m) + "]",
"Raw: " + curr
);
continue;
}
paramInfo["type"] = m[1].Value;
}
else if (curr.StartsWith("P"))
{
// Param Arg Name
var m = Regex.Match(curr, @"P\[(\@\S+?)\].*", RegexOptions.Compiled).Groups;
if (m[1].Value == "")
{
Program.Log(LogLevel.WARN,
@"Failed to parse ""P"" option",
"Captured: [" + string.Join(", ", m) + "]",
"Raw: " + curr
);
continue;
}
paramInfo["param"] = m[1].Value;
}
else
{
Program.Log(LogLevel.WARN,
$"Skipped unknown info [{args[i]}]"
);
}
}
return (args[1], paramInfo);
}
}
}