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;
///
/// 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();
UniqueVariables = DictionaryPool.Pool.Get();
UniquePlayerVariables = 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 Name { 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 the line the script is currently on.
///
public int CurrentLine { get; private set; }
///
/// 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.UtcNow - 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 Disabled => HasFlag("DISABLE");
///
/// Gets a value indicating whether or not the script is running in debug mode.
///
public bool Debug => 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 or sets a value indicating whether an IF statement is blocking the execution of actions.
///
public bool IfActionBlocksExecution { get; set; } = false;
///
/// Gets or sets a of variables that are unique to this script.
///
public Dictionary UniqueVariables { get; set; }
///
/// Gets or sets a of player variables that are unique to this script.
///
public Dictionary UniquePlayerVariables { get; set; }
///
/// 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 or sets the original action arguments from when the script was read for the first time.
///
public Dictionary OriginalActionArgs { get; set; } = new();
///
/// Gets or sets the smart arguments for specified action.
///
public Dictionary SmartArguments { get; set; } = new();
///
/// Gets or sets the names under which to create variables as result of an successful action.
///
public Dictionary ResultVariableNames { get; set; } = new();
///
public void Dispose()
{
Logger.Debug($"Disposing script object | ID: {UniqueId}");
Sender = null;
Actions = null;
RawText = null;
FilePath = null;
DictionaryPool.Pool.Return(Labels);
ListPool.Pool.Return(Flags);
DictionaryPool.Pool.Return(UniqueVariables);
DictionaryPool.Pool.Return(UniquePlayerVariables);
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 (Debug)
Exiled.API.Features.Log.Send($"[{MainPlugin.Singleton.Name}] {input}", LogLevel.Debug, ConsoleColor.Green);
}
///
/// Execute the script.
///
/// Whether or not to dispose at conclusion of execution.
public void Execute(bool dispose = true) => MainPlugin.ScriptModule.RunScript(this, dispose);
///
/// Adds a variable.
///
/// Name of the variable.
/// Description of the variable.
/// The value of the variable.
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));
}
///
/// Adds a player variable.
///
/// Name of the variable.
/// Description of the variable.
/// The of Players for this variable.
public void AddPlayerVariable(string name, string desc, IEnumerable 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 arguments = null)
=> Flags.Add(new(key, arguments));
}
}