Main/Common/SevenZip.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: 00dea6db89fa7bf48906e1612fbf177e folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/Common/SevenZip/lzma.cs
New file @@ -0,0 +1,873 @@ #if !(UNITY_IOS || UNITY_IPHONE) using System; using System.Runtime.InteropServices; using UnityEngine; using System.Collections.Generic; using System.IO; #if (UNITY_WSA_8_1 || UNITY_WP_8_1 || UNITY_WINRT_8_1) && !UNITY_EDITOR using File = UnityEngine.Windows.File; #else using File = System.IO.File; #endif #if NETFX_CORE #if UNITY_WSA_10_0 using System.IO.IsolatedStorage; using static System.IO.Directory; using static System.IO.File; using static System.IO.FileStream; #endif #endif public class lzma { //if you want to be able to call the functions: get7zinfo, get7zSize, decode2Buffer from a thread set this string before to the Application.persistentDataPath ! public static string persitentDataPath = ""; #if !(UNITY_WSA || UNITY_WP_8_1) || UNITY_EDITOR internal static int[] props = new int[7]; internal static bool defaultsSet = false; //0 = level, /* 0 <= level <= 9, default = 5 */ //1 = dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ //2 = lc, /* 0 <= lc <= 8, default = 3 */ //3 = lp, /* 0 <= lp <= 4, default = 0 */ //4 = pb, /* 0 <= pb <= 4, default = 2 */ //5 = fb, /* 5 <= fb <= 273, default = 32 */ //6 = numThreads /* 1 or 2, default = 2 */ //A function that sets the compression properties for the lzma compressor. Will affect the lzma alone file and the lzma buffer compression. //A simple usage of this function is to call it only with the 1st parameter that sets the compression level: setProps(9); // //Multithread safe advice: call this function before starting any thread operations !!! public static void setProps(int level = 5, int dictSize = 16777216, int lc = 3, int lp = 0, int pb = 2, int fb = 32, int numThreads = 2) { defaultsSet = true; props[0] = level; props[1] = dictSize; props[2] = lc; props[3] = lp; props[4] = pb; props[5] = fb; props[6] = numThreads; } #endif #if (UNITY_WEBGL) && !UNITY_EDITOR #if (!UNITY_WEBGL) [DllImport("__Internal")] public static extern int lsetPermissions(string filePath, string _user, string _group, string _other); [DllImport("__Internal")] private static extern int decompress7zip(string filePath, string exctractionPath, bool fullPaths, string entry, IntPtr progress, IntPtr FileBuffer, int FileBufferLength); #endif [DllImport("__Internal")] private static extern int decompress7zip2(string filePath, string exctractionPath, bool fullPaths, string entry, IntPtr progress, IntPtr FileBuffer, int FileBufferLength); [DllImport("__Internal")] private static extern int _getSize(string filePath, string tempPath, IntPtr FileBuffer, int FileBufferLength); [DllImport("__Internal")] internal static extern int lzmaUtil(bool encode, string inPath, string outPath, IntPtr Props); [DllImport("__Internal")] internal static extern int decode2Buf(string filePath, string entry, IntPtr buffer, IntPtr FileBuffer, int FileBufferLength); [DllImport("__Internal")] internal static extern void _releaseBuffer(IntPtr buffer); [DllImport("__Internal")] internal static extern IntPtr Lzma_Compress( IntPtr buffer, int bufferLength, bool makeHeader, ref int v, IntPtr Props); [DllImport("__Internal")] internal static extern int Lzma_Uncompress( IntPtr buffer, int bufferLength, int uncompressedSize, IntPtr outbuffer,bool useHeader); #endif #if UNITY_5_4_OR_NEWER #if (UNITY_ANDROID || UNITY_STANDALONE_LINUX) && (!UNITY_EDITOR || UNITY_EDITOR_LINUX) private const string libname = "lzma"; #elif UNITY_EDITOR || UNITY_STANDALONE_WIN private const string libname = "liblzma"; #endif #else #if (UNITY_ANDROID || UNITY_STANDALONE_LINUX) && !UNITY_EDITOR private const string libname = "lzma"; #endif #if UNITY_EDITOR || UNITY_STANDALONE_WIN private const string libname = "liblzma"; #endif #endif #if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_ANDROID || UNITY_STANDALONE_LINUX #if ( UNITY_STANDALONE_LINUX || UNITY_ANDROID || UNITY_EDITOR_LINUX) && !UNITY_EDITOR_WIN //set permissions of a file in user, group, other. Each string should contain any or all chars of "rwx". //returns 0 on success [DllImport(libname, EntryPoint = "lsetPermissions")] internal static extern int lsetPermissions(string filePath, string _user, string _group, string _other); #endif [DllImport(libname, EntryPoint = "decompress7zip")] internal static extern int decompress7zip(string filePath, string exctractionPath, bool fullPaths, string entry, IntPtr progress, IntPtr FileBuffer, int FileBufferLength); [DllImport(libname, EntryPoint = "decompress7zip2")] internal static extern int decompress7zip2(string filePath, string exctractionPath, bool fullPaths, string entry, IntPtr progress, IntPtr FileBuffer, int FileBufferLength); [DllImport(libname, EntryPoint = "_getSize")] internal static extern int _getSize(string filePath, string tempPath, IntPtr FileBuffer, int FileBufferLength); [DllImport(libname, EntryPoint = "lzmaUtil")] internal static extern int lzmaUtil(bool encode, string inPath, string outPath, IntPtr Props); [DllImport(libname, EntryPoint = "decode2Buf")] internal static extern int decode2Buf(string filePath, string entry, IntPtr buffer, IntPtr FileBuffer, int FileBufferLength); [DllImport(libname, EntryPoint = "_releaseBuffer")] internal static extern void _releaseBuffer(IntPtr buffer); [DllImport(libname, EntryPoint = "Lzma_Compress")] internal static extern IntPtr Lzma_Compress(IntPtr buffer, int bufferLength, bool makeHeader, ref int v, IntPtr Props); [DllImport(libname, EntryPoint = "Lzma_Uncompress")] internal static extern int Lzma_Uncompress(IntPtr buffer, int bufferLength, int uncompressedSize, IntPtr outbuffer, bool useHeader); #endif #if (UNITY_WP_8_1 || UNITY_WSA) && !UNITY_EDITOR #if UNITY_WSA_10_0 [DllImport("liblzma", EntryPoint = "decompress7zip")] internal static extern int decompress7zip(string filePath, string exctractionPath, bool fullPaths, string entry, IntPtr progress, IntPtr FileBuffer, int FileBufferLength); #endif [DllImport("liblzma", EntryPoint = "decompress7zip2")] internal static extern int decompress7zip2(string filePath, string exctractionPath, bool fullPaths, string entry, IntPtr progress, IntPtr FileBuffer, int FileBufferLength); [DllImport("liblzma", EntryPoint = "_getSize")] internal static extern int _getSize(string filePath, string tempPath, IntPtr FileBuffer, int FileBufferLength); [DllImport("liblzma", EntryPoint = "decode2Buf")] internal static extern int decode2Buf(string filePath, string entry, IntPtr buffer, IntPtr FileBuffer, int FileBufferLength); [DllImport("liblzma", EntryPoint = "Lzma_Uncompress")] internal static extern int Lzma_Uncompress( IntPtr buffer, int bufferLength, int uncompressedSize, IntPtr outbuffer,bool useHeader); #endif // set permissions of a file in user, group, other. // Each string should contain any or all chars of "rwx". // returns 0 on success public static int setFilePermissions(string filePath, string _user, string _group, string _other) { #if (UNITY_STANDALONE_LINUX || UNITY_ANDROID || UNITY_EDITOR_LINUX) && !UNITY_EDITOR_WIN return lsetPermissions(filePath, _user, _group, _other); #else return -1; #endif } // An integer variable to store the total number of files in a 7z archive, excluding the folders. public static int trueTotalFiles = 0; //ERROR CODES: // 1 : OK // 2 : Could not find requested file in archive // -1 : Could not open input(7z) file // -2 : Decoder doesn't support this archive // -3 : Can not allocate memory // -4 : CRC error of 7z file // -5 : Unknown error // -6 : Can not open output file (usually when the path to write to, is invalid) // -7 : Can not write output file // -8 : Can not close output file //The most common use of this library is to download a 7z file in your Application.persistentDataPath directory //and decompress it in a folder that you want. //int lz=lzma.doDecompress7zip(Application.persistentDataPath+"/myCompresedFile.7z",Application.persistentDataPath+"/myUncompressedFiles/"); //WSA8.1 does not support large files. //filePath : the full path to the archive, including the archives name. (/myPath/myArchive.7z) //exctractionPath : the path in where you want your files to be extracted //progress : a single item integer array to get the progress of the extracted files (use this function when calling from a separate thread, otherwise call the 2nd implementation) // : (for ios this integer is not properly updated. So we use the lzma.getProgressCount() function to get the progress. See example.) //largeFiles : set this to true if you are extracting files larger then 30-40 Mb. It is slower though but prevents crashing your app when extracting large files! //fullPaths : set this to true if you want to keep the folder structure of the 7z file. //entry : set the name of a single file file you want to extract from your archive. If the file resides in a folder, the full path should be added. // (for example game/meshes/small/table.mesh ) //FileBuffer : A buffer that holds a 7zip file. When assigned the function will decompress from this buffer and will ignore the filePath. (Linux, iOS, Android, MacOSX) //use this function from a separate thread to get the progress of the extracted files in the referenced 'progress' integer. // public static int doDecompress7zip(string filePath, string exctractionPath, int[] progress, bool largeFiles = false, bool fullPaths = false, string entry = null, byte[] FileBuffer = null) { int res = 0; GCHandle ibuf = GCHandle.Alloc(progress, GCHandleType.Pinned); #if (UNITY_ANDROID || UNITY_STANDALONE_LINUX || UNITY_EDITOR) && !UNITY_EDITOR_WIN if(FileBuffer != null) { GCHandle fbuf = GCHandle.Alloc(FileBuffer, GCHandleType.Pinned); if (largeFiles){ res = decompress7zip(null, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject() , fbuf.AddrOfPinnedObject(), FileBuffer.Length); }else{ res = decompress7zip2(null, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject() , fbuf.AddrOfPinnedObject(), FileBuffer.Length); } fbuf.Free(); ibuf.Free(); return res; } else { if (largeFiles){ res = decompress7zip(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject() , IntPtr.Zero, 0); ibuf.Free(); return res; }else{ res = decompress7zip2(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject() , IntPtr.Zero, 0); ibuf.Free(); return res; } } #endif #if (!UNITY_WSA && !UNITY_WEBGL && !UNITY_STANDALONE_LINUX && !UNITY_ANDROID) || UNITY_EDITOR_WIN || UNITY_WSA_10_0 if (largeFiles) { res = decompress7zip(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; } else { res = decompress7zip2(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; } #endif #if (UNITY_WSA_8_1 || UNITY_WP_8_1 || UNITY_WINRT_8_1 || UNITY_WEBGL) && !UNITY_EDITOR res = decompress7zip2(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; #endif } //same as above only the progress integer is a local variable. //use this when you don't want to get the progress of the extracted files and when not calling the function from a separate thread. public static int doDecompress7zip(string filePath, string exctractionPath, bool largeFiles = false, bool fullPaths = false, string entry = null, byte[] FileBuffer = null) { //make a check if the last '/' exists at the end of the exctractionPath and add it if it is missing if (@exctractionPath.Substring(@exctractionPath.Length - 1, 1) != "/") { @exctractionPath += "/"; } int[] progress = new int[1]; GCHandle ibuf = GCHandle.Alloc(progress, GCHandleType.Pinned); int res = 0; #if (UNITY_ANDROID || UNITY_STANDALONE_LINUX || UNITY_EDITOR) && !UNITY_EDITOR_WIN if(FileBuffer != null) { GCHandle fbuf = GCHandle.Alloc(FileBuffer, GCHandleType.Pinned); if (largeFiles){ res = decompress7zip(null, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), fbuf.AddrOfPinnedObject(), FileBuffer.Length); }else{ res = decompress7zip2(null, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), fbuf.AddrOfPinnedObject(), FileBuffer.Length); } fbuf.Free(); ibuf.Free(); return res; } else { if (largeFiles){ res = decompress7zip(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; }else{ res = decompress7zip2(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; } } #endif #if (!UNITY_WSA && !UNITY_WEBGL && !UNITY_STANDALONE_LINUX && !UNITY_ANDROID) || UNITY_EDITOR_WIN || UNITY_WSA_10_0 if (largeFiles) { res = decompress7zip(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; } else { res = decompress7zip2(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; } #endif #if (UNITY_WSA_8_1 || UNITY_WP_8_1 || UNITY_WINRT_8_1 || UNITY_WEBGL) && !UNITY_EDITOR res = decompress7zip2(@filePath, @exctractionPath, fullPaths, entry, ibuf.AddrOfPinnedObject(), IntPtr.Zero, 0); ibuf.Free(); return res; #endif } #if !(UNITY_WSA || UNITY_WP_8_1) || UNITY_EDITOR //ERROR CODES (for both encode/decode LzmaUtil functions): // 1 : OK // -10 : Can not read input file // -11 : Can not write output file // -12 : Can not allocate memory // -13 : Data error //This function encodes a single archive in lzma alone format. //inPath : the file to be encoded. (use full path + file name) //outPath : the .lzma file that will be produced. (use full path + file name) // //You can set the compression properties by calling the setProps function before. //setProps(9) for example will set compression evel to highest level. public static int LzmaUtilEncode(string inPath, string outPath) { if (!defaultsSet) setProps(); GCHandle prps = GCHandle.Alloc(props, GCHandleType.Pinned); int res = lzmaUtil(true, @inPath, @outPath, prps.AddrOfPinnedObject()); prps.Free(); return res; } //This function decodes a single archive in lzma alone format. //inPath : the .lzma file that will be decoded. (use full path + file name) //outPath : the decoded file. (use full path + file name) public static int LzmaUtilDecode(string inPath, string outPath) { return lzmaUtil(false, @inPath, @outPath, IntPtr.Zero); } #endif //Lists get filled with filenames (including path if the file is in a folder) and uncompressed file sizes public static List<string> ninfo = new List<string>();//filenames public static List<long> sinfo = new List<long>();//file sizes //this function fills the ArrayLists with the filenames and file sizes that are in the 7zip file //returns : the total size in bytes of the files in the 7z archive // //filePath : the full path to the archive, including the archives name. (/myPath/myArchive.7z) //tempPath : (optional) a temp path that will be used to write the files info (otherwise the path of the 7z archive will be used) // : this is useful when your 7z archive resides in a read only location. // : the tempPath should be in this form: 'dir/dir/myTempLog' with no slash in the end. The last name will be used as the log's filename. //FileBuffer : A buffer that holds a 7zip file. When assigned the function will read from this buffer and will ignore the filePath. (Linux, iOS, Android, MacOSX) // //trueTotalFiles is an integer variable to store the total number of files in a 7z archive, excluding the folders. public static long get7zInfo(string filePath, string tempPath = null, byte[] FileBuffer = null) { ninfo.Clear(); sinfo.Clear(); trueTotalFiles = 0; int res = -1; string logPath = ""; #if !NETFX_CORE if (@tempPath == null) { if (persitentDataPath.Length > 0) logPath = @persitentDataPath + "/sevenZip.log"; else logPath = @Application.persistentDataPath + "/sevenZip.log"; } else { logPath = @tempPath; } #endif //for WSA, logPath should always be: Application.persistentDataPath + "/sevenZip.log"; #if NETFX_CORE #if UNITY_WSA_10_0 if(persitentDataPath.Length>0) logPath = @persitentDataPath + "/sevenZip.log"; else logPath = @Application.persistentDataPath + "/sevenZip.log"; #endif #if UNITY_WSA_8_1 || UNITY_WP_8_1 || UNITY_WINRT_8_1 if(persitentDataPath.Length>0) logPath = @persitentDataPath + "/sevenZip.log"; else logPath = @UnityEngine.Windows.Directory.localFolder + "/sevenZip.log"; #endif #endif if (File.Exists(logPath + ".txt")) File.Delete(logPath + ".txt"); #if (UNITY_ANDROID || UNITY_STANDALONE_LINUX || UNITY_EDITOR) && !UNITY_EDITOR_WIN if(FileBuffer != null) { GCHandle fbuf = GCHandle.Alloc(FileBuffer, GCHandleType.Pinned); res = _getSize(null, logPath, fbuf.AddrOfPinnedObject(), FileBuffer.Length); fbuf.Free(); }else { res = _getSize(@filePath, logPath, IntPtr.Zero, 0); } #else res = _getSize(@filePath, logPath, IntPtr.Zero, 0); #endif if (res == -1) { /*Debug.Log("Input file not found.");*/ return -1; } if (!File.Exists(logPath + ".txt")) {/* Debug.Log("Info file not found.");*/ return -3; } #if !NETFX_CORE StreamReader r = new StreamReader(logPath + ".txt"); #endif #if NETFX_CORE #if UNITY_WSA_10_0 IsolatedStorageFile ipath = IsolatedStorageFile.GetUserStoreForApplication(); StreamReader r = new StreamReader(new IsolatedStorageFileStream("sevenZip.log.txt", FileMode.Open, ipath)); #endif #if UNITY_WSA_8_1 || UNITY_WP_8_1 || UNITY_WINRT_8_1 var data = UnityEngine.Windows.File.ReadAllBytes(logPath + ".txt"); string ss = System.Text.Encoding.UTF8.GetString(data,0,data.Length); StringReader r = new StringReader(ss); #endif #endif string line; string[] rtt; long t = 0, sum = 0; while ((line = r.ReadLine()) != null) { rtt = line.Split('|'); ninfo.Add(rtt[0]); long.TryParse(rtt[1], out t); sum += t; sinfo.Add(t); if (t > 0) trueTotalFiles++; } #if !NETFX_CORE r.Close(); #endif r.Dispose(); File.Delete(logPath + ".txt"); return sum; } //this function returns the uncompressed file size of a given file in the 7z archive if specified, //otherwise it will return the total uncompressed size of all the files in the archive. // //If you don't fill the filePath parameter it will assume that the get7zInfo function has already been called. // // //filePath : the full path to the archive, including the archives name. (/myPath/myArchive.7z) // : if you call the function with filePath as null, it will try to find file sizes from the last call. //fileName : the file name we want to get the file size (if it resides in a folder add the folder path also) //tempPath : (optional) a temp path that will be used to write the files info (otherwise the path of the 7z archive will be used) // : this is useful when your 7z archive resides in a read only location. // : the tempPath should be in this form: 'dir/dir/myTempLog' with no slash in the end. The last name will be used as the log's filename. //FileBuffer : A buffer that holds a 7zip file. When assigned the function will read from this buffer and will ignore the filePath. (Linux, iOS, Android, MacOSX) public static long get7zSize(string filePath = null, string fileName = null, string tempPath = null, byte[] FileBuffer = null) { if (filePath != null) { if (get7zInfo(@filePath, @tempPath, FileBuffer) < 0) { return -1; } } if (ninfo == null) { if (ninfo.Count == 0) { return -1; } } long sum = 0; if (fileName != null) { for (int i = 0; i < ninfo.Count; i++) { if (ninfo[i].ToString() == fileName) { return (long)sinfo[i]; } } } else { for (int i = 0; i < ninfo.Count; i++) { sum += (long)sinfo[i]; } return sum; } return -1;//nothing was found } //A function to decode a specific archive in a 7z archive to a byte buffer // //filePath : the full path to the 7z archive //entry : the file name to decode to a buffer. If the file resides in a folder, the full path should be used. //tempPath : (optional) a temp path that will be used to write the files info (otherwise the path of the 7z archive will be used) // : this is useful when your 7z archive resides in a read only location. // : the tempPath should be in this form: 'dir/dir/myTempLog' with no slash in the end. The last name will be used as the log's filename. //FileBuffer : A buffer that holds a 7zip file. When assigned the function will read from this buffer and will ignore the filePath. (Linux, iOS, Android, MacOSX) public static byte[] decode2Buffer(string filePath, string entry, string tempPath = null, byte[] FileBuffer = null) { int bufs = (int)get7zSize(@filePath, entry, @tempPath, FileBuffer); if (bufs <= 0) return null;//entry error or it does not exist byte[] nb = new byte[bufs]; int res = 0; GCHandle dec2buf = GCHandle.Alloc(nb, GCHandleType.Pinned); #if (UNITY_ANDROID || UNITY_STANDALONE_LINUX || UNITY_EDITOR) && !UNITY_EDITOR_WIN if(FileBuffer != null) { GCHandle fbuf = GCHandle.Alloc(FileBuffer, GCHandleType.Pinned); res = decode2Buf(null, entry, dec2buf.AddrOfPinnedObject(), fbuf.AddrOfPinnedObject(), FileBuffer.Length); fbuf.Free(); }else { res = decode2Buf(@filePath, entry, dec2buf.AddrOfPinnedObject(), IntPtr.Zero, 0); } #else res = decode2Buf(@filePath, entry, dec2buf.AddrOfPinnedObject(), IntPtr.Zero, 0); #endif dec2buf.Free(); if (res == 1) { return nb; } else { nb = null; return null; } } #if !(UNITY_WSA || UNITY_WP_8_1) || UNITY_EDITOR //This function encodes inBuffer to lzma alone format into the outBuffer provided. //The buffer can be saved also into a file and can be opened by applications that opens the lzma alone format. //This buffer can be uncompressed by the decompressBuffer function. //Returns true if success //if makeHeader==false then the lzma 13 bytes header will not be added to the buffer. // //You can set the compression properties by calling the setProps function before. //setProps(9) for example will set compression level to the highest level. // public static bool compressBuffer(byte[] inBuffer, ref byte[] outBuffer, bool makeHeader = true) { if (!defaultsSet) setProps(); GCHandle prps = GCHandle.Alloc(props, GCHandleType.Pinned); GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); IntPtr ptr; int res = 0; ptr = Lzma_Compress(cbuf.AddrOfPinnedObject(), inBuffer.Length, makeHeader, ref res, prps.AddrOfPinnedObject()); cbuf.Free(); prps.Free(); if (res == 0 || ptr == IntPtr.Zero) { _releaseBuffer(ptr); return false; } Array.Resize(ref outBuffer, res); Marshal.Copy(ptr, outBuffer, 0, res); _releaseBuffer(ptr); return true; } //same as the above function, only it compresses a part of the input buffer. // //inBufferPartialLength: the size of the input buffer that should be compressed //inBufferPartialIndex: the offset of the input buffer from where the compression will start // public static bool compressBufferPartial(byte[] inBuffer, int inBufferPartialIndex, int inBufferPartialLength, ref byte[] outBuffer, bool makeHeader = true) { if (inBufferPartialIndex + inBufferPartialLength > inBuffer.Length) return false; if (!defaultsSet) setProps(); GCHandle prps = GCHandle.Alloc(props, GCHandleType.Pinned); GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); IntPtr ptr; IntPtr ptrPartial; int res = 0; ptrPartial = new IntPtr(cbuf.AddrOfPinnedObject().ToInt64() + inBufferPartialIndex); ptr = Lzma_Compress(ptrPartial, inBufferPartialLength, makeHeader, ref res, prps.AddrOfPinnedObject()); cbuf.Free(); if (res == 0 || ptr == IntPtr.Zero) { _releaseBuffer(ptr); return false; } Array.Resize(ref outBuffer, res); Marshal.Copy(ptr, outBuffer, 0, res); _releaseBuffer(ptr); return true; } //same as compressBufferPartial, only this function will compress the data into a fixed size buffer //the compressed size is returned so you can manipulate it at will. public static int compressBufferPartialFixed(byte[] inBuffer, int inBufferPartialIndex, int inBufferPartialLength, ref byte[] outBuffer, bool safe = true, bool makeHeader = true) { if (inBufferPartialIndex + inBufferPartialLength > inBuffer.Length) return 0; if (!defaultsSet) setProps(); GCHandle prps = GCHandle.Alloc(props, GCHandleType.Pinned); GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); IntPtr ptr; IntPtr ptrPartial; int res = 0; ptrPartial = new IntPtr(cbuf.AddrOfPinnedObject().ToInt64() + inBufferPartialIndex); ptr = Lzma_Compress(ptrPartial, inBufferPartialLength, makeHeader, ref res, prps.AddrOfPinnedObject()); cbuf.Free(); if (res == 0 || ptr == IntPtr.Zero) { _releaseBuffer(ptr); return 0; } //if the compressed buffer is larger then the fixed size buffer we use: //1. then write only the data that fit in it. //2. or we return 0. //It depends on if we set the safe flag to true or not. if (res > outBuffer.Length) { if (safe) { _releaseBuffer(ptr); return 0; } else { res = outBuffer.Length; } } Marshal.Copy(ptr, outBuffer, 0, res); _releaseBuffer(ptr); return res; } //same as the compressBuffer function, only this function will put the result in a fixed size buffer to avoid memory allocations. //the compressed size is returned so you can manipulate it at will. public static int compressBufferFixed(byte[] inBuffer, ref byte[] outBuffer, bool safe = true, bool makeHeader = true) { if (!defaultsSet) setProps(); GCHandle prps = GCHandle.Alloc(props, GCHandleType.Pinned); GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); IntPtr ptr; int res = 0; ptr = Lzma_Compress(cbuf.AddrOfPinnedObject(), inBuffer.Length, makeHeader, ref res, prps.AddrOfPinnedObject()); cbuf.Free(); prps.Free(); if (res == 0 || ptr == IntPtr.Zero) { _releaseBuffer(ptr); return 0; } //if the compressed buffer is larger then the fixed size buffer we use: //1. then write only the data that fit in it. //2. or we return 0. //It depends on if we set the safe flag to true or not. if (res > outBuffer.Length) { if (safe) { _releaseBuffer(ptr); return 0; } else { res = outBuffer.Length; } } Marshal.Copy(ptr, outBuffer, 0, res); _releaseBuffer(ptr); return res; } #endif //This function will decompress a compressed asset bundle. //It finds the magic number of the lzma format and extracts from there. // //inBuffer: the buffer that stores a compressed asset bundle. //outBuffer: a referenced buffer where the asset bundle will be uncompressed. //The error codes /* OK 0 ERROR_DATA 1 ERROR_MEM 2 ERROR_UNSUPPORTED 4 ERROR_PARAM 5 ERROR_INPUT_EOF 6 ERROR_OUTPUT_EOF 7 ERROR_FAIL 11 ERROR_THREAD 12 */ public static int decompressAssetBundle(byte[] inBuffer, ref byte[] outbuffer) { int offset = 0; for (int i = 0; i < inBuffer.Length; i++) { if (i > 1024) break; if (inBuffer[i] == 0x5d) { if (inBuffer[i + 1] == 0x00) { if (inBuffer[i + 2] == 0x00) { if (inBuffer[i + 3] == 0x08) { offset = i; break; } } } } } if (offset == 0 || offset > 1024) return 4; GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); IntPtr ptrBundle = new IntPtr(cbuf.AddrOfPinnedObject().ToInt64() + offset); int uncompressedSize = (int)BitConverter.ToUInt64(inBuffer, offset + 5); if (uncompressedSize < 0) { cbuf.Free(); return 4; } Array.Resize(ref outbuffer, uncompressedSize); GCHandle obuf = GCHandle.Alloc(outbuffer, GCHandleType.Pinned); int res = Lzma_Uncompress(ptrBundle, inBuffer.Length - offset, uncompressedSize, obuf.AddrOfPinnedObject(), true); cbuf.Free(); obuf.Free(); //if(res!=0){/*Debug.Log("ERROR: "+res.ToString());*/ return res; } return res; } /* //this will decompress an lzma alone format file. public static int decompressLzmaAlone(string inFile, string outFile){ if(File.Exists(inFile)) { var inBuffer = File.ReadAllBytes(inFile); int offset = 0; for(int i=0; i<inBuffer.Length; i++) { if(i>16) break; if(inBuffer[i] == 0x5d) { if(inBuffer[i+1] == 0x00) { if(inBuffer[i+2] == 0x00) { if(inBuffer[i+3] == 0x00) { offset = i; break; } } } } } if(offset>16) { inBuffer=null; return 4; } GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); IntPtr ptrBundle = new IntPtr(cbuf.AddrOfPinnedObject().ToInt64() + offset); int uncompressedSize = (int)BitConverter.ToUInt64(inBuffer,offset+5); if(uncompressedSize<0) { cbuf.Free(); return 4; } byte[] outBuffer = new byte[uncompressedSize]; GCHandle obuf = GCHandle.Alloc(outBuffer, GCHandleType.Pinned); int res = Lzma_Uncompress(ptrBundle, inBuffer.Length-offset, uncompressedSize, obuf.AddrOfPinnedObject(), true); cbuf.Free(); obuf.Free(); File.WriteAllBytes(outFile, outBuffer); Array.Resize(ref outBuffer, 0); Array.Resize(ref inBuffer, 0); outBuffer = null; inBuffer = null; GC.Collect(); return res; } else { return -1; } } */ //This function decompresses an lzma compressed byte buffer. //If the useHeader flag is false you have to provide the uncompressed size of the buffer via the customLength integer. //if res==0 operation was successful //The error codes /* OK 0 ERROR_DATA 1 ERROR_MEM 2 ERROR_UNSUPPORTED 4 ERROR_PARAM 5 ERROR_INPUT_EOF 6 ERROR_OUTPUT_EOF 7 ERROR_FAIL 11 ERROR_THREAD 12 */ public static int decompressBuffer(byte[] inBuffer, ref byte[] outbuffer, bool useHeader = true, int customLength = 0) { GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); int uncompressedSize = 0; //if the lzma header will be used to extract the uncompressed size of the buffer. If the buffer does not have a header //provide the known uncompressed size through the customLength integer. if (useHeader) uncompressedSize = (int)BitConverter.ToUInt64(inBuffer, 5); else uncompressedSize = customLength; Array.Resize(ref outbuffer, uncompressedSize); GCHandle obuf = GCHandle.Alloc(outbuffer, GCHandleType.Pinned); int res = Lzma_Uncompress(cbuf.AddrOfPinnedObject(), inBuffer.Length, uncompressedSize, obuf.AddrOfPinnedObject(), useHeader); cbuf.Free(); obuf.Free(); //if(res!=0){/*Debug.Log("ERROR: "+res.ToString());*/ return res; } return res; } public static byte[] decompressBuffer(byte[] inBuffer, bool useHeader = true, int customLength = 0) { GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); int uncompressedSize = 0; //if the lzma header will be used to extract the uncompressed size of the buffer. If the buffer does not have a header //provide the known uncompressed size through the customLength integer. if (useHeader) uncompressedSize = (int)BitConverter.ToUInt64(inBuffer, 5); else uncompressedSize = customLength; byte[] outbuffer = new byte[uncompressedSize]; GCHandle obuf = GCHandle.Alloc(outbuffer, GCHandleType.Pinned); int res = Lzma_Uncompress(cbuf.AddrOfPinnedObject(), inBuffer.Length, uncompressedSize, obuf.AddrOfPinnedObject(), useHeader); cbuf.Free(); obuf.Free(); if (res != 0) {/*Debug.Log("ERROR: "+res.ToString());*/ return null; } return outbuffer; } //same as above function. Only this one outputs to a buffer of fixed which size isn't resized to avoid memory allocations. //The fixed buffer should have a size that will be able to hold the incoming decompressed data. //returns the uncompressed size. public static int decompressBufferFixed(byte[] inBuffer, ref byte[] outbuffer, bool safe = true, bool useHeader = true, int customLength = 0) { int uncompressedSize = 0; //if the lzma header will be used to extract the uncompressed size of the buffer. If the buffer does not have a header //provide the known uncompressed size through the customLength integer. if (useHeader) uncompressedSize = (int)BitConverter.ToUInt64(inBuffer, 5); else uncompressedSize = customLength; //Check if the uncompressed size is bigger then the size of the fixed buffer. Then: //1. write only the data that fit in it. //2. or return a negative number. //It depends on if we set the safe flag to true or not. if (uncompressedSize > outbuffer.Length) { if (safe) return -101; else uncompressedSize = outbuffer.Length; } GCHandle cbuf = GCHandle.Alloc(inBuffer, GCHandleType.Pinned); GCHandle obuf = GCHandle.Alloc(outbuffer, GCHandleType.Pinned); int res = Lzma_Uncompress(cbuf.AddrOfPinnedObject(), inBuffer.Length, uncompressedSize, obuf.AddrOfPinnedObject(), useHeader); cbuf.Free(); obuf.Free(); if (res != 0) {/*Debug.Log("ERROR: "+res.ToString());*/ return -res; } return uncompressedSize; } } #endif Main/Common/SevenZip/lzma.cs.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: 13c1c59b80961f74e9c2c894f0961517 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: Main/Core/GameEngine/Launch.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: 1a1192b48924f274e8e3ce3c265331a8 folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/AssetCopyTask.cs
New file @@ -0,0 +1,266 @@ using System; using System.Collections.Generic; using System.IO; using UnityEngine; public class AssetCopyTask : LaunchTask { int completedCount = 0; int totalCount = -1; List<FileInfo> copyTasks = new List<FileInfo>(); public override float expectTime { get { return LocalSave.GetFloat("AssetCopyTask_ExpectTime", 70f); } protected set { LocalSave.SetFloat("AssetCopyTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.AssetCopy; duration = Mathf.Max(0.5f, expectTime); outTime = 50f; if (Application.isEditor) { done = true; } else { switch (Application.platform) { case RuntimePlatform.Android: AndroidCopyAsset(); break; case RuntimePlatform.IPhonePlayer: IOSCopyAsset(); break; case RuntimePlatform.WindowsPlayer: StandaloneCopyAsset(); break; } } } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); if (!Application.isEditor) { switch (Application.platform) { case RuntimePlatform.Android: AndroidProcessCopyComplete(); break; case RuntimePlatform.IPhonePlayer: IOSProcessCopyComplete(); break; } } } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!Application.isEditor) { switch (Application.platform) { case RuntimePlatform.Android: AndroidWaitCopyAssetComplete(); break; case RuntimePlatform.IPhonePlayer: case RuntimePlatform.WindowsPlayer: IOSorStandaloneWaitCopyAssetComplete(); break; } } ExceptionReport(); } private void AndroidCopyAsset() { switch (VersionConfig.Get().assetAccess) { case InstalledAsset.FullAsset: case InstalledAsset.HalfAsset: case InstalledAsset.IngoreDownLoad: if (!SDKUtils.Instance.AssetCopyFinished) { SDKUtils.Instance.CopyAsset(); done = false; progress = 0f; } else { done = true; } break; case InstalledAsset.NullAsset: done = true; break; } } private void IOSCopyAsset() { if (VersionUtility.Instance.versionInfo != null && VersionUtility.Instance.versionInfo.downAsset == 1) { switch (VersionConfig.Get().assetAccess) { case InstalledAsset.FullAsset: case InstalledAsset.HalfAsset: case InstalledAsset.IngoreDownLoad: if (!SDKUtils.Instance.AssetCopyFinished) { copyTasks = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(ResourcesPath.Instance.StreamingAssetPath, copyTasks); for (var i = copyTasks.Count - 1; i >= 0; i--) { var fileInfo = copyTasks[i]; var destPath = fileInfo.FullName.Replace(ResourcesPath.Instance.StreamingAssetPath, ResourcesPath.Instance.ExternalStorePath); if (File.Exists(destPath)) { copyTasks.RemoveAt(i); } } completedCount = 0; totalCount = copyTasks.Count; } if (totalCount > 0) { done = false; progress = 0f; } else { done = true; } break; case InstalledAsset.NullAsset: done = true; break; } } else { done = true; } } private void StandaloneCopyAsset() { if (VersionUtility.Instance.versionInfo != null && VersionUtility.Instance.versionInfo.downAsset == 1) { switch (VersionConfig.Get().assetAccess) { case InstalledAsset.FullAsset: case InstalledAsset.HalfAsset: case InstalledAsset.IngoreDownLoad: copyTasks = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(ResourcesPath.Instance.StreamingAssetPath, copyTasks); for (var i = copyTasks.Count - 1; i >= 0; i--) { var fileInfo = copyTasks[i]; var destPath = fileInfo.FullName.Replace(ResourcesPath.Instance.StreamingAssetPath, ResourcesPath.Instance.ExternalStorePath); if (File.Exists(destPath)) { copyTasks.RemoveAt(i); } } completedCount = 0; totalCount = copyTasks.Count; if (totalCount > 0) { done = false; progress = 0f; } else { done = true; } break; case InstalledAsset.NullAsset: done = true; break; } } else { done = true; } } private void AndroidWaitCopyAssetComplete() { if (!SDKUtils.Instance.AssetCopyFinished) { done = false; progress = timer / duration; } else { done = true; } } private void IOSorStandaloneWaitCopyAssetComplete() { if (totalCount > 0) { if (completedCount < totalCount) { var fileInfo = copyTasks[0]; var destPath = fileInfo.FullName.Replace(ResourcesPath.Instance.StreamingAssetPath, ResourcesPath.Instance.ExternalStorePath); var destDirectoryName = Path.GetDirectoryName(destPath); if (!Directory.Exists(destDirectoryName)) { Directory.CreateDirectory(destDirectoryName); } Debug.LogFormat("拷贝文件:{0}", fileInfo.Name); File.Copy(fileInfo.FullName, destPath, true); copyTasks.RemoveAt(0); completedCount++; done = false; progress = (float)completedCount / totalCount; } else { done = true; } } else { done = true; } } private void AndroidProcessCopyComplete() { } private void IOSProcessCopyComplete() { LocalSave.SetString("AssetCopyCompleted_IOSorStandalone", VersionConfig.Get().version); } } Main/Core/GameEngine/Launch/AssetCopyTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 64943b900511811419130066733f1396 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/AssetDeCompressTask.cs
New file @@ -0,0 +1,204 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using System.Threading; public class AssetDeCompressTask { public static string assetDeCompressVersion { get { return LocalSave.GetString("AssetDeCompressVersion"); } set { LocalSave.SetString("AssetDeCompressVersion", value); } } public static bool assetDeCompressCompleted { get { if (string.IsNullOrEmpty(assetDeCompressVersion)) { return false; } else { return assetDeCompressVersion == VersionConfig.Get().version; } } } public static void Decompress(string path) { var files = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(path, files); foreach (var item in files) { var fullName = item.FullName; if (fullName.EndsWith(".7z")) { SevenZipUtility.DeCompress(fullName, Path.GetDirectoryName(fullName)); } } } public static DecompressProgress DecompressAync(string path) { var progress = new DecompressProgress(); var files = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(path, files); for (var i = files.Count - 1; i >= 0; i--) { var fullName = files[i].FullName; if (!fullName.EndsWith(".7z")) { files.RemoveAt(i); } } var total = files.Count; if (total == 0) { progress.progress = 1f; progress.done = true; return progress; } ThreadPool.QueueUserWorkItem((object a) => { var index = 0; foreach (var item in files) { var fullName = item.FullName; if (fullName.EndsWith(".7z")) { SevenZipUtility.DeCompress(fullName, Path.GetDirectoryName(fullName)); index++; progress.progress = index / (float)total; } } progress.done = true; }); return progress; } public static void Delete7zFiles(string path) { var files = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(path, files); for (var i = files.Count - 1; i >= 0; i--) { var fullName = files[i].FullName; if (fullName.EndsWith(".7z")) { files[i].Delete(); } } } public class DecompressProgress { object progressLock = new object(); float m_Progress = 0f; public float progress { get { return m_Progress; } set { lock (progressLock) { m_Progress = value; } } } object doneLock = new object(); bool m_Done = false; public bool done { get { return m_Done; } set { lock (doneLock) { m_Done = value; } } } } } public class AssetDecompressTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("AssetDecompressTask_ExpectTime", 5f); } protected set { LocalSave.SetFloat("AssetDecompressTask_ExpectTime", value); } } AssetDeCompressTask.DecompressProgress deCompressProgress = null; float waitTimer = 0f; public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.AssetDecompress; duration = Mathf.Max(0.5f, expectTime); if (!AssetDeCompressTask.assetDeCompressCompleted) { deCompressProgress = AssetDeCompressTask.DecompressAync(ResourcesPath.Instance.ExternalStorePath); done = false; } else { done = true; } } public override void End() { AssetDeCompressTask.assetDeCompressVersion = VersionConfig.Get().version; AssetDeCompressTask.Delete7zFiles(ResourcesPath.Instance.ExternalStorePath); } public override void Update() { if (done) { return; } timer += Time.deltaTime; progress = timer / duration; if (deCompressProgress == null || deCompressProgress.done) { waitTimer += Time.deltaTime; if (waitTimer > 2f) { done = true; } } } } Main/Core/GameEngine/Launch/AssetDeCompressTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 7ff0a94221f3cda4689ea3b7882f2562 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/BuiltInAssetCopyTask.cs
New file @@ -0,0 +1,249 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using System; public class BuiltInAssetCopyTask : LaunchTask { bool firstLaunch = false; public override void Begin() { duration = Mathf.Max(0.2f, expectTime); //非安卓平台的时间,安卓由sdk拷贝完成回调 if (Application.isEditor) { EditorCopyAsset(); } else { //安卓每次由sdk回调拷贝成功,其他平台由unity自己存储标记 switch (Application.platform) { case RuntimePlatform.Android: AndroidCopyAsset(); break; case RuntimePlatform.IPhonePlayer: IosCopyAsset(); break; case RuntimePlatform.WindowsPlayer: StandaloneCopyAsset(); break; } } if (!firstLaunch) { done = true; } } public override void End() { if (!AssetSource.builtInFromEditor) { AssetBundleUtility.Instance.InitBuiltInAsset(); } // TODO YYL // ConfigInitiator.SyncInit(); // WindowCenter.Instance.DestoryWinsByStage(WindowCenter.WindowStage.Launch); // WindowCenter.Instance.OpenFromLocal<LaunchWin>(); Language.InitDefaultLanguage(); } public override void Update() { if (done) { return; } if (!Application.isEditor) { //安卓每次由sdk回调拷贝成功,其他平台由unity自己存储标记 if (Application.platform == RuntimePlatform.Android) { AndroidWaitCopyAssetComplete(); } else { if (timer > duration) { done = true; } else { done = false; progress = timer / duration; } } } timer += Time.deltaTime; } private void AndroidWaitCopyAssetComplete() { if (!SDKUtils.Instance.AssetCopyFinished) { done = false; progress = timer / duration; } else { done = true; } } private void AndroidCopyAsset() { if (!SDKUtils.Instance.AssetCopyFinished) { //每次由sdk回调拷贝成功 firstLaunch = true; UnityEngine.Debug.Log("开始拷贝builtin资源"); SDKUtils.Instance.CopyAsset(1); //ynmbxxjUtil.Instance.CopyOneAsset("builtin_assetbundle"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin_assetbundle.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/musics"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/musics.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/prefabs"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/prefabs.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/sprites"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/sprites.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/animationclips"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/animationclips.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/materials"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/materials.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/scriptableobjects"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/scriptableobjects.manifest"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/font"); //ynmbxxjUtil.Instance.CopyOneAsset("builtin/font.manifest"); //foreach (var config in ConfigInitiator.builtinConfig) //{ // ynmbxxjUtil.Instance.CopyOneAsset("config/" + config); //} //AssetDeCompressTask.Decompress(ResourcesPath.Instance.ExternalStorePath); //LocalSave.SetString("BuiltInAssetCopyCompleted_Android", VersionConfig.Get().version); } else UnityEngine.Debug.Log("builtin资源已经拷贝过了"); } private void IosCopyAsset() { if (!VersionUtility.Instance.InIosAuditTime()) { if (!SDKUtils.builtinAssetCopyFinished) { firstLaunch = true; var targetDirectory = ResourcesPath.Instance.ExternalStorePath; if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } var fileNames = new List<string>(); //var files = new List<FileInfo>(); //FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, "builtin"), files); //foreach (var file in files) //{ // var name = Path.GetFileName(file.FullName); // fileNames.Add(StringUtility.Contact("builtin", Path.DirectorySeparatorChar, name)); //} //fileNames.Add("builtin_assetbundle"); //fileNames.Add("builtin_assetbundle.manifest"); var configFiles = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, "config"), configFiles); foreach (var file in configFiles) { var name = Path.GetFileName(file.FullName); fileNames.Add(StringUtility.Contact("config", Path.DirectorySeparatorChar, name)); } foreach (var item in fileNames) { var fromPath = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, item); var toPath = StringUtility.Contact(targetDirectory, item); var destDirectoryName = Path.GetDirectoryName(toPath); if (!Directory.Exists(destDirectoryName)) { Directory.CreateDirectory(destDirectoryName); } File.Copy(fromPath, toPath, true); } LocalSave.SetString("BuiltInAssetCopyCompleted_IOSorStandalone", VersionConfig.Get().version); } } } private void StandaloneCopyAsset() { var targetDirectory = ResourcesPath.Instance.ExternalStorePath; if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } var fileNames = new List<string>(); //var files = new List<FileInfo>(); //FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, "builtin"), files); //foreach (var file in files) //{ // var name = Path.GetFileName(file.FullName); // fileNames.Add(StringUtility.Contact("builtin", Path.DirectorySeparatorChar, name)); //} //fileNames.Add("builtin_assetbundle"); //fileNames.Add("builtin_assetbundle.manifest"); var configFiles = new List<FileInfo>(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, "config"), configFiles); foreach (var file in configFiles) { var name = Path.GetFileName(file.FullName); fileNames.Add(StringUtility.Contact("config", Path.DirectorySeparatorChar, name)); } foreach (var item in fileNames) { var fromPath = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, item); var toPath = StringUtility.Contact(targetDirectory, item); if (File.Exists(toPath)) { continue; } var destDirectoryName = Path.GetDirectoryName(toPath); if (!Directory.Exists(destDirectoryName)) { Directory.CreateDirectory(destDirectoryName); } File.Copy(fromPath, toPath, true); } } private void EditorCopyAsset() { if (!AssetSource.allFromEditor) { // FileExtersion.DirectoryCopy(ResourcesPath.CONFIG_FODLER, ResourcesPath.Instance.StreamingAssetPath + "config"); // FileExtersion.DirectoryCopy(ResourcesPath.ResourcesOutPath + "BuiltIn", ResourcesPath.Instance.StreamingAssetPath + "builtin"); } } } Main/Core/GameEngine/Launch/BuiltInAssetCopyTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 1761a3254ef37ba4fbd60b602c1c786d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/CheckAssetValidTask.cs
New file @@ -0,0 +1,73 @@ using System; using System.Collections.Generic; using System.IO; using UnityEngine; public class CheckAssetValidTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("CheckAssetValidTask_ExpectTime", 3f); } protected set { LocalSave.SetFloat("CheckAssetValidTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.CheckAsset; duration = Mathf.Max(0.5f, expectTime); ServerListCenter.Instance.RequestJumpUrl(); // TODO YYL // OperationLogCollect.Instance.RecordLauchEvent(2); // OperationLogCollect.Instance.RecordEvent(2); if (VersionUtility.Instance.NeedDownAsset()) { var remoteURL = StringUtility.Contact(VersionUtility.Instance.versionInfo.GetResourcesURL(VersionConfig.Get().branch), Language.fixPath, "/config/PriorBundle.txt"); var localURL = StringUtility.Contact(ResourcesPath.Instance.ExternalStorePath, "config/PriorBundle.txt"); var downloadTask = new DownloadTask(remoteURL, localURL); downloadTask.BeginDownload(AssetVersionUtility.OnDownLoadPriorBundle); //AssetVersionUtility.GetAssetVersionFile(); done = false; progress = 0f; } else { //if (Application.isEditor) // PatchLoader.InitLocalPatchAsset(); done = true; } } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); // TODO YYL // GameNotice.OpenGameNotice(); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!AssetVersionUtility.checkAssetCompleted) { done = false; progress = timer / expectTime; } else { done = true; } ExceptionReport(); } } Main/Core/GameEngine/Launch/CheckAssetValidTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 8a5baa7ec7f114141b60eae7f1ed95b6 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/DownLoadAssetTask.cs
New file @@ -0,0 +1,277 @@ using System; using System.Collections.Generic; using System.IO; using UnityEngine; public class DownLoadAssetTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("DownLoadAssetTask_ExpectTime", 3f); } protected set { LocalSave.SetFloat("DownLoadAssetTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.DownLoad; outTime = 9999f; duration = Mathf.Max(0.5f, expectTime); if (VersionUtility.Instance.NeedDownAsset()) { if (!AssetVersionUtility.priorAssetDownLoadDone) { AssetVersionUtility.BeginDownLoadTask(true); done = false; progress = 0f; } else { done = true; } } else { done = true; } } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); if (!AssetVersionUtility.unPriorAssetDownLoadDone) { AssetVersionUtility.BeginDownLoadTask(false); } } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!AssetVersionUtility.priorAssetDownLoadDone) { done = false; progress = 0f; } else { done = true; } ExceptionReport(); } } public class AssetBundleInitTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("AssetBundleInitTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("AssetBundleInitTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.AssetBundleInit; duration = Mathf.Max(0.5f, expectTime); if (!AssetSource.allFromEditor) { AssetBundleUtility.Instance.Initialize(); done = false; progress = 0f; } else { done = true; } } public override void End() { expectTime = timer; // TODO YYL // UILoader.LoadWindowAsync("LaunchBackGroundWin", null); Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); } public override void Update() { if (done) { return; } if (AssetBundleUtility.Instance.initialized && AssetBundleUtility.Instance.initializedUIAssetBundle) { done = true; } else { done = false; progress = timer / duration; } ExceptionReport(); } } public class ConfigInitTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("ConfigInitTask_ExpectTime", 10f); } protected set { LocalSave.SetFloat("ConfigInitTask_ExpectTime", value); } } float threshold = 1f; public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.ConfigInit; duration = Mathf.Max(0.5f, expectTime); threshold = Application.platform == RuntimePlatform.WindowsEditor ? 1f : 0.9f; // LaunchPostProcess.Instance.Begin(); // InitialFunctionConfig.Init(true); //有更新再初始化一次 } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); // TODO YYL // OperationLogCollect.Instance.RecordLauchEvent(3); // OperationLogCollect.Instance.RecordEvent(3); } public override void Update() { if (done) { return; } timer += Time.deltaTime; // if (!ConfigInitiator.IsLoginConfigInited)\ // TODO YYL // if (!ConfigInitiator.done) // { // done = false; // progress = timer / duration; // } // else { done = true; } ExceptionReport(); } } public class LaunchFadeOutTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("LaunchFadeOutTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("LaunchFadeOutTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.Complete; duration = 0.5f; ShaderUtility.WarmUpAll(); //SpeechTranslate.Instance.RequestGetToken(); // TODO CYL // WindowCenter.Instance.Open<LaunchBackGroundWin>(true); // var launchWin = WindowCenter.Instance.Get<LaunchWin>(); // if (launchWin != null) // { // launchWin.FadeOut(); // } // try // { // LogicLauncher.LaunchStart(); // } // catch (Exception e) // { // UnityEngine.Debug.LogError(e); // } } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (timer >= 0.5f)//&& ILLauncherProxy.Instance.started) { done = true; } else { done = false; progress = Mathf.Clamp01(timer / expectTime); } ExceptionReport(); } } public class WaitTask : LaunchTask { public WaitTask(float seconds) { expectTime = Mathf.Max(0.1f, seconds); } public override void Begin() { } public override void End() { } public override void Update() { timer += Time.deltaTime; if (timer >= expectTime) { done = true; } else { done = false; progress = Mathf.Clamp01(timer / expectTime); } } } Main/Core/GameEngine/Launch/DownLoadAssetTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 16185d13cc99c3443bb2e65696e1f1ce MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/GetVersionInfoTask.cs
New file @@ -0,0 +1,78 @@ using UnityEngine; using System.Collections; using vnxbqy.UI; using System; using System.Collections.Generic; using System.IO; public class GetVersionInfoTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("GetVersionInfoTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("GetVersionInfoTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.ClientVersion; duration = Mathf.Max(0.5f, expectTime); if (Application.isEditor) { if (InGameDownTestUtility.enable) { VersionUtility.Instance.RequestVersionCheck(); done = false; progress = 0f; } else { done = true; } } else { if (!VersionUtility.Instance.InIosAuditTime()) { VersionUtility.Instance.RequestVersionCheck(); done = false; progress = 0f; } else { done = true; } } } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!VersionUtility.Instance.completed) { done = false; progress = timer / expectTime; } else { done = true; } ExceptionReport(); } } Main/Core/GameEngine/Launch/GetVersionInfoTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e97b6f5762db50844882605678e5798d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/InitSettingTask.cs
New file @@ -0,0 +1,54 @@ using UnityEngine; public class InitSettingTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("InitSettingTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("InitSettingTask_ExpectTime", value); } } public override void Begin() { ShaderUtility.InitGlobalParams(); SoundPlayer.CreateSoundPlayer(); SoundPlayer.Instance.PlayLoginMusic(); SystemSetting.Instance.SetSoundVolume(SystemSetting.Instance.GetSoundVolume()); SystemSetting.Instance.SetSoundEffect(SystemSetting.Instance.GetSoundEffect()); SystemSetting.Instance.SetGameFps(SystemSetting.Instance.GetGameFps()); SystemSetting.Instance.LetFPSUnLimit(); DebugUtility.Instance.Init(); DebugUtility.Instance.CreateDebugRoot(); GameObjectPoolManager.Instance.gameObject.name = "GameObjectPool"; GameObjectPoolManager.Instance.Initialize(); //ExceptionCatcher.Init(); //ExceptionCatcher.Catch(); GlobalTimeEvent.Instance.Begin(); PackageRegedit.Init(); Clock.Init(); // TODO YYL // if (VersionConfig.Get().appId.Equals("test")) // { // SnxxzGame.Instance.gameObject.AddComponent<PocoManager>(); // } done = true; } public override void End() { expectTime = timer; } public override void Update() { timer += Time.deltaTime; } } Main/Core/GameEngine/Launch/InitSettingTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: ff71585fde92d814d97586fe3c01aa6d MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/LaunchInHot.cs
New file @@ -0,0 +1,180 @@ using UnityEngine; using System.Collections; using vnxbqy.UI; using System; using System.Collections.Generic; using System.IO; public class LaunchInHot : MonoBehaviour { static int step = 0; public static LaunchStage m_CurrentStage = LaunchStage.None; public static LaunchProgressInfo progressInfo { get; private set; } float timer = 0f; Queue<LaunchTask> tasks = new Queue<LaunchTask>(); LaunchTask currentTask = null; bool launchComplete = false; float surplusProgress = 0f; float surplusTime = 0f; void Start() { System.Net.ServicePointManager.DefaultConnectionLimit = 100;//设置http最大连接数 Application.backgroundLoadingPriority = ThreadPriority.High; Screen.sleepTimeout = SleepTimeout.NeverSleep; SDKUtils.Instance.Init(); //原sdk接口 var builtInAssetCopyTask = new BuiltInAssetCopyTask(); var requestPermissionStart = new RequestPermissionStart(); var initSettingTask = new InitSettingTask(); var sdkInitedTask = new SDKInitedTask(); //var assetCopyTask = new AssetCopyTask(); //var assetDecompressTask = new AssetDecompressTask(); var getVersionInfoTask = new GetVersionInfoTask(); var checkAssetValidTask = new CheckAssetValidTask(); var downLoadAssetTask = new DownLoadAssetTask(); var assetBundleInitTask = new AssetBundleInitTask(); var configInitTask = new ConfigInitTask(); var launchFadeOutTask = new LaunchFadeOutTask(); tasks.Enqueue(builtInAssetCopyTask); tasks.Enqueue(requestPermissionStart); tasks.Enqueue(initSettingTask); if (!Application.isEditor) { tasks.Enqueue(sdkInitedTask); } switch (Application.platform) { case RuntimePlatform.OSXEditor: case RuntimePlatform.WindowsEditor: tasks.Enqueue(getVersionInfoTask); break; case RuntimePlatform.Android: tasks.Enqueue(getVersionInfoTask); //tasks.Enqueue(assetCopyTask); //tasks.Enqueue(assetDecompressTask); break; case RuntimePlatform.IPhonePlayer: tasks.Enqueue(getVersionInfoTask); //tasks.Enqueue(assetCopyTask); break; case RuntimePlatform.WindowsPlayer: //tasks.Enqueue(assetCopyTask); tasks.Enqueue(getVersionInfoTask); break; } tasks.Enqueue(checkAssetValidTask); tasks.Enqueue(downLoadAssetTask); tasks.Enqueue(assetBundleInitTask); tasks.Enqueue(configInitTask); tasks.Enqueue(launchFadeOutTask); CalculateExpectTotalTime(); } void Update() { if (!launchComplete) { if (currentTask == null) { if (tasks.Count > 0) { currentTask = tasks.Dequeue(); currentTask.Begin(); } else { launchComplete = true; } } if (currentTask != null) { currentTask.Update(); } if (currentTask != null && currentTask.done) { currentTask.End(); CalculateExpectTotalTime(); currentTask = null; } if (m_CurrentStage == LaunchStage.DownLoad) { progressInfo = new LaunchProgressInfo(m_CurrentStage, 1, progressInfo.totalProgress, 0f); } else { timer += Time.deltaTime; var progress = progressInfo.totalProgress + surplusProgress * (Time.deltaTime / surplusTime); progress = Mathf.Clamp(progress, 0, 0.98f); var partProgress = 0f; if (currentTask == null) { partProgress = 0f; } else { var temp = currentTask.timer / Mathf.Min(2f, currentTask.duration); step = (int)temp + 1; partProgress = temp - (int)temp; } progressInfo = new LaunchProgressInfo(m_CurrentStage, step, Mathf.Clamp01(progress), partProgress); } } if (launchComplete) { UnityEngine.Debug.LogFormat("启动耗时:{0}", timer); progressInfo = new LaunchProgressInfo(m_CurrentStage, 1, 1f, 1f); this.enabled = false; // 启动流程结束 要去哪里 TODO YYL // StageLoad.Instance.PushSceneLoadCommand(new StageLoad.StageLoadCommand() // { // toMapId = 1, // toLineId = 0, // needEmpty = false, // needLoadResource = true, // serverType = ServerType.Main, // isClientLoadMap = true // }); } } public static int GetLaunchStage() { return (int)m_CurrentStage; } /// <summary> /// 计算总的预期时间 /// </summary> void CalculateExpectTotalTime() { surplusTime = 0f; foreach (var item in tasks) { surplusTime += item.expectTime; } surplusProgress = 1 - progressInfo.totalProgress; } } Main/Core/GameEngine/Launch/LaunchInHot.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 906ac694e0545124cbf74afe1c69b703 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/LaunchProgressInfo.cs
New file @@ -0,0 +1,17 @@ public struct LaunchProgressInfo { public LaunchStage stage; public int step; public float totalProgress; public float partProgress; public LaunchProgressInfo(LaunchStage stage, int step, float totalProgress, float partProgress) { this.stage = stage; this.step = step; this.totalProgress = totalProgress; this.partProgress = partProgress; } } Main/Core/GameEngine/Launch/LaunchProgressInfo.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 4ab1175bb98c09842bf2bb1026a8d7cb MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/LaunchStage.cs
New file @@ -0,0 +1,14 @@ public enum LaunchStage { None = 0, SDKInit = 1, AssetCopy = 2, AssetDecompress = 3, ClientVersion = 4, CheckAsset = 5, DownLoad = 6, AssetBundleInit = 7, ConfigInit = 8, Complete = 9, } Main/Core/GameEngine/Launch/LaunchStage.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: f3341cae2e8b8e64fba6fedb5d37723a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/LaunchTask.cs
New file @@ -0,0 +1,34 @@ using UnityEngine; public abstract class LaunchTask { public float timer { get; protected set; } public float duration { get; protected set; } bool exceptionReported = false; public bool done { get; protected set; } public float progress { get; protected set; } public virtual float expectTime { get; protected set; } protected float outTime = 15f; public abstract void Begin(); public abstract void Update(); public abstract void End(); public void ExceptionReport() { if (!exceptionReported && timer > outTime && !done) { var content = string.Format("任务:{0};网络状态:{1}", this.GetType().Name, Application.internetReachability); exceptionReported = true; } } } Main/Core/GameEngine/Launch/LaunchTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 8f8006ef67733114da2ae2e8e0679323 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/RequestPermissionStart.cs
New file @@ -0,0 +1,38 @@ //同意隐私权限后才可以申请权限 public class RequestPermissionStart : LaunchTask { public override void Begin() { if (LocalSave.GetBool("secretToggleStart5")) { SDKUtils.Instance.IsAgreeSecret = true; SDKUtils.Instance.RequestAndroidPermissionStart(); } else { //先弹隐私政策,同意之后才可以申请权限 继续游戏 // YYL TODO // WindowCenter.Instance.OpenFromLocal<RequestSecretWin>(); } } public override void End() { } public override void Update() { if (done) { return; } if (SDKUtils.Instance.IsAgreeSecret) { done = true; } } } Main/Core/GameEngine/Launch/RequestPermissionStart.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: d683f8dc80b4bf24b93f9be3077bd724 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Launch/SDKInitedTask.cs
New file @@ -0,0 +1,58 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using System; public class SDKInitedTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("SDKInitedTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("SDKInitedTask_ExpectTime", value); } } public override void Begin() { LaunchInHot.m_CurrentStage = LaunchStage.SDKInit; duration = Mathf.Max(0.1f, expectTime); } public override void End() { expectTime = timer; Debug.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); // TODO YYL // OperationLogCollect.Instance.RecordLauchEvent(1); // OperationLogCollect.Instance.RecordEvent(1); var cpu = 2; var memory = 2048; DeviceUtility.GetCpuAndMemory(out cpu, out memory); Debug.LogFormat("获得机器信息:cpu {0}----内存 {1}", cpu, memory); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (SDKUtils.Instance.InitFinished) { done = true; } else { done = false; progress = timer / duration; } ExceptionReport(); } } Main/Core/GameEngine/Launch/SDKInitedTask.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 6bf40baa355319f45b1de7b03576713a MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Core/GameEngine/Login.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: 8eda8f1b1cda90b408dd25bd730b25ab folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/Manager/ResManager.cs
@@ -128,7 +128,16 @@ } public string GetAssetFilePath(string _assetKey) { var path = Path.Combine(ExternalStorePath, _assetKey); if (!File.Exists(path)) { path = Path.Combine(StreamingAssetPath, _assetKey); } return path; } } Main/Manager/StageManager.cs
@@ -13,9 +13,9 @@ { public StageName currentStage; public Action AfterEnterGame; public Action AfterLoadingGameScene; public Action BeforeEnterGame; public Action BeforeLoadingGameScene; // public Action OnSwitchAccount; @@ -26,8 +26,8 @@ public void Release() { AfterEnterGame = null; BeforeEnterGame = null; AfterLoadingGameScene = null; BeforeLoadingGameScene = null; } public async UniTaskVoid ToLoginScene() @@ -70,8 +70,8 @@ public async UniTaskVoid ToGameScene() { UIManager.Instance.DestroyAllUI(); AfterEnterGame?.Invoke(); BeforeLoadingGameScene?.Invoke(); // ResManager.Instance.PrewarmResources(); @@ -82,7 +82,7 @@ // 加载初始化数据完成 currentStage = StageName.Game; BeforeEnterGame?.Invoke(); AfterLoadingGameScene?.Invoke(); UIManager.Instance.OpenWindow<MainWin>(); } Main/ResModule/AssetBundle/AssetBundleUtility.cs
@@ -3,7 +3,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; public class AssetBundleUtility : SingletonMonobehaviour<AssetBundleUtility> { @@ -97,23 +97,23 @@ assetBundle = null; } public IEnumerator Initialize() public async UniTask Initialize() { yield return StartCoroutine(Co_LoadMainfestFile("audio")); yield return StartCoroutine(Co_LoadMainfestFile("video")); yield return StartCoroutine(Co_LoadMainfestFile("mobeffectshader")); yield return StartCoroutine(Co_LoadMainfestFile("config")); yield return StartCoroutine(Co_LoadMainfestFile("maps")); yield return StartCoroutine(Co_LoadMainfestFile("ui")); await Co_LoadMainfestFile("audio"); await Co_LoadMainfestFile("video"); await Co_LoadMainfestFile("mobeffectshader"); await Co_LoadMainfestFile("config"); await Co_LoadMainfestFile("maps"); await Co_LoadMainfestFile("ui"); yield return StartCoroutine(Co_LoadAssetBundle(ResourcesPath.windowFileBundleName)); yield return StartCoroutine(Co_LoadAssetBundle(ResourcesPath.uiprefabFileBundleName)); await Co_LoadAssetBundle(ResourcesPath.windowFileBundleName); await Co_LoadAssetBundle(ResourcesPath.uiprefabFileBundleName); initializedUIAssetBundle = true; initialized = true; } private IEnumerator Co_LoadMainfestFile(string _category) private async UniTask Co_LoadMainfestFile(string _category) { var path = AssetVersionUtility.GetAssetFilePath(StringUtility.Contact(AssetVersionUtility.EncodeFileName(_category), "_assetbundle"), false); var _assetBundle = AssetBundle.LoadFromFile(path); @@ -121,14 +121,14 @@ if (_assetBundle == null) { Debug.LogErrorFormat("AssetBundleManifest的包文件为空或者加载出错. Path:{0}", path); yield break; return; } AssetBundleManifest _assetBundleManifest = _assetBundle.LoadAsset<AssetBundleManifest>(ResourcesPath.AssetDependentFileAssetName); if (_assetBundleManifest == null) { Debug.LogErrorFormat("AssetBundleManifest的包文件为空或者加载出错. Path:{0}", path); yield break; return; } string[] _assetBundleNames = _assetBundleManifest.GetAllAssetBundles(); @@ -172,10 +172,10 @@ return; } StartCoroutine(Co_DoLoadAsset(assetBundleName, assetName, callBack)); Co_DoLoadAsset(assetBundleName, assetName, callBack).Forget(); } private IEnumerator Co_LoadAssetBundle(string assetBundleName) private async UniTask<AssetBundle> Co_LoadAssetBundle(string assetBundleName) { #if UNITY_5||UNITY_5_3_OR_NEWER assetBundleName = assetBundleName.ToLower(); @@ -183,7 +183,7 @@ if (JudgeExistAssetBundle(assetBundleName)) { yield break; return m_AssetBundleDict[assetBundleName]; } if (m_LoadingAssetBundleList.Contains(assetBundleName)) @@ -191,9 +191,9 @@ while (!m_AssetBundleDict.ContainsKey(assetBundleName)) { // Debug.Log(Time.frameCount + " ] 正在加载AssetBundle: " + assetBundleName + ", 请等待..."); yield return null; await UniTask.Yield(); } yield break; return m_AssetBundleDict[assetBundleName]; } m_LoadingAssetBundleList.Add(assetBundleName); @@ -202,12 +202,13 @@ if (_assetBundleInfo == null) { Debug.LogErrorFormat("Co_LoadAssetBundle(): {0}出现错误 => 不存在AssetBundleInfo. ", assetBundleName); yield break; m_LoadingAssetBundleList.Remove(assetBundleName); return null; } if (_assetBundleInfo.dependentBundles.Length > 0) { yield return Co_LoadAssetBundleDependenice(_assetBundleInfo); await Co_LoadAssetBundleDependenice(_assetBundleInfo); } var isBuiltin = assetBundleName.Contains("builtin"); @@ -216,44 +217,41 @@ Debug.LogFormat("Co_LoadAssetBundle(): 将要加载的assetBundle包路径 => {0}", filePath); var _request = AssetBundle.LoadFromFileAsync(filePath); while (!_request.isDone) { yield return null; } await _request; CacheAssetBundle(assetBundleName, _request.assetBundle); m_LoadingAssetBundleList.Remove(assetBundleName); return _request.assetBundle; } private IEnumerator Co_LoadAssetBundleDependenice(AssetBundleInfo assetBundleInfo) private async UniTask Co_LoadAssetBundleDependenice(AssetBundleInfo assetBundleInfo) { AssetBundle _assetBundle = null; if (assetBundleInfo.dependentBundles == null || assetBundleInfo.dependentBundles.Length == 0) { yield break; return; } for (int i = 0; i < assetBundleInfo.dependentBundles.Length; ++i) { if (m_AssetBundleDict.TryGetValue(assetBundleInfo.dependentBundles[i], out _assetBundle) == false) { yield return Co_LoadAssetBundle(assetBundleInfo.dependentBundles[i]); await Co_LoadAssetBundle(assetBundleInfo.dependentBundles[i]); } else { if (_assetBundle == null) { yield return Co_LoadAssetBundle(assetBundleInfo.dependentBundles[i]); await Co_LoadAssetBundle(assetBundleInfo.dependentBundles[i]); } } } } private IEnumerator Co_DoLoadAsset(string assetBundleName, string assetName, Action<bool, UnityEngine.Object> callBack = null) private async UniTask Co_DoLoadAsset(string assetBundleName, string assetName, Action<bool, UnityEngine.Object> callBack = null) { #if UNITY_5||UNITY_5_3_OR_NEWER assetBundleName = assetBundleName.ToLower(); @@ -263,7 +261,7 @@ RunTimeABLoadLog.AddLog(assetBundleName, assetName, UnityEngine.SceneManagement.SceneManager.GetActiveScene().name); #endif yield return Co_LoadAssetBundle(assetBundleName); await Co_LoadAssetBundle(assetBundleName); if (!m_AssetBundleDict.ContainsKey(assetBundleName)) { @@ -271,7 +269,7 @@ { callBack(false, null); } yield break; return; } string _checkTag = assetBundleName + "@" + assetName; @@ -281,7 +279,7 @@ || !m_AssetDict[assetBundleName].ContainsKey(assetName)) { // Debug.Log(Time.frameCount + " ] 正在加载Asset: " + _checkTag + ", 请等待..."); yield return null; await UniTask.Yield(); } if (callBack != null) @@ -289,16 +287,13 @@ callBack(true, m_AssetDict[assetBundleName][assetName]); } yield break; return; } m_LoadingAssetList.Add(_checkTag); var request = m_AssetBundleDict[assetBundleName].LoadAssetAsync(assetName); while (!request.isDone) { yield return null; } await request; if (request.asset != null) { @@ -319,14 +314,14 @@ m_LoadingAssetList.Remove(_checkTag); } private IEnumerator Co_DoLoadAsset(AssetInfo assetInfo, Action<bool, UnityEngine.Object> callBack = null) private async UniTask Co_DoLoadAsset(AssetInfo assetInfo, Action<bool, UnityEngine.Object> callBack = null) { if (assetInfo == null) { Debug.LogErrorFormat("Co_DoLoadAsset(): {0}, 出现错误 => 存入的AssetInfo为null. ", assetInfo); yield break; return; } yield return Co_DoLoadAsset(assetInfo.assetBundleName, assetInfo.name, callBack); await Co_DoLoadAsset(assetInfo.assetBundleName, assetInfo.name, callBack); } #endregion Main/Utility/SevenZipUtility.cs
New file @@ -0,0 +1,45 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; public class SevenZipUtility { static string m_SevenZipToolPath = string.Empty; static string sevenZipToolPath { get { if (string.IsNullOrEmpty(m_SevenZipToolPath)) { if (Directory.Exists("C:/Program Files/7-Zip")) { m_SevenZipToolPath = "C:/Program Files/7-Zip"; } else { m_SevenZipToolPath = "C:/Program Files (x86)/7-Zip"; } } return m_SevenZipToolPath; } } public static void Compress(string from, string to) { if (File.Exists(to)) { File.Delete(to); } var cmd = string.Format("\"{0}\\7z\" a {1} {2} -mx9", sevenZipToolPath, to, from); SystemCMD.RunCmd(cmd); } public static void DeCompress(string from, string to) { #if !(UNITY_IOS || UNITY_IPHONE) lzma.doDecompress7zip(from, to, false, true); #endif } } Main/Utility/SevenZipUtility.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: b621d727b43cf804d96bdadc965bc774 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/Utility/ShaderUtility.cs
New file @@ -0,0 +1,28 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShaderUtility { public static void InitGlobalParams() { Shader.SetGlobalColor("_Gbl_Lgt", new Color(0.8f, 0.8f, 0.8f, 1)); Shader.SetGlobalColor("_Gbl_Pnt", new Color(1, 1, 1, 1)); Shader.SetGlobalColor("_Gbl_Amb", new Color(1, 1, 1, 1)); Shader.SetGlobalColor("_Gbl_Spc", new Color(0.8f, 0.8f, 0.8f, 1)); Shader.SetGlobalColor("_Gbl_Rim", new Color(1, 1, 1, 1)); Shader.SetGlobalColor("_Gbl_Wat", new Color(1, 1, 1, 1)); } public static void WarmUpAll() { if (!AssetSource.shaderFromEditor) { AssetBundleUtility.Instance.Sync_LoadAllAssets("graphic/shader"); Shader.WarmupAllShaders(); } } } Main/Utility/ShaderUtility.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 474969e2043f6864aad54234f84d18c3 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: