This commit is contained in:
Даниил Заикин
2026-06-17 20:44:53 +03:00
parent 9d153773c2
commit b133e7c656
1880 changed files with 244545 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 015e5afa17239334c8f085479673d346
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,153 @@
#if NET_4_6 && !NET_STANDARD_2_0
#define QC_SUPPORTED
#endif
using Mono.CSharp;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Reflection.Emit;
using System.Text;
#if QC_SUPPORTED
namespace CSharpCompiler
{
public class CodeCompiler : ICodeCompiler
{
static long assemblyCounter = 0;
public CompilerResults CompileAssemblyFromDom(CompilerParameters options, CodeCompileUnit compilationUnit)
{
return CompileAssemblyFromDomBatch(options, new[] { compilationUnit });
}
public CompilerResults CompileAssemblyFromDomBatch(CompilerParameters options, CodeCompileUnit[] ea)
{
if (options == null)
{
throw new ArgumentNullException("options");
}
try
{
return CompileFromDomBatch(options, ea);
}
finally
{
options.TempFiles.Delete();
}
}
private CompilerResults CompileFromDomBatch(CompilerParameters options, CodeCompileUnit[] ea)
{
throw new NotImplementedException("sorry ICodeGenerator is not implemented, feel free to fix it and request merge");
}
public CompilerResults CompileAssemblyFromFile(CompilerParameters options, string fileName)
{
return CompileAssemblyFromFileBatch(options, new[] { fileName });
}
public CompilerResults CompileAssemblyFromFileBatch(CompilerParameters options, string[] fileNames)
{
var settings = ParamsToSettings(options);
foreach (var fileName in fileNames)
{
string path = Path.GetFullPath(fileName);
var unit = new SourceFile(fileName, path, settings.SourceFiles.Count + 1);
settings.SourceFiles.Add(unit);
}
return CompileFromCompilerSettings(settings, options.GenerateInMemory);
}
public CompilerResults CompileAssemblyFromSource(CompilerParameters options, string source)
{
return CompileAssemblyFromSourceBatch(options, new[] { source });
}
public CompilerResults CompileAssemblyFromSourceBatch(CompilerParameters options, string[] sources)
{
var settings = ParamsToSettings(options);
int i = 0;
foreach (var _source in sources)
{
var source = _source;
Func<Stream> getStream = () => { return new MemoryStream(Encoding.UTF8.GetBytes(source ?? "")); };
var fileName = i.ToString();
var unit = new SourceFile(fileName, fileName, settings.SourceFiles.Count + 1, getStream);
settings.SourceFiles.Add(unit);
i++;
}
return CompileFromCompilerSettings(settings, options.GenerateInMemory);
}
CompilerResults CompileFromCompilerSettings(CompilerSettings settings, bool generateInMemory)
{
var compilerResults = new CompilerResults(new TempFileCollection(Path.GetTempPath()));
var driver = new CustomDynamicDriver(new CompilerContext(settings, new CustomReportPrinter(compilerResults)));
AssemblyBuilder outAssembly = null;
try
{
driver.Compile(out outAssembly, AppDomain.CurrentDomain, generateInMemory);
}
catch (Exception e)
{
compilerResults.Errors.Add(new CompilerError()
{
IsWarning = false,
ErrorText = e.Message,
});
}
compilerResults.CompiledAssembly = outAssembly;
return compilerResults;
}
CompilerSettings ParamsToSettings(CompilerParameters parameters)
{
var settings = new CompilerSettings();
foreach (var assembly in parameters.ReferencedAssemblies) settings.AssemblyReferences.Add(assembly);
settings.Encoding = System.Text.Encoding.UTF8;
settings.GenerateDebugInfo = parameters.IncludeDebugInformation;
settings.MainClass = parameters.MainClass;
settings.Platform = Platform.AnyCPU;
settings.StdLibRuntimeVersion = RuntimeVersion.v4;
if (parameters.GenerateExecutable)
{
settings.Target = Target.Exe;
settings.TargetExt = ".exe";
}
else
{
settings.Target = Target.Library;
settings.TargetExt = ".dll";
}
if (parameters.GenerateInMemory) settings.Target = Target.Library;
if (string.IsNullOrEmpty(parameters.OutputAssembly))
{
parameters.OutputAssembly = settings.OutputFile = "DynamicAssembly_" + assemblyCounter + settings.TargetExt;
assemblyCounter++;
}
settings.OutputFile = parameters.OutputAssembly; // if it is not being outputted, we use this to set name of the dynamic assembly
settings.Version = LanguageVersion.Default;
settings.WarningLevel = parameters.WarningLevel;
settings.WarningsAreErrors = parameters.TreatWarningsAsErrors;
return settings;
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f3f2a9227250eeb43a8e3c138ce1a6a1
timeCreated: 1438909233
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,317 @@
// modified version of Mono.CSharp.Driver
// driver.cs: The compiler command line driver.
//
// Authors:
// Miguel de Icaza (miguel@gnu.org)
// Marek Safar (marek.safar@gmail.com)
//
// Dual licensed under the terms of the MIT X11 or GNU GPL
//
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
// Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
// Copyright 2011 Xamarin Inc
//
#if NET_4_6 && !NET_STANDARD_2_0
#define QC_SUPPORTED
#endif
#if QC_SUPPORTED
using Mono.CSharp;
using System;
using System.IO;
using System.Reflection.Emit;
namespace CSharpCompiler
{
/// <summary>
/// The compiler driver.
/// </summary>
public class CustomDynamicDriver
{
readonly CompilerContext ctx;
public CustomDynamicDriver(CompilerContext ctx)
{
this.ctx = ctx;
}
public Report Report
{
get
{
return ctx.Report;
}
}
void tokenize_file(SourceFile sourceFile, ModuleContainer module, ParserSession session)
{
Stream input;
try
{
input = sourceFile.GetDataStream();
}
catch
{
Report.Error(2001, "Source file `" + sourceFile.Name + "' could not be found");
return;
}
using (input)
{
SeekableStreamReader reader = new SeekableStreamReader(input, ctx.Settings.Encoding);
var file = new CompilationSourceFile(module, sourceFile);
Tokenizer lexer = new Tokenizer(reader, file, session, ctx.Report);
int token, tokens = 0, errors = 0;
while ((token = lexer.token()) != Token.EOF)
{
tokens++;
if (token == Token.ERROR)
errors++;
}
Console.WriteLine("Tokenized: " + tokens + " found " + errors + " errors");
}
return;
}
public void Parse(ModuleContainer module)
{
bool tokenize_only = module.Compiler.Settings.TokenizeOnly;
var sources = module.Compiler.SourceFiles;
Location.Initialize(sources);
var session = new ParserSession
{
UseJayGlobalArrays = true,
LocatedTokens = new LocatedToken[15000]
};
for (int i = 0; i < sources.Count; ++i)
{
if (tokenize_only)
{
tokenize_file(sources[i], module, session);
}
else
{
Parse(sources[i], module, session, Report);
}
}
}
public void Parse(SourceFile file, ModuleContainer module, ParserSession session, Report report)
{
Stream input;
try
{
input = file.GetDataStream();
}
catch
{
report.Error(2001, "Source file `{0}' could not be found", file.Name);
return;
}
// Check 'MZ' header
if (input.ReadByte() == 77 && input.ReadByte() == 90)
{
report.Error(2015, "Source file `{0}' is a binary file and not a text file", file.Name);
input.Close();
return;
}
input.Position = 0;
SeekableStreamReader reader = new SeekableStreamReader(input, ctx.Settings.Encoding, session.StreamReaderBuffer);
Parse(reader, file, module, session, report);
if (ctx.Settings.GenerateDebugInfo && report.Errors == 0 && !file.HasChecksum)
{
input.Position = 0;
var checksum = session.GetChecksumAlgorithm();
file.SetChecksum(checksum.ComputeHash(input));
}
reader.Dispose();
input.Close();
}
public static void Parse(SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, ParserSession session, Report report)
{
var file = new CompilationSourceFile(module, sourceFile);
module.AddTypeContainer(file);
CSharpParser parser = new CSharpParser(reader, file, report, session);
parser.parse();
}
//
// Main compilation method
//
public bool Compile(out AssemblyBuilder outAssembly, AppDomain domain, bool generateInMemory)
{
var settings = ctx.Settings;
outAssembly = null;
//
// If we are an exe, require a source file for the entry point or
// if there is nothing to put in the assembly, and we are not a library
//
if (settings.FirstSourceFile == null &&
((settings.Target == Target.Exe || settings.Target == Target.WinExe || settings.Target == Target.Module) ||
settings.Resources == null))
{
Report.Error(2008, "No files to compile were specified");
return false;
}
if (settings.Platform == Platform.AnyCPU32Preferred && (settings.Target == Target.Library || settings.Target == Target.Module))
{
Report.Error(4023, "Platform option `anycpu32bitpreferred' is valid only for executables");
return false;
}
TimeReporter tr = new TimeReporter(settings.Timestamps);
ctx.TimeReporter = tr;
tr.StartTotal();
var module = new ModuleContainer(ctx);
RootContext.ToplevelTypes = module;
tr.Start(TimeReporter.TimerType.ParseTotal);
Parse(module);
tr.Stop(TimeReporter.TimerType.ParseTotal);
if (Report.Errors > 0)
return false;
if (settings.TokenizeOnly || settings.ParseOnly)
{
tr.StopTotal();
tr.ShowStats();
return true;
}
var output_file = settings.OutputFile;
string output_file_name;
/* if (output_file == null)
{
var source_file = settings.FirstSourceFile;
if (source_file == null)
{
Report.Error(1562, "If no source files are specified you must specify the output file with -out:");
return false;
}
output_file_name = source_file.Name;
int pos = output_file_name.LastIndexOf('.');
if (pos > 0)
output_file_name = output_file_name.Substring(0, pos);
output_file_name += settings.TargetExt;
output_file = output_file_name;
}
else
{*/
output_file_name = Path.GetFileName(output_file);
/* if (string.IsNullOrEmpty(Path.GetFileNameWithoutExtension(output_file_name)) ||
output_file_name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
{
Report.Error(2021, "Output file name is not valid");
return false;
}
}*/
var assembly = new AssemblyDefinitionDynamic(module, output_file_name, output_file);
module.SetDeclaringAssembly(assembly);
var importer = new ReflectionImporter(module, ctx.BuiltinTypes);
assembly.Importer = importer;
var loader = new DynamicLoader(importer, ctx);
loader.LoadReferences(module);
if (!ctx.BuiltinTypes.CheckDefinitions(module))
return false;
if (!assembly.Create(domain, AssemblyBuilderAccess.RunAndSave))
return false;
module.CreateContainer();
loader.LoadModules(assembly, module.GlobalRootNamespace);
module.InitializePredefinedTypes();
if (settings.GetResourceStrings != null)
module.LoadGetResourceStrings(settings.GetResourceStrings);
tr.Start(TimeReporter.TimerType.ModuleDefinitionTotal);
module.Define();
tr.Stop(TimeReporter.TimerType.ModuleDefinitionTotal);
if (Report.Errors > 0)
return false;
if (settings.DocumentationFile != null)
{
var doc = new DocumentationBuilder(module);
doc.OutputDocComment(output_file, settings.DocumentationFile);
}
assembly.Resolve();
if (Report.Errors > 0)
return false;
tr.Start(TimeReporter.TimerType.EmitTotal);
assembly.Emit();
tr.Stop(TimeReporter.TimerType.EmitTotal);
if (Report.Errors > 0)
{
return false;
}
tr.Start(TimeReporter.TimerType.CloseTypes);
module.CloseContainer();
tr.Stop(TimeReporter.TimerType.CloseTypes);
tr.Start(TimeReporter.TimerType.Resouces);
if (!settings.WriteMetadataOnly)
assembly.EmbedResources();
tr.Stop(TimeReporter.TimerType.Resouces);
if (Report.Errors > 0)
return false;
if (!generateInMemory) assembly.Save();
outAssembly = assembly.Builder;
tr.StopTotal();
tr.ShowStats();
return Report.Errors == 0;
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e389d8a5b0e25ae44a841060cecca276
timeCreated: 1435446720
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,53 @@
#if NET_4_6 && !NET_STANDARD_2_0
#define QC_SUPPORTED
#endif
using Mono.CSharp;
using System.CodeDom.Compiler;
#if QC_SUPPORTED
namespace CSharpCompiler
{
public class CustomReportPrinter : ReportPrinter
{
readonly CompilerResults compilerResults;
#region Properties
public new int ErrorsCount { get; protected set; }
public new int WarningsCount { get; private set; }
#endregion
public CustomReportPrinter(CompilerResults compilerResults)
{
this.compilerResults = compilerResults;
}
public override void Print(AbstractMessage msg, bool showFullPath)
{
if (msg.IsWarning)
{
++WarningsCount;
}
else
{
++ErrorsCount;
}
compilerResults.Errors.Add(new CompilerError()
{
IsWarning = msg.IsWarning,
Column = msg.Location.Column,
Line = msg.Location.Row,
ErrorNumber = msg.Code.ToString(),
ErrorText = msg.Text,
FileName = showFullPath ? msg.Location.SourceFile.FullPathName : msg.Location.SourceFile.Name,
// msg.RelatedSymbols // extra info
});
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 39ec208e78505e342a2829289445b934
timeCreated: 1438909233
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,99 @@
/*
Implementation of ISynchronizeInvoke for Unity3D game engine.
Can be used to invoke anything on main Unity thread.
ISynchronizeInvoke is used extensively in .NET forms it's is elegant and quite useful in Unity as well.
I implemented it so i can use it with System.IO.FileSystemWatcher.SynchronizingObject.
help from: http://www.codeproject.com/Articles/12082/A-DelegateQueue-Class
example usage: https://gist.github.com/aeroson/90bf21be3fdc4829e631
license: WTFPL (http://www.wtfpl.net/)
contact: aeroson (theaeroson @gmail.com)
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
public class DeferredSynchronizeInvoke : ISynchronizeInvoke
{
Queue<UnityAsyncResult> fifoToExecute = new Queue<UnityAsyncResult>();
Thread mainThread;
public bool InvokeRequired { get { return mainThread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId; } }
public DeferredSynchronizeInvoke()
{
mainThread = Thread.CurrentThread;
}
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
var asyncResult = new UnityAsyncResult()
{
method = method,
args = args,
IsCompleted = false,
AsyncWaitHandle = new ManualResetEvent(false),
};
lock (fifoToExecute)
{
fifoToExecute.Enqueue(asyncResult);
}
return asyncResult;
}
public object EndInvoke(IAsyncResult result)
{
if (!result.IsCompleted)
{
result.AsyncWaitHandle.WaitOne();
}
return result.AsyncState;
}
public object Invoke(Delegate method, object[] args)
{
if (InvokeRequired)
{
var asyncResult = BeginInvoke(method, args);
return EndInvoke(asyncResult);
}
else
{
return method.DynamicInvoke(args);
}
}
public void ProcessQueue()
{
if (Thread.CurrentThread != mainThread)
{
throw new TargetException(
this.GetType() + "." + MethodBase.GetCurrentMethod().Name + "() " +
"must be called from the same thread it was created on " +
"(created on thread id: " + mainThread.ManagedThreadId + ", called from thread id: " + Thread.CurrentThread.ManagedThreadId
);
}
bool loop = true;
UnityAsyncResult data = null;
while (loop)
{
lock (fifoToExecute)
{
loop = fifoToExecute.Count > 0;
if (!loop) break;
data = fifoToExecute.Dequeue();
}
data.AsyncState = Invoke(data.method, data.args);
data.IsCompleted = true;
}
}
class UnityAsyncResult : IAsyncResult
{
public Delegate method;
public object[] args;
public bool IsCompleted { get; set; }
public WaitHandle AsyncWaitHandle { get; internal set; }
public object AsyncState { get; set; }
public bool CompletedSynchronously { get { return IsCompleted; } }
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f6228134abfaad746965d9639b73908a
timeCreated: 1435576341
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,21 @@
Copyright (c) 2001, 2002, 2003 Ximian, Inc and the individuals listed
on the ChangeLog entries.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 09298e73731a3b64fbedf483cf7d4e42
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2ce9bfedd125d1c49adb5c65c9e8ce53
folderAsset: yes
timeCreated: 1435432572
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
fileFormatVersion: 2
guid: 0447405aaa6f3bd4c96d4c64631542fd
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,172 @@
#if NET_4_6 && !NET_STANDARD_2_0
#define QC_SUPPORTED
#endif
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
#if QC_SUPPORTED
namespace CSharpCompiler
{
public class ScriptBundleLoader
{
public Func<Type, object> createInstance = (Type type) => { return Activator.CreateInstance(type); };
public Action<object> destroyInstance = delegate { };
public TextWriter logWriter = Console.Out;
ISynchronizeInvoke synchronizedInvoke;
List<ScriptBundle> allFilesBundle = new List<ScriptBundle>();
public ScriptBundleLoader(ISynchronizeInvoke synchronizedInvoke)
{
this.synchronizedInvoke = synchronizedInvoke;
}
/// <summary>
///
/// </summary>
/// <param name="fileSources"></param>
/// <returns>true on success, false on failure</returns>
public ScriptBundle LoadAndWatchScriptsBundle(IEnumerable<string> fileSources)
{
var bundle = new ScriptBundle(this, fileSources);
allFilesBundle.Add(bundle);
return bundle;
}
/// <summary>
/// Manages a bundle of files which form one assembly, if one file changes entire assembly is recompiled.
/// </summary>
public class ScriptBundle
{
Assembly assembly;
IEnumerable<string> filePaths;
List<FileSystemWatcher> fileSystemWatchers = new List<FileSystemWatcher>();
List<object> instances = new List<object>();
ScriptBundleLoader manager;
string[] assemblyReferences;
public ScriptBundle(ScriptBundleLoader manager, IEnumerable<string> filePaths)
{
this.filePaths = filePaths.Select(x => Path.GetFullPath(x));
this.manager = manager;
var domain = System.AppDomain.CurrentDomain;
this.assemblyReferences = domain
.GetAssemblies()
.Where(a => !(a is System.Reflection.Emit.AssemblyBuilder) && !string.IsNullOrEmpty(a.Location))
.Select(a => a.Location)
.ToArray();
manager.logWriter.WriteLine("loading " + string.Join(", ", filePaths.ToArray()));
CompileFiles();
CreateFileWatchers();
CreateNewInstances();
}
void CompileFiles()
{
filePaths = filePaths.Where(x => File.Exists(x)).ToArray();
var options = new CompilerParameters();
options.GenerateExecutable = false;
options.GenerateInMemory = true;
options.ReferencedAssemblies.AddRange(assemblyReferences);
var compiler = new CodeCompiler();
var result = compiler.CompileAssemblyFromFileBatch(options, filePaths.ToArray());
foreach (var err in result.Errors)
{
manager.logWriter.WriteLine(err);
}
this.assembly = result.CompiledAssembly;
}
void CreateFileWatchers()
{
foreach (var filePath in filePaths)
{
FileSystemWatcher watcher = new FileSystemWatcher();
fileSystemWatchers.Add(watcher);
watcher.Path = Path.GetDirectoryName(filePath);
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = Path.GetFileName(filePath);
// Add event handlers.
watcher.Changed += new FileSystemEventHandler((object o, FileSystemEventArgs a) => { Reload(recreateWatchers: false); });
//watcher.Created += new FileSystemEventHandler((object o, FileSystemEventArgs a) => { });
watcher.Deleted += new FileSystemEventHandler((object o, FileSystemEventArgs a) => { Reload(recreateWatchers: false); });
watcher.Renamed += new RenamedEventHandler((object o, RenamedEventArgs a) =>
{
filePaths = filePaths.Select(x =>
{
if (x == a.OldFullPath) return a.FullPath;
else return x;
});
Reload(recreateWatchers: true);
});
watcher.SynchronizingObject = manager.synchronizedInvoke;
// Begin watching.
watcher.EnableRaisingEvents = true;
}
}
void StopFileWatchers()
{
foreach (var w in fileSystemWatchers)
{
w.EnableRaisingEvents = false;
w.Dispose();
}
fileSystemWatchers.Clear();
}
void Reload(bool recreateWatchers = false)
{
manager.logWriter.WriteLine("reloading " + string.Join(", ", filePaths.ToArray()));
StopInstances();
CompileFiles();
CreateNewInstances();
if (recreateWatchers)
{
StopFileWatchers();
CreateFileWatchers();
}
}
void CreateNewInstances()
{
if (assembly == null) return;
foreach (var type in assembly.GetTypes())
{
manager.synchronizedInvoke.Invoke((System.Action)(() =>
{
instances.Add(manager.createInstance(type));
}), null);
}
}
void StopInstances()
{
foreach (var instance in instances)
{
manager.synchronizedInvoke.Invoke((System.Action)(() =>
{
manager.destroyInstance(instance);
}), null);
}
instances.Clear();
}
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3dfc88ca39a87dc46bc7fd337be863bb
timeCreated: 1440503653
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,110 @@
#if NET_4_6 && !NET_STANDARD_2_0
#define QC_SUPPORTED
#endif
#if QC_SUPPORTED && !QC_DISABLED && !QC_DISABLE_BUILTIN_ALL && !QC_DISABLE_BUILTIN_EXTRA
using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
namespace QFSW.QC
{
public static class DynamicCodeCommands
{
private const Platform execAvailability = Platform.AllPlatforms ^ (Platform.WebGLPlayer | Platform.IPhonePlayer | Platform.XboxOne | Platform.PS4 | Platform.Switch);
[CommandDescription("Loads the code at the specified file and compiles it to C# which will then be executed. Use with caution as no safety checks will be performed. Not supported in AOT (IL2CPP) builds." +
"\n\nBy default, boiler plate code will NOT be inserted around the code you provide. Please see 'exec' for more information about boilerplate insertion")]
[Command("exec-extern", execAvailability)]
private static async Task ExecuteExternalArbitaryCodeAsync(string filePath, bool insertBoilerplate = false)
{
if (!File.Exists(filePath)) { throw new ArgumentException($"file at the specified path '{filePath}' did not exist."); }
string code = File.ReadAllText(filePath);
await ExecuteArbitaryCodeAsync(code.Replace("”", "\"").Replace("“", "\""), insertBoilerplate);
}
[CommandDescription("Compiles the given code to C# which will then be executed. Use with caution as no safety checks will be performed. Not supported in AOT (IL2CPP) builds." +
"\n\nBy default, boiler plate code will be inserted around the code you provide. This means various namespaces will be included, and the main class and main function entry point will " +
"provided. In this case, the code you provide should be code that would exist within the body of the main function, and thus cannot contain things such as class definition. If you " +
"disable boiler plate insertion, you can write whatever code you want, however you must provide a static entry point called Main in a static class called Program")]
[Command("exec", execAvailability)]
private static async Task ExecuteArbitaryCodeAsync(string code, bool insertBoilerplate = true)
{
#if !UNITY_EDITOR && ENABLE_IL2CPP
await Task.FromException(new Exception("exec is not supported on AOT platforms such as IL2CPP and requires JIT (Mono)."));
#else
MethodInfo entryPoint = await Task.Run(() =>
{
string fullCode = string.Empty;
if (insertBoilerplate)
{
string[] includedNamespaces = new string[] { "System", "System.Collections", "System.Collections.Generic",
"System.Reflection", "System.Linq", "System.Text", "System.Globalization",
"UnityEngine", "UnityEngine.Events", "UnityEngine.EventSystems", "UnityEngine.UI" };
for (int i = 0; i < includedNamespaces.Length; i++) { fullCode += $"using {includedNamespaces[i]};\n"; }
fullCode += @"
public class Program
{
public static void Main()
{"
+ code +
@"}
}";
}
else { fullCode = code; }
Assembly assembly = CompileCode(fullCode);
BindingFlags searchFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
Type program = assembly.GetType("Program");
if (program == null) { throw new ArgumentException("Code Execution Failure - required static class Program could not be found"); }
entryPoint = program.GetMethod("Main", searchFlags);
if (entryPoint == null) { throw new ArgumentException("Code Execution Failure - required static entry point Main could not be found"); }
return entryPoint;
});
entryPoint.Invoke(null, null);
#endif
}
private static Assembly CompileCode(string code)
{
#if !UNITY_EDITOR && ENABLE_IL2CPP
throw new Exception("Code compilation is not supported on AOT platforms such as IL2CPP and requires JIT (Mono).");
#else
CSharpCompiler.CodeCompiler compiler = new CSharpCompiler.CodeCompiler();
CompilerParameters compilerParams = new CompilerParameters();
Assembly[] allLoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
compilerParams.GenerateExecutable = false;
compilerParams.GenerateInMemory = true;
for (int i = 0; i < allLoadedAssemblies.Length; i++)
{
if (!allLoadedAssemblies[i].IsDynamic)
{
string dllName = allLoadedAssemblies[i].Location;
compilerParams.ReferencedAssemblies.Add(dllName);
}
}
CompilerResults compiledCode = compiler.CompileAssemblyFromSource(compilerParams, code);
if (compiledCode.Errors.HasErrors)
{
string errorMessage = "Code Compilation Failure";
for (int i = 0; i < compiledCode.Errors.Count; i++)
{
errorMessage += $"\n{compiledCode.Errors[i].ErrorNumber} - {compiledCode.Errors[i].ErrorText}";
}
throw new ArgumentException(errorMessage);
}
return compiledCode.CompiledAssembly;
#endif
}
}
}
#endif
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e32a67fb03a2f6548b653203ff9fedf3
timeCreated: 1553955853
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: