395 lines
13 KiB
C#
395 lines
13 KiB
C#
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
using XLua;
|
|
using static XLua.LuaEnv;
|
|
|
|
namespace XGame
|
|
{
|
|
public class LuaManager : MonoBehaviour
|
|
{
|
|
public static LuaEnv m_LuaEnv = null;// new LuaEnv();
|
|
public static LuaEnv.CustomLoader m_CustomLoader;
|
|
|
|
private const string LUA_SUFFIX = ".lua";
|
|
private const string BYTES_SUFFIX = ".bytes";
|
|
private const float INTERVAL = 1.0f;
|
|
|
|
//private bool m_bStart = false;
|
|
private float m_Timestamp = 0;
|
|
|
|
public static LuaManager m_Instance = null;
|
|
|
|
//系统lua
|
|
private AssetBundle m_LuaAB = null;
|
|
private LuaTable m_LuaMain = null;
|
|
private Action m_MainUpdate = null;
|
|
private Action m_MainLateUpdate = null;
|
|
private Action m_MainLogicUpdate = null;
|
|
private Action m_MainGUI = null;
|
|
private Action m_MainQuit = null;
|
|
//XWorld lua
|
|
private Dictionary<string, AssetBundle> m_LuaXWABs = new Dictionary<string, AssetBundle>();//xid, ab
|
|
private string m_curXID;
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
m_Instance = this;
|
|
}
|
|
private void Start()
|
|
{
|
|
}
|
|
private IEnumerator LoadBaseLuaAB()
|
|
{
|
|
yield return XResLoader.GetFileDataOrigin("XWorld","bs.unity3d", (uwr) =>
|
|
{
|
|
if (uwr == null)
|
|
{
|
|
Debug.LogError($"Load AB Error: bs.unity3d");
|
|
}
|
|
else
|
|
{
|
|
byte[] decrypt = AESManager.Decrypt(uwr.downloadHandler.data);//bs.unity3d
|
|
m_LuaAB = AssetBundle.LoadFromMemory(decrypt);
|
|
Debug.Log("m_LuaAB Load OK!");
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
//Key : local或xid
|
|
public IEnumerator LoadAB(string Path, string Xid = null)
|
|
{
|
|
yield return XResLoader.coLoadFile(Path, (data) =>
|
|
{
|
|
if (data == null)
|
|
{
|
|
Debug.LogError($"Load AB Error: {Path}");
|
|
}
|
|
else
|
|
{
|
|
byte[] decrypt = AESManager.Decrypt(data);//bs.unity3d
|
|
AssetBundle ab = AssetBundle.LoadFromMemory(decrypt);
|
|
if (Xid != null)
|
|
m_LuaXWABs[Xid] = ab;
|
|
else
|
|
m_LuaXWABs[GlobalData.CurNode] = ab;
|
|
|
|
}
|
|
});
|
|
yield break;
|
|
}
|
|
|
|
public void ReleaseLua(string Xid)
|
|
{
|
|
if (Xid == null)
|
|
{//基础Lua,可能不需要即时释放
|
|
//释放lua
|
|
//。。。
|
|
//m_LuaAB.Unload(true);
|
|
}
|
|
else
|
|
{
|
|
if (m_LuaXWABs.ContainsKey(Xid))
|
|
{
|
|
AssetBundle ab = null;
|
|
if(m_LuaXWABs.TryGetValue(Xid, out ab))
|
|
{
|
|
ab.Unload(true);
|
|
m_LuaXWABs.Remove(Xid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private IEnumerator LocalInit()
|
|
{
|
|
|
|
m_CustomLoader = (ref string path) =>
|
|
{//加载器 默认先从基础文件找,然后再去当前库找
|
|
string originalFixedPath = path.Replace('.', '/');
|
|
string fixedPath = originalFixedPath.ToLower();
|
|
//Debug.Log($"Base Loader : {fixedPath}");
|
|
|
|
byte[] content = null;
|
|
#if UNITY_EDITOR
|
|
//编辑器查找底层lua本地文件
|
|
if (File.Exists($"assets/lua/{fixedPath}.lua"))
|
|
{
|
|
content = System.IO.File.ReadAllBytes($"assets/lua/{fixedPath}.lua");
|
|
if (content != null)
|
|
{
|
|
return content;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
TextAsset textAsset;
|
|
|
|
//然后查找底层ab
|
|
//根据文件路径在Assets/lua/路径里(或者luabytes里)加载lua
|
|
//先加载系统lua文件
|
|
string luaPath = $"assets/l/{fixedPath}.bytes";
|
|
if (m_LuaAB != null)
|
|
{
|
|
textAsset = m_LuaAB.LoadAsset<TextAsset>(luaPath);//
|
|
|
|
if (textAsset != null)
|
|
{
|
|
content = textAsset.bytes;
|
|
return content;
|
|
//Debug.LogError($"lua {path} not found!");
|
|
}
|
|
}
|
|
//Debug.LogError($"m_LuaAB {luaPath} not found!");
|
|
//非系统lua则寻找节点lua
|
|
//编辑器找本地
|
|
#if UNITY_EDITOR
|
|
//编辑器查找节点lua本地文件
|
|
//luaPath = $"assets/{GlobalData.CurNode}/script/{fixedPath}.lua";
|
|
luaPath = $"{Application.dataPath}/../../Lua/{fixedPath}.lua";
|
|
if (File.Exists(luaPath))
|
|
{
|
|
content = System.IO.File.ReadAllBytes(luaPath);
|
|
if (content != null)
|
|
{
|
|
return content;
|
|
}
|
|
}
|
|
luaPath = $"{Application.dataPath}/lua/{originalFixedPath}.lua";
|
|
if (File.Exists(luaPath))
|
|
{
|
|
content = System.IO.File.ReadAllBytes(luaPath);
|
|
if (content != null)
|
|
{
|
|
return content;
|
|
}
|
|
}
|
|
luaPath = $"{Application.dataPath}/lua/{fixedPath}.lua";
|
|
if (File.Exists(luaPath))
|
|
{
|
|
content = System.IO.File.ReadAllBytes(luaPath);
|
|
if (content != null)
|
|
{
|
|
return content;
|
|
}
|
|
}
|
|
luaPath = $"{Application.dataPath}/../../{originalFixedPath}.lua";
|
|
if (File.Exists(luaPath))
|
|
{
|
|
content = System.IO.File.ReadAllBytes(luaPath);
|
|
if (content != null)
|
|
{
|
|
return content;
|
|
}
|
|
}
|
|
luaPath = $"{Application.dataPath}/../../{fixedPath}.lua";
|
|
if (File.Exists(luaPath))
|
|
{
|
|
content = System.IO.File.ReadAllBytes(luaPath);
|
|
if (content != null)
|
|
{
|
|
return content;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
luaPath = $"assets/l/{fixedPath}.bytes";
|
|
//Debug.Log($"lua {path} size:{textAsset.bytes.Length}!");
|
|
AssetBundle luaAB = null;
|
|
|
|
if (m_curXID != null && m_LuaXWABs.ContainsKey(m_curXID))
|
|
{
|
|
luaAB = m_LuaXWABs[m_curXID];
|
|
if (luaAB != null)
|
|
{
|
|
textAsset = m_LuaAB.LoadAsset<TextAsset>(luaPath);//
|
|
if (textAsset != null)
|
|
{
|
|
return textAsset.bytes;
|
|
}
|
|
}
|
|
}
|
|
foreach (var ab in m_LuaXWABs)
|
|
{
|
|
if (ab.Value != null && ab.Value != luaAB)
|
|
{
|
|
textAsset = m_LuaAB.LoadAsset<TextAsset>(luaPath);//
|
|
if (textAsset != null)
|
|
{
|
|
return textAsset.bytes;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
yield return RestartLua();
|
|
|
|
yield break;
|
|
}
|
|
|
|
public IEnumerator RestartLua()
|
|
{
|
|
if (m_LuaEnv != null)
|
|
{
|
|
m_LuaEnv.Dispose();
|
|
m_LuaEnv = null;
|
|
if (m_LuaAB != null)
|
|
{
|
|
m_LuaAB.Unload(true);
|
|
m_LuaAB = null;
|
|
}
|
|
m_LuaMain = null;
|
|
m_MainUpdate = null;
|
|
m_MainLateUpdate = null;
|
|
m_MainLogicUpdate = null;
|
|
m_MainGUI = null;
|
|
m_MainQuit = null;
|
|
GC.Collect();
|
|
}
|
|
//修改默认加载位置xid或local
|
|
m_LuaEnv = new LuaEnv();//*/
|
|
if (m_LuaAB == null)
|
|
{
|
|
Debug.Log("Init m_LuaAB");
|
|
yield return LoadBaseLuaAB();
|
|
}
|
|
m_LuaEnv.AddLoader(m_CustomLoader);
|
|
//默认函数
|
|
m_LuaEnv.Global.Set("XWorldGetTime", (System.Func<double>)Utility.XWorldGetTime);
|
|
Debug.Log($"LuaManager Init 'XWMain' {m_LuaEnv.Memroy}KB");
|
|
|
|
//无需使用lua
|
|
yield break;
|
|
//默认lua入口文件
|
|
m_LuaEnv.DoString("require'XWBaseLua.XWMain'");
|
|
Debug.Log("require'XWBaseLua.XWMain'");
|
|
m_LuaMain = m_LuaEnv.Global.Get<LuaTable>("XWMain");
|
|
if (m_LuaMain == null)
|
|
{
|
|
Debug.LogError("Error: Lua 'Main' Not Found !");
|
|
yield break;
|
|
}
|
|
//m_LuaEnv.DoString("_G.Main=nil");//全局的置空
|
|
Action initFunc = m_LuaMain.Get<Action>("XWInit");
|
|
if (initFunc != null)
|
|
{
|
|
initFunc();
|
|
}
|
|
//m_LuaEnv.DoString("MaPlayerPrefsin.Init()");
|
|
m_MainUpdate = m_LuaMain.Get<Action>("XWUpdate");
|
|
m_MainLateUpdate = m_LuaMain.Get<Action>("XWLateUpdate");
|
|
m_MainLogicUpdate = m_LuaMain.Get<Action>("XWFixedUpdate");
|
|
m_MainGUI = m_LuaMain.Get<Action>("XWGUI");
|
|
m_MainQuit = m_LuaMain.Get<Action>("XWQuit");
|
|
//Debug.Log($"'Main' Loaded {m_LuaEnv.Memroy}KB");
|
|
//m_bStart = true;
|
|
|
|
//加载默认节点
|
|
string xid = XData.GetString("XWorldID");
|
|
//默认加载Lua开发模块
|
|
//Action<string> AddModule = m_LuaMain.Get<Action<string>>("AddModule");
|
|
//AddModule("client/client");
|
|
#if UNITY_EDITOR
|
|
|
|
#endif
|
|
yield break;
|
|
}
|
|
|
|
public static IEnumerator Init()
|
|
{
|
|
yield return m_Instance.LocalInit();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
float now = Time.time;
|
|
if (m_MainUpdate != null)
|
|
{
|
|
try
|
|
{
|
|
m_MainUpdate();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError(e);
|
|
}
|
|
}
|
|
if (!(now > m_Timestamp + INTERVAL))
|
|
{
|
|
return;
|
|
}
|
|
m_Timestamp = now;
|
|
if(m_LuaEnv != null)
|
|
m_LuaEnv.Tick();
|
|
}
|
|
private void LateUpdate()
|
|
{
|
|
if (m_MainLateUpdate != null)
|
|
{
|
|
try
|
|
{
|
|
m_MainLateUpdate();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError(e);
|
|
}
|
|
}
|
|
}
|
|
private void FixedUpdate()
|
|
{ //
|
|
if (m_MainLogicUpdate != null)
|
|
{
|
|
m_MainLogicUpdate();
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
if (m_MainGUI != null)
|
|
{
|
|
try
|
|
{
|
|
m_MainGUI();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DoString(string sLuaString)
|
|
{
|
|
m_LuaEnv.DoString(sLuaString);
|
|
}
|
|
private void OnApplicationQuit()
|
|
{
|
|
if(m_MainQuit != null)
|
|
m_MainQuit();
|
|
}
|
|
#if UNITY_EDITOR
|
|
//热更新lua
|
|
private void OnLuaFileChange(string filePath)
|
|
{
|
|
if (string.IsNullOrEmpty(filePath) || !filePath.EndsWith(LUA_SUFFIX, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return;
|
|
}
|
|
//重载文件
|
|
//filePath = filePath.Replace('\\', '/');
|
|
//int startIndex = filePath.IndexOf(LuaEditorBaseUrl) + 7;
|
|
//filePath = filePath.Substring(startIndex, filePath.Length - startIndex - LUA_SUFFIX.Length);
|
|
//Invoke("ToolManager.ReloadLuaFile", filePath);
|
|
}
|
|
#endif
|
|
}
|
|
}
|