[add] BJ_Casino_Rank贏分
This commit is contained in:
parent
87fa594dd4
commit
844c15072b
13
package-lock.json
generated
13
package-lock.json
generated
@ -18,6 +18,7 @@
|
|||||||
"vue-loading-overlay": "^5.0.3"
|
"vue-loading-overlay": "^5.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^17.0.24",
|
||||||
"@vitejs/plugin-vue": "^2.3.0",
|
"@vitejs/plugin-vue": "^2.3.0",
|
||||||
"typescript": "^4.5.4",
|
"typescript": "^4.5.4",
|
||||||
"vite": "^2.9.0",
|
"vite": "^2.9.0",
|
||||||
@ -157,6 +158,12 @@
|
|||||||
"@types/lodash": "*"
|
"@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": {
|
"node_modules/@vitejs/plugin-vue": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz",
|
||||||
@ -1940,6 +1947,12 @@
|
|||||||
"@types/lodash": "*"
|
"@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": {
|
"@vitejs/plugin-vue": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz",
|
||||||
|
@ -43,6 +43,10 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-tabs__item {
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-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<{ BJ_Casino: BJ_Casino_Data }>()
|
||||||
|
|
||||||
// const props = defineProps({
|
|
||||||
// list: {
|
|
||||||
// type: Array,
|
|
||||||
// default: () => [],
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
|
|
||||||
let Title = ref("");
|
let Title = ref("");
|
||||||
let RankData = ref([]);
|
let RankData = ref([]);
|
||||||
const self = {
|
const self = {
|
||||||
Title: Title,
|
Title: Title,
|
||||||
RankData: RankData,
|
RankData: RankData,
|
||||||
// BJ_Casino: props.list[0].value,
|
|
||||||
BJ_Casino: props.BJ_Casino,
|
BJ_Casino: props.BJ_Casino,
|
||||||
}
|
}
|
||||||
const Script = new BJ_Casino_Magnification(self);
|
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<{ BJ_Casino: BJ_Casino_Data }>()
|
||||||
|
|
||||||
// const props = defineProps({
|
|
||||||
// list: {
|
|
||||||
// type: Array,
|
|
||||||
// default: () => [],
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
|
|
||||||
let Title = ref("");
|
let Title = ref("");
|
||||||
let RankData = ref([]);
|
let RankData = ref([]);
|
||||||
const self = {
|
const self = {
|
||||||
Title: Title,
|
Title: Title,
|
||||||
RankData: RankData,
|
RankData: RankData,
|
||||||
// BJ_Casino: props.list[0].value,
|
|
||||||
BJ_Casino: props.BJ_Casino,
|
BJ_Casino: props.BJ_Casino,
|
||||||
}
|
}
|
||||||
const Script = new BJ_Casino_WinMoney(self);
|
const Script = new BJ_Casino_WinMoney(self);
|
||||||
@ -32,7 +24,7 @@ const Script = new BJ_Casino_WinMoney(self);
|
|||||||
<tr>
|
<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>
|
<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 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 {
|
export class BJ_Casino_Data {
|
||||||
|
|
||||||
@ -14,12 +22,15 @@ export class BJ_Casino_Data {
|
|||||||
|
|
||||||
//#region private
|
//#region private
|
||||||
|
|
||||||
|
private _conn: NetConnector = null!;
|
||||||
private _ws: any;
|
private _ws: any;
|
||||||
|
|
||||||
private _rankMagnificationData: any[] = [];
|
private _rankMagnificationData: any[] = [];
|
||||||
private _rankWinMoneyData: any[] = [];
|
private _rankWinMoneyData: any[] = [];
|
||||||
|
|
||||||
private _nowSearchContestID: number = 0;
|
private _nowSearchMagnificationID: number = 0;
|
||||||
|
|
||||||
|
private _nowSearchWinMoneyID: number = 0;
|
||||||
|
|
||||||
private _nowContestIndex: number = 0;
|
private _nowContestIndex: number = 0;
|
||||||
|
|
||||||
@ -47,6 +58,8 @@ export class BJ_Casino_Data {
|
|||||||
|
|
||||||
public get RankMagnificationData(): any[] { return this._rankMagnificationData };
|
public get RankMagnificationData(): any[] { return this._rankMagnificationData };
|
||||||
|
|
||||||
|
public get RankWinMoneyData(): any[] { return this._rankWinMoneyData };
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Lifecycle
|
//#region Lifecycle
|
||||||
@ -59,14 +72,28 @@ export class BJ_Casino_Data {
|
|||||||
this.onLoad();
|
this.onLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLoad() {
|
public async onLoad() {
|
||||||
|
// CoroutineV2.Single(this.aaa()).Start();
|
||||||
let self: this = this;
|
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 {
|
try {
|
||||||
// const URL = document.getElementById("URL").value;
|
// const URL = document.getElementById("URL").value;
|
||||||
// const Port = document.getElementById("Port").value;
|
// const Port = document.getElementById("Port").value;
|
||||||
|
|
||||||
const URL = "wss://game.online-bj.com";
|
// const URL = "wss://game.online-bj.com";
|
||||||
const Port = "9005";
|
// const Port = "9005";
|
||||||
const Account = { "p": 0, "device_info": ["Windows", "Windows"], "fcm_token": "", "a": "ct00000691", "pw": "4lsAyoalajm7", "ver": "1.3.0" };
|
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";
|
// const URL = "ws://192.168.5.12";
|
||||||
@ -105,11 +132,92 @@ export class BJ_Casino_Data {
|
|||||||
this.AddLog(ex);
|
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
|
//#endregion
|
||||||
|
|
||||||
//#region Custom
|
//#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) {
|
public SendData(Method: string, Data: any) {
|
||||||
let json = [Method];
|
let json = [Method];
|
||||||
if (Data != null && Data != undefined) {
|
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"];
|
let id = +data["id"];
|
||||||
this._nowSearchContestID = id;
|
this._nowSearchMagnificationID = id;
|
||||||
this._nowContestID = id;
|
this._nowContestID = id;
|
||||||
this._nowContestDate = moment().format("MM/DD");
|
this._nowContestDate = moment().format("MM/DD");
|
||||||
for (let i = 0; i < this.ContestData.length; i++) {
|
for (let i = 0; i < this.ContestData.length; i++) {
|
||||||
@ -185,27 +293,33 @@ export class BJ_Casino_Data {
|
|||||||
this.ParseRankMagnificationData(data);
|
this.ParseRankMagnificationData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParseRankMagnificationData(data: any) {
|
public async ParseRankMagnificationData(data: any) {
|
||||||
let id = this._nowSearchContestID;
|
let id = this._nowSearchMagnificationID;
|
||||||
this.RankDataMagnificationAddDate(id, data["rank"]);
|
this.RankDataAddDate(id, data["rank"]);
|
||||||
this._rankMagnificationData = this._rankMagnificationData.concat(data["rank"]);
|
this._rankMagnificationData = this._rankMagnificationData.concat(data["rank"]);
|
||||||
if (id !== this._nowContestStartIndex) {
|
if (id !== this._nowContestStartIndex) {
|
||||||
this._nowSearchContestID = id - 1;
|
this._nowSearchMagnificationID = id - 1;
|
||||||
this.SendData("rank.history", { "id": this._nowSearchContestID, "t": 12, "p": 2 });
|
// 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 {
|
} else {
|
||||||
this.OrganizeRankMagnificationData(this._rankMagnificationData);
|
this.OrganizeRankMagnificationData(this._rankMagnificationData);
|
||||||
this.SetRankMagnificationData(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) {
|
public OrganizeRankMagnificationData(rankdata: any) {
|
||||||
rankdata.sort((a: any, b: any) => {
|
rankdata.sort((a: any, b: any) => {
|
||||||
return b[1] - a[1];
|
return b[1] - a[1];
|
||||||
@ -220,16 +334,73 @@ export class BJ_Casino_Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SetRankMagnificationData(rankdata: any) {
|
public SetRankMagnificationData(rankdata: any) {
|
||||||
this._ws.close();
|
|
||||||
this._isOK[0] = true;
|
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._isOK[1] = true;
|
||||||
this._checkOK();
|
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() {
|
private _checkOK() {
|
||||||
if (this._isOK.includes(false)) {
|
if (this._isOK.includes(false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
NetManager.Disconnect();
|
||||||
this.Client.isLoading.value = false;
|
this.Client.isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ export class BJ_Casino_WinMoney {
|
|||||||
//#region Custom
|
//#region Custom
|
||||||
|
|
||||||
public SendData() {
|
public SendData() {
|
||||||
this._client.RankData.value = this.BJ_Casino?.RankMagnificationData;
|
this._client.RankData.value = this.BJ_Casino?.RankWinMoneyData;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
//#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": {}
|
||||||
|
}
|
12
src/script/Engine/Utils/Number.meta
Normal file
12
src/script/Engine/Utils/Number.meta
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.1.2",
|
||||||
|
"uuid": "d6e55fc6-00b6-496a-aae2-74d694c1223b",
|
||||||
|
"isBundle": false,
|
||||||
|
"bundleName": "",
|
||||||
|
"priority": 1,
|
||||||
|
"compressionType": {},
|
||||||
|
"optimizeHotUpdate": {},
|
||||||
|
"inlineSpriteFrames": {},
|
||||||
|
"isRemoteBundle": {},
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user