Reorganizes Project (#41)
This commit is contained in:
parent
08bf44af9a
commit
3614a66aee
3499 changed files with 79 additions and 55 deletions
215
Projects/Server/ScriptCompiler.cs
Normal file
215
Projects/Server/ScriptCompiler.cs
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/***************************************************************************
|
||||
* ScriptCompiler.cs
|
||||
* -------------------
|
||||
* begin : May 1, 2002
|
||||
* copyright : (C) The RunUO Software Team
|
||||
* email : info@runuo.com
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
#if NETCORE
|
||||
using System.Runtime.Loader;
|
||||
#endif
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class ScriptCompiler
|
||||
{
|
||||
private static Dictionary<Assembly, TypeCache> m_TypeCaches = new Dictionary<Assembly, TypeCache>();
|
||||
private static TypeCache m_NullCache;
|
||||
public static Assembly[] Assemblies { get; set; }
|
||||
|
||||
public static string ScriptsPath = EnsureDirectory("Assemblies");
|
||||
|
||||
public static bool LoadScripts(string path = null)
|
||||
{
|
||||
string[] files = Directory.GetFiles(path ?? ScriptsPath, "*.dll");
|
||||
|
||||
List<Assembly> assemblies = new List<Assembly>();
|
||||
|
||||
AssemblyName[] names = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
|
||||
|
||||
int loaded = 0;
|
||||
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
#if NETCORE
|
||||
assemblies.Add(AssemblyLoadContext.Default.LoadFromAssemblyPath(files[i]));
|
||||
loaded++;
|
||||
#else
|
||||
Assemblies[i] = Assembly.LoadFrom(files[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
Assemblies = assemblies.ToArray();
|
||||
|
||||
return loaded > 0;
|
||||
}
|
||||
|
||||
public static void Invoke(string method)
|
||||
{
|
||||
List<MethodInfo> invoke = new List<MethodInfo>();
|
||||
|
||||
for (int a = 0; a < Assemblies.Length; ++a)
|
||||
{
|
||||
Type[] types = Assemblies[a].GetTypes();
|
||||
|
||||
for (int i = 0; i < types.Length; ++i)
|
||||
{
|
||||
MethodInfo m = types[i].GetMethod(method, BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
if (m != null)
|
||||
invoke.Add(m);
|
||||
}
|
||||
}
|
||||
|
||||
invoke.Sort(new CallPriorityComparer());
|
||||
|
||||
for (int i = 0; i < invoke.Count; ++i)
|
||||
invoke[i].Invoke(null, null);
|
||||
}
|
||||
|
||||
public static TypeCache GetTypeCache(Assembly asm)
|
||||
{
|
||||
if (asm == null)
|
||||
{
|
||||
return m_NullCache ?? (m_NullCache = new TypeCache(null));
|
||||
}
|
||||
if (!m_TypeCaches.TryGetValue(asm, out TypeCache c))
|
||||
m_TypeCaches[asm] = c = new TypeCache(asm);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Type FindTypeByFullName(string fullName)
|
||||
{
|
||||
return FindTypeByFullName(fullName, true);
|
||||
}
|
||||
|
||||
public static Type FindTypeByFullName(string fullName, bool ignoreCase)
|
||||
{
|
||||
Type type = null;
|
||||
|
||||
for (int i = 0; type == null && i < Assemblies.Length; ++i)
|
||||
type = GetTypeCache(Assemblies[i]).GetTypeByFullName(fullName, ignoreCase);
|
||||
|
||||
return type ?? GetTypeCache(Core.Assembly).GetTypeByFullName(fullName, ignoreCase);
|
||||
}
|
||||
|
||||
public static Type FindTypeByName(string name)
|
||||
{
|
||||
return FindTypeByName(name, true);
|
||||
}
|
||||
|
||||
public static Type FindTypeByName(string name, bool ignoreCase)
|
||||
{
|
||||
Type type = null;
|
||||
|
||||
for (int i = 0; type == null && i < Assemblies.Length; ++i)
|
||||
type = GetTypeCache(Assemblies[i]).GetTypeByName(name, ignoreCase);
|
||||
|
||||
return type ?? GetTypeCache(Core.Assembly).GetTypeByName(name, ignoreCase);
|
||||
}
|
||||
|
||||
public static string EnsureDirectory(string dir)
|
||||
{
|
||||
string path = Path.Combine(Core.BaseDirectory, dir);
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeCache
|
||||
{
|
||||
public TypeCache(Assembly asm)
|
||||
{
|
||||
Types = asm == null ? Type.EmptyTypes : asm.GetTypes();
|
||||
|
||||
Names = new TypeTable(Types.Length);
|
||||
FullNames = new TypeTable(Types.Length);
|
||||
|
||||
Type typeofTypeAliasAttribute = typeof(TypeAliasAttribute);
|
||||
|
||||
for (int i = 0; i < Types.Length; ++i)
|
||||
{
|
||||
Type type = Types[i];
|
||||
|
||||
Names.Add(type.Name, type);
|
||||
FullNames.Add(type.FullName, type);
|
||||
|
||||
if (type.IsDefined(typeofTypeAliasAttribute, false))
|
||||
{
|
||||
object[] attrs = type.GetCustomAttributes(typeofTypeAliasAttribute, false);
|
||||
|
||||
if (attrs.Length > 0 && attrs[0] is TypeAliasAttribute attr)
|
||||
for (int j = 0; j < attr.Aliases.Length; ++j)
|
||||
FullNames.Add(attr.Aliases[j], type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Type[] Types{ get; }
|
||||
|
||||
public TypeTable Names{ get; }
|
||||
|
||||
public TypeTable FullNames{ get; }
|
||||
|
||||
public Type GetTypeByName(string name, bool ignoreCase)
|
||||
{
|
||||
return Names.Get(name, ignoreCase);
|
||||
}
|
||||
|
||||
public Type GetTypeByFullName(string fullName, bool ignoreCase)
|
||||
{
|
||||
return FullNames.Get(fullName, ignoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeTable
|
||||
{
|
||||
private Dictionary<string, Type> m_Sensitive, m_Insensitive;
|
||||
|
||||
public TypeTable(int capacity)
|
||||
{
|
||||
m_Sensitive = new Dictionary<string, Type>(capacity);
|
||||
m_Insensitive = new Dictionary<string, Type>(capacity, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public void Add(string key, Type type)
|
||||
{
|
||||
m_Sensitive[key] = type;
|
||||
m_Insensitive[key] = type;
|
||||
}
|
||||
|
||||
public Type Get(string key, bool ignoreCase)
|
||||
{
|
||||
Type t;
|
||||
|
||||
if (ignoreCase)
|
||||
m_Insensitive.TryGetValue(key, out t);
|
||||
else
|
||||
m_Sensitive.TryGetValue(key, out t);
|
||||
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue