예제 #1
0
        public void TestVoidFunc()
        {
            HashSet <string> recordedMembers = new HashSet <string>();
            HashSet <string> compiledMembers = new HashSet <string>();

            var cachedPath = "Assets/Mods/CapsLua/LuaPrecompile/MemberList.txt";

            //var cachedPath = "EditorOutput/LuaPrecompile/CachedCommands.txt";
            if (PlatDependant.IsFileExist(cachedPath))
            {
                try
                {
                    using (var sr = PlatDependant.OpenReadText(cachedPath))
                    {
                        while (true)
                        {
                            var line = sr.ReadLine();
                            if (line == null)
                            {
                                break;
                            }

                            if (!string.IsNullOrEmpty(line))
                            {
                                recordedMembers.Add(line);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    PlatDependant.LogError(e);
                }
            }
        }
예제 #2
0
        public static void LogError(this IntPtr l, object message)
        {
            PushLuaStackTrace(l);
            var lstack = l.tostring(-1);

            l.pop(1);
            var m = (message ?? "nullptr").ToString() + "\n" + lstack;

            PlatDependant.LogError(m);
        }
예제 #3
0
 public static void ReinitGlobalLuaInEditor()
 {
     if (!Application.isPlaying)
     {
         ReinitGlobalLua();
     }
     else
     {
         PlatDependant.LogError("Cannot reinit global lua while playing.");
     }
 }
예제 #4
0
        public static void TestPack <TLuaPack>()
            where TLuaPack : struct, ILuaPack
        {
            var      l    = GlobalLua.L.L;
            TLuaPack pin  = default;
            TLuaPack pout = default;

            l.CallGlobal("TestPack", pin, out pout);
            for (int i = 0; i < pout.ElementCount; ++i)
            {
                PlatDependant.LogError(pout[i]);
            }
        }
예제 #5
0
        public static void TestLua()
        {
            UnityEditor.AssetDatabase.OpenAsset(UnityEditor.AssetDatabase.LoadMainAssetAtPath(ResManager.__ASSET__), ResManager.__LINE__);

            var l = GlobalLua.L.L;

            using (var lr = l.CreateStackRecover())
            {
                l.pushnumber(250);
                string str;
                l.CallGlobal(out str, "dump", LuaPack.Pack(l.OnStack(-1)));
                PlatDependant.LogError(str);
            }
        }
예제 #6
0
 internal static void DisposeObj(IntPtr handle)
 {
     if (handle != IntPtr.Zero)
     {
         try
         {
             var gchandle = (GCHandle)handle;
             gchandle.Free();
         }
         catch (Exception e)
         {
             PlatDependant.LogError(e);
         }
     }
 }
예제 #7
0
        public int TestReturnOutFunc(string filePath, int times, out string rv)
        {
            string last = null;

            for (int i = 0; i < times; ++i)
            {
                if (i == 3)
                {
                    rv = i.ToString();
                    return(i);
                }
                HashSet <string> recordedMembers = new HashSet <string>();
                HashSet <string> compiledMembers = new HashSet <string>();

                var cachedPath = filePath + i;
                //var cachedPath = "EditorOutput/LuaPrecompile/CachedCommands.txt";
                if (PlatDependant.IsFileExist(cachedPath))
                {
                    try
                    {
                        using (var sr = PlatDependant.OpenReadText(cachedPath))
                        {
                            while (true)
                            {
                                var line = sr.ReadLine();
                                if (line == null)
                                {
                                    break;
                                }
                                last = line;
                                if (!string.IsNullOrEmpty(line))
                                {
                                    recordedMembers.Add(line);
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        PlatDependant.LogError(e);
                        rv = e.Message;
                        return(i);
                    }
                }
            }
            rv = last;
            return(last?.Length ?? 0);
        }
예제 #8
0
        public static T GetContainer <T>() where T : class
        {
            var handle = NativeImported.GetThreadLocalContainer();

            if (handle != IntPtr.Zero)
            {
                object obj = null;
                try
                {
                    obj = ((GCHandle)handle).Target;
                }
                catch (Exception e)
                {
                    PlatDependant.LogError(e);
                }
                return(obj as T);
            }
            return(null);
        }
예제 #9
0
        public void TestParamFunc(string filePath, int times)
        {
            for (int i = 0; i < times; ++i)
            {
                HashSet <string> recordedMembers = new HashSet <string>();
                HashSet <string> compiledMembers = new HashSet <string>();

                var cachedPath = filePath + i;
                //var cachedPath = "EditorOutput/LuaPrecompile/CachedCommands.txt";
                if (PlatDependant.IsFileExist(cachedPath))
                {
                    try
                    {
                        using (var sr = PlatDependant.OpenReadText(cachedPath))
                        {
                            while (true)
                            {
                                var line = sr.ReadLine();
                                if (line == null)
                                {
                                    break;
                                }

                                if (!string.IsNullOrEmpty(line))
                                {
                                    recordedMembers.Add(line);
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        PlatDependant.LogError(e);
                    }
                }
            }
        }
예제 #10
0
 public static void LogError(object obj)
 {
     PlatDependant.LogError(obj);
 }
예제 #11
0
        public static TaskProgress MakeZipBackground(string zipFile, string srcDir, IList <string> entries, System.Threading.EventWaitHandle waithandle)
        {
            return(PlatDependant.RunBackground(progress =>
            {
                try
                {
                    if (string.IsNullOrEmpty(zipFile) || entries == null || entries.Count == 0 || !System.IO.Directory.Exists(srcDir))
                    {
                        return;
                    }
                    progress.Total = entries.Count;
                    using (var stream = PlatDependant.OpenWrite(zipFile))
                    {
                        using (var zip = new ZipArchive(stream, ZipArchiveMode.Create))
                        {
                            if (!srcDir.EndsWith("/") && !srcDir.EndsWith("\\"))
                            {
                                srcDir += "/";
                            }
                            for (int i = 0; i < entries.Count; ++i)
                            {
                                progress.Length = i;
                                var entry = entries[i];
                                if (string.IsNullOrEmpty(entry))
                                {
                                    continue;
                                }

                                var src = srcDir + entry;
                                if (PlatDependant.IsFileExist(src))
                                {
                                    try
                                    {
                                        using (var srcstream = PlatDependant.OpenRead(src))
                                        {
                                            var zentry = zip.CreateEntry(entry.Replace('\\', '/'));
                                            using (var dststream = zentry.Open())
                                            {
                                                srcstream.CopyTo(dststream);
                                            }
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        PlatDependant.LogError("zip entry FAIL! " + entry);
                                        PlatDependant.LogError(e);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    PlatDependant.LogError("Build zip FAIL! " + zipFile);
                    PlatDependant.LogError(e);
                }
                finally
                {
                    if (waithandle != null)
                    {
                        waithandle.Set();
                    }
                }
            }));
        }
예제 #12
0
        public static void MakeObb(string dest, params string[] subzips)
        {
            if (!string.IsNullOrEmpty(dest) && subzips != null && subzips.Length > 0)
            {
                HashSet <string> reskeys = new HashSet <string>();
                HashSet <string> sptkeys = new HashSet <string>();
                using (var sdest = PlatDependant.OpenWrite(dest))
                {
                    using (var zdest = new ZipArchive(sdest, ZipArchiveMode.Create))
                    {
                        for (int i = 0; i < subzips.Length; ++i)
                        {
                            try
                            {
                                var sfile = subzips[i];
                                if (PlatDependant.IsFileExist(sfile))
                                {
                                    var              key        = System.IO.Path.GetFileNameWithoutExtension(sfile).ToLower();
                                    bool             isres      = false;
                                    bool             isspt      = false;
                                    HashSet <string> entrynames = new HashSet <string>();
                                    using (var ssrc = PlatDependant.OpenRead(sfile))
                                    {
                                        using (var zsrc = new ZipArchive(ssrc, ZipArchiveMode.Read))
                                        {
                                            foreach (var sentry in zsrc.Entries)
                                            {
                                                var fullname = sentry.FullName;
                                                if (fullname.StartsWith("res/"))
                                                {
                                                    isres = true;
                                                }
                                                else if (fullname.StartsWith("spt/"))
                                                {
                                                    isspt = true;
                                                }
                                                if (entrynames.Add(fullname))
                                                {
                                                    var dentry = zdest.CreateEntry(fullname, isres ? CompressionLevel.NoCompression : CompressionLevel.Optimal);
                                                    using (var ses = sentry.Open())
                                                    {
                                                        using (var des = dentry.Open())
                                                        {
                                                            ses.CopyTo(des);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    if (isres)
                                    {
                                        reskeys.Add(key);
                                    }
                                    if (isspt)
                                    {
                                        sptkeys.Add(key);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                PlatDependant.LogError(e);
                            }
                        }

                        if (reskeys.Count > 0)
                        {
                            var resindex = zdest.CreateEntry("res/index.txt", CompressionLevel.Optimal);
                            using (var sindex = resindex.Open())
                            {
                                using (var swindex = new System.IO.StreamWriter(sindex, System.Text.Encoding.UTF8))
                                {
                                    foreach (var key in reskeys)
                                    {
                                        swindex.WriteLine(key);
                                    }
                                }
                            }
                        }
                        if (sptkeys.Count > 0)
                        {
                            var sptindex = zdest.CreateEntry("spt/index.txt", CompressionLevel.Optimal);
                            using (var sindex = sptindex.Open())
                            {
                                using (var swindex = new System.IO.StreamWriter(sindex, System.Text.Encoding.UTF8))
                                {
                                    foreach (var key in sptkeys)
                                    {
                                        swindex.WriteLine(key);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #13
0
        public static System.IO.Stream GetLuaStream(string name, out string location)
        {
#if UNITY_EDITOR
            try
            {
                if (!string.IsNullOrEmpty(name))
                {
                    if (name.Length > 0 && name[0] == '?')
                    {
                        var    real = name.Substring("?raw.".Length);
                        string mod  = null;
                        string norm = real;
                        if (real.StartsWith("mod."))
                        {
                            if (real.StartsWith("mod.\""))
                            {
                                var mindex = real.IndexOf('\"', "mod.\"".Length);
                                if (mindex > 0)
                                {
                                    mod  = real.Substring("mod.\"".Length, mindex - "mod.\"".Length);
                                    norm = real.Substring(mindex + 2);
                                }
                            }
                            else
                            {
                                var mindex = real.IndexOf('.', "mod.".Length);
                                if (mindex > 0)
                                {
                                    mod  = real.Substring("mod.".Length, mindex - "mod.".Length);
                                    norm = real.Substring(mindex + 1);
                                }
                            }
                        }
                        norm = norm.Replace('.', '/');
                        bool isFileExist = false;
                        if (mod == null)
                        {
                            real = "Assets/CapsSpt/" + norm + ".lua";
                        }
                        else
                        {
                            string package;
                            ResManager.EditorResLoader.ResRuntimeCache.ModToPackage.TryGetValue(mod, out package);
                            if (!string.IsNullOrEmpty(package))
                            {
                                real = "Packages/" + package + "/CapsSpt/" + norm + ".lua";
                                //real = EditorToClientUtils.GetPathFromAssetName(real);
                                isFileExist = !string.IsNullOrEmpty(real) && PlatDependant.IsFileExist(real);
                            }
                            if (!isFileExist)
                            {
                                real = "Assets/Mods/" + mod + "/CapsSpt/" + norm + ".lua";
                            }
                        }
                        if (isFileExist || PlatDependant.IsFileExist(real))
                        {
                            location = real;
                            return(PlatDependant.OpenRead(real));
                        }
                    }
                    else
                    {
                        var    file = "CapsSpt/" + name.Replace('.', '/') + ".lua";
                        string found;
                        if (ThreadLocalObj.GetThreadId() == ThreadSafeValues.UnityThreadID)
                        {
                            found = ResManager.EditorResLoader.CheckDistributePath(file, true);
                        }
                        else
                        {
                            found = ResManager.EditorResLoader.CheckDistributePathSafe(file);
                        }
                        //if (found != null)
                        //{
                        //    if (found.StartsWith("Packages/"))
                        //    {
                        //        found = EditorToClientUtils.GetPathFromAssetName(found);
                        //    }
                        //}
                        if (found != null)
                        {
                            location = found;
                            return(PlatDependant.OpenRead(found));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                PlatDependant.LogError(e);
            }
#elif UNITY_ENGINE || UNITY_5_3_OR_NEWER
            try
            {
                if (name.Length > 0 && name[0] == '?')
                {
                    if (name.StartsWith("?raw."))
                    {
                        if (_RuntimeRawManifest != null)
                        {
                            var real = name.Substring("?raw.".Length);
                            real = real.Replace("\"", "");
                            string archreal = Environment.Is64BitProcess ? "@64." + real : "@32." + real;
                            CapsResManifestNode node;
                            if (_RuntimeRawManifest.TryGetItemIgnoreExt(archreal, out node, _LuaRequireSeperateChars) || _RuntimeRawManifest.TryGetItemIgnoreExt(real, out node, _LuaRequireSeperateChars))
                            {
                                if (node != null && node.Item != null)
                                {
                                    var item = node.Item;
                                    while (item.Ref != null)
                                    {
                                        item = item.Ref;
                                    }
                                    return(GetLuaStream(item, out location));
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (_RuntimeManifest != null)
                    {
                        var node = _RuntimeManifest.GetItem(name, _LuaRequireSeperateChars);
                        if (node != null && node.Item != null)
                        {
                            var item = node.Item;
                            while (item.Ref != null)
                            {
                                item = item.Ref;
                            }
                            return(GetLuaStream(item, out location));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                PlatDependant.LogError(e);
            }
#else
            try
            {
                if (!string.IsNullOrEmpty(name))
                {
                    if (name.Length > 0 && name[0] == '?')
                    {
                        var    real = name.Substring("?raw.".Length);
                        string mod  = null;
                        string norm = real;
                        if (real.StartsWith("mod."))
                        {
                            if (real.StartsWith("mod.\""))
                            {
                                var mindex = real.IndexOf('\"', "mod.\"".Length);
                                if (mindex > 0)
                                {
                                    mod  = real.Substring("mod.\"".Length, mindex - "mod.\"".Length);
                                    norm = real.Substring(mindex + 2);
                                }
                            }
                            else
                            {
                                var mindex = real.IndexOf('.', "mod.".Length);
                                if (mindex > 0)
                                {
                                    mod  = real.Substring("mod.".Length, mindex - "mod.".Length);
                                    norm = real.Substring(mindex + 1);
                                }
                            }
                        }
                        norm = norm.Replace('.', '/');
                        if (mod == null)
                        {
                            real = "/spt/" + norm + ".lua";
                        }
                        else
                        {
                            real = "/mod/" + mod + "/spt/" + norm + ".lua";
                        }
                        var stream = ResManager.LoadFileRelative(real);
                        if (stream != null)
                        {
                            location = real;
                            return(stream);
                        }
                    }
                    else
                    {
                        var    file = "/spt/" + name.Replace('.', '/') + ".lua";
                        string real, mod, dist;
                        real = ResManager.FindFile(file, out mod, out dist);
                        if (real != null)
                        {
                            try
                            {
                                var stream = PlatDependant.OpenRead(real);
                                if (stream != null)
                                {
                                    location = file;
                                    if (!string.IsNullOrEmpty(dist))
                                    {
                                        location = "/dist/" + dist + location;
                                    }
                                    if (!string.IsNullOrEmpty(mod))
                                    {
                                        location = "/mod/" + mod + location;
                                    }
                                    return(stream);
                                }
                            }
                            catch (Exception e)
                            {
                                PlatDependant.LogError(e);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                PlatDependant.LogError(e);
            }
#endif
            location = "";
            return(null);
        }
예제 #14
0
        private static System.IO.Stream GetLuaStream(CapsResManifestItem item, out string location)
        {
            try
            {
                var rnode = item.Node;
                System.Text.StringBuilder sbpath = new System.Text.StringBuilder();
                while (rnode.Parent != null)
                {
                    if (sbpath.Length > 0)
                    {
                        sbpath.Insert(0, '/');
                    }
                    sbpath.Insert(0, rnode.PPath);
                    rnode = rnode.Parent;
                }
                var path = sbpath.ToString();

                // load from update path
                var sptpath = ThreadSafeValues.UpdatePath + "/spt/" + path;
                if (PlatDependant.IsFileExist(sptpath))
                {
                    location = sptpath;
                    return(PlatDependant.OpenRead(sptpath));
                }
                // load from package
                if (ThreadSafeValues.AppStreamingAssetsPath.Contains("://"))
                {
                    if (ThreadSafeValues.AppPlatform == RuntimePlatform.Android.ToString() && ResManager.LoadAssetsFromApk)
                    {
                        // Obb
                        if (ResManager.LoadAssetsFromObb && ResManager.ObbZipArchive != null)
                        {
                            sptpath = "spt/" + path;
                            int retryTimes = 10;
                            for (int i = 0; i < retryTimes; ++i)
                            {
                                Exception error = null;
                                do
                                {
                                    ZipArchive za = ResManager.ObbZipArchive;
                                    if (za == null)
                                    {
                                        PlatDependant.LogError("Obb Archive Cannot be read.");
                                        break;
                                    }
                                    try
                                    {
                                        var entry = za.GetEntry(sptpath);
                                        if (entry != null)
                                        {
                                            location = sptpath;
                                            return(entry.Open());
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        error = e;
                                        break;
                                    }
                                } while (false);
                                if (error != null)
                                {
                                    if (i == retryTimes - 1)
                                    {
                                        PlatDependant.LogError(error);
                                    }
                                    else
                                    {
                                        PlatDependant.LogError(error);
                                        PlatDependant.LogInfo("Need Retry " + i);
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        // Apk
                        //if (true)
                        {
                            sptpath = "assets/spt/" + path;
                            int retryTimes = 10;
                            for (int i = 0; i < retryTimes; ++i)
                            {
                                Exception error = null;
                                do
                                {
                                    ZipArchive za = ResManager.AndroidApkZipArchive;
                                    if (za == null)
                                    {
                                        PlatDependant.LogError("Apk Archive Cannot be read.");
                                        break;
                                    }
                                    try
                                    {
                                        var entry = za.GetEntry(sptpath);
                                        if (entry != null)
                                        {
                                            location = sptpath;
                                            return(entry.Open());
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        error = e;
                                        break;
                                    }
                                } while (false);
                                if (error != null)
                                {
                                    if (i == retryTimes - 1)
                                    {
                                        PlatDependant.LogError(error);
                                    }
                                    else
                                    {
                                        PlatDependant.LogError(error);
                                        PlatDependant.LogInfo("Need Retry " + i);
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    sptpath = ThreadSafeValues.AppStreamingAssetsPath + "/spt/" + path;
                    if (PlatDependant.IsFileExist(sptpath))
                    {
                        location = sptpath;
                        return(PlatDependant.OpenRead(sptpath));
                    }
                }
            }
            catch (Exception e)
            {
                PlatDependant.LogError(e);
            }
            location = "";
            return(null);
        }
예제 #15
0
        private static void LoadRuntimeManifest(TaskProgress progress)
        {
            try
            {
                var maniPath = ThreadSafeValues.UpdatePath + "/spt/manifest.m.txt";
                if (PlatDependant.IsFileExist(maniPath))
                {
                    _RuntimeRawManifest = LoadManifest(maniPath);
                }
                else
                {
                    CapsResManifest mani = new CapsResManifest();
                    // load from update path
                    var sptfolder = ThreadSafeValues.UpdatePath + "/spt/";
                    try
                    {
                        var files = PlatDependant.GetAllFiles(sptfolder);
                        if (files != null && files.Length > 0)
                        {
                            for (int i = 0; i < files.Length; ++i)
                            {
                                var file = files[i];
                                var part = file.Substring(sptfolder.Length).Replace('\\', '/');
                                var node = mani.AddOrGetItem(part);
                                if (node.Item == null)
                                {
                                    CapsResManifestItem item;
                                    item      = new CapsResManifestItem(node);
                                    node.Item = item;
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        PlatDependant.LogError(e);
                    }
                    // load from package
                    if (ThreadSafeValues.AppStreamingAssetsPath.Contains("://"))
                    {
                        if (ThreadSafeValues.AppPlatform == RuntimePlatform.Android.ToString() && ResManager.LoadAssetsFromApk)
                        {
                            // Obb
                            if (ResManager.LoadAssetsFromObb && ResManager.ObbZipArchive != null)
                            {
                                sptfolder = "spt/";
                                int retryTimes = 10;
                                int entryindex = 0;
                                for (int i = 0; i < retryTimes; ++i)
                                {
                                    Exception error = null;
                                    do
                                    {
                                        ZipArchive za = ResManager.ObbZipArchive;
                                        if (za == null)
                                        {
                                            PlatDependant.LogError("Obb Archive Cannot be read.");
                                            break;
                                        }
                                        try
                                        {
                                            var entries = za.Entries;
                                            while (entryindex < entries.Count)
                                            {
                                                var entry    = entries[entryindex];
                                                var fullname = entry.FullName;
                                                if (fullname.StartsWith(sptfolder))
                                                {
                                                    var part = fullname.Substring(sptfolder.Length);
                                                    var node = mani.AddOrGetItem(part);
                                                    if (node.Item == null)
                                                    {
                                                        CapsResManifestItem item;
                                                        item      = new CapsResManifestItem(node);
                                                        node.Item = item;
                                                    }
                                                }
                                                ++entryindex;
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            error = e;
                                            break;
                                        }
                                    } while (false);
                                    if (error != null)
                                    {
                                        if (i == retryTimes - 1)
                                        {
                                            PlatDependant.LogError(error);
                                        }
                                        else
                                        {
                                            PlatDependant.LogError(error);
                                            PlatDependant.LogInfo("Need Retry " + i);
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            // Apk
                            //if (true)
                            {
                                sptfolder = "assets/spt/";
                                int retryTimes = 10;
                                int entryindex = 0;
                                for (int i = 0; i < retryTimes; ++i)
                                {
                                    Exception error = null;
                                    do
                                    {
                                        ZipArchive za = ResManager.AndroidApkZipArchive;
                                        if (za == null)
                                        {
                                            PlatDependant.LogError("Apk Archive Cannot be read.");
                                            break;
                                        }
                                        try
                                        {
                                            var entries = za.Entries;
                                            while (entryindex < entries.Count)
                                            {
                                                var entry    = entries[entryindex];
                                                var fullname = entry.FullName;
                                                if (fullname.StartsWith(sptfolder))
                                                {
                                                    var part = fullname.Substring(sptfolder.Length);
                                                    var node = mani.AddOrGetItem(part);
                                                    if (node.Item == null)
                                                    {
                                                        CapsResManifestItem item;
                                                        item      = new CapsResManifestItem(node);
                                                        node.Item = item;
                                                    }
                                                }
                                                ++entryindex;
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            error = e;
                                            break;
                                        }
                                    } while (false);
                                    if (error != null)
                                    {
                                        if (i == retryTimes - 1)
                                        {
                                            PlatDependant.LogError(error);
                                        }
                                        else
                                        {
                                            PlatDependant.LogError(error);
                                            PlatDependant.LogInfo("Need Retry " + i);
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        sptfolder = ThreadSafeValues.AppStreamingAssetsPath + "/spt/";
                        try
                        {
                            var files = PlatDependant.GetAllFiles(sptfolder);
                            if (files != null && files.Length > 0)
                            {
                                for (int i = 0; i < files.Length; ++i)
                                {
                                    var file = files[i];
                                    var part = file.Substring(sptfolder.Length).Replace('\\', '/');
                                    var node = mani.AddOrGetItem(part);
                                    if (node.Item == null)
                                    {
                                        CapsResManifestItem item;
                                        item      = new CapsResManifestItem(node);
                                        node.Item = item;
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            PlatDependant.LogError(e);
                        }
                    }

                    mani.TrimExcess();
                    _RuntimeRawManifest = mani;
                    _RuntimeManifestReady.Set();
                    SaveManifest(mani, maniPath);
                }
            }
            finally
            {
                _RuntimeManifestReady.Set();
                _RuntimeManifestTaskIdle.Set();
            }
        }
예제 #16
0
        public static bool BuildResUpdate(string oldz, string newz, string diff)
        {
            LinkedList<IDisposable> lstToDispose = new LinkedList<IDisposable>();
            try
            {
                ZipArchive olda = null, newa = null, diffa = null;

                try
                {
                    var olds = File.OpenRead(oldz);
                    lstToDispose.AddFirst(olds);
                    olda = new ZipArchive(olds, ZipArchiveMode.Read);
                    lstToDispose.AddFirst(olda);
                }
                catch { }
                try
                {
                    var news = File.OpenRead(newz);
                    lstToDispose.AddFirst(news);
                    newa = new ZipArchive(news, ZipArchiveMode.Read);
                    lstToDispose.AddFirst(newa);
                }
                catch { }

                HashSet<string> diffb = new HashSet<string>();
                if (newa == null)
                {
                    return false;
                }
                else if (Path.GetFileNameWithoutExtension(oldz) != Path.GetFileNameWithoutExtension(newz))
                {
                    PlatDependant.LogError("Build update diff error - the old zip and new zip have different names.");
                    return false;
                }
                else
                {
                    string mentry = "res/mani/" + Path.GetFileNameWithoutExtension(newz).ToLower() + ".m.ab";
                    CapsResManifest mold = null;
                    CapsResManifest mnew = null;

                    // get mani of old
                    try
                    {
                        if (olda != null)
                        {
                            var oldme = olda.GetEntry(mentry);
                            if (oldme != null)
                            {
                                using (var stream = oldme.Open())
                                {
                                    using (var mems = new MemoryStream())
                                    {
                                        stream.CopyTo(mems);
                                        var mab = UnityEngine.AssetBundle.LoadFromMemory(mems.ToArray());
                                        if (mab)
                                        {
                                            var allassets = mab.LoadAllAssets<CapsResOnDiskManifest>();
                                            if (allassets != null && allassets.Length > 0)
                                            {
                                                mold = CapsResManifest.Load(allassets[0]);
                                            }
                                            mab.Unload(true);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch { }
                    // get mani of new
                    try
                    {
                        var newme = newa.GetEntry(mentry);
                        if (newme != null)
                        {
                            using (var stream = newme.Open())
                            {
                                using (var mems = new MemoryStream())
                                {
                                    stream.CopyTo(mems);
                                    var mab = UnityEngine.AssetBundle.LoadFromMemory(mems.ToArray());
                                    if (mab)
                                    {
                                        var allassets = mab.LoadAllAssets<CapsResOnDiskManifest>();
                                        if (allassets != null && allassets.Length > 0)
                                        {
                                            mnew = CapsResManifest.Load(allassets[0]);
                                        }
                                        mab.Unload(true);
                                    }
                                }
                            }
                        }
                    }
                    catch { }

                    string abrootold = "res/";
                    string umpathold = "res/res";
                    if (mold != null && !string.IsNullOrEmpty(mold.MFlag))
                    {
                        abrootold += "mod/" + mold.MFlag + "/";
                        umpathold = abrootold + mold.MFlag;
                    }
                    string abrootnew = "res/";
                    string umpathnew = "res/res";
                    if (mnew != null && !string.IsNullOrEmpty(mnew.MFlag))
                    {
                        abrootnew += "mod/" + mnew.MFlag + "/";
                        umpathnew = abrootnew + mnew.MFlag;
                    }

                    // parse old manifest
                    UnityEngine.AssetBundleManifest maniold = null;
                    try
                    {
                        if (olda != null)
                        {
                            var emani = olda.GetEntry(umpathold);
                            if (emani != null)
                            {
                                using (var smani = emani.Open())
                                {
                                    using (var mems = new MemoryStream())
                                    {
                                        smani.CopyTo(mems);
                                        var resab = UnityEngine.AssetBundle.LoadFromMemory(mems.ToArray());
                                        if (resab)
                                        {
                                            var allassets = resab.LoadAllAssets<UnityEngine.AssetBundleManifest>();
                                            if (allassets != null && allassets.Length > 0)
                                            {
                                                maniold = allassets[0];
                                                if (maniold)
                                                {
                                                    maniold = Object.Instantiate(maniold);
                                                }
                                            }
                                            resab.Unload(true);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch { }
                    // parse new manifest
                    UnityEngine.AssetBundleManifest maninew = null;
                    try
                    {
                        var emani = newa.GetEntry(umpathnew);
                        if (emani != null)
                        {
                            using (var smani = emani.Open())
                            {
                                using (var mems = new MemoryStream())
                                {
                                    smani.CopyTo(mems);
                                    var resab = UnityEngine.AssetBundle.LoadFromMemory(mems.ToArray());
                                    if (resab)
                                    {
                                        var allassets = resab.LoadAllAssets<UnityEngine.AssetBundleManifest>();
                                        if (allassets != null && allassets.Length > 0)
                                        {
                                            maninew = allassets[0];
                                            if (maninew != null)
                                            {
                                                maninew = Object.Instantiate(maninew);
                                            }
                                        }
                                        resab.Unload(true);
                                    }
                                }
                            }
                        }
                    }
                    catch { }
                    // both manifest found?
                    if (maninew == null)
                    {
                        File.Copy(newz, diff, true);
                        return true;
                    }

                    // parse diff assets and bundles
                    if (maninew != null)
                    {
                        var allbundles = maninew.GetAllAssetBundles();
                        foreach (var bundle in allbundles)
                        {
                            var newe = newa.GetEntry(abrootnew + bundle);
                            if (newe == null)
                            {
                                continue;
                            }
                            if (maniold != null && maninew.GetAssetBundleHash(bundle) == maniold.GetAssetBundleHash(bundle))
                            {
                                if (olda != null)
                                {
                                    var olde = olda.GetEntry(abrootold + bundle);
                                    if (olde != null)
                                    {
                                        if (olde.Length == newe.Length)
                                        {
                                            // TODO: sometimes the AssetBundleHash may be same (example: we deleted a sprite-atlas).
                                            // we can diff these from: AssetBundle TypeTreeHash. we should load bundle.manifest and parse it use YAML. it's so difficult.
                                            // or we can get the ab file's change time. but this information is not recorded to zip
                                            // or we can get the crc of the entry. but it's private.
                                            // or we can get md5 of the entry. but need full read.
                                            // so we choose use length. In this condition, the ab file length's diff is almost a must.
                                            continue;
                                        }
                                    }
                                }
                            }
                            diffb.Add(bundle);
                        }
                    }

                    // create update zip
                    if (diffb.Count > 0)
                    {
                        try
                        {
                            var streama = PlatDependant.OpenWrite(diff);
                            if (streama != null)
                            {
                                lstToDispose.AddFirst(streama);
                                diffa = new ZipArchive(streama, ZipArchiveMode.Create);
                                if (diffa != null)
                                {
                                    lstToDispose.AddFirst(diffa);

                                    // each bundle
                                    foreach (var bundle in diffb)
                                    {
                                        try
                                        {
                                            var ename = abrootnew + bundle;
                                            var entryn = newa.GetEntry(ename);
                                            if (entryn != null)
                                            {
                                                var entryd = diffa.CreateEntry(ename, CompressionLevel.Optimal);
                                                if (entryd != null)
                                                {
                                                    using (var streamn = entryn.Open())
                                                    {
                                                        using (var streamd = entryd.Open())
                                                        {
                                                            streamn.CopyTo(streamd);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        catch { }
                                    }

                                    // mani / unity manifest / version.txt
                                    string[] rawcopyentries = new[] { mentry, umpathnew, "res/version.txt" };
                                    for (int i = 0; i < rawcopyentries.Length; ++i)
                                    {
                                        var ename = rawcopyentries[i];
                                        try
                                        {
                                            var entrys = newa.GetEntry(ename);
                                            if (entrys != null)
                                            {
                                                var entryd = diffa.CreateEntry(ename, CompressionLevel.Optimal);
                                                if (entryd != null)
                                                {
                                                    using (var streams = entrys.Open())
                                                    {
                                                        using (var streamd = entryd.Open())
                                                        {
                                                            streams.CopyTo(streamd);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        catch { }
                                    }
                                }
                            }
                        }
                        catch { }
                        return true;
                    }
                }
            }
            catch { }
            finally
            {
                foreach (var dis in lstToDispose)
                {
                    if (dis != null)
                    {
                        dis.Dispose();
                    }
                }
            }
            return false;
        }