You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
435 lines
15 KiB
435 lines
15 KiB
1 month ago
|
#if ILRUNTIME_MODE
|
||
|
|
||
|
using ILRuntime.CLR.TypeSystem;
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.IO;
|
||
|
using System.Linq;
|
||
|
using System.Reflection;
|
||
|
using System.Text;
|
||
|
using Sog;
|
||
|
using Battle;
|
||
|
using LitJson;
|
||
|
|
||
|
|
||
|
namespace BattleServer
|
||
|
{
|
||
|
interface IILRuntimeable
|
||
|
{
|
||
|
bool Init(string fileName);
|
||
|
bool Init(ILRuntime.Runtime.Enviorment.AppDomain app);
|
||
|
bool Init(ILRuntime.Runtime.Enviorment.AppDomain app, string type, string method);
|
||
|
void Run();
|
||
|
bool Check();
|
||
|
ILResultInfo CheckResult();
|
||
|
}
|
||
|
|
||
|
public class ILResultInfo
|
||
|
{
|
||
|
public ILResultInfo(string ILname, bool result, string message)
|
||
|
{
|
||
|
ILName = ILname;
|
||
|
Result = result;
|
||
|
Message = message;
|
||
|
}
|
||
|
|
||
|
|
||
|
public string ILName { get; private set; }
|
||
|
|
||
|
public bool Result { get; private set; }
|
||
|
|
||
|
public string Message { get; private set; }
|
||
|
}
|
||
|
|
||
|
public abstract class BaseILUnit : IILRuntimeable
|
||
|
{
|
||
|
protected ILRuntime.Runtime.Enviorment.AppDomain App;
|
||
|
protected string AssemblyName;
|
||
|
protected string TypeName;
|
||
|
protected string MethodName;
|
||
|
protected bool Pass;
|
||
|
protected StringBuilder Message = null;//= new StringBuilder();
|
||
|
|
||
|
public string ILName { get { return TypeName + "." + MethodName; } }
|
||
|
|
||
|
#region 接口方法
|
||
|
|
||
|
public bool Init(string fileName)
|
||
|
{
|
||
|
AssemblyName = fileName;
|
||
|
if (!File.Exists(AssemblyName))
|
||
|
return false;
|
||
|
using (var fs = new System.IO.FileStream(AssemblyName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||
|
{
|
||
|
App = new ILRuntime.Runtime.Enviorment.AppDomain();
|
||
|
var path = System.IO.Path.GetDirectoryName(AssemblyName);
|
||
|
var name = System.IO.Path.GetFileNameWithoutExtension(AssemblyName);
|
||
|
using (var fs2 = new System.IO.FileStream(string.Format("{0}\\{1}.pdb", path, name), System.IO.FileMode.Open))
|
||
|
App.LoadAssembly(fs, fs2, new Mono.Cecil.Pdb.PdbReaderProvider());
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool Init(ILRuntime.Runtime.Enviorment.AppDomain app)
|
||
|
{
|
||
|
if (app == null)
|
||
|
return false;
|
||
|
|
||
|
App = app;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public bool Init(ILRuntime.Runtime.Enviorment.AppDomain app, string type, string method)
|
||
|
{
|
||
|
if (app == null)
|
||
|
return false;
|
||
|
|
||
|
TypeName = type;
|
||
|
MethodName = method;
|
||
|
|
||
|
App = app;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//需要子类去实现
|
||
|
public abstract void Run();
|
||
|
|
||
|
public abstract bool Check();
|
||
|
|
||
|
public abstract ILResultInfo CheckResult();
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region 常用工具方法
|
||
|
|
||
|
public Object getInstance(string type)
|
||
|
{
|
||
|
throw new NotImplementedException();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// call Method with no params and no return value;
|
||
|
/// </summary>
|
||
|
/// <param name="Instance">Instacne, if it is null means static method,else means instance method</param>
|
||
|
/// <param name="type">TypeName ,eg "Namespace.ClassType"</param>
|
||
|
/// <param name="method">MethodName</param>
|
||
|
public void Invoke(Object Instance, string type, string method)
|
||
|
{
|
||
|
Message = new StringBuilder();
|
||
|
var sw = new System.Diagnostics.Stopwatch();
|
||
|
sw.Start();
|
||
|
App.Invoke(type, method, null); //InstanceTest
|
||
|
sw.Stop();
|
||
|
Message.AppendLine("Elappsed Time:" + sw.ElapsedMilliseconds + "ms\n");
|
||
|
}
|
||
|
|
||
|
public void Invoke(string type, string method)
|
||
|
{
|
||
|
Message = new StringBuilder();
|
||
|
try
|
||
|
{
|
||
|
var sw = new System.Diagnostics.Stopwatch();
|
||
|
Console.WriteLine("Invoking {0}.{1}", type, method);
|
||
|
sw.Start();
|
||
|
var res = App.Invoke(type, method, null); //InstanceTest
|
||
|
sw.Stop();
|
||
|
if (res != null)
|
||
|
Message.AppendLine("Return:" + res);
|
||
|
Message.AppendLine("Elappsed Time:" + sw.ElapsedMilliseconds + "ms\n");
|
||
|
Pass = true;
|
||
|
}
|
||
|
catch (ILRuntime.Runtime.Intepreter.ILRuntimeException e)
|
||
|
{
|
||
|
Message.AppendLine(e.Message);
|
||
|
if (!string.IsNullOrEmpty(e.ThisInfo))
|
||
|
{
|
||
|
Message.AppendLine("this:");
|
||
|
Message.AppendLine(e.ThisInfo);
|
||
|
}
|
||
|
Message.AppendLine("Local Variables:");
|
||
|
Message.AppendLine(e.LocalInfo);
|
||
|
Message.AppendLine(e.StackTrace);
|
||
|
if (e.InnerException != null)
|
||
|
Message.AppendLine(e.InnerException.ToString());
|
||
|
Pass = false;
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
Message.AppendLine(ex.ToString());
|
||
|
Pass = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////无返回值
|
||
|
//void Invoke<T>(Object Instance, string type, string method, T param)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//void Invoke<T1, T2>(Object Instance, string type, string method, T1 param1, T2 param2)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//void Invoke<T1, T2, T3>(Object Instance, string type, string method, T1 param1, T2 param2, T3 param3)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//void Invoke<T1, T2, T3, T4>(Object Instance, string type, string method, T1 param1, T2 param2, T3 param3, T4 param4)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//void Invoke<T1, T2, T3, T4, T5>(Object Instance, string type, string method, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
////有返回值
|
||
|
//T Invoke<T>(Object Instance, string type, string method)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//T Invoke<T, T1, T2>(Object Instance, string type, string method, T1 param1, T2 param2)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//T Invoke<T, T1, T2, T3>(Object Instance, string type, string method, T1 param1, T2 param2, T3 param3)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//T Invoke<T, T1, T2, T3, T4>(Object Instance, string type, string method, T1 param1, T2 param2, T3 param3, T4 param4)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//T Invoke<T, T1, T2, T3, T4, T5>(Object Instance, string type, string method, T1 param1, T2 param2, T3 param3, T4 param4, T5 param5)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//protected bool AssertToBe<T>(T assertValue, T result)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//protected bool AssertNotToBe<T>(T errorValue, T result)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//protected void Assert(bool expression, string errorLog)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
//protected void Assert(bool expression, Action<bool> resAction)
|
||
|
//{
|
||
|
// throw new NotImplementedException();
|
||
|
//}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
}
|
||
|
|
||
|
class StaticTestUnit : BaseILUnit
|
||
|
{
|
||
|
//protected object _returnType;
|
||
|
|
||
|
public override void Run()
|
||
|
{
|
||
|
Invoke(TypeName, MethodName);
|
||
|
}
|
||
|
|
||
|
public override bool Check()
|
||
|
{
|
||
|
return Pass;
|
||
|
}
|
||
|
|
||
|
public override ILResultInfo CheckResult()
|
||
|
{
|
||
|
return new ILResultInfo(TypeName + "." + MethodName, Pass, Message.ToString());
|
||
|
}
|
||
|
}
|
||
|
public class BattleILRuntime
|
||
|
{
|
||
|
|
||
|
public static ILRuntime.Runtime.Enviorment.AppDomain appdomain;
|
||
|
private Assembly _assembly;
|
||
|
private static bool _isLoadAssembly;
|
||
|
public static List<ILResultInfo> _resList = new List<ILResultInfo>();
|
||
|
public static List<BaseILUnit> ILUnitList = new List<BaseILUnit>();
|
||
|
public static StringBuilder Message = new StringBuilder();
|
||
|
public static bool Pass;
|
||
|
public static void InitIL()
|
||
|
{
|
||
|
appdomain = new ILRuntime.Runtime.Enviorment.AppDomain();
|
||
|
appdomain.DebugService.StartDebugService(56000);
|
||
|
|
||
|
//string txtPath = "C:\\Users\\Yinlf\\Desktop\\ILRuntime\\TestCases\\bin\\Debug\\TestCases.dll";
|
||
|
string txtPath = BattleServerUtils.GetILRuntimeDllPath();
|
||
|
using (FileStream fs = new FileStream(txtPath, FileMode.Open, FileAccess.Read))
|
||
|
{
|
||
|
var path = Path.GetDirectoryName(txtPath);
|
||
|
var name = Path.GetFileNameWithoutExtension(txtPath);
|
||
|
var pdbPath = Path.Combine(path, name) + ".pdb";
|
||
|
if (!File.Exists(pdbPath))
|
||
|
{
|
||
|
name = Path.GetFileName(txtPath);
|
||
|
pdbPath = Path.Combine(path, name) + ".mdb";
|
||
|
}
|
||
|
|
||
|
using (var fs2 = new System.IO.FileStream(pdbPath, FileMode.Open))
|
||
|
{
|
||
|
Mono.Cecil.Cil.ISymbolReaderProvider symbolReaderProvider = null;
|
||
|
if (pdbPath.EndsWith(".pdb"))
|
||
|
{
|
||
|
symbolReaderProvider = new Mono.Cecil.Pdb.PdbReaderProvider();
|
||
|
}
|
||
|
else if (pdbPath.EndsWith(".mdb"))
|
||
|
{
|
||
|
symbolReaderProvider = new Mono.Cecil.Mdb.MdbReaderProvider();
|
||
|
}
|
||
|
|
||
|
appdomain.LoadAssembly(fs, fs2, symbolReaderProvider);
|
||
|
_isLoadAssembly = true;
|
||
|
}
|
||
|
LoadIL();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void LoadIL()
|
||
|
{
|
||
|
ILUnitList.Clear();
|
||
|
_resList.Clear();
|
||
|
|
||
|
var types = appdomain.LoadedTypes.Values.ToList();
|
||
|
foreach (var type in types)
|
||
|
{
|
||
|
var ilType = type as ILType;
|
||
|
if (ilType == null)
|
||
|
continue;
|
||
|
var methods = ilType.GetMethods();
|
||
|
foreach (var methodInfo in methods)
|
||
|
{
|
||
|
string fullName = ilType.FullName;
|
||
|
//Console.WriteLine("call the method:{0},return type {1},params count{2}", fullName + "." + methodInfo.Name, methodInfo.ReturnType, methodInfo.GetParameters().Length);
|
||
|
//目前只支持无参数,无返回值测试
|
||
|
if (methodInfo.IsStatic)
|
||
|
{
|
||
|
var Unit = new StaticTestUnit();
|
||
|
Unit.Init(appdomain, fullName, methodInfo.Name);
|
||
|
ILUnitList.Add(Unit);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static Object Invoke(string type, string method, params object[] obj)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
var sw = new System.Diagnostics.Stopwatch();
|
||
|
Console.WriteLine("Invoking {0}.{1}", type, method);
|
||
|
sw.Start();
|
||
|
var res = appdomain.Invoke(type, method, null, obj); //InstanceTest
|
||
|
sw.Stop();
|
||
|
if (res == null)
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
Pass = true;
|
||
|
return res;
|
||
|
}
|
||
|
catch (ILRuntime.Runtime.Intepreter.ILRuntimeException e)
|
||
|
{
|
||
|
Message.AppendLine(e.Message);
|
||
|
if (!string.IsNullOrEmpty(e.ThisInfo))
|
||
|
{
|
||
|
Message.AppendLine("this:");
|
||
|
Message.AppendLine(e.ThisInfo);
|
||
|
}
|
||
|
Message.AppendLine("Local Variables:");
|
||
|
Message.AppendLine(e.LocalInfo);
|
||
|
Message.AppendLine(e.StackTrace);
|
||
|
if (e.InnerException != null)
|
||
|
Message.AppendLine(e.InnerException.ToString());
|
||
|
Pass = false;
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
Message.AppendLine(ex.ToString());
|
||
|
Pass = false;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public static void GetOutput(object aiMachine)
|
||
|
{
|
||
|
|
||
|
string outputJson = (string)appdomain.Invoke("Battle.AIMachine", "Output", aiMachine, null);
|
||
|
while (outputJson != null)
|
||
|
{
|
||
|
BattleCommIO output = JsonMapper.ToObject<BattleCommIO>(outputJson);
|
||
|
|
||
|
TraceLog.Trace("output succesee,IOType:{0}\n,DataJson:{1}", output.IOType, output.DataJson);
|
||
|
PrintOutput(output);
|
||
|
|
||
|
outputJson = (string)appdomain.Invoke("Battle.AIMachine", "Output", aiMachine, null);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public static void PrintOutput(BattleCommIO output)
|
||
|
{
|
||
|
switch (output.IOType)
|
||
|
{
|
||
|
case (int)BattleIOType.BattleInit:
|
||
|
BattleInitOutput init = JsonMapper.ToObject<BattleInitOutput>(output.DataJson);
|
||
|
TraceLog.Trace("PrintOutput BattleInit uid {0}", init.battleInfo.RoleA.Uid);
|
||
|
foreach (EnterHeroInfo info in init.allHeros)
|
||
|
{
|
||
|
TraceLog.Trace("PrintOutput BattleInit hero {0} obj {1} hp {2}"
|
||
|
, info.DescId, info.ObjId, info.Hp);
|
||
|
}
|
||
|
break;
|
||
|
case (int)BattleIOType.ActorShowEnd:
|
||
|
ActorShowEndOutput show = JsonMapper.ToObject<ActorShowEndOutput>(output.DataJson);
|
||
|
foreach (var spell in show.SpellList)
|
||
|
{
|
||
|
TraceLog.Trace("PrintOutput ActorShowEnd spell {0}",spell.CreateSpellId);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case (int)BattleIOType.HeroHurt:
|
||
|
HeroHurtOutput hurt = JsonMapper.ToObject<HeroHurtOutput>(output.DataJson);
|
||
|
TraceLog.Trace("PrintOutput HeroHurt caster {0} target {1} chgHp {2} newHp {3}"
|
||
|
, hurt.Caster, hurt.Target, hurt.ChgHp, hurt.NewHp);
|
||
|
break;
|
||
|
case (int)BattleIOType.HeroDie:
|
||
|
TraceLog.Trace("PrintOutput HeroDie ...");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
TraceLog.Trace("PrintOutput type {0}", (BattleIOType)output.IOType);
|
||
|
}
|
||
|
|
||
|
public static void LoadGameConfig()
|
||
|
{
|
||
|
string cfgPath = BattleServerUtils.GetILRuntimeCfgPath();
|
||
|
object gameCfgMgr = appdomain.Invoke("Sog.GameConfigMgr", "get_Instance", null, null);
|
||
|
appdomain.Invoke("Sog.GameConfigMgr", "ReadAllConfig", gameCfgMgr, cfgPath);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|