forked from ScriptedEvents/ScriptedEvents
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScript.cs
More file actions
330 lines (274 loc) · 11.5 KB
/
Script.cs
File metadata and controls
330 lines (274 loc) · 11.5 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
namespace ScriptedEvents
{
using System;
using System.Collections.Generic;
using System.Linq;
using CommandSystem;
using Discord;
using Exiled.API.Features;
using Exiled.API.Features.Pools;
using ScriptedEvents.API.Enums;
using ScriptedEvents.API.Features;
using ScriptedEvents.API.Interfaces;
using ScriptedEvents.Structures;
using ScriptedEvents.Variables;
/// <summary>
/// Represents a script.
/// </summary>
public class Script : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="Script"/> class.
/// Creates a new script and assigns its <see cref="UniqueId"/> to a new <see cref="Guid"/>.
/// </summary>
public Script()
{
Labels = DictionaryPool<string, int>.Pool.Get();
FunctionLabels = DictionaryPool<string, int>.Pool.Get();
Flags = ListPool<Flag>.Pool.Get();
UniqueVariables = DictionaryPool<string, CustomVariable>.Pool.Get();
UniquePlayerVariables = DictionaryPool<string, CustomPlayerVariable>.Pool.Get();
UniqueId = Guid.NewGuid();
Logger.Debug($"Created new script object | ID: {UniqueId}");
}
/// <summary>
/// Finalizes an instance of the <see cref="Script"/> class.
/// </summary>
~Script()
{
Dispose();
}
/// <summary>
/// Gets the unique ID referring to this Script instance.
/// </summary>
public Guid UniqueId { get; }
/// <summary>
/// Gets or sets the name of the script.
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the permission required to read the script.
/// </summary>
public string ReadPermission { get; set; } = "script.read";
/// <summary>
/// Gets or sets the permission required to execute the script.
/// </summary>
public string ExecutePermission { get; set; } = "script.execute";
/// <summary>
/// Gets or sets the path to the script, on the host's computer.
/// </summary>
public string FilePath { get; set; }
/// <summary>
/// Gets or sets the last time the script was read.
/// </summary>
public DateTime LastRead { get; set; }
/// <summary>
/// Gets or sets the last time the script was edited.
/// </summary>
public DateTime LastEdited { get; set; }
/// <summary>
/// Gets or sets the raw text of the script.
/// </summary>
public string RawText { get; set; } = string.Empty;
/// <summary>
/// Gets or sets a list of <see cref="IAction"/> of each action.
/// </summary>
public IAction[] Actions { get; set; }
/// <summary>
/// Gets or sets a list of Labels.
/// </summary>
public Dictionary<string, int> Labels { get; set; }
/// <summary>
/// Gets or sets a list of function labels.
/// </summary>
public Dictionary<string, int> FunctionLabels { get; set; }
/// <summary>
/// Gets the line the script is currently on.
/// </summary>
public int CurrentLine { get; private set; }
/// <summary>
/// Gets a value indicating whether or not the script is currently executing.
/// </summary>
public bool IsRunning { get; internal set; } = false;
/// <summary>
/// Gets or sets a value indicating the time that the script began running.
/// </summary>
public DateTime RunDate { get; set; }
/// <summary>
/// Gets the amount of time the script has been running.
/// </summary>
public TimeSpan RunDuration => DateTime.UtcNow - RunDate;
/// <summary>
/// Gets a list of flags on the script.
/// </summary>
public List<Flag> Flags { get; }
/// <summary>
/// Gets a value indicating whether or not the script is enabled.
/// </summary>
public bool Disabled => HasFlag("DISABLE");
/// <summary>
/// Gets a value indicating whether or not the script is running in debug mode.
/// </summary>
public bool Debug => HasFlag("DEBUG") || MainPlugin.Configs.Debug;
/// <summary>
/// Gets a value indicating whether or not the script is marked as an admin-event (CedMod compatibility).
/// </summary>
public bool AdminEvent => HasFlag("ADMINEVENT");
/// <summary>
/// Gets a value indicating whether or not warnings are suppressed.
/// </summary>
public bool SuppressWarnings => HasFlag("SUPPRESSWARNINGS");
/// <summary>
/// Gets the context that the script was executed in.
/// </summary>
public ExecuteContext Context { get; internal set; }
/// <summary>
/// Gets the sender of the user who executed the script.
/// </summary>
public ICommandSender Sender { get; internal set; }
/// <summary>
/// Gets or sets all line positions from where a JUMP action was executed.
/// </summary>
public List<int> FunctionLabelHistory { get; set; } = new();
/// <summary>
/// Gets the original script which ran this script using the CALL action.
/// </summary>
public Script CallerScript { get; internal set; }
/// <summary>
/// Gets or sets a value indicating whether an IF statement is blocking the execution of actions.
/// </summary>
public bool IfActionBlocksExecution { get; set; } = false;
/// <summary>
/// Gets or sets a <see cref="Dictionary{TKey, TValue}"/> of variables that are unique to this script.
/// </summary>
public Dictionary<string, CustomVariable> UniqueVariables { get; set; }
/// <summary>
/// Gets or sets a <see cref="Dictionary{TKey, TValue}"/> of player variables that are unique to this script.
/// </summary>
public Dictionary<string, CustomPlayerVariable> UniquePlayerVariables { get; set; }
/// <summary>
/// Gets a <see cref="List{T}"/> of coroutines run by this script.
/// </summary>
public List<CoroutineData> Coroutines { get; } = new();
/// <summary>
/// Gets or sets the info about an ongoing player loop.
/// </summary>
public PlayerLoopInfo PlayerLoopInfo { get; set; } = null;
/// <summary>
/// Gets or sets the original action arguments from when the script was read for the first time.
/// </summary>
public Dictionary<IAction, string[]> OriginalActionArgs { get; set; } = new();
/// <summary>
/// Gets or sets the smart arguments for specified action.
/// </summary>
public Dictionary<IAction, string[]> SmartArguments { get; set; } = new();
/// <summary>
/// Gets or sets the names under which to create variables as result of an successful action.
/// </summary>
public Dictionary<IAction, string[]> ResultVariableNames { get; set; } = new();
/// <inheritdoc/>
public void Dispose()
{
Logger.Debug($"Disposing script object | ID: {UniqueId}");
Sender = null;
Actions = null;
RawText = null;
FilePath = null;
DictionaryPool<string, int>.Pool.Return(Labels);
ListPool<Flag>.Pool.Return(Flags);
DictionaryPool<string, CustomVariable>.Pool.Return(UniqueVariables);
DictionaryPool<string, CustomPlayerVariable>.Pool.Return(UniquePlayerVariables);
GC.SuppressFinalize(this);
}
/// <summary>
/// Moves the <see cref="CurrentLine"/> to the specified line.
/// </summary>
/// <param name="line">The line to move to.</param>
public void Jump(int line)
{
CurrentLine = line - 1;
}
/// <summary>
/// Moves the <see cref="CurrentLine"/> to the specified location.
/// </summary>
/// <param name="keyword">Keyword (START, label, or number).</param>
/// <returns>Whether or not the jump was successful.</returns>
public bool JumpToLabel(string keyword)
{
switch (keyword.ToUpper())
{
case "START":
CurrentLine = -1;
return true;
}
if (Labels.TryGetValue(keyword, out int line))
{
CurrentLine = line;
return true;
}
return false;
}
public bool JumpToFunctionLabel(string keyword)
{
if (FunctionLabels.TryGetValue(keyword, out int line))
{
CurrentLine = line;
return true;
}
return false;
}
/// <summary>
/// Moves to the next line.
/// </summary>
public void NextLine() => CurrentLine++;
/// <summary>
/// Logs a debug message to the console.
/// </summary>
/// <param name="input">The input to Logger.</param>
public void DebugLog(string input)
{
if (Debug)
Log.Send($"[{MainPlugin.Singleton.Name}] {input}", LogLevel.Debug, ConsoleColor.Green);
}
/// <summary>
/// Execute the script.
/// </summary>
/// <param name="dispose">Whether or not to dispose at conclusion of execution.</param>
public void Execute(bool dispose = true) => MainPlugin.ScriptModule.RunScript(this, dispose);
/// <summary>
/// Adds a variable.
/// </summary>
/// <param name="name">Name of the variable.</param>
/// <param name="desc">Description of the variable.</param>
/// <param name="value">The value of the variable.</param>
public void AddVariable(string name, string desc, string value)
{
name = name.ToUpper();
if (UniqueVariables.ContainsKey(name))
UniqueVariables.Remove(name);
UniqueVariables.Add(name, new(name, desc, value));
}
/// <summary>
/// Adds a player variable.
/// </summary>
/// <param name="name">Name of the variable.</param>
/// <param name="desc">Description of the variable.</param>
/// <param name="value">The <see cref="IEnumerable{T}"/> of Players for this variable.</param>
public void AddPlayerVariable(string name, string desc, IEnumerable<Player> value)
{
name = name.ToUpper();
if (UniquePlayerVariables.ContainsKey(name))
UniquePlayerVariables.Remove(name);
UniquePlayerVariables.Add(name, new(name, desc, value.ToList()));
}
public bool HasFlag(string key, out Flag flag)
{
flag = Flags.FirstOrDefault(fl => fl.Key == key);
return flag.Key is not null;
}
public bool HasFlag(string key)
=> HasFlag(key, out _);
public void AddFlag(string key, IEnumerable<string> arguments = null)
=> Flags.Add(new(key, arguments));
}
}