This repository was archived by the owner on Dec 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathScriptingProvider.cs
More file actions
213 lines (180 loc) · 7.66 KB
/
Copy pathScriptingProvider.cs
File metadata and controls
213 lines (180 loc) · 7.66 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
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Rocket.API;
using Rocket.API.Configuration;
using Rocket.API.DependencyInjection;
using Rocket.API.Plugins;
using Rocket.Core.Configuration;
using Rocket.Core.Logging;
namespace Rocket.Scripting
{
public abstract class ScriptingProvider : IPluginManager, IConfigurationContext, IScriptingProvider
{
public IDependencyContainer Container { get; }
protected ScriptingProvider(IDependencyContainer container)
{
Container = container.CreateChildContainer();
}
/// <summary>
/// List of all scripting contexts
/// </summary>
public ICollection<IScriptContext> Contexts { get; } = new List<IScriptContext>();
/// <summary>
/// File types associated with the scripting language (e.g. ".js", ".javascript")
/// </summary>
public abstract string[] FileTypes { get; }
/// <summary>
/// Full name of the scripting language (e.g. "JavaScript")
/// </summary>
public abstract string ScriptName { get; }
/// <inheritdoc />
public abstract IEnumerable<IPlugin> Plugins { get; }
/// <inheritdoc />
public IEnumerator<IPlugin> GetEnumerator()
{
return Plugins.GetEnumerator();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <inheritdoc />
public IPlugin GetPlugin(string name)
{
return Plugins.FirstOrDefault(c => c.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
}
/// <inheritdoc />
public bool PluginExists(string name)
{
return GetPlugin(name) != null;
}
/// <inheritdoc />
public void Init()
{
BaseLogger.SkipTypeFromLogging(typeof(GlobalMembersHelper));
if (!Directory.Exists(WorkingDirectory))
Directory.CreateDirectory(WorkingDirectory);
LoadPlugins();
}
/// <inheritdoc />
public void ExecuteSoftDependCode(string pluginName, Action<IPlugin> action)
{
throw new NotSupportedException();
}
/// <summary>
/// <p>Searches for the "Plugin.[filetype]" (e.g. Plugin.js) and runs it</p>
/// <p>Will generate a new plugin instance if context is null</p>
/// </summary>
/// <param name="path">The path to the directory containing the script files</param>
/// <param name="context">The script context. Can be null if there is none.</param>
public virtual ScriptResult LoadPluginFromDirectory(string path, ref IScriptContext context)
{
var files = Directory.GetFiles(path);
if (files.Length == 0)
{
return new ScriptResult(ScriptExecutionResult.FileNotFound);
}
ScriptPluginMeta meta = GetPluginMeta(path);
string targetFile = null;
foreach (var file in files)
{
string fileName = Path.GetFileNameWithoutExtension(file);
string ext = Path.GetExtension(file);
if (fileName.Equals("plugin", StringComparison.OrdinalIgnoreCase) &&
FileTypes.Any(c => c.Equals(ext, StringComparison.OrdinalIgnoreCase)))
{
targetFile = file;
}
}
if (targetFile == null)
return new ScriptResult(ScriptExecutionResult.FileNotFound);
return ExecuteFile(targetFile, Container, ref context, meta, true);
}
/// <summary>
/// Get information about the plugin in the given directory.
/// </summary>
/// <param name="path">The plugin directory.</param>
/// <returns></returns>
public virtual ScriptPluginMeta GetPluginMeta(string path)
{
IConfiguration jsonConfiguration = Container.Resolve<IConfiguration>("json");
var metaFile = Path.Combine(path, "plugin.json");
if (!File.Exists(metaFile))
throw new FileNotFoundException(null, metaFile);
var dir = Path.GetDirectoryName(metaFile);
var name = Path.GetFileNameWithoutExtension(metaFile);
var configContext = new ConfigurationContext(dir, name);
jsonConfiguration.Load(configContext);
return jsonConfiguration.Get<ScriptPluginMeta>();
}
/// <summary>
/// Registers the context to the scripting engine.
/// </summary>
/// <param name="context">The script context.</param>
public virtual void RegisterContext(IScriptContext context)
{
Contexts.Add(context);
}
public virtual void UnregisterContext(IScriptContext context)
{
Contexts.Remove(context);
}
public abstract bool SupportsRepl { get; }
/// <summary>
/// Executes the given script file
/// </summary>
/// <param name="path">The path to the file.</param>
/// <param name="entryPoint">The entry function to call.</param>
/// <param name="context">The script context. Can be null if there is none.</param>
/// <param name="createPluginInstanceOnNull">Create a new plugin instance when <paramref name="context"/> is null?</param>
/// <param name="container">The dependency container.</param>
/// <param name="meta">Metadata for the plugin if <paramref name="createPluginInstanceOnNull"/> is true and <paramref name="context"/> is null. Can be null if <paramref name="createPluginInstanceOnNull"/> is false.</param>
/// <param name="arguments">The arguments for the entry point.</param>
/// <returns>The result of the script execution.</returns>
public abstract ScriptResult ExecuteFile(
string path,
IDependencyContainer container,
ref IScriptContext context,
ScriptPluginMeta meta,
bool createPluginInstanceOnNull = false,
string entryPoint = null,
params object[] arguments
);
/// <summary>
/// Executes the given script file
/// </summary>
/// <param name="path">The path to the file.</param>
/// <param name="entryPoint">The entry function to call.</param>
/// <param name="context">The script context. Can be null if there is none.</param>
/// <param name="container">The dependency container.</param>
/// <param name="arguments">The arguments for the entry point.</param>
/// <returns>The result of the script execution.</returns>
public virtual ScriptResult ExecuteFile(
string path,
IDependencyContainer container,
ref IScriptContext context,
string entryPoint,
params object[] arguments
) =>
ExecuteFile(path, container, ref context, null, false, entryPoint, arguments);
public abstract IScriptContext CreateScriptContext(IDependencyContainer container);
public abstract void LoadPlugins();
public abstract void UnloadPlugins();
/// <inheritdoc />
public string WorkingDirectory
{
get
{
var baseDir = Container.Resolve<IRuntime>().WorkingDirectory;
return Path.Combine(Path.Combine(baseDir, "Scripts"), ScriptName);
}
}
/// <inheritdoc />
public string ConfigurationName => ScriptName;
public abstract string ServiceName { get; }
}
}