-
Notifications
You must be signed in to change notification settings - Fork 1
/
DM_Find dangerous ESL plugins.pas
136 lines (111 loc) · 2.93 KB
/
DM_Find dangerous ESL plugins.pas
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
{
Find ESL plugins that can corrupt save games and cause crashes.
}
unit FindDangerousESL;
const
// Change to <false> to display only errors.
displayNoErrorsFound = true;
// ************************************************
// * Don't edit values below here
// ************************************************
iESLMaxRecords = $800; // max possible new records in ESL
AnalysisSuccess = 0;
HasTooManyRecords = 2;
HasOtherError = 3;
var
errors: TStringList;
function CheckRecords(f: IInterface): Integer;
var
i: Integer;
e: IInterface;
RecCount, RecMaxFormID, fid: Cardinal;
msg: string;
const
overflowFmt = '%s > "%s": %s';
manyRecsFmt = 'Plugin has too many records and can not ever be turned into an ESL.';
begin
Result := AnalysisSuccess;
for i := 0 to Pred(RecordCount(f)) do begin
e := RecordByIndex(f, i);
// override doesn't affect ESL
if not IsMaster(e) then Continue;
Inc(RecCount);
if RecCount > iESLMaxRecords then begin
errors.Add(manyRecsFmt);
Result := HasTooManyRecords;
Exit;
end;
msg := Check(e);
if msg <> '' then begin
errors.Add(Format(overflowFmt, [Signature(e), EditorID(e), msg]));
Result := HasOtherError;
end;
end;
end;
procedure AddSeparator;
const
sep = '**********************************************';
begin
if displayNoErrorsFound then AddMessage(sep)
else AddMessage(' ');
end;
procedure DisplayAnalysisMessage(espName: string; RecordAnalysis: Integer);
var
msg: string;
i: Integer;
ctdFriendly: Boolean;
const
corruption = #13#10'If you continue to use this plugin, it will surely lead to CTDs.';
successFmt = '%s has no errors.';
errorsFmt = '%s has errors:';
errorFmt = ' %s';
begin
if RecordAnalysis = AnalysisSuccess then begin
if displayNoErrorsFound then
AddMessage(Format(successFmt, [espName]));
Exit;
end;
ctdFriendly := false;
AddSeparator;
AddMessage(Format(errorsFmt, [espName]));
for i := 0 to errors.Count - 1 do begin
msg := errors[i];
ctdFriendly := ctdFriendly or
ContainsText(msg, 'invalid for a light module') or
ContainsText(msg, 'too many records');
AddMessage(Format(errorFmt, [msg]));
end;
if ctdFriendly then AddMessage(corruption);
AddSeparator;
end;
procedure CheckForESL(f: IInterface);
var
msg: string;
begin
errors.Clear;
msg := Check(f);
if msg <> '' then
errors.Add(msg);
DisplayAnalysisMessage(Name(f), CheckRecords(f));
end;
function IsESL(f: IInterface): Boolean;
begin
Result := GetElementEditValues(ElementByIndex(f, 0), 'Record Header\Record Flags\ESL') = 1;
end;
function Initialize: integer;
var
i: integer;
f: IInterface;
begin
errors := TStringList.Create;
// iterate over loaded plugins
for i := 0 to Pred(FileCount) do begin
f := FileByIndex(i);
if (IsESL(f)) then CheckForESL(f);
end;
end;
function Finalize: Integer;
begin
errors.Free;
end;
end.