[add] first
This commit is contained in:
commit
1f37d21bf0
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["johnsoncodehk.volar"]
|
||||
}
|
19
README.md
Normal file
19
README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Vue 3 + Typescript + Vite
|
||||
|
||||
1. npm install
|
||||
2. npm run dev
|
||||
|
||||
This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||
|
||||
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
18
index.html
Normal file
18
index.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link href="./src/assets/ZenMaruGothic-Regular.ttf" rel="stylesheet">
|
||||
<!-- <link href="https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic&display=swap" rel="stylesheet"> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>BJ_Casino_Bot</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
3138
package-lock.json
generated
Normal file
3138
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
package.json
Normal file
26
package.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "bj-casino-rank",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^6.1.0",
|
||||
"@popperjs/core": "^2.11.5",
|
||||
"axios": "^0.26.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"dayjs": "^1.11.2",
|
||||
"element-plus": "^2.1.9",
|
||||
"vue": "^3.2.25",
|
||||
"vue-loading-overlay": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^2.3.0",
|
||||
"typescript": "^4.5.4",
|
||||
"vite": "^2.9.0",
|
||||
"vue-tsc": "^0.29.8"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 264 KiB |
38
src/App.vue
Normal file
38
src/App.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import 'vue-loading-overlay/dist/vue-loading.css';
|
||||
import BJ_Casino_BotController from './components/BJ_Casino_BotController.vue';
|
||||
|
||||
let isLoading = ref(true)
|
||||
const self = {
|
||||
isLoading: isLoading,
|
||||
}
|
||||
// const BJ_Casino = new BJ_Casino_Data(self)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>BJ_Casino_Bot</h1>
|
||||
<div>
|
||||
<BJ_Casino_BotController />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@import url('../src/assets/fonts.css');
|
||||
@import url('../src/assets/style.css');
|
||||
|
||||
.el-tabs__nav {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 0px;
|
||||
font-family: 'Zen Maru Gothic', sans-serif;
|
||||
}
|
||||
</style>
|
7
src/assets/fonts.css
Normal file
7
src/assets/fonts.css
Normal file
@ -0,0 +1,7 @@
|
||||
@font-face {
|
||||
/* 重命名字体名 */
|
||||
font-family: 'Zen Maru Gothic';
|
||||
src: url('./fonts/ZenMaruGothic-Regular.ttf');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
BIN
src/assets/fonts/ZenMaruGothic-Regular.ttf
Normal file
BIN
src/assets/fonts/ZenMaruGothic-Regular.ttf
Normal file
Binary file not shown.
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
16
src/assets/style.css
Normal file
16
src/assets/style.css
Normal file
@ -0,0 +1,16 @@
|
||||
.BJ_Casino_Bot {
|
||||
/* float: left; */
|
||||
border-width: 3px;
|
||||
border-style: double;
|
||||
border-color: #000000;
|
||||
padding: 5px;
|
||||
height: 130px;
|
||||
}
|
||||
|
||||
.BJ_Casino_BotController {
|
||||
/* float: left; */
|
||||
border-width: 1px;
|
||||
border-style: dashed;
|
||||
border-color: #000000;
|
||||
padding: 5px;
|
||||
}
|
40
src/components/BJ_Casino_Bot.vue
Normal file
40
src/components/BJ_Casino_Bot.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { BJ_Casino_Bot } from "../script/BJ_Casino_Bot";
|
||||
import BJ_Casino_Bot_Info from './BJ_Casino_Bot_Info.vue';
|
||||
import BJ_Casino_Bot_Lobby from './BJ_Casino_Bot_Lobby.vue';
|
||||
import BJ_Casino_Bot_Slot from './BJ_Casino_Bot_Slot.vue';
|
||||
|
||||
const props = defineProps<{ BJ_Casino: any }>()
|
||||
|
||||
const self = {
|
||||
BJ_Casino: props.BJ_Casino,
|
||||
}
|
||||
const Script = new BJ_Casino_Bot(self);
|
||||
const disabled = false;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Info -->
|
||||
<div class="BJ_Casino_Bot" style="float: left;text-align: left;width:10%;">
|
||||
<BJ_Casino_Bot_Info :Client="self" :Script="Script" />
|
||||
</div>
|
||||
|
||||
<!-- Game -->
|
||||
<div class="BJ_Casino_Bot" style="float: left;text-align: left;width:60%;">
|
||||
<!-- Lobby -->
|
||||
<div style="float: left;width:30%;" v-show="Script.LobbyShow.value">
|
||||
<BJ_Casino_Bot_Lobby :Client="self" :Script="Script" />
|
||||
</div>
|
||||
|
||||
<!-- Slot -->
|
||||
<div v-show="Script.SlotShow.value">
|
||||
<BJ_Casino_Bot_Slot :Client="self" :Script="Script" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Log -->
|
||||
<div class="BJ_Casino_Bot" style="text-align: left;">
|
||||
<el-input id="DIV_LOG" v-model="Script.Log.value" :rows="5" type="textarea" placeholder="Please input"
|
||||
style="width:20%;" />
|
||||
</div>
|
||||
</template>
|
22
src/components/BJ_Casino_BotController.vue
Normal file
22
src/components/BJ_Casino_BotController.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { BJ_Casino_BotController } from "../script/BJ_Casino_BotController";
|
||||
import BJ_Casino_Bot from './BJ_Casino_Bot.vue';
|
||||
|
||||
let Title = ref("");
|
||||
const self = {
|
||||
Title: Title,
|
||||
}
|
||||
const aaa = null;
|
||||
const Script = new BJ_Casino_BotController(self);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="BJ_Casino_BotController">
|
||||
<BJ_Casino_Bot :BJ_Casino="aaa" />
|
||||
</div>
|
||||
<!-- <div class="BJ_Casino_BotController">
|
||||
<BJ_Casino_Bot :BJ_Casino="aaa" />
|
||||
</div> -->
|
||||
</template>
|
13
src/components/BJ_Casino_Bot_Info.vue
Normal file
13
src/components/BJ_Casino_Bot_Info.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">import { BJ_Casino_Bot } from '../script/BJ_Casino_Bot';
|
||||
|
||||
|
||||
const props = defineProps<{ Client: any, Script: BJ_Casino_Bot }>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
AID:{{ Script.AID.value }}<br>
|
||||
NickName:{{ Script.NickName.value }}<br>
|
||||
Level:{{ Script.Level.value }}<br>
|
||||
Exp:{{ Script.Exp.value }}<br>
|
||||
Money:{{ Script.Money.value }}<br>
|
||||
</template>
|
30
src/components/BJ_Casino_Bot_Lobby.vue
Normal file
30
src/components/BJ_Casino_Bot_Lobby.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">import { BJ_Casino_Bot } from '../script/BJ_Casino_Bot';
|
||||
import { BJ_Casino_Bot_Lobby } from '../script/BJ_Casino_Bot_Lobby';
|
||||
|
||||
|
||||
const props = defineProps<{ Client: any, Script: BJ_Casino_Bot }>()
|
||||
const LobbyScript = new BJ_Casino_Bot_Lobby(props.Script);
|
||||
props.Script.LobbyScript = LobbyScript;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
廳別:
|
||||
<el-select v-model="LobbyScript.LobbyDefault.value" filterable
|
||||
@change="(data: any) => { LobbyScript.SelectLobby(data) }">
|
||||
<el-option v-for="(item, index) in LobbyScript.GetLobby()" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div>
|
||||
機台:
|
||||
<el-input v-model="LobbyScript.Slot.value" style="width:20%;" />
|
||||
桌號:{{ LobbyScript.Table }}
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="success"
|
||||
@click.native="() => { LobbyScript.OnclickSlotIn(LobbyScript.Lobby.value, +LobbyScript.Slot.value) }" round>
|
||||
確定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
28
src/components/BJ_Casino_Bot_Slot.vue
Normal file
28
src/components/BJ_Casino_Bot_Slot.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">import { BJ_Casino_Bot } from '../script/BJ_Casino_Bot';
|
||||
import { BJ_Casino_Bot_Slot } from '../script/BJ_Casino_Bot_Slot';
|
||||
|
||||
|
||||
const props = defineProps<{ Client: any, Script: BJ_Casino_Bot }>()
|
||||
const SlotScript = new BJ_Casino_Bot_Slot(props.Script);
|
||||
props.Script.SlotScript = SlotScript;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
押注:
|
||||
<el-select v-model="SlotScript.BetDefault.value" filterable
|
||||
@change="(data: any) => { SlotScript.SelectBet(data) }">
|
||||
<el-option v-for="(item, index) in SlotScript.BetGroup" :key="item" :label="item" :value="index" />
|
||||
</el-select>
|
||||
延遲:
|
||||
<el-input v-model="SlotScript.SpinDelay.value" :rows="5" style="width:5%;" />秒
|
||||
<div>
|
||||
<el-button type="success" @click.native="() => { SlotScript.OnclickSpin() }" round>
|
||||
Spin
|
||||
</el-button>
|
||||
<el-button type="success" @click.native="() => { SlotScript.OnclickStop() }" round>
|
||||
Stop
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
67
src/components/BJ_Casino_Magnification.vue
Normal file
67
src/components/BJ_Casino_Magnification.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { BJ_Casino_Data } from "../script/BJ_Casino_Data";
|
||||
import { BJ_Casino_Magnification } from "../script/BJ_Casino_Magnification";
|
||||
|
||||
const props = defineProps<{ BJ_Casino: BJ_Casino_Data }>()
|
||||
|
||||
// const props = defineProps({
|
||||
// list: {
|
||||
// type: Array,
|
||||
// default: () => [],
|
||||
// },
|
||||
// })
|
||||
|
||||
let Title = ref("");
|
||||
let RankData = ref([]);
|
||||
const self = {
|
||||
Title: Title,
|
||||
RankData: RankData,
|
||||
// BJ_Casino: props.list[0].value,
|
||||
BJ_Casino: props.BJ_Casino,
|
||||
}
|
||||
const Script = new BJ_Casino_Magnification(self);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ Title }}</h1>
|
||||
<div class="d-flex justify-content-center">
|
||||
<table class="table table-striped table-info table-hover">
|
||||
<thead>
|
||||
<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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr v-for="(item, index) in RankData" :key="index">
|
||||
<td>
|
||||
<font size="5"><b>{{ item[0] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[2][1] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ Math.floor(item[1]) }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[3][0] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[3][1] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[4] }}</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
67
src/components/BJ_Casino_WinMoney.vue
Normal file
67
src/components/BJ_Casino_WinMoney.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { BJ_Casino_Data } from "../script/BJ_Casino_Data";
|
||||
import { BJ_Casino_WinMoney } from "../script/BJ_Casino_WinMoney";
|
||||
|
||||
const props = defineProps<{ BJ_Casino: BJ_Casino_Data }>()
|
||||
|
||||
// const props = defineProps({
|
||||
// list: {
|
||||
// type: Array,
|
||||
// default: () => [],
|
||||
// },
|
||||
// })
|
||||
|
||||
let Title = ref("");
|
||||
let RankData = ref([]);
|
||||
const self = {
|
||||
Title: Title,
|
||||
RankData: RankData,
|
||||
// BJ_Casino: props.list[0].value,
|
||||
BJ_Casino: props.BJ_Casino,
|
||||
}
|
||||
const Script = new BJ_Casino_WinMoney(self);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ Title }}</h1>
|
||||
<div class="d-flex justify-content-center">
|
||||
<table class="table table-striped table-info table-hover">
|
||||
<thead>
|
||||
<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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr v-for="(item, index) in RankData" :key="index">
|
||||
<td>
|
||||
<font size="5"><b>{{ item[0] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[2][1] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ Math.floor(item[1]) }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[3][0] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[3][1] }}</b></font>
|
||||
</td>
|
||||
<td align="left">
|
||||
<font size="5"><b>{{ item[4] }}</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
8
src/env.d.ts
vendored
Normal file
8
src/env.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
12
src/main.ts
Normal file
12
src/main.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import "@popperjs/core";
|
||||
import "bootstrap";
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import ElementPlus from "element-plus";
|
||||
import "element-plus/dist/index.css";
|
||||
import locale from "element-plus/lib/locale/lang/zh-tw";
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import "./script/Engine/CatanEngine/CSharp/String";
|
||||
|
||||
|
||||
createApp(App).use(ElementPlus, { locale }).mount("#app");
|
166
src/script/BJ_Casino_Bot.ts
Normal file
166
src/script/BJ_Casino_Bot.ts
Normal file
@ -0,0 +1,166 @@
|
||||
import { Ref, ref } from "vue";
|
||||
import CSMessage from "./Base/CSMessage";
|
||||
import { AccountLoginRequest, CustomLoginRequest } from "./Base/Request/AccountRequest";
|
||||
import { BJ_Casino_Bot_Lobby } from "./BJ_Casino_Bot_Lobby";
|
||||
import { BJ_Casino_Bot_Slot } from "./BJ_Casino_Bot_Slot";
|
||||
import { BJ_Casino_UserData } from "./BJ_Casino_Userdata";
|
||||
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_Bot {
|
||||
//#region public
|
||||
|
||||
public UserData: BJ_Casino_UserData = null!;
|
||||
|
||||
public LobbyScript: BJ_Casino_Bot_Lobby = null!;
|
||||
|
||||
public SlotScript: BJ_Casino_Bot_Slot = null!;
|
||||
|
||||
// Main
|
||||
public Log: Ref<string> = ref("");
|
||||
|
||||
// Info
|
||||
public AID: Ref<string> = ref("");
|
||||
public NickName: Ref<string> = ref("");
|
||||
public Money: Ref<number> = ref(0);
|
||||
public Level: Ref<number> = ref(0);
|
||||
public Exp: Ref<number> = ref(0);
|
||||
|
||||
// Lobby
|
||||
public LobbyShow: Ref<boolean> = ref(false);
|
||||
|
||||
// Slot
|
||||
public SlotShow: Ref<boolean> = ref(false);
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _client: any;
|
||||
|
||||
private _conn: NetConnector = null!;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(client: any) {
|
||||
this._client = client;
|
||||
this.onLoad();
|
||||
}
|
||||
|
||||
public async onLoad(): Promise<void> {
|
||||
await this._login();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
private async _login(): Promise<void> {
|
||||
let self: this = this;
|
||||
// const URL: string = "https://game.online-bj.com";
|
||||
// const Port: string = "9005";
|
||||
const URL: string = "http://220.134.195.1";
|
||||
const Port: string = "19005";
|
||||
await this.ConnectAsync(URL, +Port);
|
||||
let a: string = "TS000001";
|
||||
let p: string = "a123456";
|
||||
// 取得帳號資料
|
||||
let resp: any = await this._accountLogin(a, p);
|
||||
await this._getAccountInfo(resp.a, resp.pw);
|
||||
this.LobbyShow.value = true;
|
||||
this._setUI();
|
||||
}
|
||||
private async _accountLogin(account: string, password: string): Promise<any> {
|
||||
let req: CustomLoginRequest = new CustomLoginRequest(account, password);
|
||||
await req.SendAsync(true);
|
||||
let resp: INetResponse<any> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Registe Account Error!");
|
||||
return;
|
||||
}
|
||||
return resp.Data;
|
||||
}
|
||||
|
||||
private async _getAccountInfo(a: string, pw: string): Promise<void> {
|
||||
// 取得帳號資料
|
||||
let req: AccountLoginRequest = new AccountLoginRequest(a, pw);
|
||||
await req.SendAsync(true);
|
||||
let resp: INetResponse<any> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Login Account Error!");
|
||||
return;
|
||||
}
|
||||
this.UserData = new BJ_Casino_UserData(resp.Data["id"].toString(), resp.Data["name"].toString(), +resp.Data["m"], +resp.Data["lv"], +resp.Data["exp"]);
|
||||
}
|
||||
|
||||
private _setUI(): void {
|
||||
this.AID.value = this.UserData.AID;
|
||||
this.NickName.value = this.UserData.NickName;
|
||||
this.Money.value = this.UserData.Money;
|
||||
this.Level.value = this.UserData.Level;
|
||||
this.Exp.value = this.UserData.Exp;
|
||||
}
|
||||
|
||||
public AddLog(log: string): void {
|
||||
console.log(log);
|
||||
this.Log.value += log + "\n";
|
||||
const textarea: HTMLElement | null = document.getElementById("DIV_LOG")!;
|
||||
if (textarea) {
|
||||
textarea.scrollTop = textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Onclick
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 網路相關
|
||||
|
||||
/** 連線(目前沒有重連機制) */
|
||||
public async ConnectAsync(host: string, port: number): Promise<void> {
|
||||
var url: string = "https://api.ipify.org/?format=json";
|
||||
var xhr: XMLHttpRequest = new XMLHttpRequest();
|
||||
let ip: string = "";
|
||||
xhr.onreadystatechange = function (): void {
|
||||
if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 400)) {
|
||||
ip = JSON.parse(xhr.responseText)["ip"];
|
||||
}
|
||||
};
|
||||
xhr.open("GET", url, true);
|
||||
xhr.send();
|
||||
this.AddLog("[事件]準備連線...");
|
||||
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);
|
||||
this.AddLog("[事件]連線中...");
|
||||
// 同個connector要再次連線, 可以不用叫CasinoNetManager.Initialize(), 但要先叫CasinoNetManager.Disconnect()
|
||||
await NetManager.ConnectAsync();
|
||||
this.AddLog(String.Format("[事件]連線狀態: {0}", NetManager.IsConnected));
|
||||
}
|
||||
|
||||
private _onNetDisconnected(): void {
|
||||
this.AddLog("[事件] 收到連線中斷事件");
|
||||
this._conn.OnDataReceived.RemoveAllCallbacks();
|
||||
// MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]);
|
||||
}
|
||||
|
||||
private _onNetDataReceived(resp: INetResponse<any>): void {
|
||||
this.AddLog(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`);
|
||||
// MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
48
src/script/BJ_Casino_BotController.ts
Normal file
48
src/script/BJ_Casino_BotController.ts
Normal file
@ -0,0 +1,48 @@
|
||||
// import { BJ_Casino_Data } from "./BJ_Casino_Data";
|
||||
|
||||
export class BJ_Casino_BotController {
|
||||
//#region Lifecycle
|
||||
|
||||
// public BJ_Casino: BJ_Casino_Data | undefined;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _client: any;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(client: any) {
|
||||
this._client = client;
|
||||
// this.BJ_Casino = client.BJ_Casino;
|
||||
// this.onLoad();
|
||||
}
|
||||
|
||||
// public async onLoad() {
|
||||
// await this.SetInit();
|
||||
// };
|
||||
|
||||
// public async SetInit() {
|
||||
// while (this.BJ_Casino?.Client.isLoading.value) {
|
||||
// await Tools.Sleep(50);
|
||||
// }
|
||||
// this._client.Title.value = this.BJ_Casino?.Title;
|
||||
// this.SendData();
|
||||
// };
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
// public SendData() {
|
||||
// this._client.RankData.value = this.BJ_Casino?.RankWinMoneyData;
|
||||
// }
|
||||
|
||||
//#endregion
|
||||
}
|
133
src/script/BJ_Casino_Bot_Lobby.ts
Normal file
133
src/script/BJ_Casino_Bot_Lobby.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import { Ref, ref } from "vue";
|
||||
import CSMessage from "./Base/CSMessage";
|
||||
import { BJ_Casino_Bot } from "./BJ_Casino_Bot";
|
||||
import { SeatListRequest } from "./Common/ChooseSeat/ChooseSeatRequest";
|
||||
import { SlotInRequest } from "./Common/Subgame/GameRequest";
|
||||
import { INetResponse } from "./Engine/CatanEngine/NetManagerV2/Core/INetResponse";
|
||||
|
||||
export class BJ_Casino_Bot_Lobby {
|
||||
//#region public
|
||||
|
||||
public LobbyCongig: any[] = [2, [
|
||||
"不選擇資源路徑",
|
||||
"體驗聽",
|
||||
"一般聽",
|
||||
"高手聽",
|
||||
"至尊聽",
|
||||
]];
|
||||
|
||||
public LobbyShow: Ref<boolean> = ref(false);
|
||||
public Lobby: Ref<number> = ref(0);
|
||||
public Slot: Ref<string> = ref("");
|
||||
public Table: Ref<number> = ref(0);
|
||||
public LobbyDefault: Ref<string> = ref("");
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _bj_Casino_Bot: BJ_Casino_Bot;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(bj_Casino_Bot: BJ_Casino_Bot) {
|
||||
this._bj_Casino_Bot = bj_Casino_Bot;
|
||||
this.onLoad();
|
||||
}
|
||||
|
||||
public async onLoad(): Promise<void> {
|
||||
this.Lobby.value = this.LobbyCongig[0];
|
||||
this.LobbyDefault.value = this.LobbyCongig[1][this.Lobby.value];
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
public GetLobby(): { key: string; value: string; label: string; }[] {
|
||||
const patchs: any[] = this.LobbyCongig[1];
|
||||
let options: any[] = [];
|
||||
for (let i: number = 0; i < patchs.length; i++) {
|
||||
const patch: any = patchs[i];
|
||||
options.push({
|
||||
value: i,
|
||||
label: patch,
|
||||
});
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
public SelectLobby(data: any): void {
|
||||
// data为el-option上:value绑定的对象
|
||||
this.Lobby.value = data;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Onclick
|
||||
|
||||
public async OnclickSlotIn(hall: number, slot: number): Promise<void> {
|
||||
let table: number = 1;
|
||||
let req: SeatListRequest = new SeatListRequest(hall, slot);
|
||||
await req.SendAsync(true);
|
||||
let resp: INetResponse<JSON> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "機台列表獲取失敗");
|
||||
return;
|
||||
}
|
||||
let data: any = resp.Data;
|
||||
for (let i: number = 0; i < data.length; i++) {
|
||||
const element: any = data[i];
|
||||
if (element[0].length > 0) {
|
||||
let aid: string = element[0][0];
|
||||
if (aid === this._bj_Casino_Bot.UserData.AID) {
|
||||
table = i + 1;
|
||||
break;
|
||||
} else {
|
||||
table = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let resp_slotIn: any = await this._slotIn(hall, slot, table);
|
||||
this.Table.value = table;
|
||||
this._bj_Casino_Bot.SlotScript.GameIn(resp_slotIn);
|
||||
this._bj_Casino_Bot.SlotShow.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
private async _slotIn(hall: number, slot: number, uid: number): Promise<any> {
|
||||
let req: SlotInRequest = new SlotInRequest(slot, hall, uid);
|
||||
await req.SendAsync(true);
|
||||
let resp: INetResponse<JSON> = req.Result;
|
||||
if (resp.IsValid) {
|
||||
this._bj_Casino_Bot.AddLog(`進機台成功 slot: ${slot}, hall: ${hall}, table: ${uid}`);
|
||||
return resp;
|
||||
} else {
|
||||
switch (resp.Status) {
|
||||
case 11:
|
||||
// this._messageInfo(1003);
|
||||
break;
|
||||
case 101:
|
||||
// CSMessage.CreateYesMsg(CSSettingsV3.prototype.CommonString(16));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CSMessage.NetError(resp.Method, resp.Status, "進遊戲失敗");
|
||||
}
|
||||
}
|
||||
|
||||
public OnclickChangeSlot(): void {
|
||||
// await this._login();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#endregion
|
||||
}
|
95
src/script/BJ_Casino_Bot_Slot.ts
Normal file
95
src/script/BJ_Casino_Bot_Slot.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import { Ref, ref } from "vue";
|
||||
import { BJ_Casino_Bot } from "./BJ_Casino_Bot";
|
||||
import { Tools } from "./Tools";
|
||||
|
||||
export class BJ_Casino_Bot_Slot {
|
||||
//#region public
|
||||
|
||||
public BetDefault: Ref<string> = ref("");
|
||||
|
||||
public SpinDelay: Ref<number> = ref(1);
|
||||
|
||||
public GameInData: any = null!;
|
||||
|
||||
public BetGroup: number[] = [];
|
||||
|
||||
public NowBetIndex: number = null!;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _bj_Casino_Bot: BJ_Casino_Bot;
|
||||
|
||||
private _isSpin: boolean = false;
|
||||
|
||||
private _isRun: boolean = false;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region get set
|
||||
|
||||
public get NowBet(): number { return this.BetGroup[this.NowBetIndex]; }
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(bj_Casino_Bot: BJ_Casino_Bot) {
|
||||
this._bj_Casino_Bot = bj_Casino_Bot;
|
||||
this.onLoad();
|
||||
}
|
||||
|
||||
public async onLoad(): Promise<void> {
|
||||
//
|
||||
}
|
||||
|
||||
public async GameIn(gameInData: any): Promise<void> {
|
||||
this.GameInData = gameInData;
|
||||
let Data: any = gameInData.Data;
|
||||
this.BetGroup = Data.br;
|
||||
this.NowBetIndex = Data.db;
|
||||
this.BetDefault.value = this.BetGroup[Data.db].toString();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
public async Spin(): Promise<void> {
|
||||
this._isRun = true;
|
||||
this._bj_Casino_Bot.AddLog(`Spin Bet: ${this.NowBet}`);
|
||||
await Tools.Sleep(this.SpinDelay.value * 1000);
|
||||
if (this._isSpin) {
|
||||
this.Spin();
|
||||
} else {
|
||||
this._isRun = false;
|
||||
}
|
||||
}
|
||||
|
||||
public SelectBet(data: any): void {
|
||||
this.NowBetIndex = data;
|
||||
this._bj_Casino_Bot.AddLog(`改變Bet: ${this.NowBet}`);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Onclick
|
||||
|
||||
public async OnclickSpin(): Promise<void> {
|
||||
if (this._isRun) {
|
||||
return;
|
||||
}
|
||||
this._isSpin = true;
|
||||
this.Spin();
|
||||
}
|
||||
|
||||
public async OnclickStop(): Promise<void> {
|
||||
this._isSpin = false;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
561
src/script/BJ_Casino_Data.ts
Normal file
561
src/script/BJ_Casino_Data.ts
Normal file
@ -0,0 +1,561 @@
|
||||
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 {
|
||||
|
||||
//#region public
|
||||
|
||||
public ContestData: string[] = ["5/9~5/15", "5/16~5/22"];
|
||||
|
||||
public Title: string = "";
|
||||
|
||||
public Client: any;
|
||||
|
||||
public Current: any[] = [];
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _conn: NetConnector = null!;
|
||||
private _ws: any;
|
||||
|
||||
private _rankMagnificationData: any[] = [];
|
||||
private _rankWinMoneyData: any[] = [];
|
||||
|
||||
private _nowSearchMagnificationID: number = 0;
|
||||
|
||||
private _nowSearchWinMoneyID: number = 0;
|
||||
|
||||
private _nowContestIndex: number = 0;
|
||||
|
||||
private _nowContestStartIndex: number = 0;
|
||||
|
||||
private _nowContestEndIndex: number = 0;
|
||||
|
||||
private _nowContestID: number = 0;
|
||||
|
||||
private _nowContestDate: string = "";
|
||||
|
||||
private _nowContestStart: string = "";
|
||||
|
||||
private _nowContestEnd: string = "";
|
||||
|
||||
private _isIDupup: boolean = false;
|
||||
|
||||
/**
|
||||
* 0 _rankMagnificationData
|
||||
* 1 _rankWinMoneyData
|
||||
*/
|
||||
private _isOK: any[] = [false, false];
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region get set
|
||||
|
||||
public get RankMagnificationData(): any[] { return this._rankMagnificationData; }
|
||||
|
||||
public get RankWinMoneyData(): any[] { return this._rankWinMoneyData; }
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(client: any) {
|
||||
this.Client = client;
|
||||
this.onLoad();
|
||||
}
|
||||
|
||||
public async onLoad(): Promise<void> {
|
||||
await this.ConnectServer();
|
||||
await this.SendRankData();
|
||||
}
|
||||
|
||||
public SetCurrent(current: any): void {
|
||||
this.Current.push(current);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 網路相關
|
||||
|
||||
/** 連線 */
|
||||
public async ConnectServer(): Promise<void> {
|
||||
const URL: string = "https://game.online-bj.com";
|
||||
const Port: string = "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;
|
||||
}
|
||||
}
|
||||
|
||||
/** 連線(目前沒有重連機制) */
|
||||
public async ConnectAsync(host: string, port: number): Promise<void> {
|
||||
var url: string = "https://api.ipify.org/?format=json";
|
||||
var xhr: XMLHttpRequest = new XMLHttpRequest();
|
||||
let ip: string = "";
|
||||
xhr.onreadystatechange = function (): void {
|
||||
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(): void {
|
||||
console.log("[事件] 收到連線中斷事件");
|
||||
this._conn.OnDataReceived.RemoveAllCallbacks();
|
||||
// MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.NetDisconnected]);
|
||||
}
|
||||
|
||||
private _onNetDataReceived(resp: INetResponse<any>): void {
|
||||
console.log(`[事件] 收到server呼叫: ${resp.Method}(${JSON.stringify(resp.Data)}), 狀態: ${resp.Status}`);
|
||||
// MainControl.DataReceivedEvent.DispatchCallback([MainControl.DataType.ServerData, resp]);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
public async SendRankData(): Promise<void> {
|
||||
this.SendRankMagnificationData();
|
||||
this.SendRankWinMoneyData();
|
||||
}
|
||||
|
||||
public async SendRankMagnificationData(): Promise<void> {
|
||||
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 無資料");
|
||||
this.OrganizeRankMagnificationData(this._rankMagnificationData);
|
||||
this.SetRankMagnificationDataOK();
|
||||
} else {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.SetRankMagnificationSearchData(resp.Data);
|
||||
this.ParseRankMagnificationData(resp.Data);
|
||||
}
|
||||
|
||||
public async SendRankWinMoneyData(): Promise<void> {
|
||||
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 無資料");
|
||||
this.OrganizeRankMagnificationData(this._rankMagnificationData);
|
||||
this.SetRankMagnificationDataOK();
|
||||
} else {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.SetRankWinMoneySearchData(resp.Data);
|
||||
this.ParseRankWinMoneyData(resp.Data);
|
||||
}
|
||||
|
||||
public SetRankMagnificationSearchData(data: any): void {
|
||||
let id: number = +data["id"];
|
||||
this._nowSearchMagnificationID = id;
|
||||
this._nowContestID = id;
|
||||
this._nowContestDate = moment().format("MM/DD");
|
||||
for (let i: number = 0; i < this.ContestData.length; i++) {
|
||||
const contest: string = this.ContestData[i];
|
||||
let str: string[] = contest.split("~");
|
||||
let my: moment.Moment = this._getMomentFormString(this._nowContestDate);
|
||||
let start: moment.Moment = this._getMomentFormString(str[0]);
|
||||
let end: moment.Moment = this._getMomentFormString(str[1]);
|
||||
let diff: number = my.diff(end, "day");
|
||||
if (diff <= 0) {
|
||||
this._nowContestIndex = i;
|
||||
this._nowContestStart = moment(start).format("MM/DD");
|
||||
this._nowContestEnd = moment(end).format("MM/DD");
|
||||
this._nowContestStartIndex = this._contestIDFormDate(this._nowContestStart);
|
||||
this._nowContestEndIndex = this._contestIDFormDate(this._nowContestEnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.Title = `${this._nowContestStart}~${this._nowContestEnd}`;
|
||||
}
|
||||
|
||||
public async ParseRankMagnificationData(data: any = null): Promise<void> {
|
||||
let id: number = this._nowSearchMagnificationID;
|
||||
if (data) {
|
||||
this.RankDataAddDate(id, data["rank"]);
|
||||
this._rankMagnificationData = this._rankMagnificationData.concat(data["rank"]);
|
||||
}
|
||||
let targetIndex: number = this._nowContestStartIndex;
|
||||
if (this._isIDupup) {
|
||||
targetIndex = this._nowContestEndIndex;
|
||||
}
|
||||
if (id !== targetIndex) {
|
||||
if (this._isIDupup) {
|
||||
this._nowSearchMagnificationID = id + 1;
|
||||
} else {
|
||||
this._nowSearchMagnificationID = id - 1;
|
||||
}
|
||||
let req: any = await this.GetRankData(12, this._nowSearchMagnificationID);
|
||||
let resp: INetResponse<any> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
if (resp.Status === 11) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料");
|
||||
this.ParseRankMagnificationData(resp.Data);
|
||||
} else {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.ParseRankMagnificationData(resp.Data);
|
||||
return;
|
||||
} else {
|
||||
this.OrganizeRankMagnificationData(this._rankMagnificationData);
|
||||
this.SetRankMagnificationDataOK();
|
||||
}
|
||||
}
|
||||
|
||||
public async GetRankData(type: number, dayIdid: number): Promise<any> {
|
||||
let req: any = null;
|
||||
req = new AppRankHistory(type, 2, dayIdid);
|
||||
if (dayIdid === this._nowContestID) {
|
||||
req = new AppRankInfo(type, 2);
|
||||
}
|
||||
await req.SendAsync(true);
|
||||
return req;
|
||||
}
|
||||
|
||||
public OrganizeRankMagnificationData(rankdata: any): void {
|
||||
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: number = 0; i < rankdata.length; i++) {
|
||||
rankdata[i][0] = i + 1;
|
||||
}
|
||||
this._rankMagnificationData = rankdata;
|
||||
}
|
||||
|
||||
public SetRankMagnificationDataOK(): void {
|
||||
this._isOK[0] = true;
|
||||
this._checkOK();
|
||||
}
|
||||
|
||||
public SetRankWinMoneySearchData(data: any): void {
|
||||
let id: number = +data["id"];
|
||||
this._nowSearchWinMoneyID = id;
|
||||
}
|
||||
|
||||
public async ParseRankWinMoneyData(data: any = null): Promise<void> {
|
||||
let id: number = this._nowSearchWinMoneyID;
|
||||
if (data) {
|
||||
this.RankDataAddDate(id, data["rank"]);
|
||||
this._rankWinMoneyData = this._rankWinMoneyData.concat(data["rank"]);
|
||||
}
|
||||
let targetIndex: number = this._nowContestStartIndex;
|
||||
if (this._isIDupup) {
|
||||
targetIndex = this._nowContestEndIndex;
|
||||
}
|
||||
if (id !== targetIndex) {
|
||||
if (this._isIDupup) {
|
||||
this._nowSearchWinMoneyID = id + 1;
|
||||
} else {
|
||||
this._nowSearchWinMoneyID = id - 1;
|
||||
}
|
||||
let req: any = await this.GetRankData(11, this._nowSearchWinMoneyID);
|
||||
let resp: INetResponse<any> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
if (resp.Status === 11) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料");
|
||||
this.ParseRankWinMoneyData();
|
||||
} else {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.ParseRankWinMoneyData(resp.Data);
|
||||
return;
|
||||
} else {
|
||||
this.OrganizeRankWinMoneyData(this._rankWinMoneyData);
|
||||
this.SetRankWinMoneyDataOK();
|
||||
}
|
||||
}
|
||||
|
||||
public OrganizeRankWinMoneyData(rankdata: any): void {
|
||||
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: number = 0; i < rankdata.length; i++) {
|
||||
rankdata[i][0] = i + 1;
|
||||
}
|
||||
this._rankWinMoneyData = rankdata;
|
||||
}
|
||||
|
||||
public SetRankWinMoneyDataOK(): void {
|
||||
this._isOK[1] = true;
|
||||
this._checkOK();
|
||||
}
|
||||
|
||||
public RankDataAddDate(id: number, rankdata: any): any {
|
||||
let date: string = this._contestDateFormID(id);
|
||||
for (let i: number = 0; i < rankdata.length; i++) {
|
||||
rankdata[i].push(date);
|
||||
}
|
||||
return rankdata;
|
||||
}
|
||||
|
||||
private _checkOK(): void {
|
||||
if (this._isOK.includes(false)) {
|
||||
return;
|
||||
}
|
||||
NetManager.Disconnect();
|
||||
for (let i: number = 0; i < this.Current.length; i++) {
|
||||
const current: any = this.Current[i];
|
||||
current.SetInit();
|
||||
}
|
||||
this.Client.isLoading.value = false;
|
||||
}
|
||||
|
||||
public async PrevWeek(): Promise<void> {
|
||||
let nowContestIndex: number = this._nowContestIndex;
|
||||
if (nowContestIndex - 1 >= 0) {
|
||||
nowContestIndex--;
|
||||
} else {
|
||||
alert(`到底了`);
|
||||
return;
|
||||
}
|
||||
this._isIDupup = false;
|
||||
await this.RunSetWeek(nowContestIndex);
|
||||
// const contest: string = this.ContestData[nowContestIndex];
|
||||
// let str: string[] = contest.split("~");
|
||||
// let my: moment.Moment = this._getMomentFormString(this._nowContestDate);
|
||||
// let start: moment.Moment = this._getMomentFormString(str[0]);
|
||||
// let end: moment.Moment = this._getMomentFormString(str[1]);
|
||||
// let diff: number = my.diff(start, "day");
|
||||
// if (diff < 0) {
|
||||
// alert(`還沒開放`);
|
||||
// return;
|
||||
// }
|
||||
// this.Client.isLoading.value = true;
|
||||
// this._isOK[0] = false;
|
||||
// this._isOK[1] = false;
|
||||
|
||||
// this._nowContestStart = moment(start).format("MM/DD");
|
||||
// this._nowContestEnd = moment(end).format("MM/DD");
|
||||
// this._nowContestStartIndex = this._contestIDFormDate(this._nowContestStart);
|
||||
// this._nowContestEndIndex = this._nowSearchMagnificationID = this._contestIDFormDate(this._nowContestEnd);
|
||||
// this.Title = `${this._nowContestStart}~${this._nowContestEnd}`;
|
||||
|
||||
// await this.ConnectServer();
|
||||
// this.RunRankMagnificationWeek();
|
||||
// this.RunRankWinMoneyWeek();
|
||||
}
|
||||
|
||||
public async NextWeek(): Promise<void> {
|
||||
let nowContestIndex: number = this._nowContestIndex;
|
||||
if (nowContestIndex + 1 < this.ContestData.length) {
|
||||
nowContestIndex++;
|
||||
} else {
|
||||
alert(`到底了`);
|
||||
return;
|
||||
}
|
||||
|
||||
this._isIDupup = true;
|
||||
await this.RunSetWeek(nowContestIndex);
|
||||
}
|
||||
|
||||
public async RunSetWeek(nowContestIndex: number): Promise<void> {
|
||||
const contest: string = this.ContestData[nowContestIndex];
|
||||
let str: string[] = contest.split("~");
|
||||
let my: moment.Moment = this._getMomentFormString(this._nowContestDate);
|
||||
let start: moment.Moment = this._getMomentFormString(str[0]);
|
||||
let end: moment.Moment = this._getMomentFormString(str[1]);
|
||||
let diff: number = my.diff(start, "day");
|
||||
if (diff < 0) {
|
||||
alert(`還沒開放`);
|
||||
return;
|
||||
}
|
||||
this._nowContestIndex = nowContestIndex;
|
||||
this.Client.isLoading.value = true;
|
||||
this._isOK[0] = false;
|
||||
this._isOK[1] = false;
|
||||
|
||||
this._nowContestStart = moment(start).format("MM/DD");
|
||||
this._nowContestEnd = moment(end).format("MM/DD");
|
||||
this._nowContestStartIndex = this._contestIDFormDate(this._nowContestStart);
|
||||
this._nowContestEndIndex = this._contestIDFormDate(this._nowContestEnd);
|
||||
if (this._isIDupup) {
|
||||
this._nowSearchMagnificationID = this._nowSearchWinMoneyID = this._contestIDFormDate(this._nowContestStart);
|
||||
} else {
|
||||
this._nowSearchMagnificationID = this._nowSearchWinMoneyID = this._contestIDFormDate(this._nowContestEnd);
|
||||
}
|
||||
this.Title = `${this._nowContestStart}~${this._nowContestEnd}`;
|
||||
|
||||
await this.ConnectServer();
|
||||
this.RunRankMagnificationWeek();
|
||||
this.RunRankWinMoneyWeek();
|
||||
}
|
||||
|
||||
public async RunRankMagnificationWeek(): Promise<void> {
|
||||
this._rankMagnificationData = [];
|
||||
let req: any = await this.GetRankData(12, this._nowSearchMagnificationID);
|
||||
let resp: INetResponse<any> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
if (resp.Status === 11) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料");
|
||||
this.OrganizeRankMagnificationData(this._rankMagnificationData);
|
||||
this.SetRankMagnificationDataOK();
|
||||
} else {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.ParseRankMagnificationData(resp.Data);
|
||||
}
|
||||
|
||||
public async RunRankWinMoneyWeek(): Promise<void> {
|
||||
this._rankWinMoneyData = [];
|
||||
let req: any = await this.GetRankData(11, this._nowSearchWinMoneyID);
|
||||
let resp: INetResponse<any> = req.Result;
|
||||
if (!resp.IsValid) {
|
||||
if (resp.Status === 11) {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Rank 無資料");
|
||||
this.OrganizeRankWinMoneyData(this._rankWinMoneyData);
|
||||
this.SetRankWinMoneyDataOK();
|
||||
} else {
|
||||
CSMessage.NetError(resp.Method, resp.Status, "Get RankInfo Fail");
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.ParseRankWinMoneyData(resp.Data);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Get
|
||||
|
||||
private _contestIDFormDate(date: string): number {
|
||||
let my: moment.Moment = this._getMomentFormString(this._nowContestDate);
|
||||
let target: moment.Moment = this._getMomentFormString(date);
|
||||
let diffday: number = my.diff(target, "day");
|
||||
let id: number = this._nowContestID - diffday;
|
||||
if (id < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
private _contestDateFormID(id: number): string {
|
||||
let my: number = this._nowContestID;
|
||||
let target: number = id;
|
||||
let diffid: number = my - target;
|
||||
if (diffid < 0) {
|
||||
diffid = 0;
|
||||
}
|
||||
let date: string = moment().subtract(diffid, "day").format("MM/DD");
|
||||
return date;
|
||||
}
|
||||
|
||||
private _getMomentFormString(str: string): moment.Moment {
|
||||
let data: string[] = str.split("/");
|
||||
let m: number = +data[0] - 1;
|
||||
let d: number = +data[1];
|
||||
let date: Date = new Date();
|
||||
date.setMonth(m);
|
||||
date.setDate(d);
|
||||
let mymoment: moment.Moment = moment(date);
|
||||
return mymoment;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Tools Function
|
||||
|
||||
/**
|
||||
* 陣列排序,asc&key陣列長度請一樣
|
||||
* PS. boolean 帶false是先true在false
|
||||
* @link JavaScript Object 排序 http://www.eion.com.tw/Blogger/?Pid=1170#:~:text=JavaScript%20Object%20排序
|
||||
* @param Arr 需排序陣列
|
||||
* @param asc 是否升序排列(小到大)
|
||||
* @param key 需排序的key(優先順序左到右)(沒有就放空)
|
||||
*/
|
||||
public ObjectSort(Arr: any[], asc: boolean[] = [true], key?: string[]): any[] {
|
||||
if (!key || key.length === 0 || Arr.length === 0 || Arr[0][key[0]] === undefined) {
|
||||
console.error(`ObjectSort key error`);
|
||||
return Arr;
|
||||
} else if (asc.length !== key.length) {
|
||||
console.error(`ObjectSort key asc error asc.length: ${asc.length}, key.length: ${key.length}`);
|
||||
return Arr;
|
||||
}
|
||||
let count: number = key ? key.length : 1;
|
||||
for (let i: number = count - 1; i >= 0; i--) {
|
||||
Arr = Arr.sort(function (a: any, b: any): 1 | -1 {
|
||||
let mya: any = a;
|
||||
let myb: any = b;
|
||||
if (key) {
|
||||
mya = a[key[i]];
|
||||
myb = b[key[i]];
|
||||
}
|
||||
|
||||
// 加個等於數字相同不要再去排序到
|
||||
if (asc[i]) {
|
||||
return mya >= myb ? 1 : -1;
|
||||
} else {
|
||||
return mya <= myb ? 1 : -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
return Arr;
|
||||
}
|
||||
|
||||
public Sleep(ms: number): Promise<any> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
public AddLog(log: any): void {
|
||||
console.log(log);
|
||||
// var textarea = document.getElementById("Log");
|
||||
// textarea.value += log + "\n";
|
||||
// textarea.scrollTop = textarea.scrollHeight;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
49
src/script/BJ_Casino_Magnification.ts
Normal file
49
src/script/BJ_Casino_Magnification.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { BJ_Casino_Data } from "./BJ_Casino_Data";
|
||||
import { Tools } from "./Tools";
|
||||
|
||||
export class BJ_Casino_Magnification {
|
||||
//#region Lifecycle
|
||||
|
||||
public BJ_Casino: BJ_Casino_Data | undefined;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _client: any;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(client: any) {
|
||||
this._client = client;
|
||||
this.BJ_Casino = client.BJ_Casino;
|
||||
this.onLoad();
|
||||
}
|
||||
|
||||
public async onLoad() {
|
||||
await this.SetInit();
|
||||
};
|
||||
|
||||
public async SetInit() {
|
||||
while (this.BJ_Casino?.Client.isLoading.value) {
|
||||
await Tools.Sleep(50);
|
||||
}
|
||||
this._client.Title.value = this.BJ_Casino?.Title;
|
||||
this.SendData();
|
||||
};
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
public SendData() {
|
||||
this._client.RankData.value = this.BJ_Casino?.RankMagnificationData;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
27
src/script/BJ_Casino_UserData.ts
Normal file
27
src/script/BJ_Casino_UserData.ts
Normal file
@ -0,0 +1,27 @@
|
||||
export class BJ_Casino_UserData {
|
||||
//#region public
|
||||
|
||||
public AID: string = "";
|
||||
|
||||
public NickName: string = "";
|
||||
|
||||
public Money: number = 0;
|
||||
|
||||
public Level: number = 0;
|
||||
|
||||
public Exp: number = 0;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
constructor(aid: string, nickName: string, money: number, level: number, exp: number) {
|
||||
this.AID = aid;
|
||||
this.NickName = nickName;
|
||||
this.Money = money;
|
||||
this.Level = level;
|
||||
this.Exp = exp;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
49
src/script/BJ_Casino_WinMoney.ts
Normal file
49
src/script/BJ_Casino_WinMoney.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { BJ_Casino_Data } from "./BJ_Casino_Data";
|
||||
import { Tools } from "./Tools";
|
||||
|
||||
export class BJ_Casino_WinMoney {
|
||||
//#region Lifecycle
|
||||
|
||||
public BJ_Casino: BJ_Casino_Data | undefined;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region private
|
||||
|
||||
private _client: any;
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Lifecycle
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor(client: any) {
|
||||
this._client = client;
|
||||
this.BJ_Casino = client.BJ_Casino;
|
||||
this.onLoad();
|
||||
}
|
||||
|
||||
public async onLoad() {
|
||||
await this.SetInit();
|
||||
};
|
||||
|
||||
public async SetInit() {
|
||||
while (this.BJ_Casino?.Client.isLoading.value) {
|
||||
await Tools.Sleep(50);
|
||||
}
|
||||
this._client.Title.value = this.BJ_Casino?.Title;
|
||||
this.SendData();
|
||||
};
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Custom
|
||||
|
||||
public SendData() {
|
||||
this._client.RankData.value = this.BJ_Casino?.RankWinMoneyData;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
237
src/script/Base/BusinessTypeSetting.ts
Normal file
237
src/script/Base/BusinessTypeSetting.ts
Normal file
@ -0,0 +1,237 @@
|
||||
export module BusinessEnum {
|
||||
export enum BusinessType {
|
||||
Type1 = "H5",
|
||||
Type2 = "App"
|
||||
}
|
||||
export enum ServerType {
|
||||
/** WEB格式 */
|
||||
Web = 1,
|
||||
/** 外版 */
|
||||
Out = 2,
|
||||
/** 送審環境 */
|
||||
Submit = 3,
|
||||
/** 內版商業DEMO測試(B2B) */
|
||||
Internal_release = 4,
|
||||
/** 內版開發(內網&4G) */
|
||||
Internal_Dev = 5,
|
||||
/** 外部商業DEMO(B2B) */
|
||||
Out_B2B = 6
|
||||
}
|
||||
export enum LogoType {
|
||||
/** 完美(目前只有WEB) */
|
||||
WM = 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
產品商業類別設定檔
|
||||
@explain 讀不同表就代表不同商業類別.要多開GIT並設定新測試環境
|
||||
@explain 遊戲一定都一樣不能改動介面
|
||||
*/
|
||||
export default class BusinessTypeSetting {
|
||||
/** 產品商業類別字串(組合判斷用) */
|
||||
public static readonly TYPE_BUSINESS: string = "App";
|
||||
/** 編譯版本 */
|
||||
public static readonly COMPILE_VERSION: string = "1.4.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
|
||||
};
|
||||
}
|
||||
}
|
51
src/script/Common/ChooseSeat/ChooseSeatRequest.ts
Normal file
51
src/script/Common/ChooseSeat/ChooseSeatRequest.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
|
||||
|
||||
|
||||
interface SeatListResquest {
|
||||
hall: number;
|
||||
slot: number;
|
||||
}
|
||||
/** 機台所有座位 */
|
||||
export class SeatListRequest extends NetRequest<SeatListResquest, JSON> {
|
||||
get Method(): string {
|
||||
return "seat.list";
|
||||
}
|
||||
constructor(HallType: number, SlotID: number) {
|
||||
super();
|
||||
this.Data = {
|
||||
hall: HallType,
|
||||
slot: SlotID
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface SeatInfoResquest {
|
||||
hall: number;
|
||||
slot: number;
|
||||
id: number;
|
||||
}
|
||||
|
||||
/** 獨立座位資料 */
|
||||
export class SeatInfoRequest extends NetRequest<SeatInfoResquest, JSON> {
|
||||
get Method(): string {
|
||||
return "seat.info";
|
||||
}
|
||||
constructor(HallType: number, SlotID: number, ID: number) {
|
||||
super();
|
||||
this.Data = {
|
||||
hall: HallType,
|
||||
slot: SlotID,
|
||||
id: ID
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** 機台佔用 */
|
||||
export class SeatOccupy extends NetRequest<null, null> {
|
||||
get Method(): string {
|
||||
return "seat.occupy";
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
69
src/script/Common/Subgame/GameRequest.ts
Normal file
69
src/script/Common/Subgame/GameRequest.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import BusinessTypeSetting, { BusinessEnum } from "../../Base/BusinessTypeSetting";
|
||||
import { NetRequest } from "../../Engine/CatanEngine/NetManagerV2/NetRequest";
|
||||
|
||||
//=======================================================================================
|
||||
// /**取得歷史紀錄網頁網址協定 */
|
||||
// export class HistoryRequest extends NetRequest<any, JSON> {
|
||||
// get Method(): string {
|
||||
// return "history.url";
|
||||
// }
|
||||
|
||||
// constructor(slotId: number) {
|
||||
// super();
|
||||
// this.Data = {
|
||||
// slot: slotId,
|
||||
// lang: LanguageManager.UseLanguageUrlStr,
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
//=======================================================================================
|
||||
export class SlotInRequest extends NetRequest<any, JSON> {
|
||||
get Method(): string {
|
||||
return "slot.in";
|
||||
}
|
||||
constructor(slotid: number, hall: number = 0, uid: number = 0) {
|
||||
super();
|
||||
switch (BusinessTypeSetting.TYPE_BUSINESS) {
|
||||
case BusinessEnum.BusinessType.Type1:
|
||||
this.Data = {
|
||||
id: slotid
|
||||
}
|
||||
break;
|
||||
case BusinessEnum.BusinessType.Type2:
|
||||
this.Data = {
|
||||
id: slotid,
|
||||
hall: hall,
|
||||
uid: uid,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
console.error("No TYPE_BUSINESS");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================================
|
||||
export class SlotOutRequest extends NetRequest<null, null> {
|
||||
get Method(): string {
|
||||
return "slot.out";
|
||||
}
|
||||
}
|
||||
//=======================================================================================
|
||||
export class FishOutRequest extends NetRequest<null, null> {
|
||||
get Method(): string {
|
||||
return "fish.out";
|
||||
}
|
||||
}
|
||||
//=======================================================================================
|
||||
export class TableOutRequest extends NetRequest<null, null> {
|
||||
get Method(): string {
|
||||
return "table.out";
|
||||
}
|
||||
}
|
||||
//=======================================================================================
|
||||
export class PinBallOutRequest extends NetRequest<null, null> {
|
||||
get Method(): string {
|
||||
return "pinball.out";
|
||||
}
|
||||
}
|
||||
//=======================================================================================
|
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": {}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user