2019-12-25 15:32:57 -05:00
|
|
|
|
using Jint;
|
|
|
|
|
using SharedLibraryCore.Database.Models;
|
2018-11-05 22:01:29 -05:00
|
|
|
|
using SharedLibraryCore.Interfaces;
|
2018-08-23 17:16:30 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2019-12-25 15:32:57 -05:00
|
|
|
|
using System.Threading;
|
2018-08-23 17:16:30 -04:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace SharedLibraryCore
|
|
|
|
|
{
|
|
|
|
|
class ScriptPlugin : IPlugin
|
|
|
|
|
{
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
|
|
|
|
public float Version { get; set; }
|
|
|
|
|
|
2018-08-26 20:20:47 -04:00
|
|
|
|
public string Author { get; set; }
|
2018-08-23 17:16:30 -04:00
|
|
|
|
|
2019-12-25 15:32:57 -05:00
|
|
|
|
private Engine ScriptEngine;
|
2018-08-23 17:16:30 -04:00
|
|
|
|
private readonly string FileName;
|
|
|
|
|
private IManager Manager;
|
2019-11-15 15:50:20 -05:00
|
|
|
|
private readonly FileSystemWatcher _watcher;
|
2019-12-25 15:32:57 -05:00
|
|
|
|
private readonly SemaphoreSlim _fileChanging;
|
|
|
|
|
private bool successfullyLoaded;
|
2018-08-23 17:16:30 -04:00
|
|
|
|
|
|
|
|
|
public ScriptPlugin(string fileName)
|
|
|
|
|
{
|
|
|
|
|
FileName = fileName;
|
2019-12-25 15:32:57 -05:00
|
|
|
|
_fileChanging = new SemaphoreSlim(1, 1);
|
2019-11-15 15:50:20 -05:00
|
|
|
|
_watcher = new FileSystemWatcher()
|
2018-08-23 17:16:30 -04:00
|
|
|
|
{
|
|
|
|
|
Path = $"{Utilities.OperatingDirectory}Plugins{Path.DirectorySeparatorChar}",
|
|
|
|
|
NotifyFilter = NotifyFilters.Size,
|
|
|
|
|
Filter = fileName.Split(Path.DirectorySeparatorChar).Last()
|
|
|
|
|
};
|
|
|
|
|
|
2019-11-15 15:50:20 -05:00
|
|
|
|
_watcher.Changed += Watcher_Changed;
|
|
|
|
|
_watcher.EnableRaisingEvents = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ScriptPlugin()
|
|
|
|
|
{
|
|
|
|
|
_watcher.Dispose();
|
2019-12-25 15:32:57 -05:00
|
|
|
|
_fileChanging.Dispose();
|
2018-08-23 17:16:30 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void Watcher_Changed(object sender, FileSystemEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
await _fileChanging.WaitAsync();
|
2018-08-23 17:16:30 -04:00
|
|
|
|
await Initialize(Manager);
|
|
|
|
|
}
|
2019-12-25 15:32:57 -05:00
|
|
|
|
|
2018-08-23 17:16:30 -04:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2019-05-08 21:34:17 -04:00
|
|
|
|
Manager.GetLogger(0).WriteError(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_IMPORTER_ERROR"].FormatExt(Name));
|
2018-10-06 12:47:14 -04:00
|
|
|
|
Manager.GetLogger(0).WriteDebug(ex.Message);
|
2018-08-23 17:16:30 -04:00
|
|
|
|
}
|
2019-12-25 15:32:57 -05:00
|
|
|
|
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
if (_fileChanging.CurrentCount == 0)
|
|
|
|
|
{
|
|
|
|
|
_fileChanging.Release(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-08-23 17:16:30 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task Initialize(IManager mgr)
|
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
// for some reason we get an event trigger when the file is not finished being modified.
|
|
|
|
|
// this must have been a change in .NET CORE 3.x
|
|
|
|
|
// so if the new file is empty we can't process it yet
|
|
|
|
|
if (new FileInfo(FileName).Length == 0L)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-26 20:20:47 -04:00
|
|
|
|
bool firstRun = ScriptEngine == null;
|
2019-12-25 15:32:57 -05:00
|
|
|
|
|
2018-08-23 17:16:30 -04:00
|
|
|
|
// it's been loaded before so we need to call the unload event
|
2018-08-26 20:20:47 -04:00
|
|
|
|
if (!firstRun)
|
2018-08-23 17:16:30 -04:00
|
|
|
|
{
|
|
|
|
|
await OnUnloadAsync();
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-25 15:32:57 -05:00
|
|
|
|
successfullyLoaded = false;
|
2018-08-23 17:16:30 -04:00
|
|
|
|
Manager = mgr;
|
2018-10-09 21:19:06 -04:00
|
|
|
|
string script;
|
|
|
|
|
|
|
|
|
|
using (var stream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
|
|
|
|
{
|
|
|
|
|
using (var reader = new StreamReader(stream, Encoding.Default))
|
|
|
|
|
{
|
|
|
|
|
script = await reader.ReadToEndAsync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-25 15:32:57 -05:00
|
|
|
|
ScriptEngine = new Engine(cfg =>
|
2018-09-04 13:40:29 -04:00
|
|
|
|
cfg.AllowClr(new[]
|
2018-08-26 20:20:47 -04:00
|
|
|
|
{
|
2018-09-02 17:59:27 -04:00
|
|
|
|
typeof(System.Net.Http.HttpClient).Assembly,
|
2018-11-05 22:01:29 -05:00
|
|
|
|
typeof(EFClient).Assembly,
|
2018-08-26 20:20:47 -04:00
|
|
|
|
})
|
|
|
|
|
.CatchClrExceptions());
|
2018-08-23 17:16:30 -04:00
|
|
|
|
|
|
|
|
|
ScriptEngine.Execute(script);
|
|
|
|
|
ScriptEngine.SetValue("_localization", Utilities.CurrentLocalization);
|
|
|
|
|
dynamic pluginObject = ScriptEngine.GetValue("plugin").ToObject();
|
|
|
|
|
|
2019-12-25 15:32:57 -05:00
|
|
|
|
Author = pluginObject.author;
|
|
|
|
|
Name = pluginObject.name;
|
|
|
|
|
Version = (float)pluginObject.version;
|
2019-01-26 21:33:37 -05:00
|
|
|
|
|
2019-01-27 19:54:18 -05:00
|
|
|
|
try
|
2019-01-26 21:33:37 -05:00
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
if(pluginObject.isParser)
|
2019-01-27 19:54:18 -05:00
|
|
|
|
{
|
|
|
|
|
await OnLoadAsync(mgr);
|
|
|
|
|
IEventParser eventParser = (IEventParser)ScriptEngine.GetValue("eventParser").ToObject();
|
|
|
|
|
IRConParser rconParser = (IRConParser)ScriptEngine.GetValue("rconParser").ToObject();
|
|
|
|
|
Manager.AdditionalEventParsers.Add(eventParser);
|
|
|
|
|
Manager.AdditionalRConParsers.Add(rconParser);
|
|
|
|
|
}
|
2019-01-26 21:33:37 -05:00
|
|
|
|
}
|
2019-01-27 19:54:18 -05:00
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
|
2018-08-26 20:20:47 -04:00
|
|
|
|
if (!firstRun)
|
2018-08-23 17:16:30 -04:00
|
|
|
|
{
|
|
|
|
|
await OnLoadAsync(mgr);
|
|
|
|
|
}
|
2019-12-25 15:32:57 -05:00
|
|
|
|
|
|
|
|
|
successfullyLoaded = true;
|
2018-08-23 17:16:30 -04:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-25 15:32:57 -05:00
|
|
|
|
public async Task OnEventAsync(GameEvent E, Server S)
|
2018-08-23 17:16:30 -04:00
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
if (successfullyLoaded)
|
2018-09-04 13:40:29 -04:00
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await _fileChanging.WaitAsync();
|
|
|
|
|
ScriptEngine.SetValue("_gameEvent", E);
|
|
|
|
|
ScriptEngine.SetValue("_server", S);
|
|
|
|
|
ScriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient(S));
|
|
|
|
|
ScriptEngine.Execute("plugin.onEventAsync(_gameEvent, _server)").GetCompletionValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
if (_fileChanging.CurrentCount == 0)
|
|
|
|
|
{
|
|
|
|
|
_fileChanging.Release(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-04 13:40:29 -04:00
|
|
|
|
}
|
2018-08-23 17:16:30 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task OnLoadAsync(IManager manager)
|
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
Manager.GetLogger(0).WriteDebug($"OnLoad executing for {Name}");
|
2018-08-23 17:16:30 -04:00
|
|
|
|
ScriptEngine.SetValue("_manager", manager);
|
|
|
|
|
return Task.FromResult(ScriptEngine.Execute("plugin.onLoadAsync(_manager)").GetCompletionValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task OnTickAsync(Server S)
|
|
|
|
|
{
|
|
|
|
|
ScriptEngine.SetValue("_server", S);
|
|
|
|
|
return Task.FromResult(ScriptEngine.Execute("plugin.onTickAsync(_server)").GetCompletionValue());
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-25 15:32:57 -05:00
|
|
|
|
public async Task OnUnloadAsync()
|
2019-01-27 19:54:18 -05:00
|
|
|
|
{
|
2019-12-25 15:32:57 -05:00
|
|
|
|
if (successfullyLoaded)
|
|
|
|
|
{
|
|
|
|
|
Manager.GetLogger(0).WriteDebug($"OnUnLoad executing for {Name}");
|
|
|
|
|
await Task.FromResult(ScriptEngine.Execute("plugin.onUnloadAsync()").GetCompletionValue());
|
|
|
|
|
}
|
2019-01-27 19:54:18 -05:00
|
|
|
|
}
|
2018-08-23 17:16:30 -04:00
|
|
|
|
}
|
|
|
|
|
}
|