[add] Engine

This commit is contained in:
2022-08-26 16:48:17 +08:00
parent f67e566f2a
commit d9c19f096c
197 changed files with 10626 additions and 0 deletions

View File

@@ -0,0 +1,522 @@
import BusinessTypeSetting from "../../_BusinessTypeSetting/BusinessTypeSetting";
import { CoroutineV2 } from "../CatanEngine/CoroutineV2/CoroutineV2";
import LocalStorageData from "../Data/LocalStorageData";
import Enum_Loading from "./Enum_Loading";
export default class AssetBundleMamagerV2 {
//#region static 屬性
private static _instance: AssetBundleMamagerV2 = null;
public static get Instance(): AssetBundleMamagerV2 { return AssetBundleMamagerV2._instance; }
//#endregion
//#region public 屬性
/** 本地VerList */
public LocalVerList: Enum_Loading.VerListObj = null;
/** 遠端VerList */
public RemoteVerList: JSON = null;
public DownloadList_Preview: Object = {};
/** 快取資源 */
public CachedFiles: Map<string, cc.Asset> = new Map<string, cc.Asset>();
//#endregion
//#region Lifecycle
constructor() {
AssetBundleMamagerV2._instance = this;
CC_PREVIEW && this._initdownloadList_Preview();
}
//#endregion
//#region 清除資料
/** 判斷更改編譯版號.清除BUNDLE記錄 */
public CheckCompileVersion(): void {
let oldCompileVersion: string = LocalStorageData.Instance.CompileVersion;
let newCompileVersion: string = BusinessTypeSetting.COMPILE_VERSION;
if (oldCompileVersion && oldCompileVersion !== newCompileVersion) {
this.ClearBundleData();
console.log("change compile version.");
}
LocalStorageData.Instance.CompileVersion = BusinessTypeSetting.COMPILE_VERSION;
}
/** 判斷更改PATCH環境.清除BUNDLE記錄 */
public CheckChangePatchUrl(): void {
let oldBundleUrl: string = LocalStorageData.Instance.BundleUrl;
let newBundleUrl: string = BusinessTypeSetting.UsePatch;
if (oldBundleUrl && oldBundleUrl !== newBundleUrl) {
this.ClearBundleData();
console.log("change patch url.");
}
LocalStorageData.Instance.BundleUrl = BusinessTypeSetting.UsePatch;
}
/** 清除Bundle資料 */
public ClearBundleData(): void {
cc.sys.localStorage.removeItem("LocalVerList");
cc.sys.localStorage.removeItem("RemoteVerList");
cc.assetManager.bundles.clear();
if (CC_JSB) {
cc.assetManager.cacheManager.clearCache();
console.log("clear bundle data.");
}
}
/** 清除所有資料重啟 */
public ClearAppDataToRestart(): void {
cc.sys.localStorage.clear();
cc.assetManager.bundles.clear();
if (CC_JSB) {
cc.assetManager.cacheManager.clearCache();
cc.game.restart();
} else {
window.location.reload();
}
}
//#endregion
//#region Custom Function
/**
* 取得Bundle
* @param {string} BundleName Bundle名稱
* @param {string} Version 版號
* @return {cc.AssetManager.Bundle} Bundle
*/
public *GetBundle(BundleName: string): IterableIterator<cc.AssetManager.Bundle> {
let self: this = this;
let bundle: cc.AssetManager.Bundle | boolean = cc.assetManager.getBundle(BundleName);
if (bundle) {
yield* this.GetDepsBundle(bundle.deps);
return bundle;
}
/** 判斷是不是要下載新版本 */
let isNeedUpdate: boolean = this.IsNeedUpdate(BundleName);
if (isNeedUpdate) {
// 下載新版本前需要先清除暫存
console.log(`removeCache: ${BundleName}`);
this.DelBundleCache(BundleName);
this.LocalVerList[BundleName].UseLocal = false;
}
/** Bundle路徑 */
let BundleUrl: string = BusinessTypeSetting.GetRemoteFileUrl(BundleName);
if (CC_DEV) {
// CC_DEVBundle路徑為: BundleName
// if (BundleName.indexOf("Script") != -1) {
BundleUrl = `${BundleName}`;
// } else {
// BundleUrl = "http://192.168.7.57/bj_casino/test/" + BundleName;
// }
} else if (this.LocalVerList[BundleName].UseLocal) {
// 本地Bundle路徑為: assets/assets/${BundleName}
BundleUrl = `assets/${BundleName}`;
}
if (CC_DEV) {
cc.assetManager.loadBundle(BundleUrl, (err: Error, resp: cc.AssetManager.Bundle) => {
if (err) {
console.error(err);
bundle = null;
return;
}
bundle = resp;
});
while (typeof bundle === "undefined") {
yield null;
}
} else if (BundleName.includes("Script")) {
bundle = yield* self.loadScriptBundle(BundleUrl);
} else {
if (CC_JSB && !this.LocalVerList[BundleName].UseLocal) {
let bundlePath: string = `${jsb.fileUtils.getWritablePath()}gamecaches/${BundleName}/`;
if (!jsb.fileUtils.isFileExist(bundlePath)) {
cc.assetManager.cacheManager["makeBundleFolder"](BundleName);
}
}
bundle = yield* self.loadUIBundle(BundleUrl);
}
if (bundle) {
yield* this.GetDepsBundle((<cc.AssetManager.Bundle>bundle).deps);
if (isNeedUpdate) {
// 下載成功後更改本地Bundle版本
self.LocalVerList[BundleName].Version = self.RemoteVerList[BundleName];
LocalStorageData.Instance.LocalVerList = JSON.stringify(self.LocalVerList);
}
}
return bundle;
}
/**
* 從Bundle取得資源
* @param {string} BundleUrl Bundle路徑
*/
public *loadScriptBundle(BundleUrl: string): IterableIterator<any> {
let fileName: string = `index.${CC_DEBUG ? "js" : "jsc"}`;
let fileUrl: string = `${BundleUrl}/${fileName}`;
let run: boolean = true;
let isSuceess: boolean = false;
cc.assetManager.loadScript(fileUrl, (err: Error) => {
if (err) {
console.error(`[Error] ${fileUrl}載入失敗 err: ${err}`);
run = false;
return;
}
isSuceess = true;
run = false;
});
while (run) {
yield null;
}
return isSuceess;
}
/**
* 從Bundle取得資源
* @param {string} BundleUrl Bundle路徑
*/
public *loadUIBundle(BundleUrl: string): IterableIterator<cc.AssetManager.Bundle> {
let fileName: string = "config.json";
let fileUrl: string = `${BundleUrl}/${fileName}`;
let data: any;
let run: boolean = true;
cc.assetManager.loadRemote(fileUrl, (err: Error, res: cc.JsonAsset) => {
if (err) {
console.error(`[Error] ${fileUrl}載入失敗 err: ${err}`);
return;
}
data = res.json;
run = false;
});
while (run) {
yield null;
}
let bundle: cc.AssetManager.Bundle = new cc.AssetManager.Bundle();
data.base = `${BundleUrl}/`;
bundle.init(data);
return bundle;
}
/**
* 取得Bundle
* @param {string} BundleName Bundle名稱
* @param {string} Version 版號
* @return {cc.AssetManager.Bundle} Bundle
*/
public *GetDepsBundle(deps: string[]): IterableIterator<any> {
if (!deps || deps.length <= 2) {
return;
}
let self: this = this;
let GetBundle_F_Arr: IterableIterator<any>[] = [];
for (const bundleName of deps) {
if (!["main", "internal"].includes(bundleName)) {
let GetBundle_F: IterableIterator<any> = function* (): IterableIterator<any> {
yield* self.GetBundle(bundleName);
}();
GetBundle_F_Arr.push(GetBundle_F);
}
}
yield CoroutineV2.Parallel(...GetBundle_F_Arr).Start();
}
/**
* 從Bundle取得資源
* @param {number} slotID slotID
* @param {Function} onFileProgress onFileProgress
*/
public *PreloadBundleScene(slotID: number, onFileProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void): IterableIterator<any> {
let BundleName: string = `Game_${slotID}`;
let SourceName: string = `Slot${slotID}`;
let run: boolean = true;
let UpdateingData: Enum_Loading.UpdateingDataObj = new Enum_Loading.UpdateingDataObj(false);
let bundle: cc.AssetManager.Bundle = yield* AssetBundleMamagerV2.Instance.GetBundle(BundleName);
if (!bundle) {
console.error(`GetBundleSource Error BundleName: ${BundleName}`);
return UpdateingData;
}
bundle.preloadScene(SourceName, onFileProgress, function (error: Error): void {
if (error) {
console.error(error);
run = false;
return;
}
UpdateingData.IsUpdatecomplete = true;
run = false;
});
while (run) {
yield null;
}
return UpdateingData;
}
/**
* 從Bundle取得資源
* @param {cc.AssetManager.Bundle | string} BundleName Bundle名稱
* @param {string} SourceName 資源名稱
* @param {string} type 資源型別
* @return {any} Source
*/
public *GetBundleSource(BundleName: cc.AssetManager.Bundle | string, SourceName: string, type?: string | Bundle_Source_Type, onFileProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void): IterableIterator<any> {
let bundle: cc.AssetManager.Bundle;
let source: any;
if (BundleName instanceof cc.AssetManager.Bundle) {
bundle = BundleName;
} else {
bundle = yield* AssetBundleMamagerV2.Instance.GetBundle(BundleName);
if (!bundle) {
cc.error(`GetBundleSource Error BundleName: ${BundleName}`);
return null;
}
}
switch (type) {
case Bundle_Source_Type.Scene: {
bundle.loadScene(SourceName, onFileProgress, function (err: Error, scene: cc.SceneAsset): void {
if (err) {
cc.error(err);
return null;
}
// cc.director.runScene(scene);
source = scene;
});
break;
}
case Bundle_Source_Type.Json: {
bundle.load(SourceName, onFileProgress, function (err: Error, json: cc.JsonAsset): void {
if (err) {
cc.error(err);
return null;
}
// source = JSON.parse(json["_nativeAsset"]);
source = json;
});
break;
}
case Bundle_Source_Type.Prefab: {
bundle.load(SourceName, cc.Prefab, onFileProgress, function (err: Error, prefab: cc.Asset): void {
if (err) {
cc.error(err);
return null;
}
// source = JSON.parse(json["_nativeAsset"]);
source = prefab;
});
break;
}
default:
bundle.load(SourceName, function (err: Error, any: any): void {
if (err) {
cc.error(err);
return null;
}
source = any;
});
break;
}
while (typeof source === "undefined") {
yield null;
}
return source;
}
/**
* 從Bundle取得資源(不卡協成)
* @param {string} bundleName bundleName
* @param {string} sourcePath Bundle資料夾下的路徑
*/
public static GetBundleSourceV2(bundleName: cc.bundleName | string, sourcePath: string): cc.Prefab {
let bundle: cc.AssetManager.Bundle = cc.assetManager.getBundle(bundleName);
if (!bundle) {
cc.error(`GetBundleSourceV2 getBundle error bundleName: ${bundleName}`);
return null;
}
let source: cc.Prefab = bundle.get(sourcePath, cc.Prefab);
if (!source) {
cc.error(`GetBundleSourceV2 bundle.get error bundleName: ${bundleName}, sourcePath: ${sourcePath}`);
return null;
}
return source;
}
/**
* 釋放Bundle
* @param {string} slotID slotID
*/
public *BundleRelease(slotID: number): IterableIterator<any> {
let gameName: string = `Game_${slotID}`;
let sceneName: string = `Slot${slotID}`;
let bundle: cc.AssetManager.Bundle = cc.assetManager.getBundle(gameName);
if (!bundle) {
cc.log(`BundleRelease Error BundleName: ${gameName}`);
return;
}
this.ReleaseSlotCache(slotID);
}
/**
* 從cachedFiles刪除暫存資源
* @param {string} BundleName Bundle名稱
*/
public DelBundleCache(BundleName: string): void {
if (CC_BUILD && cc.sys.isNative) {
let cachedFiles: Object = cc.assetManager.cacheManager.cachedFiles["_map"];
let delcache: string = BusinessTypeSetting.GetRemoteFileUrl(BundleName) + "/";
for (let cached of Object.keys(cachedFiles)) {
if (cached.includes(delcache)) {
cc.assetManager.cacheManager.removeCache(cached);
// console.log(`removeCache: ${cached}`);
}
}
}
}
/**
* 從cachedFiles釋放暫存資源
* @param {number} slotID slotID
*/
public ReleaseSlotCache(slotID: number): void {
if (!CC_JSB) {
return;
}
let delcachedKeys: string[] = [];
let cachedFiles: Map<string, cc.Asset> = this.CachedFiles;
let delcache_group: string[] = [`shared/jsons`, `Slot/Slot${slotID}`, "sounds/Slot/Default", "submit.txt"];
cachedFiles.forEach((cached: cc.Asset, key: string, map: Map<string, cc.Asset>) => {
for (var i: number = 0; i < delcache_group.length; ++i) {
let delcache: string = delcache_group[i];
if (key.includes(delcache)) {
cc.assetManager.releaseAsset(cached);
delcachedKeys.push(key);
break;
}
}
});
for (var i: number = 0; i < delcachedKeys.length; ++i) {
this.CachedFiles.delete(delcachedKeys[i]);
}
}
/**
* 判斷要不要更新
* @param {string} BundleName Bundle名稱
*/
public IsNeedUpdate(BundleName: string): boolean {
let isNeedUpdate: boolean;
// 判斷本地有無Bundle資料
if (this.LocalVerList[BundleName] && !this.LocalVerList[BundleName].HasBundle) {
if (this.RemoteVerList[BundleName]) {
// 改成有包過Bundle了,重新走下面流程
this.LocalVerList[BundleName] = null;
} else {
return true;
}
}
if (!this.LocalVerList[BundleName]) {
// 本地無Bundle資料需要新增
this.LocalVerList[BundleName] = new Enum_Loading.BundleDataObj();
LocalStorageData.Instance.LocalVerList = JSON.stringify(this.LocalVerList);
}
let version: string = this.RemoteVerList[BundleName];
if (!version) {
// !version代表還沒包Bundle
this.LocalVerList[BundleName].HasBundle = false;
LocalStorageData.Instance.LocalVerList = JSON.stringify(this.LocalVerList);
return true;
} else if (version === "0") {
// version === "0" 代表要使用本體Bundle
this.LocalVerList[BundleName].UseLocal = true;
this.LocalVerList[BundleName].Version = "0";
LocalStorageData.Instance.LocalVerList = JSON.stringify(this.LocalVerList);
}
isNeedUpdate = AssetBundleMamagerV2.Instance.versionCompareHandle(this.LocalVerList[BundleName].Version, this.RemoteVerList[BundleName]) !== 0 ? true : false;
return isNeedUpdate;
}
/**
* 比對版號(熱更能從1.0.0更新到2.0.0從2.0.0回退到1.0.0)
* 官方提供的版本比較函數,只有服務端版本>客戶端版本時才會進行更新。所以不能從2.0.0回退到1.0.0版本。
* @param {string} versionA 本地版號
* @param {string} versionB 遠程版號
* @return {number} num = -1 須更新
* @return {number} num = 0 不須更新
*/
public versionCompareHandle(versionA: string, versionB: string): number {
// console.log("Ver A " + versionA + "VerB " + versionB);
var vA: string[] = versionA.split(".");
var vB: string[] = versionB.split(".");
// 長度不相等,則進行更新
if (vA.length !== vB.length) {
return -1;
}
for (var i: number = 0; i < vA.length; ++i) {
var a: number = +vA[i];
var b: number = +vB[i] || 0;
if (a === b) {
// 數字相同,則跳過
continue;
} else {
// 數字不同(且版號比目標低),則進行更新
return a - b;
}
}
// 長度相等且數字相等,則不更新
return 0;
}
//#endregion
//#region DownloadList_Preview
private _initdownloadList_Preview(): void {
this.DownloadList_Preview = JSON.parse(LocalStorageData.Instance.DownloadList_Preview);
this.DownloadList_Preview = this.DownloadList_Preview ? this.DownloadList_Preview : {};
}
public GetIsDownload_Preview(slotID: number): boolean {
if (!this.DownloadList_Preview[slotID]) {
this.SetIsDownload_Preview(slotID, false);
}
return this.DownloadList_Preview[slotID];
}
public SetIsDownload_Preview(slotID: number, isDownload: boolean = true): void {
this.DownloadList_Preview[slotID] = isDownload;
LocalStorageData.Instance.DownloadList_Preview = JSON.stringify(this.DownloadList_Preview);
}
//#endregion
}
//#region enum
/** Bundle資源類型 */
export enum Bundle_Source_Type {
/** Json */
Json = "json",
/** Scene */
Scene = "scene",
/** Prefab */
Prefab = "prefab"
}
//#endregion

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "383b4628-2b2a-4de4-8aca-913015e91cae",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,72 @@
const { ccclass, property } = cc._decorator;
export module Enum_Loading {
//#region Enum
//#endregion
//#region Class
// /** BaseBundle資料 */
// @ccclass("BaseBundleObj")
// export class BaseBundleObj {
// @property({ displayName: "Bundle名稱", tooltip: "Bundle名稱" })
// public BundleName: string = "";
// @property({ displayName: "優先度", tooltip: "優先度", type: cc.Integer })
// public Priority: number = 1;
// }
class BundleDictionary<T> {
[x: string]: T;
}
/** VerList資料 */
@ccclass("VerListObj")
export class VerListObj extends BundleDictionary<BundleDataObj> {
}
/** Bundle資料 */
@ccclass("BundleDataObj")
export class BundleDataObj {
public Version: string = "0";
public ApkVersion: string = "0";
public UseLocal: boolean = false;
/** 有沒有包到Bundle */
public HasBundle: boolean = true;
}
/** Bundle資料 */
@ccclass("NeedUpdateDataObj")
export class NeedUpdateDataObj {
/** 是否需要更新 */
public IsNeedUpdate: boolean;
/** 更新大小 */
public TotalBytes: string;
constructor(...params: any[]) {
this.IsNeedUpdate = params[0];
this.TotalBytes = params[1] ? params[1] : null;
}
}
/** Bundle資料 */
@ccclass("UpdateingDataObj")
export class UpdateingDataObj {
/** 是否更新完成 */
public IsUpdatecomplete: boolean;
constructor(...params: any[]) {
this.IsUpdatecomplete = params[0];
}
}
//#endregion
}
export default Enum_Loading;

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "573d847e-893c-4fa2-8bd2-41918709fcf4",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,43 @@
const { ccclass, property } = cc._decorator;
export module GameData_HUD {
//#region Enum
/** BundleName */
export enum BundleName {
/** CommonSound */
CommonSound = "CommonSound",
CommonLanguageTexture = "CommonLanguageTexture",
Common = "Common",
ResourceItem = "ResourceItem",
MainControl = "MainControl",
Login = "Login",
Lobby = "Lobby",
BindAccount = "BindAccount",
Shop = "Shop",
Vip = "Vip",
Ad = "Ad",
SettingPanel = "SettingPanel",
PlayerInfo = "PlayerInfo",
Rank = "Rank",
Chat = "Chat",
Gift = "Gift",
Activity = "Activity",
Mail = "Mail",
GettingPanel = "GettingPanel",
Backpack = "Backpack",
Game_GetCoin = "Game_GetCoin",
Game_BigWinJackpot = "Game_BigWinJackpot",
Game_BottomUI_BJ = "Game_BottomUI_BJ",
Game_BottomUI_SD = "Game_BottomUI_SD",
SlotCommom = "SlotCommom",
TableCommon = "TableCommon",
FishCommon = "FishCommon",
ActivityMission = "ActivityMission"
}
//#endregion
}
export default GameData_HUD;

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "e85368d6-e018-430e-bf1d-6ecd2973c6a8",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}