See More

using ScriptedEvents.Enums; using ScriptedEvents.Interfaces; 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.Features; using ScriptedEvents.API.Modules; using ScriptedEvents.Structures; using ScriptedEvents.Variables; using ScriptedEvents.Variables.Interfaces; ///

/// Represents a script. /// public class Script : IDisposable { /// /// Initializes a new instance of the class. /// Creates a new script and assigns its to a new . /// public Script() { Labels = DictionaryPool.Pool.Get(); FunctionLabels = DictionaryPool.Pool.Get(); Flags = ListPool.Pool.Get(); LocalLiteralVariables = DictionaryPool.Pool.Get(); LocalPlayerVariables = DictionaryPool.Pool.Get(); UniqueId = Guid.NewGuid(); Logger.Debug($"Created new script object | ID: {UniqueId}"); } /// /// Finalizes an instance of the class. /// ~Script() { Dispose(); } /// /// Gets the unique ID referring to this Script instance. /// public Guid UniqueId { get; } /// /// Gets or sets the name of the script. /// public string ScriptName { get; set; } = string.Empty; /// /// Gets or sets the permission required to read the script. /// public string ReadPermission { get; set; } = "script.read"; /// /// Gets or sets the permission required to execute the script. /// public string ExecutePermission { get; set; } = "script.execute"; /// /// Gets or sets the path to the script, on the host's computer. /// public string FilePath { get; set; } /// /// Gets or sets the last time the script was read. /// public DateTime LastRead { get; set; } /// /// Gets or sets the last time the script was edited. /// public DateTime LastEdited { get; set; } /// /// Gets or sets the raw text of the script. /// public string RawText { get; set; } = string.Empty; /// /// Gets or sets a list of of each action. /// public IAction[] Actions { get; set; } /// /// Gets or sets a list of Labels. /// public Dictionary Labels { get; set; } /// /// Gets or sets a list of function labels. /// public Dictionary FunctionLabels { get; set; } /// /// Gets or sets the line the script is currently on. /// public int CurrentLine { get; set; } = 0; /// /// Gets a value indicating whether or not the script is currently executing. /// public bool IsRunning { get; internal set; } = false; /// /// Gets or sets a value indicating the time that the script began running. /// public DateTime RunDate { get; set; } /// /// Gets the amount of time the script has been running. /// public TimeSpan RunDuration => DateTime.Now - RunDate; /// /// Gets a list of flags on the script. /// public List Flags { get; } /// /// Gets a value indicating whether or not the script is enabled. /// public bool IsDisabled => HasFlag("DISABLE"); /// /// Gets a value indicating whether or not the script is running in debug mode. /// public bool IsDebug => HasFlag("DEBUG") || MainPlugin.Configs.Debug; /// /// Gets a value indicating whether or not the script is marked as an admin-event (CedMod compatibility). /// public bool AdminEvent => HasFlag("ADMINEVENT"); /// /// Gets a value indicating whether or not warnings are suppressed. /// public bool SuppressWarnings => HasFlag("SUPPRESSWARNINGS"); /// /// Gets the context that the script was executed in. /// public ExecuteContext Context { get; internal set; } /// /// Gets the sender of the user who executed the script. /// public ICommandSender? Sender { get; internal set; } /// /// Gets or sets all line positions from where a JUMP action was executed. /// public List FunctionLabelHistory { get; set; } = new(); /// /// Gets the original script which ran this script using the CALL action. /// public Script? CallerScript { get; internal set; } /// /// Gets a of variables that are unique to this script. /// public Dictionary LocalLiteralVariables { get; } /// /// Gets a of player variables that are unique to this script. /// public Dictionary LocalPlayerVariables { get; } /// /// Gets a of coroutines run by this script. /// public List Coroutines { get; } = new(); /// /// Gets or sets the info about an ongoing player loop. /// public PlayerLoopInfo? PlayerLoopInfo { get; set; } = null; /// /// Gets the original action arguments from when the script was read for the first time. /// public Dictionary OriginalActionArgs { get; } = new(); /// /// Gets the attached arguments for specified action. /// public Dictionary>[]> AttachedArguments { get; } = new(); /// /// Gets the names under which to create variables as result of an successful action. /// public Dictionary ResultVariableNames { get; } = new(); /// /// Gets the lambda method that checks if action is allowed to run. /// public Dictionary> SingleLineIfStatements { get; } = new(); /// public void Dispose() { Logger.Debug($"Disposing script object | ID: {UniqueId}"); Sender = null; Actions = Array.Empty(); RawText = string.Empty; FilePath = string.Empty; DictionaryPool.Pool.Return(Labels); ListPool.Pool.Return(Flags); DictionaryPool.Pool.Return(LocalLiteralVariables); DictionaryPool.Pool.Return(LocalPlayerVariables); GC.SuppressFinalize(this); } /// /// Moves the to the specified line. /// /// The line to move to. public void Jump(int line) { CurrentLine = line - 1; } /// /// Moves the to the specified location. /// /// Keyword (START, label, or number). /// Whether or not the jump was successful. 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; } /// /// Moves to the next line. /// public void NextLine() => CurrentLine++; /// /// Logs a debug message to the console. /// /// The input to Logger. public void DebugLog(string input) { if (IsDebug) Log.Send($"[{MainPlugin.Singleton.Name}] {input}", LogLevel.Debug, ConsoleColor.Green); } /// /// Adds a variable. /// /// Name of the variable. /// The value of the variable. /// Whether variable name has already been verified to be valid. public void AddLiteralVariable(string name, string value, bool isVariableNameVerified) { if (!VariableSystem.IsValidVariableSyntax(name, out name, out var info) && !isVariableNameVerified) { throw new ArgumentException(info!.ToTrace().Format()); } LocalLiteralVariables[name] = new(name, string.Empty, value); } /// /// Adds a player variable. /// /// Name of the variable. /// The of Players for this variable. /// Whether variable name has already been verified to be valid. public void AddPlayerVariable(string name, IEnumerable value, bool isVariableNameVerified) { if (!VariableSystem.IsValidVariableSyntax(name, out var processedName, out var info) && !isVariableNameVerified) { throw new ArgumentException(info!.ToTrace().Format()); } LocalPlayerVariables[processedName] = new(processedName, string.Empty, value); } public bool RemoveVariable(T var) where T : IVariable { return var switch { IPlayerVariable playerVariable => LocalPlayerVariables.Remove(playerVariable.Name), ILiteralVariable literalVariable => LocalLiteralVariables.Remove(literalVariable.Name), _ => throw new ArgumentException($"Variable '{var}' is not a valid variable type.") }; } public bool IsVariableLocal(T var) where T : IVariable { return var switch { IPlayerVariable playerVariable => LocalPlayerVariables.ContainsKey(playerVariable.Name), ILiteralVariable literalVariable => LocalLiteralVariables.ContainsKey(literalVariable.Name), _ => throw new ArgumentException($"Variable '{var}' is not a valid variable type.") }; } 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? arguments = null) => Flags.Add(new(key, arguments ?? Array.Empty())); } }