[add] BJ_Casino_Rank贏分
This commit is contained in:
		
							
								
								
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -18,6 +18,7 @@ | ||||
|                 "vue-loading-overlay": "^5.0.3" | ||||
|             }, | ||||
|             "devDependencies": { | ||||
|                 "@types/node": "^17.0.24", | ||||
|                 "@vitejs/plugin-vue": "^2.3.0", | ||||
|                 "typescript": "^4.5.4", | ||||
|                 "vite": "^2.9.0", | ||||
| @@ -157,6 +158,12 @@ | ||||
|                 "@types/lodash": "*" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@types/node": { | ||||
|             "version": "17.0.24", | ||||
|             "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", | ||||
|             "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "node_modules/@vitejs/plugin-vue": { | ||||
|             "version": "2.3.1", | ||||
|             "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz", | ||||
| @@ -1940,6 +1947,12 @@ | ||||
|                 "@types/lodash": "*" | ||||
|             } | ||||
|         }, | ||||
|         "@types/node": { | ||||
|             "version": "17.0.24", | ||||
|             "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", | ||||
|             "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "@vitejs/plugin-vue": { | ||||
|             "version": "2.3.1", | ||||
|             "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz", | ||||
|   | ||||
| @@ -23,4 +23,4 @@ | ||||
|         "vite": "^2.9.0", | ||||
|         "vue-tsc": "^0.29.8" | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -43,6 +43,10 @@ const handleClick = (tab: TabsPaneContext, event: Event) => { | ||||
|     float: none; | ||||
| } | ||||
|  | ||||
| .el-tabs__item { | ||||
|     font-size: 25px; | ||||
| } | ||||
|  | ||||
| #app { | ||||
|     font-family: Avenir, Helvetica, Arial, sans-serif; | ||||
|     -webkit-font-smoothing: antialiased; | ||||
|   | ||||
| @@ -5,19 +5,11 @@ import { BJ_Casino_Magnification } from "../script/BJ_Casino_Magnification"; | ||||
|  | ||||
| const props = defineProps<{ BJ_Casino: BJ_Casino_Data }>() | ||||
|  | ||||
| // const props = defineProps({ | ||||
| //     list: { | ||||
| //         type: Array, | ||||
| //         default: () => [], | ||||
| //     }, | ||||
| // }) | ||||
|  | ||||
| let Title = ref(""); | ||||
| let RankData = ref([]); | ||||
| const self = { | ||||
|     Title: Title, | ||||
|     RankData: RankData, | ||||
|     // BJ_Casino: props.list[0].value, | ||||
|     BJ_Casino: props.BJ_Casino, | ||||
| } | ||||
| const Script = new BJ_Casino_Magnification(self); | ||||
|   | ||||
| @@ -5,19 +5,11 @@ import { BJ_Casino_WinMoney } from "../script/BJ_Casino_WinMoney"; | ||||
|  | ||||
| const props = defineProps<{ BJ_Casino: BJ_Casino_Data }>() | ||||
|  | ||||
| // const props = defineProps({ | ||||
| //     list: { | ||||
| //         type: Array, | ||||
| //         default: () => [], | ||||
| //     }, | ||||
| // }) | ||||
|  | ||||
| let Title = ref(""); | ||||
| let RankData = ref([]); | ||||
| const self = { | ||||
|     Title: Title, | ||||
|     RankData: RankData, | ||||
|     // BJ_Casino: props.list[0].value, | ||||
|     BJ_Casino: props.BJ_Casino, | ||||
| } | ||||
| const Script = new BJ_Casino_WinMoney(self); | ||||
| @@ -32,7 +24,7 @@ const Script = new BJ_Casino_WinMoney(self); | ||||
|                 <tr> | ||||
|                     <th align="left">排名</th> | ||||
|                     <th align="left">名稱</th> | ||||
|                     <th align="left">倍率</th> | ||||
|                     <th align="left">贏分</th> | ||||
|                     <th align="left">機台</th> | ||||
|                     <th align="left">桌號</th> | ||||
|                     <th align="left">日期</th> | ||||
|   | ||||
| @@ -1,4 +1,12 @@ | ||||
| import moment from 'moment'; | ||||
| import CSMessage from './Base/CSMessage'; | ||||
| import { AccountLoginRequest } from './Base/Request/AccountRequest'; | ||||
| import { AppRankHistory, AppRankInfo } from './Base/Request/RankRequest'; | ||||
| import './Engine/CatanEngine/CSharp/String'; | ||||
| import { INetResponse } from './Engine/CatanEngine/NetManagerV2/Core/INetResponse'; | ||||
| import { NetConnector } from './Engine/CatanEngine/NetManagerV2/NetConnector'; | ||||
| import { NetManager } from './Engine/CatanEngine/NetManagerV2/NetManager'; | ||||
| import { Tools } from './Tools'; | ||||
|  | ||||
| export class BJ_Casino_Data { | ||||
|  | ||||
| @@ -14,12 +22,15 @@ export class BJ_Casino_Data { | ||||
|  | ||||
|     //#region private | ||||
|  | ||||
|     private _conn: NetConnector = null!; | ||||
|     private _ws: any; | ||||
|  | ||||
|     private _rankMagnificationData: any[] = []; | ||||
|     private _rankWinMoneyData: any[] = []; | ||||
|  | ||||
|     private _nowSearchContestID: number = 0; | ||||
|     private _nowSearchMagnificationID: number = 0; | ||||
|  | ||||
|     private _nowSearchWinMoneyID: number = 0; | ||||
|  | ||||
|     private _nowContestIndex: number = 0; | ||||
|  | ||||
| @@ -47,6 +58,8 @@ export class BJ_Casino_Data { | ||||
|  | ||||
|     public get RankMagnificationData(): any[] { return this._rankMagnificationData }; | ||||
|  | ||||
|     public get RankWinMoneyData(): any[] { return this._rankWinMoneyData }; | ||||
|  | ||||
|     //#endregion | ||||
|  | ||||
|     //#region Lifecycle | ||||
| @@ -59,14 +72,28 @@ export class BJ_Casino_Data { | ||||
|         this.onLoad(); | ||||
|     } | ||||
|  | ||||
|     public onLoad() { | ||||
|     public async onLoad() { | ||||
|         // CoroutineV2.Single(this.aaa()).Start(); | ||||
|         let self: this = this; | ||||
|         const URL = "https://game.online-bj.com"; | ||||
|         const Port = "9005"; | ||||
|         await this.ConnectAsync(URL, +Port); | ||||
|         // 取得帳號資料 | ||||
|         let req: AccountLoginRequest = new AccountLoginRequest("ct00000691", "4lsAyoalajm7"); | ||||
|         await req.SendAsync(true); | ||||
|         let resp: INetResponse<any> = req.Result; | ||||
|         if (!resp.IsValid) { | ||||
|             CSMessage.NetError(resp.Method, resp.Status, "Login Account Error!"); | ||||
|             return; | ||||
|         } | ||||
|         await this.SendRankData(); | ||||
|         return; | ||||
|         try { | ||||
|             // const URL = document.getElementById("URL").value; | ||||
|             // const Port = document.getElementById("Port").value; | ||||
|  | ||||
|             const URL = "wss://game.online-bj.com"; | ||||
|             const Port = "9005"; | ||||
|             // const URL = "wss://game.online-bj.com"; | ||||
|             // const Port = "9005"; | ||||
|             const Account = { "p": 0, "device_info": ["Windows", "Windows"], "fcm_token": "", "a": "ct00000691", "pw": "4lsAyoalajm7", "ver": "1.3.0" }; | ||||
|  | ||||
|             // const URL = "ws://192.168.5.12"; | ||||
| @@ -105,11 +132,92 @@ export class BJ_Casino_Data { | ||||
|             this.AddLog(ex); | ||||
|         } | ||||
|     }; | ||||
|     public *aaa(): IterableIterator<any> { | ||||
|         console.log("aaa"); | ||||
|     } | ||||
|  | ||||
|     //#endregion | ||||
|  | ||||
|     //#region 網路相關 | ||||
|  | ||||
|     /**連線(目前沒有重連機制) */ | ||||
|     public async ConnectAsync(host: string, port: number) { | ||||
|         var url = "https://api.ipify.org/?format=json"; | ||||
|         var xhr = new XMLHttpRequest(); | ||||
|         let ip: string = ""; | ||||
|         xhr.onreadystatechange = function () { | ||||
|             if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) { | ||||
|                 ip = JSON.parse(xhr.responseText)["ip"]; | ||||
|             } | ||||
|         }; | ||||
|         xhr.open("GET", url, true); | ||||
|         xhr.send(); | ||||
|         console.log("[事件]準備連線..."); | ||||
|         while (ip == "") { | ||||
|             await Tools.Sleep(1); | ||||
|         } | ||||
|         this._conn = new NetConnector(host, port, ip); | ||||
|         this._conn.OnDataReceived.AddCallback(this._onNetDataReceived, this); | ||||
|         this._conn.OnDisconnected.AddCallback(this._onNetDisconnected, this); | ||||
|         NetManager.Initialize(this._conn); | ||||
|         console.log("[事件]連線中..."); | ||||
|         // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect() | ||||
|         await NetManager.ConnectAsync(); | ||||
|         console.log(String.Format("[事件]連線狀態: {0}", NetManager.IsConnected)); | ||||
|     } | ||||
|  | ||||
|     private _onNetDisconnected() { | ||||
|         console.log("[事件] 收到連線中斷事件"); | ||||
|         this._conn.OnDataReceived.RemoveAllCallbacks(); | ||||
|         // MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]); | ||||
|     } | ||||
|  | ||||
|     private _onNetDataReceived(resp: INetResponse<any>) { | ||||
|         console.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); | ||||
|         // MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]); | ||||
|     } | ||||
|  | ||||
|     //#endregion | ||||
|  | ||||
|     //#region Custom | ||||
|  | ||||
|     public async SendRankData() { | ||||
|         this.SendRankMagnificationData(); | ||||
|         this.SendRankWinMoneyData(); | ||||
|     } | ||||
|  | ||||
|     public async SendRankMagnificationData() { | ||||
|         let req: any = null; | ||||
|         req = new AppRankInfo(12, 2); | ||||
|         await req.SendAsync(true); | ||||
|         let resp: INetResponse<any> = req.Result; | ||||
|         if (!resp.IsValid) { | ||||
|             if (resp.Status == 11) { | ||||
|                 CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); | ||||
|             } else { | ||||
|                 CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|         await this.RankMagnificationDataCallBack(resp.Data); | ||||
|     } | ||||
|  | ||||
|     public async SendRankWinMoneyData() { | ||||
|         let req: any = null; | ||||
|         req = new AppRankInfo(11, 2); | ||||
|         await req.SendAsync(true); | ||||
|         let resp: INetResponse<any> = req.Result; | ||||
|         if (!resp.IsValid) { | ||||
|             if (resp.Status == 11) { | ||||
|                 CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); | ||||
|             } else { | ||||
|                 CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|         await this.RankWinMoneyDataCallBack(resp.Data); | ||||
|     } | ||||
|  | ||||
|     public SendData(Method: string, Data: any) { | ||||
|         let json = [Method]; | ||||
|         if (Data != null && Data != undefined) { | ||||
| @@ -160,9 +268,9 @@ export class BJ_Casino_Data { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public RankMagnificationDataCallBack(data: any) { | ||||
|     public async RankMagnificationDataCallBack(data: any) { | ||||
|         let id = +data["id"]; | ||||
|         this._nowSearchContestID = id; | ||||
|         this._nowSearchMagnificationID = id; | ||||
|         this._nowContestID = id; | ||||
|         this._nowContestDate = moment().format("MM/DD"); | ||||
|         for (let i = 0; i < this.ContestData.length; i++) { | ||||
| @@ -185,27 +293,33 @@ export class BJ_Casino_Data { | ||||
|         this.ParseRankMagnificationData(data); | ||||
|     } | ||||
|  | ||||
|     public ParseRankMagnificationData(data: any) { | ||||
|         let id = this._nowSearchContestID; | ||||
|         this.RankDataMagnificationAddDate(id, data["rank"]); | ||||
|     public async ParseRankMagnificationData(data: any) { | ||||
|         let id = this._nowSearchMagnificationID; | ||||
|         this.RankDataAddDate(id, data["rank"]); | ||||
|         this._rankMagnificationData = this._rankMagnificationData.concat(data["rank"]); | ||||
|         if (id !== this._nowContestStartIndex) { | ||||
|             this._nowSearchContestID = id - 1; | ||||
|             this.SendData("rank.history", { "id": this._nowSearchContestID, "t": 12, "p": 2 }); | ||||
|             this._nowSearchMagnificationID = id - 1; | ||||
|             // this.SendData("rank.history", { "id": this._nowSearchContestID, "t": 12, "p": 2 }); | ||||
|             let req: any = null; | ||||
|             req = new AppRankHistory(12, 2, this._nowSearchMagnificationID); | ||||
|             await req.SendAsync(true); | ||||
|             let resp: INetResponse<any> = req.Result; | ||||
|             if (!resp.IsValid) { | ||||
|                 if (resp.Status == 11) { | ||||
|                     CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); | ||||
|                 } else { | ||||
|                     CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|             this.ParseRankMagnificationData(resp.Data); | ||||
|             return; | ||||
|         } else { | ||||
|             this.OrganizeRankMagnificationData(this._rankMagnificationData); | ||||
|             this.SetRankMagnificationData(this._rankMagnificationData); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public RankDataMagnificationAddDate(id: number, rankdata: any) { | ||||
|         let date: string = this._contestDateFormID(id); | ||||
|         for (let i = 0; i < rankdata.length; i++) { | ||||
|             rankdata[i].push(date); | ||||
|         } | ||||
|         return rankdata; | ||||
|     } | ||||
|  | ||||
|     public OrganizeRankMagnificationData(rankdata: any) { | ||||
|         rankdata.sort((a: any, b: any) => { | ||||
|             return b[1] - a[1]; | ||||
| @@ -220,16 +334,73 @@ export class BJ_Casino_Data { | ||||
|     } | ||||
|  | ||||
|     public SetRankMagnificationData(rankdata: any) { | ||||
|         this._ws.close(); | ||||
|         this._isOK[0] = true; | ||||
|         this._checkOK(); | ||||
|     } | ||||
|  | ||||
|     public async RankWinMoneyDataCallBack(data: any) { | ||||
|         let id = +data["id"]; | ||||
|         this._nowSearchWinMoneyID = id; | ||||
|         this.ParseRankWinMoneyData(data); | ||||
|     } | ||||
|  | ||||
|     public async ParseRankWinMoneyData(data: any) { | ||||
|         let id = this._nowSearchWinMoneyID; | ||||
|         this.RankDataAddDate(id, data["rank"]); | ||||
|         this._rankWinMoneyData = this._rankWinMoneyData.concat(data["rank"]); | ||||
|         if (id !== this._nowContestStartIndex) { | ||||
|             this._nowSearchWinMoneyID = id - 1; | ||||
|             let req: any = null; | ||||
|             req = new AppRankHistory(11, 2, this._nowSearchWinMoneyID); | ||||
|             await req.SendAsync(true); | ||||
|             let resp: INetResponse<any> = req.Result; | ||||
|             if (!resp.IsValid) { | ||||
|                 if (resp.Status == 11) { | ||||
|                     CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料"); | ||||
|                 } else { | ||||
|                     CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail"); | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|             this.ParseRankWinMoneyData(resp.Data); | ||||
|             return; | ||||
|         } else { | ||||
|             this.OrganizeRankWinMoneyData(this._rankWinMoneyData); | ||||
|             this.SetRankWinMoneyData(this._rankWinMoneyData); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public OrganizeRankWinMoneyData(rankdata: any) { | ||||
|         rankdata.sort((a: any, b: any) => { | ||||
|             return b[1] - a[1]; | ||||
|         }); | ||||
|         rankdata = rankdata.filter((rankdata: any, index: any, arr: any) => { | ||||
|             return arr.findIndex((s: any) => rankdata[2][1] === s[2][1]) === index; | ||||
|         }); | ||||
|         for (let i = 0; i < rankdata.length; i++) { | ||||
|             rankdata[i][0] = i + 1; | ||||
|         } | ||||
|         this._rankWinMoneyData = rankdata; | ||||
|     } | ||||
|  | ||||
|     public SetRankWinMoneyData(rankdata: any) { | ||||
|         this._isOK[1] = true; | ||||
|         this._checkOK(); | ||||
|     } | ||||
|  | ||||
|     public RankDataAddDate(id: number, rankdata: any) { | ||||
|         let date: string = this._contestDateFormID(id); | ||||
|         for (let i = 0; i < rankdata.length; i++) { | ||||
|             rankdata[i].push(date); | ||||
|         } | ||||
|         return rankdata; | ||||
|     } | ||||
|  | ||||
|     private _checkOK() { | ||||
|         if (this._isOK.includes(false)) { | ||||
|             return; | ||||
|         } | ||||
|         NetManager.Disconnect(); | ||||
|         this.Client.isLoading.value = false; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -42,7 +42,7 @@ export class BJ_Casino_WinMoney { | ||||
|     //#region Custom | ||||
|  | ||||
|     public SendData() { | ||||
|         this._client.RankData.value = this.BJ_Casino?.RankMagnificationData; | ||||
|         this._client.RankData.value = this.BJ_Casino?.RankWinMoneyData; | ||||
|     } | ||||
|  | ||||
|     //#endregion | ||||
|   | ||||
							
								
								
									
										237
									
								
								src/script/Base/BusinessTypeSetting.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								src/script/Base/BusinessTypeSetting.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| export module BusinessEnum { | ||||
|     export enum BusinessType { | ||||
|         Type1 = "H5", | ||||
|         Type2 = "App" | ||||
|     } | ||||
|     export enum ServerType { | ||||
|         /** WEB格式 */ | ||||
|         Web = 1, | ||||
|         /** 外版 */ | ||||
|         Out = 2, | ||||
|         /** 送審環境 */ | ||||
|         Submit = 3, | ||||
|         /** 內版商業DEMO測試(B2B) */ | ||||
|         Internal_release = 4, | ||||
|         /** 內版開發(內網&4G) */ | ||||
|         Internal_Dev = 5, | ||||
|         /** 外部商業DEMO(B2B) */ | ||||
|         Out_B2B = 6 | ||||
|     } | ||||
|     export enum LogoType { | ||||
|         /** 完美(目前只有WEB) */ | ||||
|         WM = 1 | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
| 產品商業類別設定檔 | ||||
| @explain 讀不同表就代表不同商業類別.要多開GIT並設定新測試環境 | ||||
| @explain 遊戲一定都一樣不能改動介面 | ||||
|  */ | ||||
| export default class BusinessTypeSetting { | ||||
|     /** 產品商業類別字串(組合判斷用) */ | ||||
|     public static readonly TYPE_BUSINESS: string = "App"; | ||||
|     /** 編譯版本 */ | ||||
|     public static readonly COMPILE_VERSION: string = "1.3.1"; | ||||
|     /** 編譯程式碼版號 */ | ||||
|     public static readonly SCRIPT_BUNLE_LIST: string[] = [ | ||||
|         "FormTableScript", "CommonScript", "ElementUIScript", "LoginScript", "LobbyScript", "SlotScript" | ||||
|     ]; | ||||
|     public static readonly ART_UI_BUNLE_LIST: string[] = [ | ||||
|         "Common", "CommonSound", "Login", "Lobby", "GameCommon", | ||||
|         "Game_BottomUI_SD", "Game_BigWinJackpot", "GameMessage", "CommonLanguageTexture", "MainControl", | ||||
|         "BindAccount", "SettingPanel", "Shop", "Vip", "Ad", | ||||
|         "Mail", "Chat", "PlayerInfo", "Rank", "Gift", | ||||
|         "ResourceItem", "Backpack", "GettingPanel", "Activity", "Game_BottomUI_BJ" | ||||
|     ]; | ||||
|     public static readonly DEV_ART_UI_BUNLE_LIST: string[] = [ | ||||
|  | ||||
|     ] | ||||
|     public static readonly ART_GAME_BUNLE_LIST: string[] = [ | ||||
|         "Game_1201", "Game_1202", "Game_1302" | ||||
|     ] | ||||
|     public static readonly ART_REMOTE_GAME_BUNLE_LIST: string[] = [ | ||||
|         "Game_1", "Game_2", "Game_5", "Game_8", "Game_9", | ||||
|         "Game_10", "Game_12", "Game_15", "Game_16", "Game_18", | ||||
|         "Game_23", "Game_24", "Game_25", "Game_26", "Game_27", | ||||
|         "Game_28", "Game_29", "Game_30", "Game_32", "Game_33", | ||||
|         "Game_34", "Game_35", "Game_37", "Game_36", "Game_40", | ||||
|         "Game_44", "Game_48", "Game_50", "Game_51", "Game_58", | ||||
|         "Game_1101", "Game_1401", "Game_1501", "Game_2001", "Game_2003", | ||||
|         "Game_3002", "Game_3003", "Game_3012", | ||||
|     ] | ||||
|     /** 送審旗標(讀取外版自動判斷是否送審) */ | ||||
|     public static IsSubmit: boolean = false; | ||||
|     /** 跑送審2的手動旗標(若是送審且設為true跑2號環境) */ | ||||
|     public static IsSubmitTestFlight: boolean = false; | ||||
|     /** B2B手動旗標(true寫死B2B環境) */ | ||||
|     public static IsB2B: boolean = false; | ||||
|  | ||||
|     /** 商業LOGO圖代碼(讀同一張表但UI有改的設定) */ | ||||
|     public static Logo: number = null!; | ||||
|     /** 連線IP(網頁版會接網址參數所以要多開變數直接指定) */ | ||||
|     public static UseHost: string = null!; | ||||
|     /** 連接阜(網頁版會接網址參數所以要多開變數直接指定) */ | ||||
|     public static UsePort: number = null!; | ||||
|     /** 資源伺服器網址 */ | ||||
|     public static UsePatch: string = null!; | ||||
|     /** 帳號 */ | ||||
|     public static Account: string = null!; | ||||
|     /** 密碼 */ | ||||
|     public static Password: string = null!; | ||||
|  | ||||
|     // ======================================================================================= | ||||
|     /** 執行環境ProductEnum.ServerType */ | ||||
|     public static UseServerTpye: BusinessEnum.ServerType = BusinessEnum.ServerType.Web; | ||||
|     /** 網頁是否在伺服器上 */ | ||||
|     public static readonly CheckOnServer: boolean = | ||||
|         window.location.href.indexOf("localhost") == -1 | ||||
|         && window.location.href.indexOf("/build/") == -1; | ||||
|     /** 網頁測試讀取對應資源的位置 */ | ||||
|     public static readonly FolderUrlImg: string = "shared/img/"; | ||||
|     public static readonly FolderUrlBg: string = "shared/bg/"; | ||||
|     public static readonly FolderUrlJson: string = "shared/jsons/"; | ||||
|     public static readonly FolderUrlTxt: string = "shared/txt/"; | ||||
|     public static readonly FolderUrlLoading: string = "shared/loading/"; | ||||
|     public static readonly FolderUrlMp3: string = "shared/"; | ||||
|     public static readonly FolderUrlBundle: string = `Bundle_${true ? "Debug" : "Release"}/`; | ||||
|     public static readonly FolderOS: string = "Android/"; | ||||
|     /**遠端Bundle路徑為: URL + BundleName.非遊戲資源到各自平台資料夾找BUNDLE */ | ||||
|     public static GetRemoteFileUrl(bundleName: string): string { | ||||
|         let gameNumber: string = bundleName.split("Game_")[1]; | ||||
|         var regExp: RegExp = /^[0-9]+$/; | ||||
|         let isGame: boolean = regExp.test(gameNumber); | ||||
|         let bundleUrl: string = `${BusinessTypeSetting.UsePatch}${BusinessTypeSetting.FolderUrlBundle}`; | ||||
|         if (isGame) { | ||||
|             bundleUrl = `${bundleUrl}${bundleName}`; | ||||
|         } else { | ||||
|             bundleUrl = `${bundleUrl}${BusinessTypeSetting.FolderOS}${bundleName}`; | ||||
|         } | ||||
|         return bundleUrl; | ||||
|     } | ||||
|     /** | ||||
|      * 取得PACH資原路徑 | ||||
|      * @param type 執行環境() | ||||
|      * @returns | ||||
|      */ | ||||
|     public static GetPatchUrl(type: BusinessEnum.ServerType): string { | ||||
|         if (this.UseServerTpye == BusinessEnum.ServerType.Web) { | ||||
|             // TYP2網頁版資源路路徑判斷 | ||||
|             if (this.CheckOnServer) { | ||||
|                 return "../shared/"; | ||||
|             } else { | ||||
|                 return "http://patch-dev.online-bj.com//shared/"; | ||||
|             } | ||||
|         } | ||||
|         switch (type) { | ||||
|             case BusinessEnum.ServerType.Out: | ||||
|                 return "https://patch.online-bj.com/game/"; | ||||
|             case BusinessEnum.ServerType.Submit: | ||||
|                 if (!this.IsSubmitTestFlight) { | ||||
|                     return "https://patch-submit.online-bj.com/game/"; | ||||
|                 } else { | ||||
|                     return "https://patch-submit2.online-bj.com/game/"; | ||||
|                 } | ||||
|  | ||||
|             case BusinessEnum.ServerType.Out_B2B: | ||||
|                 return "https://patch-demo.online-bj.com/game/"; | ||||
|             case BusinessEnum.ServerType.Internal_release: | ||||
|                 return "http://patch-release.online-bj.com/"; | ||||
|  | ||||
|             case BusinessEnum.ServerType.Internal_Dev: | ||||
|                 return "http://patch-dev.online-bj.com/"; | ||||
|  | ||||
|             default: | ||||
|                 console.warn("GetPatchUrl Uncheck ServerType."); | ||||
|                 return "http://patch-dev.online-bj.com/"; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * 取得連線伺服器IP | ||||
|      * @param type 執行環境 | ||||
|      * @returns | ||||
|      */ | ||||
|     public static GetHostUrl(type: BusinessEnum.ServerType): string { | ||||
|         if (this.UseServerTpye == BusinessEnum.ServerType.Web) { | ||||
|             return "app.casino.catan.com.tw"; | ||||
|         } | ||||
|         switch (type) { | ||||
|             case BusinessEnum.ServerType.Out: | ||||
|                 return "https://game.online-bj.com"; | ||||
|             case BusinessEnum.ServerType.Submit: | ||||
|                 if (!this.IsSubmitTestFlight) { | ||||
|                     return "https://submit.online-bj.com"; | ||||
|                 } else { | ||||
|                     return "https://submit2.online-bj.com"; | ||||
|                 } | ||||
|  | ||||
|             case BusinessEnum.ServerType.Out_B2B: | ||||
|                 return "https://demo.online-bj.com"; | ||||
|             case BusinessEnum.ServerType.Internal_release: | ||||
|                 return "https://demo.online-bj.com"; | ||||
|  | ||||
|             case BusinessEnum.ServerType.Internal_Dev: | ||||
|                 return "http://220.134.195.1"; | ||||
|  | ||||
|             default: | ||||
|                 console.warn("GetHostUrl Uncheck ServerType."); | ||||
|                 // 只有內網可憐IP | ||||
|                 return "app.casino.catan.com.tw"; | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * 取得伺服器連接端口 | ||||
|      * @param type 執行環境 | ||||
|      * @returns | ||||
|      */ | ||||
|     public static GetPortNum(type: BusinessEnum.ServerType): number { | ||||
|         if (this.UseServerTpye == BusinessEnum.ServerType.Web) { | ||||
|             // 網頁版測試專用.正式接網頁參數 | ||||
|             return 9005; | ||||
|         } | ||||
|         switch (type) { | ||||
|             case BusinessEnum.ServerType.Out: | ||||
|                 return 9005; | ||||
|             case BusinessEnum.ServerType.Submit: | ||||
|                 if (!this.IsSubmitTestFlight) { | ||||
|                     return 9005; | ||||
|                 } else { | ||||
|                     return 9005; | ||||
|                 } | ||||
|  | ||||
|             case BusinessEnum.ServerType.Out_B2B: | ||||
|                 return 9005; | ||||
|             case BusinessEnum.ServerType.Internal_release: | ||||
|                 return 9005; | ||||
|  | ||||
|             case BusinessEnum.ServerType.Internal_Dev: | ||||
|                 return 19005; | ||||
|  | ||||
|             default: | ||||
|                 console.warn("GePortNum Uncheck ServerType."); | ||||
|                 return 9005; | ||||
|         } | ||||
|     } | ||||
|     public static GetDownloadUrl(type: BusinessEnum.ServerType): string { | ||||
|         switch (type) { | ||||
|             case BusinessEnum.ServerType.Internal_Dev: | ||||
|                 return "http://static-dev.online-bj.com/"; | ||||
|             default: | ||||
|                 let url: string = this.GetHostUrl(type); | ||||
|                 url = url.replace("http://", ""); | ||||
|                 url = url.replace("https://", ""); | ||||
|                 return "https://static-" + url; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static GetUploadUrl(type: BusinessEnum.ServerType): string { | ||||
|         let port: string = ":9080"; | ||||
|         switch (type) { | ||||
|             case BusinessEnum.ServerType.Internal_Dev: | ||||
|                 return "http://static-dev.online-bj.com" + port; | ||||
|             default: | ||||
|                 return this.GetHostUrl(type) + port; | ||||
|         } | ||||
|     } | ||||
|     // ======================================================================================= | ||||
| } | ||||
							
								
								
									
										8
									
								
								src/script/Base/CSMessage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/script/Base/CSMessage.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| /**訊息框相關 */ | ||||
| export default class CSMessage { | ||||
|     /**網路錯誤訊息 */ | ||||
|     public static NetError(method: string, state: number, str: string = ""): void { | ||||
|         let error = String.Format("[{0}] state:{1} {2}", method, state, str); | ||||
|         console.warn("網路錯誤訊息: ", error); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								src/script/Base/Config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/script/Base/Config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| /**放跟ProductSetting沒關係的變數 */ | ||||
| export default class Config { | ||||
|     /**是否是連線模式 */ | ||||
|     public static IsOnlineMode: boolean = false; | ||||
|     /**內版帳號登入(目前只支援TYPE1.請從GM工具創好帳號在去DEMO場景加按鈕) */ | ||||
|     public static IsDemoLogin: boolean = false; | ||||
|     /**遊戲模式(0一般 1特色.WEB才有分) */ | ||||
|     public static GameMode: number = 0; | ||||
|     /**顯示金錢變動LOG */ | ||||
|     public static ShowMoneyLog: boolean = true; | ||||
|     /**顯示測試畫面 */ | ||||
|     public static ShowTest: boolean = false; | ||||
|     public static GetRunDevice(): number { | ||||
|         return 0; | ||||
|     } | ||||
|     public static IsANDROID(): boolean { | ||||
|         return false; | ||||
|     } | ||||
|     public static IsIOS(): boolean { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										237
									
								
								src/script/Base/Request/AccountRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								src/script/Base/Request/AccountRequest.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest"; | ||||
| import BusinessTypeSetting from "../BusinessTypeSetting"; | ||||
| import Config from "../Config"; | ||||
|  | ||||
| // ======================================================================================= | ||||
| /** 通用回傳SERVER創的帳號 */ | ||||
| interface CommonAccountResponse { | ||||
|     a: string; | ||||
|     pw: string; | ||||
| } | ||||
|  | ||||
| // ======================================================================================= | ||||
| interface CreateResquest { | ||||
|     p: number; | ||||
| } | ||||
| /** 直接玩(訪客給SERVER創帳號) */ | ||||
| export class AccountCreateRequest extends NetRequest<CreateResquest, CommonAccountResponse> { | ||||
|     get Method(): string { | ||||
|         return "account.create"; | ||||
|     } | ||||
|     constructor() { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             p: Config.GetRunDevice(), | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| // ======================================================================================= | ||||
| interface LoginResquest { | ||||
|     p: number; | ||||
|     device_info: string[]; | ||||
|     fcm_token: string; | ||||
|     a: string; | ||||
|     pw: string; | ||||
|     ver: string; | ||||
| } | ||||
| interface LoginResponse { | ||||
|     pr: string; | ||||
|     cu: string; | ||||
| } | ||||
| /** 通用登入 */ | ||||
| export class AccountLoginRequest extends NetRequest<LoginResquest, LoginResponse> { | ||||
|     get Method(): string { | ||||
|         return "account.login"; | ||||
|     } | ||||
|     constructor(account: string, password: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             p: Config.GetRunDevice(), | ||||
|             device_info: ["Windows", "Windows"], | ||||
|             fcm_token: "", | ||||
|             a: account, | ||||
|             pw: password, | ||||
|             ver: BusinessTypeSetting.COMPILE_VERSION | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| // ======================================================================================= | ||||
| interface CustomResquest { | ||||
|     a: string; | ||||
|     pw: string; | ||||
| } | ||||
| /** 自定帳號榜定 */ | ||||
| export class CustomBindRequest extends NetRequest<CustomResquest, null> { | ||||
|     get Method(): string { | ||||
|         return "register.account_bind"; | ||||
|     } | ||||
|     constructor(account: string, password: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             a: account, | ||||
|             pw: password, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| /** 自定帳號登入(回傳SERVER帳號) */ | ||||
| export class CustomLoginRequest extends NetRequest<CustomResquest, CommonAccountResponse> { | ||||
|     get Method(): string { | ||||
|         return "register.account_login"; | ||||
|     } | ||||
|     constructor(account: string, password: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             a: account, | ||||
|             pw: password, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| // ======================================================================================= | ||||
| interface FBResquest { | ||||
|     t: string; | ||||
| } | ||||
| /** FB綁定 */ | ||||
| export class FBBindRequest extends NetRequest<FBResquest, null> { | ||||
|     get Method(): string { | ||||
|         return "register.fb_bind"; | ||||
|     } | ||||
|     constructor(token: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             t: token, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| /** FB登入(回傳SERVER帳號) */ | ||||
| export class FBLoginRequest extends NetRequest<FBResquest, CommonAccountResponse> { | ||||
|     get Method(): string { | ||||
|         return "register.fb_login"; | ||||
|     } | ||||
|     constructor(token: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             t: token, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| // ======================================================================================= | ||||
| interface GoogleResquest { | ||||
|     c: string; | ||||
| } | ||||
| /** GOOGLE綁定 */ | ||||
| export class GoogleBindRequest extends NetRequest<GoogleResquest, null> { | ||||
|     get Method(): string { | ||||
|         return "register.google_bind"; | ||||
|     } | ||||
|     constructor(token: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             c: token, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| /** GOOGLE登入(回傳SERVER帳號) */ | ||||
| export class GoogleLoginRequest extends NetRequest<GoogleResquest, CommonAccountResponse> { | ||||
|     get Method(): string { | ||||
|         return "register.google_login"; | ||||
|     } | ||||
|     constructor(token: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             c: token, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| // ======================================================================================= | ||||
| interface AppleResquest { | ||||
|     c: string; | ||||
| } | ||||
| /** APPEL綁定 */ | ||||
| export class AppleBindRequest extends NetRequest<AppleResquest, null> { | ||||
|     get Method(): string { | ||||
|         return "register.apple_bind"; | ||||
|     } | ||||
|     constructor(token: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             c: token, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| /** APPLE登入(回傳SERVER帳號) */ | ||||
| export class AppleLoginRequest extends NetRequest<AppleResquest, CommonAccountResponse> { | ||||
|     get Method(): string { | ||||
|         return "register.apple_login"; | ||||
|     } | ||||
|     constructor(token: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             c: token, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| // ======================================================================================= | ||||
| /** 電話驗證 */ | ||||
| export interface PhoneCodeRequest { | ||||
|     p: string; | ||||
| } | ||||
|  | ||||
| export class PhoneGet extends NetRequest<PhoneCodeRequest, string> { | ||||
|     get Method(): string { | ||||
|         return "register.phone_code"; | ||||
|     } | ||||
|     constructor(p: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             p: p | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| export interface PhoneBindRequest { | ||||
|     c: string; | ||||
| } | ||||
|  | ||||
| export class PhoneBind extends NetRequest<PhoneBindRequest, string> { | ||||
|     get Method(): string { | ||||
|         return "register.phone_bind"; | ||||
|     } | ||||
|     constructor(c: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             c: c | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // ======================================================================================= | ||||
| /** 旗標更新 */ | ||||
| export class FlagOpenAdd extends NetRequest<number, string> { | ||||
|     get Method(): string { | ||||
|         return "flag.open_add"; | ||||
|     } | ||||
|     constructor(type: number) { | ||||
|         super(); | ||||
|         this.Data = type; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // ======================================================================================== | ||||
| export interface ForgotInfo { | ||||
|     a: string; | ||||
|     p: string; | ||||
| } | ||||
|  | ||||
| /** 忘記密碼 */ | ||||
| export class ForgotPassword extends NetRequest<ForgotInfo, null> { | ||||
|     get Method(): string { | ||||
|         return "register.account_forget"; | ||||
|     } | ||||
|     constructor(account: string, phone: string) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             a: account, | ||||
|             p: phone, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										72
									
								
								src/script/Base/Request/RankRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/script/Base/Request/RankRequest.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest"; | ||||
|  | ||||
| export interface RankInfo { | ||||
|     t: number; | ||||
|     p?: number; | ||||
|     id?: number; | ||||
| } | ||||
|  | ||||
| export class AppRankInfo extends NetRequest<RankInfo, JSON> { | ||||
|     get Method(): string { | ||||
|         return "rank.info"; | ||||
|     } | ||||
|     constructor(Type: number, Parameter?: number) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             t: Type, | ||||
|             p: Parameter, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| export class AppRankHistory extends NetRequest<RankInfo, JSON> { | ||||
|     get Method(): string { | ||||
|         return "rank.history"; | ||||
|     } | ||||
|     constructor(Type: number, Parameter: number, DayId: number) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             id: DayId, | ||||
|             t: Type, | ||||
|             p: Parameter | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| export interface RankReplayInfo { | ||||
|     id: number; | ||||
|     t: number; | ||||
|     r: number; | ||||
|     p: number; | ||||
| } | ||||
|  | ||||
|  | ||||
| export class AppRankLog extends NetRequest<RankReplayInfo, JSON> { | ||||
|     get Method(): string { | ||||
|         return "rank.log"; | ||||
|     } | ||||
|     constructor(DayId: number, Type: number, rank: number, Parameter: number) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             id: DayId, | ||||
|             t: Type, | ||||
|             r: rank, | ||||
|             p: Parameter | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| export class TestAppRankLog extends NetRequest<RankReplayInfo, JSON> { | ||||
|     get Method(): string { | ||||
|         return "rank.log_test"; | ||||
|     } | ||||
|     constructor(DayId: number, Type: number, rank: number, Parameter: number) { | ||||
|         super(); | ||||
|         this.Data = { | ||||
|             id: DayId, | ||||
|             t: Type, | ||||
|             r: rank, | ||||
|             p: Parameter | ||||
|         }; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "a69fe64f-177f-4e4b-83f0-1f418203d85f", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/CSharp.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/CSharp.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "f9edb32f-c4ab-4e5d-8270-71fa609e1db7", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/script/Engine/CatanEngine/CSharp/String.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/script/Engine/CatanEngine/CSharp/String.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| declare global { | ||||
|     interface StringConstructor { | ||||
|         IsNullOrEmpty: (value: string) => boolean; | ||||
|         Format: (format: string, ...args: any[]) => string; | ||||
|     } | ||||
| } | ||||
|  | ||||
| String.IsNullOrEmpty = function (value: string): boolean { | ||||
|     return value === undefined || value === null || value.trim() === ''; | ||||
| }; | ||||
|  | ||||
| String.Format = function (format: string, ...args: any[]): string { | ||||
|     return format.replace(/{(\d+)}/g, (match, index) => { | ||||
|         let value = args[index]; | ||||
|         if (value === null || value === undefined) return ''; | ||||
|         return '' + value; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export { }; | ||||
							
								
								
									
										9
									
								
								src/script/Engine/CatanEngine/CSharp/String.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/CatanEngine/CSharp/String.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "0c3d1ca6-bdaf-4a00-b209-6ef460802cdc", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/CSharp/System.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/CSharp/System.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "01b35dee-e6e0-4a6e-a73c-3b49c37f1c5f", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										125
									
								
								src/script/Engine/CatanEngine/CSharp/System/Action.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								src/script/Engine/CatanEngine/CSharp/System/Action.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| /** | ||||
|  * 回呼函數: fnname (arg: TArg): void | ||||
|  */ | ||||
| interface ActionCallback<TArg> { | ||||
|     (arg: TArg): void; | ||||
| } | ||||
|  | ||||
| interface Struct<TArg> { | ||||
|     callback: ActionCallback<TArg>; | ||||
|     target: any; | ||||
|     once?: boolean; | ||||
| } | ||||
|  | ||||
| export class Action<TArg> { | ||||
|     private _queue: Struct<TArg>[] = []; | ||||
|  | ||||
|     /** | ||||
|      * 監聽事件 | ||||
|      * @param callback 回呼函數: fnname (arg: TArg): void | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     AddCallback(callback: ActionCallback<TArg>, bindTarget?: any) { | ||||
|         let q = <Struct<TArg>> { | ||||
|             callback: callback, | ||||
|             target: bindTarget | ||||
|         }; | ||||
|         this._queue.push(q); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 監聽事件 (一次性) | ||||
|      * @param callback 回呼函數: fnname (arg: TArg): void | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     AddCallbackOnce(callback: ActionCallback<TArg>, bindTarget?: any) { | ||||
|         let q = <Struct<TArg>> { | ||||
|             callback: callback, | ||||
|             target: bindTarget, | ||||
|             once: true | ||||
|         }; | ||||
|         this._queue.push(q); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param callback  | ||||
|      */ | ||||
|     RemoveByCallback(callback: ActionCallback<TArg>) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.callback === callback) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     RemoveByBindTarget(bindTarget: any) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.target === bindTarget) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除全部事件 | ||||
|      */ | ||||
|     RemoveAllCallbacks() { | ||||
|         this._queue.forEach(q => q.callback = undefined); | ||||
|         this._queue.length = 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 發送事件 | ||||
|      * @param arg 參數 | ||||
|      */ | ||||
|     DispatchCallback(arg: TArg) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             let cleanRemoved = false; | ||||
|             this._queue.slice().forEach(q => { | ||||
|                 if (!q.callback) { | ||||
|                     cleanRemoved = true; | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (q.target) { | ||||
|                     q.callback.call(q.target, arg); | ||||
|                 } else { | ||||
|                     q.callback(arg); | ||||
|                 } | ||||
|  | ||||
|                 if (q.once) { | ||||
|                     q.callback = undefined; | ||||
|                     cleanRemoved = true; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (cleanRemoved) { | ||||
|                 index = this._queue.length; | ||||
|                 if (index > 0) { | ||||
|                     while (index--) { | ||||
|                         let q = this._queue[index]; | ||||
|                         if (!q.callback) { | ||||
|                             this._queue.splice(index, 1); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "ea9bf762-40a7-4bab-b949-8d5b3d4289e2", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										85
									
								
								src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/script/Engine/CatanEngine/CSharp/System/ActionExample.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| import { Action } from "./Action"; | ||||
| import { ActionWithType } from "./ActionWithType"; | ||||
| import { ActionWithType2 } from "./ActionWithType2"; | ||||
|  | ||||
| const { ccclass, property } = console._decorator; | ||||
|  | ||||
| enum CustomType { | ||||
|     Ex1, Ex2 | ||||
| } | ||||
|  | ||||
| class CustomEvent extends ActionWithType<CustomType, number> { } | ||||
| class CustomEvent2 extends ActionWithType2<CustomType, number> { } | ||||
|  | ||||
| @ccclass | ||||
| export default class NewClass extends console.Component { | ||||
|     callback: Action<number> = new Action<number>(); | ||||
|     customCallback: CustomEvent = new CustomEvent(); | ||||
|     customCallback2: CustomEvent2 = new CustomEvent2(); | ||||
|  | ||||
|     private num: number = 0; | ||||
|  | ||||
|     start() { | ||||
|         this.callback.AddCallback(this.CB, this); | ||||
|         this.callback.AddCallbackOnce(this.OnceCB, this); | ||||
|  | ||||
|         this.customCallback.AddCallback(CustomType.Ex1, this.CBType, this); | ||||
|         this.customCallback.AddCallbackOnce(CustomType.Ex2, this.OnceCBType, this); | ||||
|  | ||||
|         this.customCallback2.AddCallback(CustomType.Ex2, this.CBTypeAllin1, this); | ||||
|         this.customCallback2.AddCallbackOnce(CustomType.Ex1, this.CBTypeAllin1, this); | ||||
|     } | ||||
|  | ||||
|     DispatchClick() { | ||||
|         this.num++; | ||||
|  | ||||
|         this.callback.DispatchCallback(this.num); | ||||
|  | ||||
|         this.customCallback.DispatchCallback(CustomType.Ex1, this.num); | ||||
|         this.customCallback.DispatchCallback(CustomType.Ex2, this.num); | ||||
|  | ||||
|         this.customCallback2.DispatchCallback(CustomType.Ex1, this.num); | ||||
|         this.customCallback2.DispatchCallback(CustomType.Ex2, this.num); | ||||
|     } | ||||
|  | ||||
|     RemoveEventClick() { | ||||
|         this.callback.RemoveByCallback(this.CB); | ||||
|         // this.callback.RemoveByCallback(this.OnceCB); | ||||
|         // this.callback.RemoveByBindTarget(this); | ||||
|         // this.callback.RemoveAll(); | ||||
|  | ||||
|         // this.callbackWithType.RemoveByCallback(this.CBType); | ||||
|         // this.callbackWithType.RemoveByCallback(this.OnceCBType); | ||||
|         this.customCallback.RemoveByType(CustomType.Ex1); | ||||
|         // this.callbackWithType.RemoveByType(CustomType.Ex2); | ||||
|         // this.callbackWithType.RemoveByBindTarget(this); | ||||
|         // this.callbackWithType.RemoveAll(); | ||||
|     } | ||||
|  | ||||
|     OnceCB(x: number) { | ||||
|         console.log(`OnceCB [${this.num}]`); | ||||
|     } | ||||
|  | ||||
|     CB(x: number) { | ||||
|         console.log(`CB [${this.num}]`); | ||||
|     } | ||||
|  | ||||
|     OnceCBType(x: number) { | ||||
|         console.log(`OnceCBType [${this.num}]`); | ||||
|     } | ||||
|  | ||||
|     CBType(x: number) { | ||||
|         console.log(`CBType [${this.num}]`); | ||||
|     } | ||||
|  | ||||
|     CBTypeAllin1(type: CustomType, x: number) { | ||||
|         // switch (type) { | ||||
|         //     case CustomType.Ex1: | ||||
|         //         break; | ||||
|         //     case CustomType.Ex2: | ||||
|         //         break; | ||||
|         // } | ||||
|  | ||||
|         console.log(`CBTypeAllin1 [${CustomType[type]}][${this.num}]`); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "cc645b73-6192-414d-a5bc-4220c24e322d", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										166
									
								
								src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/script/Engine/CatanEngine/CSharp/System/ActionWithType.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| /** | ||||
|  * 回呼函數: fnname (arg: TArg): void | ||||
|  */ | ||||
| interface ActionCallback<TArg> { | ||||
|     (arg: TArg): void; | ||||
| } | ||||
|  | ||||
| interface Struct<TType, TArg> { | ||||
|     callback: ActionCallback<TArg>; | ||||
|     target: any; | ||||
|     type: TType; | ||||
|     once?: boolean; | ||||
| } | ||||
|  | ||||
| export class ActionWithType<TType, TArg> { | ||||
|     private _queue: Struct<TType, TArg>[] = []; | ||||
|  | ||||
|     /** | ||||
|      * 監聽事件 | ||||
|      * @param callback 回呼函數: fnname (arg: TArg): void | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     AddCallback(type: TType, callback: ActionCallback<TArg>, bindTarget?: any) { | ||||
|         let q = <Struct<TType, TArg>> { | ||||
|             callback: callback, | ||||
|             target: bindTarget, | ||||
|             type: type | ||||
|         }; | ||||
|         this._queue.push(q); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 監聽事件 (一次性) | ||||
|      * @param callback 回呼函數: fnname (arg: TArg): void | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     AddCallbackOnce(type: TType, callback: ActionCallback<TArg>, bindTarget?: any) { | ||||
|         let q = <Struct<TType, TArg>> { | ||||
|             callback: callback, | ||||
|             target: bindTarget, | ||||
|             type: type, | ||||
|             once: true | ||||
|         }; | ||||
|         this._queue.push(q); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param callback  | ||||
|      */ | ||||
|     RemoveByCallback(callback: ActionCallback<TArg>) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.callback === callback) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     RemoveByBindTarget(bindTarget: any) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.target === bindTarget) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param type 事件類型 | ||||
|      */ | ||||
|     RemoveByType(type: TType) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.type === type) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param type 事件類型 | ||||
|      * @param callback  | ||||
|      */ | ||||
|     RemoveCallback(type:TType, callback: ActionCallback<TArg>) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || (q.type === type && q.callback === callback)) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除全部事件 | ||||
|      */ | ||||
|     RemoveAllCallbacks() { | ||||
|         this._queue.forEach(q => q.callback = undefined); | ||||
|         this._queue.length = 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 發送事件 | ||||
|      * @param type 事件類型 | ||||
|      * @param arg 參數 | ||||
|      */ | ||||
|     DispatchCallback(type: TType, arg: TArg) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             let cleanRemoved = false; | ||||
|             this._queue.slice().forEach(q => { | ||||
|                 if (!q.callback) | ||||
|                 { | ||||
|                     cleanRemoved = true; | ||||
|                     return; | ||||
|                 } | ||||
|                 if (q.type !== type) return; | ||||
|  | ||||
|                 if (q.target) { | ||||
|                     q.callback.call(q.target, arg); | ||||
|                 } else { | ||||
|                     q.callback(arg); | ||||
|                 } | ||||
|                  | ||||
|                 if (q.once) { | ||||
|                     q.callback = undefined; | ||||
|                     cleanRemoved = true; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (cleanRemoved) { | ||||
|                 index = this._queue.length; | ||||
|                 if (index > 0) { | ||||
|                     while (index--) { | ||||
|                         let q = this._queue[index]; | ||||
|                         if (!q.callback) { | ||||
|                             this._queue.splice(index, 1); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "61d770ec-24e2-425b-b66b-2b03e192e45b", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										166
									
								
								src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/script/Engine/CatanEngine/CSharp/System/ActionWithType2.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| /** | ||||
|  * 回呼函數: fnname (type: TType, arg: TArg): void | ||||
|  */ | ||||
| interface ActionCallback<TType, TArg> { | ||||
|     (type: TType, arg: TArg): void; | ||||
| } | ||||
|  | ||||
| interface Struct<TType, TArg> { | ||||
|     callback: ActionCallback<TType, TArg>; | ||||
|     target: any; | ||||
|     type: TType; | ||||
|     once?: boolean; | ||||
| } | ||||
|  | ||||
| export class ActionWithType2<TType, TArg> { | ||||
|     private _queue: Struct<TType, TArg>[] = []; | ||||
|  | ||||
|     /** | ||||
|      * 監聽事件 | ||||
|      * @param callback 回呼函數: fnname (type: TType, arg: TArg): void | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     AddCallback(type: TType, callback: ActionCallback<TType, TArg>, bindTarget?: any) { | ||||
|         let q = <Struct<TType, TArg>> { | ||||
|             callback: callback, | ||||
|             target: bindTarget, | ||||
|             type: type | ||||
|         }; | ||||
|         this._queue.push(q); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 監聽事件 (一次性) | ||||
|      * @param callback 回呼函數: fnname (type: TType, arg: TArg): void | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     AddCallbackOnce(type: TType, callback: ActionCallback<TType, TArg>, bindTarget?: any) { | ||||
|         let q = <Struct<TType, TArg>> { | ||||
|             callback: callback, | ||||
|             target: bindTarget, | ||||
|             type: type, | ||||
|             once: true | ||||
|         }; | ||||
|         this._queue.push(q); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param callback  | ||||
|      */ | ||||
|     RemoveByCallback(callback: ActionCallback<TType, TArg>) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.callback === callback) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param bindTarget 回呼時this綁定的對象 | ||||
|      */ | ||||
|     RemoveByBindTarget(bindTarget: any) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.target === bindTarget) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param type 事件類型 | ||||
|      */ | ||||
|     RemoveByType(type: TType) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || q.type === type) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除事件 | ||||
|      * @param type 事件類型 | ||||
|      * @param callback  | ||||
|      */ | ||||
|     RemoveCallback(type:TType, callback: ActionCallback<TType, TArg>) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             while (index--) { | ||||
|                 let q = this._queue[index]; | ||||
|                 if (!q.callback || (q.type === type && q.callback === callback)) { | ||||
|                     q.callback = undefined; | ||||
|                     this._queue.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 移除全部事件 | ||||
|      */ | ||||
|     RemoveAllCallbacks() { | ||||
|         this._queue.forEach(q => q.callback = undefined); | ||||
|         this._queue.length = 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 發送事件 | ||||
|      * @param type 事件類型 | ||||
|      * @param arg 參數 | ||||
|      */ | ||||
|     DispatchCallback(type: TType, arg: TArg) { | ||||
|         let index = this._queue.length; | ||||
|         if (index > 0) { | ||||
|             let cleanRemoved = false; | ||||
|             this._queue.slice().forEach(q => { | ||||
|                 if (!q.callback) | ||||
|                 { | ||||
|                     cleanRemoved = true; | ||||
|                     return; | ||||
|                 } | ||||
|                 if (q.type !== type) return; | ||||
|  | ||||
|                 if (q.target) { | ||||
|                     q.callback.call(q.target, type, arg); | ||||
|                 } else { | ||||
|                     q.callback(type, arg); | ||||
|                 } | ||||
|                  | ||||
|                 if (q.once) { | ||||
|                     q.callback = undefined; | ||||
|                     cleanRemoved = true; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (cleanRemoved) { | ||||
|                 index = this._queue.length; | ||||
|                 if (index > 0) { | ||||
|                     while (index--) { | ||||
|                         let q = this._queue[index]; | ||||
|                         if (!q.callback) { | ||||
|                             this._queue.splice(index, 1); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "ed703ebd-efd4-4ec9-9b84-de748ef8f9e8", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/CSharp/System/Text.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/CSharp/System/Text.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "09d69d12-a6d1-4bb1-bcfe-faa811632467", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										68
									
								
								src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/script/Engine/CatanEngine/CSharp/System/Text/Encoding.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| export module Encoding.UTF8 { | ||||
|      | ||||
|     export function GetBytes(str: string) { | ||||
|         let len = str.length, resPos = -1; | ||||
|         let resArr = new Uint8Array(len * 3); | ||||
|         for (let point = 0, nextcode = 0, i = 0; i !== len; ) { | ||||
|             point = str.charCodeAt(i), i += 1; | ||||
|             if (point >= 0xD800 && point <= 0xDBFF) { | ||||
|                 if (i === len) { | ||||
|                     resArr[resPos += 1] = 0xef;  | ||||
|                     resArr[resPos += 1] = 0xbf; | ||||
|                     resArr[resPos += 1] = 0xbd;  | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 nextcode = str.charCodeAt(i); | ||||
|                 if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) { | ||||
|                     point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000; | ||||
|                     i += 1; | ||||
|                     if (point > 0xffff) { | ||||
|                         resArr[resPos += 1] = (0x1e << 3) | (point >>> 18); | ||||
|                         resArr[resPos += 1] = (0x2 << 6) | ((point >>> 12) & 0x3f); | ||||
|                         resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f); | ||||
|                         resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); | ||||
|                         continue; | ||||
|                     } | ||||
|                 } else { | ||||
|                     resArr[resPos += 1] = 0xef;  | ||||
|                     resArr[resPos += 1] = 0xbf; | ||||
|                     resArr[resPos += 1] = 0xbd;  | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
|             if (point <= 0x007f) { | ||||
|                 resArr[resPos += 1] = (0x0 << 7) | point; | ||||
|             } else if (point <= 0x07ff) { | ||||
|                 resArr[resPos += 1] = (0x6 << 5) | (point >>> 6); | ||||
|                 resArr[resPos += 1] = (0x2 << 6)  | (point & 0x3f); | ||||
|             } else { | ||||
|                 resArr[resPos += 1] = (0xe << 4) | (point >>> 12); | ||||
|                 resArr[resPos += 1] = (0x2 << 6) | ((point >>> 6) & 0x3f); | ||||
|                 resArr[resPos += 1] = (0x2 << 6) | (point & 0x3f); | ||||
|             } | ||||
|         } | ||||
|         return resArr.subarray(0, resPos + 1); | ||||
|     } | ||||
|  | ||||
|     export function GetString(array: Uint8Array) { | ||||
|         let str = ""; | ||||
|         let i = 0, len = array.length; | ||||
|         while(i < len) { | ||||
|             let c = array[i++]; | ||||
|             switch (c >> 4) | ||||
|             {  | ||||
|                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: | ||||
|                     str += String.fromCharCode(c); | ||||
|                     break; | ||||
|                 case 12: case 13: | ||||
|                     str += String.fromCharCode(((c & 0x1F) << 6) | (array[i++] & 0x3F)); | ||||
|                     break; | ||||
|                 case 14: | ||||
|                     str += String.fromCharCode(((c & 0x0F) << 12) | ((array[i++] & 0x3F) << 6) | ((array[i++] & 0x3F) << 0)); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         return str; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "43bf5724-e939-4189-b981-c32ef694e5a5", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/CoroutineV2.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/CoroutineV2.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "9f510f2b-83d8-4097-8683-32d6134323fb", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,43 @@ | ||||
| const CANCEL = Symbol(); | ||||
|  | ||||
| export interface CancellationToken { | ||||
|     readonly IsCancellationRequested: boolean; | ||||
|     ThrowIfCancellationRequested(): void; | ||||
| } | ||||
|  | ||||
| export class CancellationTokenSource { | ||||
|     readonly Token: CancellationToken; | ||||
|  | ||||
|     constructor() { | ||||
|         this.Token = new CancellationTokenImpl(); | ||||
|     } | ||||
|  | ||||
|     Cancel() { | ||||
|         this.Token[CANCEL](); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export class TaskCancelledException extends Error { | ||||
|     constructor() { | ||||
|         super("Task Cancelled"); | ||||
|         Reflect.setPrototypeOf(this, TaskCancelledException.prototype); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class CancellationTokenImpl implements CancellationToken { | ||||
|     IsCancellationRequested: boolean; | ||||
|  | ||||
|     constructor() { | ||||
|         this.IsCancellationRequested = false; | ||||
|     } | ||||
|  | ||||
|     ThrowIfCancellationRequested() { | ||||
|         if (this.IsCancellationRequested) { | ||||
|             throw new TaskCancelledException(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [CANCEL]() { | ||||
|         this.IsCancellationRequested = true; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "9a414131-91a8-4d02-9921-9d1ee01764c3", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/CoroutineV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/CoroutineV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "fbfe97a8-24ca-4f67-b049-323652c7194b", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,17 @@ | ||||
| import { BaseEnumerator } from "./BaseEnumerator"; | ||||
|  | ||||
| export class ActionEnumerator extends BaseEnumerator { | ||||
|     private _action: Function; | ||||
|  | ||||
|     constructor(action: Function) { | ||||
|         super(); | ||||
|         this._action = action; | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         if (this._action) { | ||||
|             this._action(); | ||||
|         } | ||||
|         return { done: true, value: undefined }; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "3cf9e5c3-520f-48a9-8821-9be76d519765", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,87 @@ | ||||
| import { IEnumeratorV2, IEnumeratorV2Started } from "../IEnumeratorV2"; | ||||
| import { CoroutineExecutor } from "./CoroutineExecutor"; | ||||
|  | ||||
| export abstract class BaseEnumerator implements IEnumeratorV2 { | ||||
|     public nextEnumerator: BaseEnumerator; | ||||
|  | ||||
|     abstract next(value?: any): IteratorResult<any>; | ||||
|      | ||||
|     Start(target?: any): IEnumeratorV2Started { | ||||
|         let executor = LazyLoad.EnumeratorExecutor(this, target); | ||||
|         CoroutineExecutor.instance.StartCoroutine(executor); | ||||
|         return executor; | ||||
|     } | ||||
|  | ||||
|     Then(iterator: Iterator<any>): IEnumeratorV2 { | ||||
|         if (!iterator) return this; | ||||
|  | ||||
|         if (iterator instanceof BaseEnumerator) { | ||||
|             BaseEnumerator.getLastEnumerator(this).nextEnumerator = iterator; | ||||
|             return this; | ||||
|         } else { | ||||
|             let enumerator = LazyLoad.SingleEnumerator(iterator); | ||||
|             BaseEnumerator.getLastEnumerator(this).nextEnumerator = enumerator; | ||||
|             return this; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     ThenSerial(...iterators: Iterator<any>[]): IEnumeratorV2 { | ||||
|         let last = BaseEnumerator.getLastEnumerator(this); | ||||
|         for (let iterator of iterators) { | ||||
|             if (iterator instanceof BaseEnumerator) { | ||||
|                 last.nextEnumerator = iterator; | ||||
|             } else { | ||||
|                 let enumerator = LazyLoad.SingleEnumerator(iterator); | ||||
|                 last.nextEnumerator = enumerator; | ||||
|             } | ||||
|             last = last.nextEnumerator; | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     ThenParallel(...iterators: Iterator<any>[]): IEnumeratorV2 { | ||||
|         return this.Then(LazyLoad.ParallelEnumerator(...iterators)); | ||||
|     } | ||||
|  | ||||
|     ThenAction(action: Function, delaySeconds?:number): IEnumeratorV2 { | ||||
|         if (delaySeconds > 0) { | ||||
|             return this.ThenSerial(LazyLoad.WaitTimeEnumerator(delaySeconds), LazyLoad.ActionEnumerator(action)); | ||||
|         } else { | ||||
|             return this.Then(LazyLoad.ActionEnumerator(action)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ThenWaitTime(seconds: number): IEnumeratorV2 { | ||||
|         return this.Then(LazyLoad.WaitTimeEnumerator(seconds)); | ||||
|     } | ||||
|  | ||||
|     static getLastEnumerator(enumerator: BaseEnumerator): BaseEnumerator { | ||||
|         let next = enumerator; | ||||
|         while (next.nextEnumerator) { | ||||
|             next = next.nextEnumerator; | ||||
|         } | ||||
|         return next; | ||||
|     } | ||||
| } | ||||
|  | ||||
| module LazyLoad { | ||||
|     export function EnumeratorExecutor(enumerator: BaseEnumerator, target: any) { | ||||
|         return new (require("./EnumeratorExecutor") as typeof import("./EnumeratorExecutor")).EnumeratorExecutor(enumerator, target); | ||||
|     } | ||||
|  | ||||
|     export function SingleEnumerator(iterator: Iterator<any>) { | ||||
|         return new (require("./SingleEnumerator") as typeof import("./SingleEnumerator")).SingleEnumerator(iterator); | ||||
|     } | ||||
|  | ||||
|     export function ParallelEnumerator(...iterators: Iterator<any>[]) { | ||||
|         return new (require("./ParallelEnumerator") as typeof import("./ParallelEnumerator")).ParallelEnumerator(iterators); | ||||
|     } | ||||
|  | ||||
|     export function WaitTimeEnumerator(seconds: number) { | ||||
|         return new (require("./WaitTimeEnumerator") as typeof import("./WaitTimeEnumerator")).WaitTimeEnumerator(seconds); | ||||
|     } | ||||
|  | ||||
|     export function ActionEnumerator(action: Function) { | ||||
|         return new (require("./ActionEnumerator") as typeof import("./ActionEnumerator")).ActionEnumerator(action); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "4084537c-c7e8-4d47-b283-39be77ef9685", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,94 @@ | ||||
| import { EnumeratorExecutor } from "./EnumeratorExecutor"; | ||||
|  | ||||
| export class CoroutineExecutor { | ||||
|     private static _instance: CoroutineExecutor; | ||||
|     static get instance() { | ||||
|         return CoroutineExecutor._instance = CoroutineExecutor._instance || new CoroutineExecutor(); | ||||
|     } | ||||
|  | ||||
|     private _executors: EnumeratorExecutor[] = []; | ||||
|     private _nextExecutors: EnumeratorExecutor[] = []; | ||||
|     private _isRunning: boolean = false; | ||||
|     private _cleanRemoved: boolean = false; | ||||
|     private _scheduler: console.Scheduler; | ||||
|  | ||||
|     constructor() { | ||||
|         this._scheduler = console.director.getScheduler(); | ||||
|         this._scheduler.enableForTarget(this); | ||||
|         this._scheduler.scheduleUpdate(this, 0, true); | ||||
|     } | ||||
|  | ||||
|     StartCoroutine(executor: EnumeratorExecutor) { | ||||
|         executor.next(0); | ||||
|         //TODO: 這邊要考量next後馬上接BaseEnumerator/Iterator的情形 | ||||
|  | ||||
|         if (!this._isRunning) { | ||||
|             this._executors.push(executor); | ||||
|  | ||||
|             if (this._scheduler.isTargetPaused(this)) { | ||||
|                 this._scheduler.resumeTarget(this); | ||||
|             } | ||||
|         } else { | ||||
|             this._nextExecutors.push(executor); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     StopCoroutineBy(target: any) { | ||||
|         if (!target) return; | ||||
|  | ||||
|         for (let r of this._executors) { | ||||
|             if (target === r.target) { | ||||
|                 r.Stop(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (let r of this._nextExecutors) { | ||||
|             if (target === r.target) { | ||||
|                 r.Stop(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     update(delta: number) { | ||||
|         if (this._nextExecutors.length) { | ||||
|             this._executors.push(...this._nextExecutors); | ||||
|             this._nextExecutors.length = 0; | ||||
|         } | ||||
|  | ||||
|         if (this._cleanRemoved) { | ||||
|             // 移除[doneFlag=true]的協程 | ||||
|             let index = this._executors.length; | ||||
|             while (index--) { | ||||
|                 let r = this._executors[index]; | ||||
|                 if (r.doneFlag) { | ||||
|                     this._executors.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|             this._cleanRemoved = false; | ||||
|         } | ||||
|  | ||||
|         if (this._executors.length == 0) { | ||||
|             if (true) { | ||||
|                 console.log("[CoroutineV2] All coroutines done"); | ||||
|             } | ||||
|             this._scheduler.pauseTarget(this); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._isRunning = true; | ||||
|  | ||||
|         // 執行協程 | ||||
|         for (let r of this._executors) { | ||||
|             if (r.doneFlag || r.pauseFlag || r.childFlag) { | ||||
|                 if (r.doneFlag) { | ||||
|                     this._cleanRemoved = true; | ||||
|                 } | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             r.next(delta); | ||||
|         } | ||||
|  | ||||
|         this._isRunning = false; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "f25b1e42-90d8-4fc0-9925-6e7e92296d57", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,168 @@ | ||||
| import { IEnumeratorV2Started } from "../IEnumeratorV2"; | ||||
| import { BaseEnumerator } from "./BaseEnumerator"; | ||||
| import { SingleEnumerator } from "./SingleEnumerator"; | ||||
|  | ||||
| export class EnumeratorExecutor implements IEnumeratorV2Started { | ||||
|     public Current: any; | ||||
|  | ||||
|     public target: any; | ||||
|     public pauseFlag: boolean; | ||||
|     public doneFlag: boolean; | ||||
|     public childFlag: boolean; | ||||
|     public asyncFlag: boolean; | ||||
|     public error: any; | ||||
|  | ||||
|     private _executor: EnumeratorExecutor; | ||||
|     private _enumerator: BaseEnumerator; | ||||
|  | ||||
|     constructor(enumerator: BaseEnumerator, target: any) { | ||||
|         this.target = target; | ||||
|         this._enumerator = enumerator; | ||||
|     } | ||||
|  | ||||
|     next(delta?: any): IteratorResult<any> { | ||||
|         if (this._executor && this._executor.doneFlag) { | ||||
|             this._executor = null; | ||||
|         } | ||||
|  | ||||
|         if (this.doneFlag || (!this._enumerator && !this._executor)) { | ||||
|             this.doneFlag = true; | ||||
|             return { done: true, value: undefined }; | ||||
|         } | ||||
|  | ||||
|         if (this.asyncFlag || this.pauseFlag) return { done: false, value: undefined }; | ||||
|  | ||||
|         let result: IteratorResult<any>; | ||||
|  | ||||
|         if (this._executor) { | ||||
|             result = this._executor.next(delta); | ||||
|             this.Current = this._executor.Current; | ||||
|             if (this._executor.doneFlag) { | ||||
|                 this._executor = null; | ||||
|             } else { | ||||
|                 result.done = false; | ||||
|                 return result; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!this._enumerator) { | ||||
|             this.doneFlag = true; | ||||
|             return { done: true, value: undefined }; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             result = this._enumerator.next(delta); | ||||
|             let value = result.value; | ||||
|             let done = result.done; | ||||
|  | ||||
|             if (value) { | ||||
|                 // Iterator | ||||
|                 if (typeof value[Symbol.iterator] === 'function') { | ||||
|                     value = new SingleEnumerator(<Iterator<any>>value); | ||||
|                 } | ||||
|  | ||||
|                 if (value instanceof BaseEnumerator) { | ||||
|                     if (!done) { | ||||
|                         BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator; | ||||
|                     } | ||||
|                     this._enumerator = value; | ||||
|                     result = this._enumerator.next(delta); | ||||
|                     value = result.value; | ||||
|                     done = result.done; | ||||
|  | ||||
|                     if (value) { | ||||
|                         // Iterator again | ||||
|                         if (typeof value[Symbol.iterator] === 'function') { | ||||
|                             value = new SingleEnumerator(<Iterator<any>>value); | ||||
|                         } | ||||
|  | ||||
|                         if (value instanceof BaseEnumerator) { | ||||
|                             if (!done) { | ||||
|                                 BaseEnumerator.getLastEnumerator(value).nextEnumerator = this._enumerator; | ||||
|                             } | ||||
|                             this._enumerator = value; | ||||
|                             result.done = false; | ||||
|                             done = false; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (value instanceof EnumeratorExecutor) { | ||||
|                     if (done) { | ||||
|                         this._enumerator = this._enumerator.nextEnumerator; | ||||
|                     } | ||||
|                     value.childFlag = true; | ||||
|                     result.done = false; | ||||
|                     done = false; | ||||
|                     this._executor = value; | ||||
|                 } else if (Promise.resolve(value) === value) { | ||||
|                     this.asyncFlag = true; | ||||
|                     result.done = false; | ||||
|                     done = false; | ||||
|                     (<Promise<any>>value) | ||||
|                         .then(v => { | ||||
|                             this.asyncFlag = false; | ||||
|                             this.Current = v; | ||||
|                             if (done) { | ||||
|                                 this._enumerator = this._enumerator.nextEnumerator; | ||||
|                             } | ||||
|                         }) | ||||
|                         .catch(e => { | ||||
|                             this.asyncFlag = false; | ||||
|                             this.doneFlag = true; | ||||
|                             this._enumerator = null; | ||||
|                             this.error = e; | ||||
|                             if (e instanceof Error) { | ||||
|                                 console.error(e.stack); | ||||
|                             } else { | ||||
|                                 console.error(`Error: ${JSON.stringify(e)}`); | ||||
|                             } | ||||
|                         }); | ||||
|                 } | ||||
|  | ||||
|                 this.Current = value; | ||||
|             } | ||||
|  | ||||
|             if (done) { | ||||
|                 this._enumerator = this._enumerator.nextEnumerator; | ||||
|                 if (this._enumerator) { | ||||
|                     result.done = false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         catch (e) { | ||||
|             this.doneFlag = true; | ||||
|             this.error = e; | ||||
|             if (e instanceof Error) { | ||||
|                 console.error(e.stack); | ||||
|             } else { | ||||
|                 console.error(`Error: ${JSON.stringify(e)}`); | ||||
|             } | ||||
|             result = { done: true, value: e }; | ||||
|         } | ||||
|  | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     Stop(): void { | ||||
|         this.doneFlag = true; | ||||
|         if (this._executor) { | ||||
|             this._executor.Stop(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Pause(): void { | ||||
|         this.pauseFlag = true; | ||||
|         if (this._executor) { | ||||
|             this._executor.Pause(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Resume(): void { | ||||
|         this.pauseFlag = false; | ||||
|         if (this._executor) { | ||||
|             this._executor.Resume(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "91cb70ed-e6f9-4ce0-b7c5-1720087b3bd7", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,46 @@ | ||||
| import { BaseEnumerator } from "./BaseEnumerator"; | ||||
| import { EnumeratorExecutor } from "./EnumeratorExecutor"; | ||||
| import { SingleEnumerator } from "./SingleEnumerator"; | ||||
|  | ||||
| export class ParallelEnumerator extends BaseEnumerator { | ||||
|     private _executors: EnumeratorExecutor[] = []; | ||||
|  | ||||
|     constructor(iterators: Iterator<any>[]) { | ||||
|         super(); | ||||
|         if (iterators && iterators.length) { | ||||
|             for (let iterator of iterators) { | ||||
|                 if (iterator instanceof BaseEnumerator) { | ||||
|                     this._executors.push(new EnumeratorExecutor(iterator, null)); | ||||
|                 } else { | ||||
|                     this._executors.push(new EnumeratorExecutor(new SingleEnumerator(iterator), null)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         if (this._executors.length) { | ||||
|             // 先移除[doneFlag=true]協程 | ||||
|             let index = this._executors.length; | ||||
|             while (index--) { | ||||
|                 let r = this._executors[index]; | ||||
|                 if (r.doneFlag) { | ||||
|                     this._executors.splice(index, 1); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (this._executors.length == 0) { | ||||
|                 return { done: true, value: undefined }; | ||||
|             } | ||||
|  | ||||
|             // 執行協程 | ||||
|             for (let r of this._executors) { | ||||
|                 r.next(value); | ||||
|             } | ||||
|  | ||||
|             return { done: false, value: undefined }; | ||||
|         } | ||||
|  | ||||
|         return { done: true, value: undefined }; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "017ebc9a-5152-4f94-bbaf-e3b914e87b41", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,18 @@ | ||||
| import { BaseEnumerator } from "./BaseEnumerator"; | ||||
|  | ||||
| export class SingleEnumerator extends BaseEnumerator { | ||||
|     private _iterator: Iterator<any>; | ||||
|  | ||||
|     constructor(iterator: Iterator<any>) { | ||||
|         super(); | ||||
|         this._iterator = iterator; | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         if (!this._iterator) { | ||||
|             return { done: true, value: undefined }; | ||||
|         } | ||||
|  | ||||
|         return this._iterator.next(value); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "c439d019-2da8-48b8-a65b-bff928d0fda8", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,21 @@ | ||||
| import { BaseEnumerator } from "./BaseEnumerator"; | ||||
|  | ||||
| export class WaitTimeEnumerator extends BaseEnumerator { | ||||
|     private _seconds: number; | ||||
|  | ||||
|     constructor(seconds: number) { | ||||
|         super(); | ||||
|         this._seconds = seconds; | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         let delta = value as number; | ||||
|         this._seconds -= delta; | ||||
|  | ||||
|         if (this._seconds <= 0) { | ||||
|             return { done: true, value: 0 }; | ||||
|         } else { | ||||
|             return { done: false, value: this._seconds }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "a3038e6f-1bb4-4aff-a686-b69209df3592", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										197
									
								
								src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								src/script/Engine/CatanEngine/CoroutineV2/CoroutineExample.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| import { CoroutineV2 } from "./CoroutineV2"; | ||||
| import { IEnumeratorV2Started } from "./IEnumeratorV2"; | ||||
|  | ||||
| const { ccclass, property } = console._decorator; | ||||
|  | ||||
| class A { | ||||
|     private numbers: number[] = [1, 2]; | ||||
|     private index = 0; | ||||
|  | ||||
|     [Symbol.iterator](): IterableIterator<any> { | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         if (this.index < this.numbers.length) { | ||||
|             let value = this.numbers[this.index++]; | ||||
|             console.log(`A=> ${value}`); | ||||
|             return { | ||||
|                 done: false, | ||||
|                 value: value | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return { done: true, value: undefined }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ccclass | ||||
| export default class CoroutineExample extends console.Component { | ||||
|     private _routine: IEnumeratorV2Started; | ||||
|     private _obj: Object = { "a": true }; | ||||
|     private _obj2: Object = { "b": true }; | ||||
|  | ||||
|     private _num: number = 3; | ||||
|  | ||||
|     button1Clicked() { | ||||
|         // this._routine = CoroutineV2 | ||||
|         //                     .Parallel(this.Coroutine1(1, 3), this.Coroutine1(4, 6)) | ||||
|         //                     .ThenWaitTime(2) | ||||
|         //                     .Then(this.Coroutine1(7, 9)) | ||||
|         //                     .ThenWaitTime(2) | ||||
|         //                     .ThenAction(() => console.log("action callback 1")) | ||||
|         //                     .ThenWaitTime(2) | ||||
|         //                     .ThenAction(this.actionCallback) | ||||
|         //                     //.Start(this); | ||||
|         //                     .Start(this); | ||||
|         // this._routine = CoroutineV2.Single(this.FunA()).Start(this); | ||||
|  | ||||
|         this._routine = CoroutineV2.Single(this.Test1_1()).Start(this); | ||||
|         // this._routine = CoroutineV2.Single(this.Test2_1()).Start(this); | ||||
|     } | ||||
|  | ||||
|     *Test1_1() { | ||||
|         yield null; | ||||
|         yield* this.Test1_2(); | ||||
|         // CoroutineV2.Single(this.Test1_3()).Start(this); | ||||
|         yield this.Test1_3(); | ||||
|     } | ||||
|  | ||||
|     *Test1_2() { | ||||
|         yield null; | ||||
|     } | ||||
|  | ||||
|     *Test1_3() { | ||||
|         yield this.Test1_3_1(); | ||||
|         yield CoroutineV2.Single(this.Test1_4()).Start(this._obj); | ||||
|         // yield CoroutineV2.Single(this.Test1_4()); //.Start(this); | ||||
|         // yield *this.Test1_4(); | ||||
|         console.log("main wait 3"); | ||||
|         yield CoroutineV2.WaitTime(2); | ||||
|         console.log("done"); | ||||
|     } | ||||
|  | ||||
|     *Test1_3_1() { | ||||
|         yield this.Test1_3_2(); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_1.1"); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_1.2"); | ||||
|     } | ||||
|  | ||||
|     *Test1_3_2() { | ||||
|         yield this.Test1_3_3(); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_2.1"); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_2.2"); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_2.3"); | ||||
|     } | ||||
|  | ||||
|     *Test1_3_3() { | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_3.1"); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_3.2"); | ||||
|         yield CoroutineV2.WaitTime(1); | ||||
|         console.log("Test1_3_3.3"); | ||||
|     } | ||||
|  | ||||
|     *Test1_4() { | ||||
|         this._num++; | ||||
|         console.log(`WaitTime2 ${this._num}`); | ||||
|         yield CoroutineV2.WaitTime(2).Start(this._obj2); | ||||
|         this._num++; | ||||
|         console.log(`WaitTime2 ${this._num}`); | ||||
|         yield CoroutineV2.WaitTime(2).Start(this._obj2); | ||||
|         this._num++; | ||||
|         console.log(`WaitTime2 ${this._num}`); | ||||
|     } | ||||
|  | ||||
|     *Test2_1() { | ||||
|         console.log("111"); | ||||
|         CoroutineV2.Single(this.Test2_2()).Start(this); | ||||
|         console.log("333"); | ||||
|     } | ||||
|  | ||||
|     *Test2_2() { | ||||
|         console.log("222"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     button2Clicked() { | ||||
|         // this._routine && this._routine.Stop(); | ||||
|         if (this._obj2) { | ||||
|             CoroutineV2.StopCoroutinesBy(this._obj2); | ||||
|             this._obj2 = null; | ||||
|             return; | ||||
|         } | ||||
|         if (this._obj) { | ||||
|             CoroutineV2.StopCoroutinesBy(this._obj); | ||||
|             this._obj = null; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         CoroutineV2.StopCoroutinesBy(this); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     button3Clicked() { | ||||
|         // CoroutineV2.StopCoroutinesBy(this); | ||||
|         this._routine && this._routine.Pause(); | ||||
|     } | ||||
|  | ||||
|     button4Clicked() { | ||||
|         // CoroutineV2.StopCoroutinesBy(this); | ||||
|         this._routine && this._routine.Resume(); | ||||
|     } | ||||
|  | ||||
|     *Coroutine1(start: number, end: number) { | ||||
|         for (let i = start; i <= end; i++) { | ||||
|             // yield CoroutineV2.WaitTime(1).Start(); // Start()可以省略, 會由外層啟動 | ||||
|             // yield CoroutineV2.WaitTime(1).Start(this); // target也可以省略, 由外層的target控制 | ||||
|  | ||||
|             yield CoroutineV2.WaitTime(1).Start(); | ||||
|             console.log(`C1 => ${i}`); | ||||
|  | ||||
|             // 嵌套 | ||||
|             yield CoroutineV2 | ||||
|                 .WaitTime(1) | ||||
|                 .ThenParallel( | ||||
|                     // 再嵌套 | ||||
|                     CoroutineV2.Action(() => console.log("start parallel")), | ||||
|                     this.Coroutine2(10, 2), | ||||
|                     this.Coroutine2(20, 2), | ||||
|                     new A()) | ||||
|                 .ThenAction(() => console.log("end parallel")) | ||||
|                 .Start(); | ||||
|  | ||||
|             // Promise | ||||
|             yield this.loadItemAsync("settings.json"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     *Coroutine2(num: number, repeat: number) { | ||||
|         for (let i = 0; i < repeat; i++) { | ||||
|             //yield CoroutineV2.WaitTime(2); | ||||
|             yield 0; | ||||
|             console.log(`C2: ${num}`); | ||||
|             // yield CoroutineV2.WaitTime(1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     actionCallback() { | ||||
|         console.log("action callback 2"); | ||||
|     } | ||||
|  | ||||
|     loadItemAsync(id: string): Promise<{ id: string }> { | ||||
|         return new Promise((resolve) => { | ||||
|             console.log('loading item start:', id); | ||||
|             setTimeout(() => { | ||||
|                 resolve({ id: id }); | ||||
|                 console.log('loading item done:', id); | ||||
|             }, 3000); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "dfd32c11-76f6-4e38-9272-1d7966d1ef3c", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										75
									
								
								src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/script/Engine/CatanEngine/CoroutineV2/CoroutineV2.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| import { IEnumeratorV2, IEnumeratorV2Started } from "./IEnumeratorV2"; | ||||
| import { BaseEnumerator } from "./Core/BaseEnumerator"; | ||||
| import { SingleEnumerator } from "./Core/SingleEnumerator"; | ||||
| import { ParallelEnumerator } from "./Core/ParallelEnumerator"; | ||||
| import { WaitTimeEnumerator } from "./Core/WaitTimeEnumerator"; | ||||
| import { ActionEnumerator } from "./Core/ActionEnumerator"; | ||||
| import { CoroutineExecutor } from "./Core/CoroutineExecutor"; | ||||
|  | ||||
| export module CoroutineV2 { | ||||
|     /** | ||||
|      * 啟動一般協程 | ||||
|      */ | ||||
|     export function StartCoroutine(iterator: Iterator<any>, target?: any): IEnumeratorV2Started { | ||||
|         return Single(iterator).Start(target); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 依據IEnumeratorV2.Start(target)綁定的目標, 來停止協程 | ||||
|      * @param target  | ||||
|      */ | ||||
|     export function StopCoroutinesBy(target: any) { | ||||
|         CoroutineExecutor.instance.StopCoroutineBy(target); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 單一協程 | ||||
|      */ | ||||
|     export function Single(iterator: Iterator<any>): IEnumeratorV2 { | ||||
|         if (iterator instanceof BaseEnumerator) { | ||||
|             return iterator; | ||||
|         } else { | ||||
|             return new SingleEnumerator(iterator); | ||||
|         }  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 平行協程 | ||||
|      */ | ||||
|     export function Parallel(...iterators: Iterator<any>[]): IEnumeratorV2 { | ||||
|         return new ParallelEnumerator(iterators); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 序列協程 | ||||
|      */ | ||||
|     export function Serial(...iterators: Iterator<any>[]): IEnumeratorV2 { | ||||
|         let [iterator, ...others] = iterators; | ||||
|         if (iterator instanceof BaseEnumerator) { | ||||
|             return iterator.ThenSerial(...others); | ||||
|         } else { | ||||
|             return new SingleEnumerator(iterator).ThenSerial(...others); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 執行方法協程 | ||||
|      * @param action 方法 | ||||
|      * @param delaySeconds 延遲秒數 | ||||
|      */ | ||||
|     export function Action(action: Function, delaySeconds?: number): IEnumeratorV2 { | ||||
|         if (delaySeconds > 0) { | ||||
|             return new WaitTimeEnumerator(delaySeconds).Then(new ActionEnumerator(action)); | ||||
|         } else { | ||||
|             return new ActionEnumerator(action); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 等待時間協程 | ||||
|      * @param seconds 秒數 | ||||
|      */ | ||||
|     export function WaitTime(seconds: number): IEnumeratorV2 { | ||||
|         return new WaitTimeEnumerator(seconds); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "fc38e505-bd37-44c3-9e0a-fd463bb88c51", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/script/Engine/CatanEngine/CoroutineV2/IEnumeratorV2.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| export interface IEnumeratorV2 extends Iterator<any> { | ||||
|     Start(target?: any): IEnumeratorV2Started; | ||||
|     Then(iterator: Iterator<any>): IEnumeratorV2; | ||||
|     ThenSerial(...iterators: Iterator<any>[]): IEnumeratorV2; | ||||
|     ThenParallel(...iterators: Iterator<any>[]): IEnumeratorV2; | ||||
|     ThenAction(action: Function, delaySeconds?: number): IEnumeratorV2; | ||||
|     ThenWaitTime(seconds: number): IEnumeratorV2; | ||||
| } | ||||
|  | ||||
| export interface IEnumeratorV2Started { | ||||
|     readonly Current: any; | ||||
|  | ||||
|     Pause(): void; | ||||
|     Resume(): void; | ||||
|     Stop(): void; | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "df3ab07d-3d2b-4552-b454-29b95223ea85", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/NetManagerV2.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/NetManagerV2.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "6f870efd-e869-4415-9cf2-138ab667cd5d", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/NetManagerV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/NetManagerV2/Core.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "5e6c027f-ce4b-47fa-968c-f3bb6059ad81", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,13 @@ | ||||
| import { Action } from "../../CSharp/System/Action"; | ||||
| import { INetRequest } from "./INetRequest"; | ||||
| import { INetResponse } from "./INetResponse"; | ||||
|  | ||||
| export interface INetConnector { | ||||
|     readonly OnDataReceived: Action<INetResponse<any>>; | ||||
|     readonly OnDisconnected: Action<void>; | ||||
|     readonly IsConnected: boolean; | ||||
|      | ||||
|     SendAsync<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>): Iterator<any>; | ||||
|     Send<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>); | ||||
|     Logout(); | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "f97991b5-0da6-4220-ab29-13c8f8f7e405", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| import { INetResponse } from "./INetResponse"; | ||||
|  | ||||
| export interface INetRequest<TRequest, TResponse> { | ||||
|     readonly Method: string; | ||||
|     readonly MethodBack: string; | ||||
|  | ||||
|     Data: TRequest; | ||||
|     Result: INetResponse<TResponse>; | ||||
|  | ||||
|     SendAsync(): Promise<Iterator<any>>; | ||||
|     Send(); | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "339fcf27-bdb9-4b8f-ae18-dd54c9500145", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| export interface INetResponse<TResponse> { | ||||
|     readonly Method: string; | ||||
|     readonly Status: number; | ||||
|     readonly Data: TResponse; | ||||
|     readonly IsValid: boolean; | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "c4cb0cd4-b98c-4f8e-b1e6-ac3b51281b28", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/NetManagerV2/Examples.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/NetManagerV2/Examples.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "94e55972-723c-4dab-9ebc-870bd5043fca", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,69 @@ | ||||
| import { CoroutineV2 } from "../../CoroutineV2/CoroutineV2"; | ||||
| import { INetResponse } from "../Core/INetResponse"; | ||||
| import { NetConnector } from "../NetConnector"; | ||||
| import { NetManager } from "../NetManager"; | ||||
| import { Slot1_SpinRequestExample } from "./Slot1_SpinRequestExample"; | ||||
|  | ||||
| const { ccclass, property } = console._decorator; | ||||
|  | ||||
| @ccclass | ||||
| export default class NetTester extends console.Component { | ||||
|  | ||||
|     onConnectClicked() { | ||||
|         CoroutineV2.StartCoroutine(this.ConnectAsync()); | ||||
|     } | ||||
|  | ||||
|     *ConnectAsync() { | ||||
|         if (!NetManager.HasInit) { | ||||
|             let conn = new NetConnector("192.168.7.165", 9005); | ||||
|             conn.OnDataReceived.AddCallback(this.OnNetDataReceived, this); | ||||
|             conn.OnDisconnected.AddCallback(this.OnNetDisconnected, this); | ||||
|             conn.OnLoadUIMask.AddCallback(this.OnLoadUIMask, this); | ||||
|  | ||||
|             NetManager.Initialize(conn); | ||||
|         } | ||||
|  | ||||
|         console.log("連線中..."); | ||||
|         yield NetManager.ConnectAsync(); // 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect() | ||||
|         console.log(`連線狀態: ${NetManager.IsConnected}`); | ||||
|     } | ||||
|  | ||||
|     onDisconnectClicked() { | ||||
|         console.log("中斷連線中..."); | ||||
|         NetManager.Disconnect(); // 中斷連線 | ||||
|     } | ||||
|  | ||||
|     onSendMessageClicked1() { | ||||
|         console.log("發送訊息(不使用協程)"); | ||||
|         let req = new Slot1_SpinRequestExample(401); | ||||
|         req.Send(); | ||||
|         // CasinoNetManager.Send(req); | ||||
|     } | ||||
|  | ||||
|     onSendMessageClicked2() { | ||||
|         CoroutineV2.StartCoroutine(this.SendAsync()); | ||||
|     } | ||||
|  | ||||
|     *SendAsync() { | ||||
|         console.log("發送訊息中(使用協程)..."); | ||||
|         let req = new Slot1_SpinRequestExample(399); | ||||
|         yield req.SendAsync(); | ||||
|         // yield CasinoNetManager.SendAsync(req); | ||||
|  | ||||
|         let resp = req.Result; | ||||
|         console.log(`發送協程完畢, Server回應: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); | ||||
|         // console.log(`使用介面資料: ${resp.Data.slot}`); | ||||
|     } | ||||
|  | ||||
|     private OnNetDisconnected() { | ||||
|         console.log("[事件] 收到連線中斷事件"); | ||||
|     } | ||||
|  | ||||
|     private OnNetDataReceived(resp: INetResponse<any>) { | ||||
|         console.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`); | ||||
|     } | ||||
|  | ||||
|     private OnLoadUIMask(value: boolean) { | ||||
|         console.log(`[事件] LoadUIMask: ${value}`); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "0cb7df7a-d0e7-4ce1-832e-4583cf3385e5", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
| @@ -0,0 +1,37 @@ | ||||
| import { NetRequest } from "../NetRequest"; | ||||
|  | ||||
| // 送給server的結構 | ||||
| interface Request { | ||||
|     pay: number; | ||||
| } | ||||
|  | ||||
| // server回應的結構 | ||||
| interface Response { | ||||
|     pay: [[number, number]]; | ||||
|     /**拉霸結果 */ | ||||
|     slot: number[]; | ||||
|     get: any[]; | ||||
| } | ||||
|  | ||||
| // class Account_CreateRequest extends CasinoRequest<number, any> { // 也可以是基本類或any, 但不建議用any, 使用介面ts才會有提示 | ||||
| export class Slot1_SpinRequestExample extends NetRequest<Request, Response> { | ||||
|     get Method(): string { | ||||
|         return "slot1.spin"; | ||||
|     } | ||||
|  | ||||
|     // MethodBack預設回傳Method, 不一樣才需要覆寫 | ||||
|     // get MethodBack(): string { | ||||
|     //     return "slot1.freespin"; | ||||
|     // } | ||||
|  | ||||
|     constructor(totalBet: number) { | ||||
|         super(); | ||||
|  | ||||
|         // 原本的SingleValue拿掉, 統一使用Data來存送出結構 | ||||
|  | ||||
|         // this.Data = 2; | ||||
|         this.Data = { | ||||
|             pay: totalBet, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "1af9e6af-3dc3-4d02-8b24-481adc07932a", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										4
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| export default class NetConfig { | ||||
| 	/**是否顯示RPC接送JSON的LOG */ | ||||
| 	public static ShowServerLog: boolean = true; | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "c7f5f6a9-94fd-4f5f-9f0a-545cd14edca9", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										263
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,263 @@ | ||||
| import { Tools } from "../../../Tools"; | ||||
| import { BaseEnumerator } from "../CoroutineV2/Core/BaseEnumerator"; | ||||
| import { Action } from "../CSharp/System/Action"; | ||||
| import { Encoding } from "../CSharp/System/Text/Encoding"; | ||||
| import { INetRequest } from "./Core/INetRequest"; | ||||
| import { INetResponse } from "./Core/INetResponse"; | ||||
| import NetConfig from "./NetConfig"; | ||||
| import { NetManager } from "./NetManager"; | ||||
|  | ||||
| export class NetConnector { | ||||
|     readonly OnDataReceived: Action<INetResponse<any>> = new Action<INetResponse<any>>(); | ||||
|     readonly OnDisconnected: Action<void> = new Action<void>(); | ||||
|     readonly OnLoadUIMask: Action<boolean> = new Action<boolean>(); | ||||
|  | ||||
|     get IsConnected() { | ||||
|         return this._ws && this._ws.readyState === WebSocket.OPEN; | ||||
|     } | ||||
|  | ||||
|     private _host: string; | ||||
|     private _ws: WebSocket = null!; | ||||
|     private _waitings: WsRequestEnumerator[] = []; | ||||
|  | ||||
|     constructor(host: string, port: number, ip: string) { | ||||
|         let checkHttp: string = ""; | ||||
|         let index: number = host.indexOf("https://"); | ||||
|         if (index != -1) { | ||||
|             checkHttp = "https"; | ||||
|             host = host.replace("https://", ""); | ||||
|         } else { | ||||
|             checkHttp = window.location.href.substring(0, 5); | ||||
|             host = host.replace("http://", ""); | ||||
|         } | ||||
|         if (true) { | ||||
|             console.log("[事件]checkHttp=", checkHttp, host, port); | ||||
|         } | ||||
|         if (checkHttp != "https") { | ||||
|             this._host = `ws://${host}:${port}/?ip=${ip}`; | ||||
|         } | ||||
|         else { | ||||
|             this._host = `wss://${host}:${port}/?ip=${ip}`; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async ConnectAsync() { | ||||
|         if (this._ws) { | ||||
|             throw new Error("請先執行CasinoNetManager.Disconnect()中斷連線"); | ||||
|         } | ||||
|         this._ws = new WebSocket(this._host); | ||||
|  | ||||
|         this._ws.binaryType = 'arraybuffer'; | ||||
|         this._ws.onopen = this.OnWebSocketOpen.bind(this); | ||||
|         this._ws.onmessage = this.OnWebSocketMessage.bind(this); | ||||
|         this._ws.onerror = this.OnWebSocketError.bind(this); | ||||
|         this._ws.onclose = this.OnWebSocketClose.bind(this); | ||||
|  | ||||
|         while (!NetManager.IsConnected) { | ||||
|             await Tools.Sleep(1); | ||||
|         } | ||||
|         return new WsConnectEnumerator(this._ws); | ||||
|     } | ||||
|  | ||||
|     async Send(req: INetRequest<any, any>) { | ||||
|         if (!this.IsConnected) return; | ||||
|  | ||||
|         let json = [req.Method]; | ||||
|         if (req.Data != null && req.Data != undefined && req.Data) { | ||||
|             json[1] = req.Data; | ||||
|         } | ||||
|  | ||||
|         if (true && NetConfig.ShowServerLog) { | ||||
|             if (req.Data != null && req.Data != undefined && req.Data) { | ||||
|                 console.log(`[RPC] 傳送server資料: ${req.Method}(${JSON.stringify(req.Data)})`); | ||||
|             } else { | ||||
|                 console.log(`[RPC] 傳送server資料: ${req.Method}()`); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         let str = JSON.stringify(json); | ||||
|         if (str.length > 65535) { | ||||
|             throw new Error('要傳的資料太大囉'); | ||||
|         } | ||||
|  | ||||
|         let strary = Encoding.UTF8.GetBytes(str); | ||||
|         let buffer = new Uint8Array(4 + strary.byteLength); | ||||
|         let u16ary = new Uint16Array(buffer.buffer, 0, 3); | ||||
|         u16ary[0] = strary.byteLength; | ||||
|         buffer[3] = 0x01; | ||||
|         buffer.set(strary, 4); | ||||
|  | ||||
|         await this._ws.send(buffer); | ||||
|     } | ||||
|  | ||||
|     async SendAsync(req: INetRequest<any, any>, mask: boolean) { | ||||
|         let iterator = new WsRequestEnumerator(req); | ||||
|         if (!this.IsConnected) { | ||||
|             iterator.SetResponse(ErrorResponse); | ||||
|         } else { | ||||
|             this._waitings.push(iterator); | ||||
|             if (mask) { | ||||
|                 this.OnLoadUIMask.DispatchCallback(true); | ||||
|             } | ||||
|             this.Send(req); | ||||
|             while (!iterator.Done) { | ||||
|                 await Tools.Sleep(1); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         return iterator; | ||||
|     }; | ||||
|  | ||||
|     Disconnect() { | ||||
|         this.WebSocketEnded(); | ||||
|     } | ||||
|  | ||||
|     private WebSocketEnded() { | ||||
|         if (!this._ws) return; | ||||
|  | ||||
|         this._ws.close(); | ||||
|         this._ws.onopen = null; | ||||
|         this._ws.onmessage = null; | ||||
|         this._ws.onclose = () => { }; | ||||
|         this._ws = null!; | ||||
|  | ||||
|         this.CleanWaitings(); | ||||
|         this.OnDisconnected.DispatchCallback(); | ||||
|     } | ||||
|  | ||||
|     private CleanWaitings() { | ||||
|         for (let w of this._waitings) { | ||||
|             w.SetResponse(ErrorResponse); | ||||
|             this.OnLoadUIMask.DispatchCallback(false); | ||||
|         } | ||||
|         this._waitings.length = 0; | ||||
|     } | ||||
|  | ||||
|     private OnWebSocketOpen(e: Event) { | ||||
|         if (true) { | ||||
|             console.log(`[RPC] ${this._host} Connected.`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private OnWebSocketMessage(e: MessageEvent) { | ||||
|         if (e.data instanceof ArrayBuffer) { | ||||
|             this.ParseRpcMessage(e.data); | ||||
|         } else if (e.data instanceof Blob) { | ||||
|             let reader = new FileReader(); | ||||
|             reader.onload = (e) => { this.ParseRpcMessage(<ArrayBuffer>reader.result); reader.onload = null; } | ||||
|             reader.readAsArrayBuffer(e.data); | ||||
|         } else { | ||||
|             throw new Error(`未知的OnWebSocketMessage(e.data)類型: ${e.data}`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private ParseRpcMessage(buffer: ArrayBuffer) { | ||||
|         let startIndex = 0, byteLength = buffer.byteLength; | ||||
|         while (startIndex + 4 < byteLength) { | ||||
|             let strlen = new DataView(buffer, startIndex, 3).getUint16(0, true); | ||||
|             let str = Encoding.UTF8.GetString(new Uint8Array(buffer, startIndex + 4, strlen)); | ||||
|             startIndex += strlen + 4; | ||||
|  | ||||
|             try { | ||||
|                 let json = JSON.parse(str); | ||||
|                 let method = <string>json[0]; | ||||
|                 let status = <number>json[1][0]; | ||||
|                 let data = json[1][1]; | ||||
|  | ||||
|                 let resp = <INetResponse<any>>{ | ||||
|                     Method: method, | ||||
|                     Status: status, | ||||
|                     Data: data, | ||||
|                     IsValid: method && status === 0 | ||||
|                 }; | ||||
|  | ||||
|                 if (true && NetConfig.ShowServerLog) { | ||||
|                     if (data) { | ||||
|                         console.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}(${JSON.stringify(resp.Data)})`); | ||||
|                     } else { | ||||
|                         console.log(`[RPC] 收到server呼叫:(${resp.Status}): ${resp.Method}()`); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 let dispatch = true; | ||||
|                 for (let i = 0, len = this._waitings.length; i < len; i++) { | ||||
|                     let w = this._waitings[i]; | ||||
|                     if (w.MethodBack === resp.Method) { | ||||
|                         dispatch = false; | ||||
|                         this._waitings.splice(i, 1); | ||||
|                         w.SetResponse(resp); | ||||
|                         this.OnLoadUIMask.DispatchCallback(false); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (dispatch) { | ||||
|                     this.OnDataReceived.DispatchCallback(resp); | ||||
|                 } | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 throw new Error(`[RPC] 無法解析Server回應: ${str}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private OnWebSocketError(ev: Event) { | ||||
|         throw new Error(`[RPC] 無法解析Server回應: ${ev}`); | ||||
|     } | ||||
|  | ||||
|     private OnWebSocketClose(e: CloseEvent) { | ||||
|         this.WebSocketEnded(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| const ErrorResponse: INetResponse<any> = { | ||||
|     Status: -1, | ||||
|     Method: "", | ||||
|     Data: {}, | ||||
|     IsValid: false, | ||||
| }; | ||||
|  | ||||
| class WsConnectEnumerator extends BaseEnumerator { | ||||
|     private _ws: WebSocket; | ||||
|  | ||||
|     constructor(ws: WebSocket) { | ||||
|         super(); | ||||
|         this._ws = ws; | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         return { | ||||
|             done: this._ws.readyState === WebSocket.OPEN || this._ws.readyState === WebSocket.CLOSED, | ||||
|             value: undefined | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| class WsRequestEnumerator extends BaseEnumerator { | ||||
|     readonly MethodBack: string; | ||||
|  | ||||
|     private _req: INetRequest<any, any>; | ||||
|     private _done: boolean = false; | ||||
|  | ||||
|     public get Done(): boolean { return this._done; } | ||||
|  | ||||
|     constructor(req: INetRequest<any, any>) { | ||||
|         super(); | ||||
|  | ||||
|         this._req = req; | ||||
|         this.MethodBack = req.MethodBack; | ||||
|     } | ||||
|  | ||||
|     SetResponse(resp: INetResponse<any>) { | ||||
|         this._req.Result = resp; | ||||
|         this._done = true; | ||||
|     } | ||||
|  | ||||
|     next(value?: any): IteratorResult<any> { | ||||
|         return { | ||||
|             done: this._done, | ||||
|             value: undefined | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "221e1688-cc40-450d-9248-464978540a85", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										49
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| import { INetRequest } from "./Core/INetRequest"; | ||||
| import { NetConnector } from "./NetConnector"; | ||||
|  | ||||
| export class NetManager { | ||||
|     static get IsConnected() { return this._connector && this._connector.IsConnected; } | ||||
|     static get HasInit() { return this._connector != null; } | ||||
|  | ||||
|     private static _connector: NetConnector; | ||||
|  | ||||
|     static Initialize(connector: NetConnector) { | ||||
|         this._connector = connector; | ||||
|     } | ||||
|  | ||||
|     static async ConnectAsync() { | ||||
|         this.CheckConnector(); | ||||
|         return await this._connector.ConnectAsync(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 斷線 | ||||
|      */ | ||||
|     static Disconnect() { | ||||
|         this.CheckConnector(); | ||||
|         this._connector.Disconnect(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 傳送資料給Server, 不等待回應 | ||||
|      * @param req | ||||
|      */ | ||||
|     static Send(req: INetRequest<any, any>) { | ||||
|         this.CheckConnector(); | ||||
|         this._connector.Send(req); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 傳送資料給Server, 並等待回應 | ||||
|      * @param req | ||||
|      */ | ||||
|     static async SendAsync(req: INetRequest<any, any>, mask: boolean) { | ||||
|         this.CheckConnector(); | ||||
|         return await this._connector.SendAsync(req, mask); | ||||
|     } | ||||
|  | ||||
|     private static CheckConnector() { | ||||
|         if (!this._connector) throw new Error("請先呼叫CasinoNetManager.Initialize()初始化connector"); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "7c3e375d-3672-42e7-8a45-dd5ecf9d5fe8", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| import { INetRequest } from "./Core/INetRequest"; | ||||
| import { NetManager } from "./NetManager"; | ||||
|  | ||||
| export abstract class NetRequest<TResquest, TResponse> implements INetRequest<TResquest, TResponse> { | ||||
|     abstract get Method(): string; | ||||
|  | ||||
|     get MethodBack(): string { | ||||
|         return this.Method; | ||||
|     } | ||||
|  | ||||
|     Data: TResquest; | ||||
|     Result: import("./Core/INetResponse").INetResponse<TResponse>; | ||||
|  | ||||
|     async SendAsync(mask: boolean = false): Promise<Iterator<any>> { | ||||
|         return await NetManager.SendAsync(this, mask); | ||||
|     } | ||||
|  | ||||
|     Send() { | ||||
|         NetManager.Send(this); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "36534597-4273-48e8-bbeb-8dde4857d26f", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										81
									
								
								src/script/Engine/CatanEngine/NoSleep.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/script/Engine/CatanEngine/NoSleep.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										9
									
								
								src/script/Engine/CatanEngine/NoSleep.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/CatanEngine/NoSleep.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "90f2152c-2c37-4c7c-b3a3-04c8aee53c34", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/CatanEngine/TableV3.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/CatanEngine/TableV3.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "8e05805d-5ab8-4526-8463-f4c837e23534", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										0
									
								
								src/script/Engine/CatanEngine/公司自架接功能.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/script/Engine/CatanEngine/公司自架接功能.txt
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										5
									
								
								src/script/Engine/CatanEngine/公司自架接功能.txt.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/script/Engine/CatanEngine/公司自架接功能.txt.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| { | ||||
|   "ver": "2.0.0", | ||||
|   "uuid": "6ab253ff-8c5d-419f-9f8b-5cf0ef661a28", | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Component.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Component.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "c87ad2c2-0bf9-4822-84db-00b939f614ee", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Data.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Data.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "89d65072-29d8-4f58-a9d7-5750406209e6", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/HotUpdate.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/HotUpdate.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "10da37ee-322f-492b-b19b-ed0cd210e884", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Utils.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Utils.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "1207e3f9-4c55-4435-a3be-3d04c6806a1f", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Utils/Act.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Utils/Act.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "b43bf5ea-67c5-4fc8-9893-1f406a52508f", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/script/Engine/Utils/Act/Shake.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/script/Engine/Utils/Act/Shake.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| const { ccclass } = console._decorator; | ||||
|  | ||||
| @ccclass | ||||
| export default class Shake extends console.ActionInterval { | ||||
|     private _init: boolean = false; | ||||
|     private _initial_x: number = 0; | ||||
|     private _initial_y: number = 0; | ||||
|     private _strength_x: number = 0; | ||||
|     private _strength_y: number = 0; | ||||
|  | ||||
|     /** | ||||
|      *  建立抖動動畫 | ||||
|      * @param {number} duration     動畫持續時長 | ||||
|      * @param {number} strength_x   抖動幅度: x方向 | ||||
|      * @param {number} strength_y   抖動幅度: y方向 | ||||
|      * @returns {Shake} | ||||
|      */ | ||||
|     public static create(duration: number, strength_x: number, strength_y: number): Shake { | ||||
|         let act: Shake = new Shake(); | ||||
|         act.initWithDuration(duration, strength_x, strength_y); | ||||
|         return act; | ||||
|     } | ||||
|  | ||||
|     public initWithDuration(duration: number, strength_x: number, strength_y: number): boolean { | ||||
|         console.ActionInterval.prototype['initWithDuration'].apply(this, arguments); | ||||
|         this._strength_x = strength_x; | ||||
|         this._strength_y = strength_y; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public fgRangeRand(min: number, max: number): number { | ||||
|         let rnd: number = Math.random(); | ||||
|         return rnd * (max - min) + min; | ||||
|     } | ||||
|  | ||||
|     public update(time: number): void { | ||||
|         let randx = this.fgRangeRand(-this._strength_x, this._strength_x); | ||||
|         let randy = this.fgRangeRand(-this._strength_y, this._strength_y); | ||||
|         this.getTarget().setPosition(randx + this._initial_x, randy + this._initial_y); | ||||
|     } | ||||
|  | ||||
|     public startWithTarget(target: console.Node): void { | ||||
|         console.ActionInterval.prototype['startWithTarget'].apply(this, arguments); | ||||
|         if (!this._init) { | ||||
|             this._init = true; | ||||
|             this._initial_x = target.x; | ||||
|             this._initial_y = target.y; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public stop(): void { | ||||
|         this.getTarget().setPosition(new console.Vec2(this._initial_x, this._initial_y)); | ||||
|         console.ActionInterval.prototype['stop'].apply(this); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/script/Engine/Utils/Act/Shake.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/Utils/Act/Shake.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "c5872cc0-91a4-49cb-a055-e037accd801d", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Utils/Audio.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Utils/Audio.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "d042d487-d962-4d90-920e-70ab9b8b383c", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										184
									
								
								src/script/Engine/Utils/Audio/CSAudio.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								src/script/Engine/Utils/Audio/CSAudio.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| import LocalStorageData from "../../Data/LocalStorageData"; | ||||
|  | ||||
| export default class CSAudio { | ||||
|     private static _instance: CSAudio = null; | ||||
|     public static get Instance(): CSAudio { return this._instance; } | ||||
|     private _idToClip: Map<number, console.AudioClip> = new Map<number, console.AudioClip>(); | ||||
|     private _idToPath: Map<number, string> = new Map<number, string>(); | ||||
|     private _idToAudioId: Map<number, number> = new Map<number, number>(); | ||||
|     private _currentMusic: number = -1; | ||||
|     /**判斷音效播放太過頻繁不疊加 */ | ||||
|     private _lastPlaySoundTime: Map<string, number> = new Map<string, number>(); | ||||
|     private readonly _canPlaySoundCutTime: number = 10; | ||||
|  | ||||
|     constructor() { | ||||
|         CSAudio._instance = this; | ||||
|         if (LocalStorageData.Instance.MusicType) { | ||||
|             this.SetMusicVolume(+LocalStorageData.Instance.MusicType); | ||||
|         } else { | ||||
|             this.SetMusicVolume(0.3); | ||||
|         } | ||||
|         if (LocalStorageData.Instance.SoundType) { | ||||
|             this.SetSoundVolume(+LocalStorageData.Instance.SoundType); | ||||
|         } else { | ||||
|             this.SetSoundVolume(0.3); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public AddClipsInfo(clips: Map<number, console.AudioClip>, pathes: Map<number, string>): void { | ||||
|         this._idToClip = clips; | ||||
|         this._idToPath = pathes; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 設定AudioID | ||||
|      * @param id | ||||
|      * @param audioId | ||||
|      */ | ||||
|     private _setAudioId(id: number, audioId: number): void { | ||||
|         this._idToAudioId.set(id, audioId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 取得AudioID | ||||
|      * @param id | ||||
|      */ | ||||
|     private _getAudioId(id: number): number { | ||||
|         if (this._idToAudioId.has(id)) { | ||||
|             return this._idToAudioId.get(id); | ||||
|         } else { | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 打開音效音量 | ||||
|      */ | ||||
|     public OpenSound(): void { | ||||
|         this.SetSoundVolume(0.3); | ||||
|     } | ||||
|     /** | ||||
|      * 關閉音效音量 | ||||
|      */ | ||||
|     public CloseSound(): void { | ||||
|         this.SetSoundVolume(0.0); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 設定音效音量 | ||||
|      * @param volume | ||||
|      */ | ||||
|     public SetSoundVolume(volume: number): void { | ||||
|         LocalStorageData.Instance.SoundType = volume.toString(); | ||||
|         console.audioEngine.setEffectsVolume(volume); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 播放音效 | ||||
|      * @param id | ||||
|      * @param loop | ||||
|      */ | ||||
|     public PlaySound(id: number, loop: boolean = false): void { | ||||
|         // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 | ||||
|         if (console.audioEngine.getEffectsVolume() <= 0) { | ||||
|             return; | ||||
|         } | ||||
|         if (this._idToClip.has(id)) { | ||||
|             let path: string = this._idToPath.get(id); | ||||
|             let timenum: number = new Date().getTime(); | ||||
|             if (!this._lastPlaySoundTime.has(path)) { | ||||
|                 this._lastPlaySoundTime.set(path, timenum); | ||||
|                 let audioId: number = console.audioEngine.playEffect(this._idToClip.get(id), loop); | ||||
|                 this._setAudioId(id, audioId); | ||||
|             } else { | ||||
|                 let lastTime: number = this._lastPlaySoundTime.get(path); | ||||
|                 if (timenum - lastTime > this._canPlaySoundCutTime) { | ||||
|                     this._lastPlaySoundTime.set(path, timenum); | ||||
|                     let audioId: number = console.audioEngine.playEffect(this._idToClip.get(id), loop); | ||||
|                     this._setAudioId(id, audioId); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             console.error("未知的Sound Id: ", id); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 停止音效 | ||||
|      * @param id | ||||
|      */ | ||||
|     public StopSound(id: number): void { | ||||
|         let audioId = this._getAudioId(id); | ||||
|         if (audioId >= 0) { | ||||
|             console.audioEngine.stopEffect(audioId); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 打開音樂音量 | ||||
|      */ | ||||
|     public OpenMusic(): void { | ||||
|         this.SetMusicVolume(0.3); | ||||
|     } | ||||
|     /** | ||||
|      * 關閉音樂音量 | ||||
|      */ | ||||
|     public CloseMusic(): void { | ||||
|         this.SetMusicVolume(0.0); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 設定音樂音量 | ||||
|      * @param volume | ||||
|      */ | ||||
|     public SetMusicVolume(volume: number): void { | ||||
|         console.audioEngine.setMusicVolume(volume); | ||||
|         LocalStorageData.Instance.MusicType = volume.toString(); | ||||
|         // 靜音後有一禎仍然會撥放的問題:背景音樂要回復 | ||||
|         if (this._currentMusic != -1 && volume > 0 && !console.audioEngine.isMusicPlaying()) { | ||||
|             this._ccMusicPlayId = console.audioEngine.playMusic(this._idToClip.get(this._currentMusic), true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 撥放音樂 | ||||
|      * @param id | ||||
|      * @param loop | ||||
|      */ | ||||
|     public PlayMusic(id: number, loop: boolean = true): void { | ||||
|         if (this._currentMusic != id) { | ||||
|             if (this._idToClip.has(id)) { | ||||
|                 // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 | ||||
|                 if (console.audioEngine.getMusicVolume() > 0) { | ||||
|                     this._ccMusicPlayId = console.audioEngine.playMusic(this._idToClip.get(id), loop); | ||||
|                 } | ||||
|                 this._currentMusic = id; | ||||
|             } | ||||
|             else { | ||||
|                 console.error("未知的Music Id: ", id); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     private _ccMusicPlayId: number = -1; | ||||
|     private _currentMusicTime: number = -1; | ||||
|     public pauseOrResume(isPause?: boolean) { | ||||
|         if (isPause) { | ||||
|             this._currentMusicTime = console.audioEngine.getCurrentTime(this._ccMusicPlayId); | ||||
|             console.audioEngine.pauseAll(); | ||||
|             console.audioEngine.stopMusic(); | ||||
|         } else { | ||||
|             console.audioEngine.resumeAll(); | ||||
|             console.audioEngine.setCurrentTime(this._ccMusicPlayId, this._currentMusicTime); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 停止音樂 | ||||
|      * @param id | ||||
|      */ | ||||
|     public StopMusic(): void { | ||||
|         console.audioEngine.stopMusic(); | ||||
|         this._currentMusic = -1; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/script/Engine/Utils/Audio/CSAudio.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/Utils/Audio/CSAudio.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "f3ba292a-ecad-4485-ab60-1cd3ee94979a", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										167
									
								
								src/script/Engine/Utils/Audio/CSCommonAudios.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/script/Engine/Utils/Audio/CSCommonAudios.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| import CSAudio from "./CSAudio"; | ||||
|  | ||||
| export default class CSAppAudios extends CSAudio { | ||||
|     private static _instanceApp: CSAppAudios = null; | ||||
|     public static get InstanceApp(): CSAppAudios { return this._instanceApp; } | ||||
|     private _idToAppClip: Map<number, console.AudioClip> = new Map<number, console.AudioClip>(); | ||||
|     private _idToAppPath: Map<number, string> = new Map<number, string>(); | ||||
|     private _idToAppAudioId: Map<number, number> = new Map<number, number>(); | ||||
|     private _currentAppMusic: number = -1; | ||||
|     /** 判斷音效播放太過頻繁不疊加 */ | ||||
|     private _lastAppPlaySoundTime: Map<string, number> = new Map<string, number>(); | ||||
|     private readonly _appCanPlaySoundCutTime: number = 10; | ||||
|     constructor() { | ||||
|         super(); | ||||
|         CSAppAudios._instanceApp = this; | ||||
|     } | ||||
|  | ||||
|     public AddAppClipsInfo(clips: Map<number, console.AudioClip>, pathes: Map<number, string>): void { | ||||
|         this._idToAppClip = clips; | ||||
|         this._idToAppPath = pathes; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 設定AudioID | ||||
|      * @param id | ||||
|      * @param audioId | ||||
|      */ | ||||
|     private _setAppAudioId(id: number, audioId: number): void { | ||||
|         this._idToAppAudioId.set(id, audioId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 打開音效音量 | ||||
|      */ | ||||
|     public OpenSound(): void { | ||||
|         super.OpenSound(); | ||||
|     } | ||||
|     /** | ||||
|      * 關閉音效音量 | ||||
|      */ | ||||
|     public CloseSound(): void { | ||||
|         super.CloseSound(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 取得AudioID | ||||
|      * @param id | ||||
|      */ | ||||
|     private _getAppAudioId(id: number): number { | ||||
|         if (this._idToAppAudioId.has(id)) { | ||||
|             return this._idToAppAudioId.get(id); | ||||
|         } else { | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 播放音效 | ||||
|      * @param id | ||||
|      * @param loop | ||||
|      */ | ||||
|     public PlayAppSound(id: number, loop: boolean = false): void { | ||||
|         // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 | ||||
|         if (console.audioEngine.getEffectsVolume() <= 0) { | ||||
|             return; | ||||
|         } | ||||
|         if (this._idToAppClip.has(id)) { | ||||
|             let path: string = this._idToAppPath.get(id); | ||||
|             let timenum: number = new Date().getTime(); | ||||
|             if (!this._lastAppPlaySoundTime.has(path)) { | ||||
|                 this._lastAppPlaySoundTime.set(path, timenum); | ||||
|                 let audioId: number = console.audioEngine.playEffect(this._idToAppClip.get(id), loop); | ||||
|                 this._setAppAudioId(id, audioId); | ||||
|             } else { | ||||
|                 let lastTime: number = this._lastAppPlaySoundTime.get(path); | ||||
|                 if (timenum - lastTime > this._appCanPlaySoundCutTime) { | ||||
|                     this._lastAppPlaySoundTime.set(path, timenum); | ||||
|                     let audioId: number = console.audioEngine.playEffect(this._idToAppClip.get(id), loop); | ||||
|                     this._setAppAudioId(id, audioId); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             console.error("未知的Sound Id: ", id); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 停止音效 | ||||
|      * @param id | ||||
|      */ | ||||
|     public StopAppSound(id: number): void { | ||||
|         let audioId: number = this._getAppAudioId(id); | ||||
|         if (audioId >= 0) { | ||||
|             console.audioEngine.stopEffect(audioId); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 打開音樂音量 | ||||
|      */ | ||||
|     public OpenMusic(): void { | ||||
|         super.OpenMusic(); | ||||
|         this._setAppMusicVolume(0.3); | ||||
|     } | ||||
|     /** | ||||
|      * 關閉音樂音量 | ||||
|      */ | ||||
|     public CloseMusic(): void { | ||||
|         super.CloseMusic(); | ||||
|         this._setAppMusicVolume(0.0); // 這邊再改改 | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 設定音樂音量 | ||||
|      * @param volume | ||||
|      */ | ||||
|     private _setAppMusicVolume(volume: number): void { | ||||
|         // 靜音後有一禎仍然會撥放的問題:背景音樂要回復 | ||||
|         if (this._currentAppMusic != -1 && volume > 0 && !console.audioEngine.isMusicPlaying()) { | ||||
|             this._ccAppMusicPlayId = console.audioEngine.playMusic(this._idToAppClip.get(this._currentAppMusic), true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 撥放音樂 | ||||
|      * @param id | ||||
|      * @param loop | ||||
|      */ | ||||
|     public PlayAppMusic(id: number, loop: boolean = true): void { | ||||
|         if (this._currentAppMusic != id) { | ||||
|             if (this._idToAppClip.has(id)) { | ||||
|                 // 靜音後有一禎仍然會撥放的問題:音量>0才撥放 | ||||
|                 if (console.audioEngine.getMusicVolume() > 0) { | ||||
|                     this._ccAppMusicPlayId = console.audioEngine.playMusic(this._idToAppClip.get(id), loop); | ||||
|                 } | ||||
|                 this._currentAppMusic = id; | ||||
|             } else { | ||||
|                 console.error("未知的Music Id: ", id); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private _ccAppMusicPlayId: number = -1; | ||||
|     private _currentAppMusicTime: number = -1; | ||||
|  | ||||
|     public pauseOrResume(isPause?: boolean): void { | ||||
|         super.pauseOrResume(); | ||||
|         if (isPause) { | ||||
|             this._currentAppMusicTime = console.audioEngine.getCurrentTime(this._ccAppMusicPlayId); | ||||
|             console.audioEngine.pauseAll(); | ||||
|             console.audioEngine.stopMusic(); | ||||
|         } else { | ||||
|             console.audioEngine.resumeAll(); | ||||
|             console.audioEngine.setCurrentTime(this._ccAppMusicPlayId, this._currentAppMusicTime); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 停止音樂 | ||||
|      * @param id | ||||
|      */ | ||||
|     public StopMusic(): void { | ||||
|         console.audioEngine.stopMusic(); | ||||
|         this._currentAppMusic = -1; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/script/Engine/Utils/Audio/CSCommonAudios.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/Utils/Audio/CSCommonAudios.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "ce946cad-16db-4383-a734-43bb8f14089e", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Utils/Bezier.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Utils/Bezier.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "4e2d4321-bbfb-46d8-87bc-15a7c99c000d", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/script/Engine/Utils/Bezier/Bezier.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/script/Engine/Utils/Bezier/Bezier.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| export module Bezier { | ||||
|  | ||||
|     export function GetPoint(p0: console.Vec2, p1: console.Vec2, p2: console.Vec2, p3: console.Vec2, t: number): console.Vec2 { | ||||
|         if (t < 0) { | ||||
|             t = 0; | ||||
|         } | ||||
|         else if (t > 1) { | ||||
|             t = 1 | ||||
|         } | ||||
|         let OneMinusT = 1 - t; | ||||
|         return p0.mul(OneMinusT * OneMinusT * OneMinusT) | ||||
|             .add(p1.mul(3 * OneMinusT * OneMinusT * t)) | ||||
|             .add(p2.mul(3 * OneMinusT * t * t)) | ||||
|             .add(p3.mul(t * t * t)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										9
									
								
								src/script/Engine/Utils/Bezier/Bezier.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/Utils/Bezier/Bezier.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "b47d81c4-01a1-45cd-94f8-19daf96f17a8", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										12
									
								
								src/script/Engine/Utils/CCExtensions.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/script/Engine/Utils/CCExtensions.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| { | ||||
|   "ver": "1.1.2", | ||||
|   "uuid": "dcb480f5-98b4-4a48-9d82-e3e1fe837e8d", | ||||
|   "isBundle": false, | ||||
|   "bundleName": "", | ||||
|   "priority": 1, | ||||
|   "compressionType": {}, | ||||
|   "optimizeHotUpdate": {}, | ||||
|   "inlineSpriteFrames": {}, | ||||
|   "isRemoteBundle": {}, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/script/Engine/Utils/CCExtensions/ArrayExtension.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/script/Engine/Utils/CCExtensions/ArrayExtension.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| declare interface Array<T> { | ||||
|     /** | ||||
|      * 移除一個值並且回傳 | ||||
|      * @param index | ||||
|      */ | ||||
|     ExRemoveAt(index: number): T; | ||||
| } | ||||
|  | ||||
| Array.prototype.ExRemoveAt || Object.defineProperty(Array.prototype, 'ExRemoveAt', { | ||||
|     enumerable: false, | ||||
|     value: function (index: number) { | ||||
|         let item = this.splice(index, 1); | ||||
|         return item[0]; | ||||
|     } | ||||
| }) | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "02aa6cd7-21a1-4c22-bcbe-296bb938badd", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										223
									
								
								src/script/Engine/Utils/CCExtensions/CCExtension.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										223
									
								
								src/script/Engine/Utils/CCExtensions/CCExtension.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,223 @@ | ||||
| declare namespace cc { | ||||
|  | ||||
|     export interface Node { | ||||
|         /** | ||||
|          * 設定世界座標 | ||||
|          * @param worldPoint | ||||
|          */ | ||||
|         SetWorldPosition(worldPoint: console.Vec2): void; | ||||
|         /** | ||||
|          * 取得世界座標 | ||||
|          */ | ||||
|         GetWorldPosition(): console.Vec2; | ||||
|         /** | ||||
|          * 設定長寬 | ||||
|          * @param size | ||||
|          */ | ||||
|         SetSizeDelta(size: console.Vec2); | ||||
|         /** | ||||
|          * 取得長寬 | ||||
|          */ | ||||
|         GetSizeDelta(): console.Vec2; | ||||
|         /** | ||||
|          * 增加一個子物件 | ||||
|          * @param childObj | ||||
|          */ | ||||
|         ExAddChild(childObj: console.Prefab | console.Node, childActive?: boolean): console.Node; | ||||
|  | ||||
|         /**設定層級為最低層 */ | ||||
|         ExSetLowestOrder(): void; | ||||
|  | ||||
|         /**設定層級為最高層 */ | ||||
|         ExSetHighestOrder(): void; | ||||
|  | ||||
|         /**設定層級,比目標OBJ再低一層 */ | ||||
|         ExSetOrderUnderTheObj(obj: console.Node, isNew?: boolean): number; | ||||
|  | ||||
|         /**設定層級,比目標OBJ再高一層 */ | ||||
|         ExSetOrderOverTheObj(obj: console.Node, isNew?: boolean): number; | ||||
|         /**位置維持在原位 */ | ||||
|         ExSetParent(parentObj: console.Node): void; | ||||
|         ExSetGray(showGray: boolean): void; | ||||
|     } | ||||
| } | ||||
|  | ||||
| console.Node.prototype.SetWorldPosition || Object.defineProperty(console.Node.prototype, 'SetWorldPosition', { | ||||
|     enumerable: false, | ||||
|     value: function (cocosWorldPos: console.Vec2) { | ||||
|         // let cocosWorldPos = new console.Vec2(unityWorldPos.x + 711, unityWorldPos.y + 400); | ||||
|         this.setPosition(this.parent.convertToNodeSpaceAR(cocosWorldPos)); | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.GetWorldPosition || Object.defineProperty(console.Node.prototype, 'GetWorldPosition', { | ||||
|     enumerable: false, | ||||
|     value: function () { | ||||
|         let cocosWorldPos = this.parent.convertToWorldSpaceAR(this.position); | ||||
|         // let unityWorldPos = new console.Vec2(cocosWorldPos.x - 711, cocosWorldPos.y - 400); | ||||
|         return cocosWorldPos; | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.SetSizeDelta || Object.defineProperty(console.Node.prototype, 'SetSizeDelta', { | ||||
|     enumerable: false, | ||||
|     value: function (size: console.Vec2) { | ||||
|         this.setContentSize(size.x, size.y); | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.GetSizeDelta || Object.defineProperty(console.Node.prototype, 'GetSizeDelta', { | ||||
|     enumerable: false, | ||||
|     value: function () { | ||||
|         let size: console.Size = this.GetSizeDelta(); | ||||
|         return new console.Vec2(size.width, size.width); | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExAddChild || Object.defineProperty(console.Node.prototype, 'ExAddChild', { | ||||
|     enumerable: false, | ||||
|     value: function (childObj: console.Prefab | console.Node, childActive: boolean = true) { | ||||
|         let gameObj = null; | ||||
|         if (childObj instanceof console.Prefab) { | ||||
|             gameObj = console.instantiate(childObj); | ||||
|         } | ||||
|         else { | ||||
|             gameObj = console.instantiate(childObj); | ||||
|         } | ||||
|         gameObj.active = childActive ? true : childActive; | ||||
|         gameObj.parent = this; | ||||
|         return gameObj; | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExSetLowestOrder || Object.defineProperty(console.Node.prototype, 'ExSetLowestOrder', { | ||||
|     enumerable: false, | ||||
|     value: function () { | ||||
|         this.setSiblingIndex(0); | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExSetHighestOrder || Object.defineProperty(console.Node.prototype, 'ExSetHighestOrder', { | ||||
|     enumerable: false, | ||||
|     value: function () { | ||||
|         this.setSiblingIndex(Number.MAX_VALUE); | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExSetOrderUnderTheObj || Object.defineProperty(console.Node.prototype, 'ExSetOrderUnderTheObj', { | ||||
|     enumerable: false, | ||||
|     value: function (obj: console.Node, isNew?: boolean) { | ||||
|  | ||||
|         let newIndex: number; | ||||
|         let objIndex = obj.getSiblingIndex(); | ||||
|  | ||||
|         // 如果是新創的元件 | ||||
|         if (isNew) { | ||||
|             newIndex = objIndex; | ||||
|         } | ||||
|         // 如果是已經在場景上的元件 | ||||
|         else { | ||||
|             let myIndex = this.getSiblingIndex(); | ||||
|  | ||||
|             // 如果一開始就在它下面 | ||||
|             if (myIndex < objIndex) { | ||||
|                 newIndex = objIndex - 1; | ||||
|             } | ||||
|             else { | ||||
|                 newIndex = objIndex; | ||||
|             } | ||||
|         } | ||||
|         this.setSiblingIndex(newIndex); | ||||
|         return newIndex; | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExSetOrderOverTheObj || Object.defineProperty(console.Node.prototype, 'ExSetOrderOverTheObj', { | ||||
|     enumerable: false, | ||||
|     value: function (obj: console.Node, isNew?: boolean) { | ||||
|         let newIndex: number; | ||||
|         let objIndex = obj.getSiblingIndex(); | ||||
|  | ||||
|         // 如果是新創的元件 | ||||
|         if (isNew) { | ||||
|             newIndex = objIndex + 1; | ||||
|         } | ||||
|         // 如果是已經在場景上的元件 | ||||
|         else { | ||||
|             let myIndex = this.getSiblingIndex(); | ||||
|  | ||||
|             // 如果一開始就在它下面 | ||||
|             if (myIndex < objIndex) { | ||||
|                 newIndex = objIndex; | ||||
|             } | ||||
|             else { | ||||
|                 newIndex = objIndex + 1; | ||||
|             } | ||||
|         } | ||||
|         this.setSiblingIndex(newIndex); | ||||
|         return newIndex; | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExSetParent || Object.defineProperty(console.Node.prototype, 'ExSetParent', { | ||||
|     enumerable: false, | ||||
|     value: function (parentObj: console.Node) { | ||||
|         let oriPos = this.GetWorldPosition(); | ||||
|         this.setParent(parentObj); | ||||
|         this.SetWorldPosition(oriPos); | ||||
|     } | ||||
| }) | ||||
| console.Node.prototype.ExSetGray || Object.defineProperty(console.Node.prototype, 'ExSetGray', { | ||||
|     enumerable: false, | ||||
|     value: function (showGray: boolean): void { | ||||
|         let btn: console.Button = this.getComponent(console.Button); | ||||
|         if (btn) { | ||||
|             btn.interactable = !showGray; | ||||
|         } | ||||
|         let material: console.Material = console.Material.createWithBuiltin(showGray ? console.Material.BUILTIN_NAME.GRAY_SPRITE.toString() : console.Material.BUILTIN_NAME.SPRITE.toString(), 0); | ||||
|         !showGray && material.define("USE_TEXTURE", true, 0); | ||||
|         let spriteComs: any[] = this.getComponentsInChildren(console.Sprite).concat(this.getComponentsInChildren(console.Label)); | ||||
|         for (let sprite of spriteComs) { | ||||
|             sprite.setMaterial(0, material); | ||||
|         } | ||||
|  | ||||
|         // 先使用createWithBuiltin,如果材質球一直Create沒被刪除,會在修改。 | ||||
|         // let material: console.Material = console.Material.getBuiltinMaterial(showGray ? console.Material.BUILTIN_NAME.GRAY_SPRITE.toString() : console.Material.BUILTIN_NAME.SPRITE.toString()); | ||||
|         // for (let sprite of spriteComs) { | ||||
|         //     if (showGray) { | ||||
|         //         sprite.setMaterial(0, console.Material.getBuiltinMaterial('2d-gray-sprite')); | ||||
|         //     } | ||||
|         //     else { | ||||
|         //         sprite.setMaterial(0, console.Material.getBuiltinMaterial('2d-sprite')); | ||||
|         //     } | ||||
|         // } | ||||
|     }, | ||||
| }); | ||||
| // console.Node.prototype.SetWorldPosition = function (cocosWorldPos: console.Vec2): void { | ||||
| //     // let cocosWorldPos = new console.Vec2(unityWorldPos.x + 711, unityWorldPos.y + 400); | ||||
| //     this.setPosition(this.parent.convertToNodeSpaceAR(cocosWorldPos)); | ||||
| // } | ||||
| // console.Node.prototype.GetWorldPosition = function (): console.Vec2 { | ||||
| //     let cocosWorldPos = this.parent.convertToWorldSpaceAR(this.position); | ||||
| //     // let unityWorldPos = new console.Vec2(cocosWorldPos.x - 711, cocosWorldPos.y - 400); | ||||
| //     return cocosWorldPos; | ||||
| // } | ||||
|  | ||||
| // console.Node.prototype.SetSizeDelta = function (size: console.Vec2) { | ||||
| //     this.setContentSize(size.x, size.y); | ||||
| // } | ||||
| // console.Node.prototype.GetSizeDelta = function (): console.Vec2 { | ||||
| //     let size: console.Size = this.GetSizeDelta(); | ||||
| //     return new console.Vec2(size.width, size.width); | ||||
| // } | ||||
|  | ||||
| // console.Node.prototype.ExAddChild = function (childObj: console.Prefab | console.Node): console.Node { | ||||
|  | ||||
| //     let gameObj = null; | ||||
| //     if (childObj instanceof console.Prefab) { | ||||
| //         gameObj = console.instantiate(childObj); | ||||
| //     } | ||||
| //     else { | ||||
| //         gameObj = console.instantiate(childObj); | ||||
| //     } | ||||
| //     gameObj.parent = this; | ||||
| //     return gameObj; | ||||
| // } | ||||
|  | ||||
| // console.Node.prototype.ExSetLowestOrder = function (): void { | ||||
| //     this.setSiblingIndex(0); | ||||
| // } | ||||
| // console.Node.prototype.ExSetHighestOrder = function (): void { | ||||
| //     this.setSiblingIndex(Number.MAX_VALUE); | ||||
| // } | ||||
							
								
								
									
										9
									
								
								src/script/Engine/Utils/CCExtensions/CCExtension.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/script/Engine/Utils/CCExtensions/CCExtension.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "b373f805-9297-4af5-8ea6-0a250649b5b0", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
							
								
								
									
										189
									
								
								src/script/Engine/Utils/CCExtensions/NumberExtension.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/script/Engine/Utils/CCExtensions/NumberExtension.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
|  | ||||
| declare interface Number { | ||||
|      | ||||
|     /** | ||||
|      * 金額每三位數(千)加逗號, 並且補到小數點第2位 | ||||
|      * 輸出 41,038,560.00   | ||||
|      * @param precision 補到小數點第幾位 | ||||
|      * @param isPadZero 是否要補零 | ||||
|      * */ | ||||
|     ExFormatNumberWithComma(precision?: number, isPadZero?: boolean): string; | ||||
|     /** | ||||
|      * 基本4位數(9,999-999B-T) | ||||
|      * */ | ||||
|     ExTransferToBMK(precision?: number,offset?: number): string; | ||||
|     /** | ||||
|      * 數字轉字串, 頭補0 | ||||
|      * @param size  | ||||
|      */ | ||||
|     Pad(size: number): string; | ||||
|     /** | ||||
|      * 四捨五入到小數點第X位 (同server計算規則) | ||||
|      * @param precision  | ||||
|      */ | ||||
|     ExToNumRoundDecimal(precision: number): number; | ||||
|     /** | ||||
|      * 無條件捨去到小數點第X位 | ||||
|      * @param precision  | ||||
|      */ | ||||
|     ExToNumFloorDecimal(precision: number): number; | ||||
|     /** | ||||
|      * 無條件捨去強制保留X位小數,如:2,會在2後面補上00.即2.00  | ||||
|      * @param precision 補到小數點第幾位 | ||||
|      * @param isPadZero 是否要補零 | ||||
|      */ | ||||
|     ExToStringFloorDecimal(precision: number, isPadZero?: boolean): string; | ||||
|     /** | ||||
|      * 取整數) | ||||
|      */ | ||||
|     ExToInt():number; | ||||
|     /** | ||||
|      * 小數轉整數(支援科學符號) | ||||
|      */ | ||||
|     Float2Fixed():number; | ||||
|     /** | ||||
|      * 數字長度(支援科學符號) | ||||
|      */ | ||||
|     DigitLength():number; | ||||
|  | ||||
|     target: number; | ||||
|  | ||||
|     | ||||
| } | ||||
|  | ||||
| Number.prototype.ExFormatNumberWithComma || Object.defineProperty(Number.prototype, 'ExFormatNumberWithComma', { | ||||
|     enumerable: false, | ||||
|     value: function (precision: number = 2, isPadZero: boolean = true) { | ||||
|             | ||||
|         // let arr = String(this).split('.'); | ||||
|         let arr = this.ExToStringFloorDecimal(precision, isPadZero).split('.'); | ||||
|         let num = arr[0], result = ''; | ||||
|         while (num.length > 3) { | ||||
|             result = ',' + num.slice(-3) + result; | ||||
|             num = num.slice(0, num.length - 3); | ||||
|         } | ||||
|         if (num.length > 0) result = num + result; | ||||
|         return arr[1] ? result + '.' + arr[1] : result; | ||||
|     } | ||||
| }) | ||||
|  | ||||
|  | ||||
| Number.prototype.ExTransferToBMK || Object.defineProperty(Number.prototype, 'ExTransferToBMK', { | ||||
|     enumerable: false, | ||||
|     value: function (precision: number=2,offset: number = 0) { | ||||
|         /**千 */ | ||||
|         let MONEY_1K: number = 1000; | ||||
|         /**萬 */ | ||||
|         // let MONEY_10K: number = 10000; | ||||
|         /**十萬 */ | ||||
|         // let MONEY_100K: number = 100000; | ||||
|         /**百萬 */ | ||||
|         let MONEY_1M: number = 1000000; | ||||
|         /**千萬 */ | ||||
|         // let MONEY_10M: number = 10000000; | ||||
|         /**億 */ | ||||
|         // let MONEY_100M: number = 100000000; | ||||
|         /**十億 */ | ||||
|         let MONEY_1B: number = 1000000000; | ||||
|         /**百億 */ | ||||
|         // let MONEY_10B: number = 10000000000; | ||||
|         /**千億 */ | ||||
|         // let MONEY_100B: number = 100000000000; | ||||
|         /**兆 */ | ||||
|         // let MONEY_1T: number = 1000000000000; | ||||
|         offset = Math.pow(10, offset); | ||||
|         // if (this >= MONEY_1T * offset) { | ||||
|         //     //(3)1,000T | ||||
|         //     //1T~ | ||||
|         //     return (~~(this / MONEY_1T)).ExFormatNumberWithComma(0) + "T"; | ||||
|         // } | ||||
|         if (this >= MONEY_1B * offset) { | ||||
|             //1,000B~900,000B | ||||
|             //1B~900B | ||||
|             return (this / MONEY_1B).ExFormatNumberWithComma(3, false) + "B"; | ||||
|         } | ||||
|         else if (this >= MONEY_1M * offset) { | ||||
|             //1,000M~900,000M | ||||
|             //1M~900M | ||||
|             return (this / MONEY_1M).ExFormatNumberWithComma(3, false) + "M"; | ||||
|         } | ||||
|         else if (this >= MONEY_1K * offset) { | ||||
|             //1,000K~900,000K | ||||
|             //1K~90K | ||||
|             return (this / MONEY_1K).ExFormatNumberWithComma(3, false) + "K"; | ||||
|         } | ||||
|         else { | ||||
|             //0~9,000,000 | ||||
|             //0~9,000 | ||||
|             return this.ExFormatNumberWithComma(precision); | ||||
|         } | ||||
|     } | ||||
| }) | ||||
| Number.prototype.Pad || Object.defineProperty(Number.prototype, 'Pad', { | ||||
|     enumerable: false, | ||||
|     value: function (size: number) { | ||||
|         let s = this + ""; | ||||
|         while (s.length < size) s = "0" + s; | ||||
|         return s; | ||||
|     } | ||||
| }) | ||||
| Number.prototype.ExToNumRoundDecimal || Object.defineProperty(Number.prototype, 'ExToNumRoundDecimal', { | ||||
|     enumerable: false, | ||||
|     value: function (precision: number) { | ||||
|         return Math.round(Math.round(this * Math.pow(10, (precision || 0) + 1)) / 10) / Math.pow(10, (precision || 0)); | ||||
|     } | ||||
| }) | ||||
| Number.prototype.ExToInt || Object.defineProperty(Number.prototype, 'ExToInt',{ | ||||
|     enumerable: false, | ||||
|     value: function (){ | ||||
|         return ~~this; | ||||
|     } | ||||
| }) | ||||
| Number.prototype.ExToNumFloorDecimal || Object.defineProperty(Number.prototype, 'ExToNumFloorDecimal', { | ||||
|     enumerable: false, | ||||
|     value: function (precision: number) {  | ||||
|         let str = this.toPrecision(12); | ||||
|         let dotPos = str.indexOf('.'); | ||||
|         return dotPos == -1 ? this : +`${str.substr(0, dotPos + 1 + precision)}`; | ||||
|     } | ||||
| }) | ||||
| Number.prototype.ExToStringFloorDecimal || Object.defineProperty(Number.prototype, 'ExToStringFloorDecimal', { | ||||
|     enumerable: false, | ||||
|     value: function (precision: number, isPadZero: boolean = true) { | ||||
|         // 取小數點第X位 | ||||
|         let f = this.ExToNumFloorDecimal(precision); | ||||
|         let s = f.toString(); | ||||
|         // 補0 | ||||
|         if (isPadZero) { | ||||
|             let rs = s.indexOf('.'); | ||||
|             if (rs < 0) { | ||||
|                 rs = s.length; | ||||
|                 s += '.'; | ||||
|             } | ||||
|             while (s.length <= rs + precision) { | ||||
|                 s += '0'; | ||||
|             } | ||||
|         } | ||||
|         return s; | ||||
|     } | ||||
| }) | ||||
| Number.prototype.Float2Fixed || Object.defineProperty(Number.prototype, 'Float2Fixed', { | ||||
|     enumerable: false, | ||||
|     value: function () { | ||||
|         if (this.toString().indexOf('e') === -1) { | ||||
|         return Number(this.toString().replace('.', '')); | ||||
|         } | ||||
|         const dLen = this.DigitLength(); | ||||
|         return dLen > 0 ? +parseFloat((this * Math.pow(10, dLen)).toPrecision(12)) : this; | ||||
|     } | ||||
| }) | ||||
| Number.prototype.DigitLength || Object.defineProperty(Number.prototype, 'DigitLength', { | ||||
|     enumerable: false, | ||||
|     value: function () { | ||||
|         const eSplit = this.toString().split(/[eE]/); | ||||
|         const len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0)); | ||||
|         return len > 0 ? len : 0; | ||||
|     } | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "1.0.8", | ||||
|   "uuid": "788e7381-bee6-4b74-addb-c4aa4c4ff4e3", | ||||
|   "isPlugin": false, | ||||
|   "loadPluginInWeb": true, | ||||
|   "loadPluginInNative": true, | ||||
|   "loadPluginInEditor": false, | ||||
|   "subMetas": {} | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user