From c4eba7fe967f7e4e8c4eacd437266a943c1a63b5 Mon Sep 17 00:00:00 2001 From: wzdwc Date: Sun, 28 Mar 2021 03:08:26 +0800 Subject: [PATCH] fix: token lost --- .gitignore | 2 +- .idea/workspace.xml | 30 +++-- client/src/assets/less/base.less | 134 ++++++++++--------- client/src/components/SitList.vue | 38 +++++- client/src/interface/IPlayer.ts | 39 +++--- client/src/utils/request.ts | 68 +++++----- client/src/views/game.vue | 24 +++- client/src/views/home.vue | 1 + client/src/views/login.vue | 177 +++++++++++++------------ server/src.zip | Bin 54216 -> 0 bytes server/src/app/core/Player.ts | 2 + server/src/app/core/PokerGame.ts | 39 ++++-- server/src/app/io/controller/game.ts | 26 +++- server/src/app/io/middleware/join.ts | 1 + server/src/app/router.ts | 2 +- server/src/lib/baseSocketController.ts | 2 + server/src/service/account.ts | 2 +- 17 files changed, 352 insertions(+), 235 deletions(-) delete mode 100644 server/src.zip diff --git a/.gitignore b/.gitignore index 4772dd9..14ff125 100755 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,5 @@ yarn-error.log test/unit/coverage run/ logs/ -confing.prod.ts npm-debug.* +/server/src/config/ diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 31a105d..b6ebd9b 100755 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -26,19 +26,24 @@ + - - - + - - + + + + + + - + + + - + @@ -205,15 +211,17 @@ - - + + + - - + + + diff --git a/client/src/assets/less/base.less b/client/src/assets/less/base.less index 39297ec..876ada4 100644 --- a/client/src/assets/less/base.less +++ b/client/src/assets/less/base.less @@ -1,64 +1,70 @@ -@font-face { - font-family: 'iconfont'; /* project id 1801313 */ - src: url('//at.alicdn.com/t/font_1801313_4rcv94i1hxw.eot'); - src: url('//at.alicdn.com/t/font_1801313_4rcv94i1hxw.eot?#iefix') format('embedded-opentype'), - url('//at.alicdn.com/t/font_1801313_4rcv94i1hxw.woff2') format('woff2'), - url('//at.alicdn.com/t/font_1801313_4rcv94i1hxw.woff') format('woff'), - url('//at.alicdn.com/t/font_1801313_4rcv94i1hxw.ttf') format('truetype'), - url('//at.alicdn.com/t/font_1801313_4rcv94i1hxw.svg#iconfont') format('svg'); -} - -.iconfont { - font-family: "iconfont" !important; - font-size: 16px; - font-style: normal; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-account:before { - content: "\e60a"; -} - -.icon-user-avatar:before { - content: "\e636"; -} - -.icon-pot:before { - content: "\e60c"; -} - -.icon-gold:before { - content: "\e609"; -} -.icon-setting:before { - content: "\e611"; -} -.icon-password:before { - content: "\e603"; -} - -.icon-close:before { - content: "\e615"; -} - -.icon-msg:before{ - content: "\e781"; -} - -.icon-record:before{ - content: "\e657"; -} - -.icon-arrow:before{ - content: "\e623"; -} -body, p,h1,h2,ul,li,input{ - padding: 0; - margin: 0; -} -input{ - border: 0; - outline: none; -} - +@font-face { + font-family: 'iconfont'; /* project id 1801313 */ + src: url('//at.alicdn.com/t/font_1801313_jpwi7jzmcwr.eot'); + src: url('//at.alicdn.com/t/font_1801313_jpwi7jzmcwr.eot?#iefix') format('embedded-opentype'), + url('//at.alicdn.com/t/font_1801313_jpwi7jzmcwr.woff2') format('woff2'), + url('//at.alicdn.com/t/font_1801313_jpwi7jzmcwr.woff') format('woff'), + url('//at.alicdn.com/t/font_1801313_jpwi7jzmcwr.ttf') format('truetype'), + url('//at.alicdn.com/t/font_1801313_jpwi7jzmcwr.svg#iconfont') format('svg'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-account:before { + content: "\e60a"; +} + +.icon-user-avatar:before { + content: "\e636"; +} + +.icon-pot:before { + content: "\e60c"; +} + +.icon-gold:before { + content: "\e609"; +} +.icon-setting:before { + content: "\e611"; +} +.icon-password:before { + content: "\e603"; +} + +.icon-close:before { + content: "\e615"; +} + +.icon-msg:before{ + content: "\e781"; +} + +.icon-record:before{ + content: "\e657"; +} + +.icon-arrow:before{ + content: "\e623"; +} + +.icon-clock:before{ + content: "\e608"; +} + + +body, p,h1,h2,ul,li,input{ + padding: 0; + margin: 0; +} +input{ + border: 0; + outline: none; +} + diff --git a/client/src/components/SitList.vue b/client/src/components/SitList.vue index 37f4b55..fe19618 100644 --- a/client/src/components/SitList.vue +++ b/client/src/components/SitList.vue @@ -60,6 +60,11 @@
+
+ + {{sit.player.delayCount}} +
ready @@ -159,6 +164,14 @@ return map(cards); } + private delayTime() { + if(this.currPlayer.delayCount > 0) { + console.log('delay') + this.$emit('update:time', this.time + 60); + this.$emit('delay') + } + } + private sitDown(sit: ISit) { if (!sit.player && (!this.isPlay || !this.hasSit)) { if (this.currPlayer.counter <= 0) { @@ -354,6 +367,29 @@ } } + .delay-time{ + position: absolute; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 999; + min-width: 24vw; + min-height: 10vh; + background: radial-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0) 70%); + i{ + color: #fff; + font-size: 30px; + } + span{ + font-size: 12px; + color: #fff; + margin-left: 2px; + font-weight: 600; + } + } + .hand-card { position: absolute; top: 1vh; @@ -464,7 +500,7 @@ color: #fff; font-size: 14px; bottom: -48px; - width: 60 / 3.75vw; + width: 22vw; text-align: center; font-weight: 700; } diff --git a/client/src/interface/IPlayer.ts b/client/src/interface/IPlayer.ts index 3509f26..47b3582 100644 --- a/client/src/interface/IPlayer.ts +++ b/client/src/interface/IPlayer.ts @@ -1,19 +1,20 @@ -enum PlayerType { - READY, - SIT_DOWN, - GAMING, -} - -export interface IPlayer { - counter: number; - nickName: string; - actionSize: number; - actionCommand: string; - type: string; - userId?: number; - handCard?: string[]; - buyIn: number; - status: number; - income?: number; - isSit: boolean; -} +enum PlayerType { + READY, + SIT_DOWN, + GAMING, +} + +export interface IPlayer { + counter: number; + nickName: string; + actionSize: number; + actionCommand: string; + type: string; + userId?: string; + handCard?: string[]; + buyIn: number; + status: number; + income?: number; + isSit: boolean; + delayCount: number; +} diff --git a/client/src/utils/request.ts b/client/src/utils/request.ts index 3c7d649..bfcd8f3 100644 --- a/client/src/utils/request.ts +++ b/client/src/utils/request.ts @@ -1,34 +1,34 @@ -import axios, {AxiosRequestConfig, Method} from 'axios'; -import cookie from 'js-cookie'; -import origin from '@/utils/origin'; - -const request = async ({method = 'post' as Method, url = '', body = {}, timeout = 8000}) => { - if (!url) { - return Promise.reject('Request url is null!'); - } - const token = cookie.get('token'); - const headers = { - Authorization: `Bearer ${token}`, - }; - console.log('url', origin.url); - url = `${origin.url}/node${url}`; - const option: AxiosRequestConfig = { - url, - method, - timeout, - data: body, - withCredentials: true, - headers, - }; - try { - const result = await axios(option); - if (result.data.code === '000000') { - return result.data; - } else { - throw result.data; - } - } catch (e) { - throw e; - } -}; -export default request; +import axios, {AxiosRequestConfig, Method} from 'axios'; +import cookie from 'js-cookie'; +import origin from '@/utils/origin'; + +const request = async ({method = 'post' as Method, url = '', body = {}, timeout = 8000}) => { + if (!url) { + return Promise.reject('Request url is null!'); + } + const token = cookie.get('token') || localStorage.getItem('token'); + const headers = { + Authorization: `Bearer ${token}`, + }; + console.log('url', origin.url); + url = `${origin.url}/node${url}`; + const option: AxiosRequestConfig = { + url, + method, + timeout, + data: body, + withCredentials: true, + headers, + }; + try { + const result = await axios(option); + if (result.data.code === '000000') { + return result.data; + } else { + throw result.data; + } + } catch (e) { + throw e; + } +}; +export default request; diff --git a/client/src/views/game.vue b/client/src/views/game.vue index fffd66d..3f28df2 100644 --- a/client/src/views/game.vue +++ b/client/src/views/game.vue @@ -8,7 +8,8 @@ :isPlay='isPlay' :valueCards='valueCards' :roomConfig = 'roomConfig' - :time='time' + @delay="delay" + :time.sync='time' :winner="winner" :actionUserId='actionUserId' :hand-card="handCard"> @@ -107,7 +108,7 @@ } const GAME_BASE_SIZE = 1; - const ACTION_TIME = 60; + const ACTION_TIME = 30; @Component({ components: { @@ -306,6 +307,11 @@ this.emit('sitDown', { sitList: this.sitListMap() }); } + private delay() { + console.log('delay') + this.emit('delayTime'); + } + private action(command: string) { if (command === 'fold') { clearTimeout(this.timeSt); @@ -322,8 +328,8 @@ } private socketInit() { - const token = cookie.get('token'); - const roomConfig = cookie.get('roomConfig') || ''; + const token = cookie.get('token') || localStorage.getItem('token') || ''; + const roomConfig = cookie.get('roomConfig') || localStorage.getItem('roomConfig') || ''; const log = console.log; this.roomConfig = JSON.parse(roomConfig); console.log(JSON.parse(roomConfig), 'roomConfig'); @@ -445,6 +451,12 @@ this.init(); } + if (msg.action === 'delayTime') { + if (this.currPlayer?.userId !== this.actionUserId) { + this.time += 60; + } + } + if (msg.action === 'broadcast') { this.messageList.push({ message: msg.message.msg || '', @@ -455,14 +467,18 @@ // 系统事件 this.socket.on('disconnect', (msg: IMsg) => { + this.$plugin.toast('room is disconnect'); + this.socketInit() log('#disconnect', msg); }); this.socket.on('disconnecting', () => { + this.$plugin.toast('room is disconnecting'); log('#disconnecting'); }); this.socket.on('error', () => { + this.$plugin.toast('room is error'); log('#error'); }); } diff --git a/client/src/views/home.vue b/client/src/views/home.vue index 2bc8901..cb96f14 100644 --- a/client/src/views/home.vue +++ b/client/src/views/home.vue @@ -93,6 +93,7 @@ isShort: this.isShort, smallBlind: this.smallBlind, }; + localStorage.setItem('roomConfig', JSON.stringify(roomConfig)) cookie.set('roomConfig', roomConfig, {expires: 1}); this.$router.push({ name: 'game', params: { roomNumber, isOwner: '1' } }); } catch (e) { diff --git a/client/src/views/login.vue b/client/src/views/login.vue index 45bd791..e20e216 100644 --- a/client/src/views/login.vue +++ b/client/src/views/login.vue @@ -1,88 +1,89 @@ - - - + + + diff --git a/server/src.zip b/server/src.zip deleted file mode 100644 index fccfe4353579e182ee475846c1fbe4367e3c54b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54216 zcmdSB1yq)4*EURdr_$XWf`oK;cXxM7cXvrB9fEXscO!_Tq#)f$_}{mVkIsxU-+b@$ zuXoMITDP~XYq>r5v5$T1ebyx}1rC7$0{kJf%as56m*4(?03iZ#ax`L8QAPxTuI($* z#e);nBLRF|+~Gk$Aud2cK)(J<`L7mWKwy4np#@+C31C4_PewpUPD!1SK@VW;cead| zh4uen%Sa#7$V}f*|5!#^^%z+-Ox_PH?h!a83NEMvB}(9R%i}Px7-C`pc?$6X1R_;Y zrS32kY?<+iw^DRegA#9P>1606M`?#frA(-1IhZP$s-O6QeTs{kO@kv1oNVpQ-HaNo zo+Yt@0+E-3hS8!A}r?tv~+8Y6}hHGe1Eu3%@+cT`IvbN3nDIwvy}{w7msx~ z###42c+EU&6Pz0tgfDPohbg6DCX98SxPf@|NY=vSH zRqwjI~RmB zSS#F&P|kkp+K{3v5Q87q&r)xmIv+*oKtKgNa)TV>e|`{?hLi*L*sRiSB7i;EPbI

G0XZof?(6 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�j~5{YRpA6{hN<3@b?$D1z_`_2S}h1@ajqP z^S^y9hwG7kK?K+$B0wi!wG8|PzaDFl{U8D`K7Jda;*H|9{8{4Yfbd{Nf}0IuQi0}Bl5AGiSbM$mZxU(}HlKe+r6 zIry#d|9EKzU(~aJ#;@V=9S02Nf5f4H@&|`Mf>yv9{|7q}aDYJN37o?jpz&)se8&NU z`2~k>RviFL7b2>K7hp2#05AA)uj|ft4u6=7zW*>-*&6CwU9Ir{cmxB6vs^uCe($J$ zqVoqJgYK^&e}fwF#vV>804Em`0s_=@lI9mq4Mxq*>Ji{B@INF4zNN>|{2i(5!Tx~` zaP_A?#6E!qsNW&LX%bW*(){db!RY)kY<3Q|zf-;K>f~@`n#c&?k!k@z=mCr!;Hr3v z{yG>VV-tOl>)LN#3W0=XURNW91LkKC@PZRUV!jT^31FbOnxx-^0WKsekEgjq01&b6pi?tbB>@8P9AFCt zJ*1}jp|F1^0yNYa=sOxKg4YfGk8Ey(Ez>H_pV$Dw7<7LD_Yaij(@hl)`X=U<0m5br zFxY@Epg6!q9(b(ylaj5WrLmLHpLvw7W=gbMSWg=80)KyT$N(B40%B5F2Y|W&Fn-|j zwss#J?5{AtX@vlawOOqn{TkXz6*-<9(Xnu^>3c zZzjPUa|T+o6kH)d1CESW_Y9DG>%S>m`!he#Vx8b7C``a-v}?frMNw2x zETHlREsF_m0S#3Af%V5F_WM!pO2z$0^$jesdG)0EJyrTieFN`nf582Vf}5bUfNKo2 zsv@{fHC6r#Ex^I#H%nlG!T?J&g67T#hapw{0rMkYKIkWtUleQvg#jkw2Tc?Vei(jZ zejUv3rsW640gf7I?oRM6g24V~od0Up2hHdRuE9S)`WfRlbAn#c07?~*#+7sde?e(% z3Gli8fB=t5`F1}6Duk=|7n?Q^1N0gMYT(@Riv(c&lyuk0~^0zFuFRVTBM7qJfL`u?5z7fWmOw=Y>I({fxl76TJE&`%KL24Te^!}5-_olm&2KU5`k@42 c_q(2^a#FAW^ArSx8Q`By8VHECY~Y{%9}vcb;Q#;t diff --git a/server/src/app/core/Player.ts b/server/src/app/core/Player.ts index 832b46b..e86d3d4 100644 --- a/server/src/app/core/Player.ts +++ b/server/src/app/core/Player.ts @@ -12,6 +12,7 @@ export interface IPlayer { status: number; actionSize: number; actionCommand: string; + delayCount?: number; } export enum ECommand { @@ -37,6 +38,7 @@ export class Player { position: number = 0; counter: number = 0; userId: string = ''; + delayCount: number = 3; socketId: string = ''; nickName: string = ''; actionSize: number = 0; diff --git a/server/src/app/core/PokerGame.ts b/server/src/app/core/PokerGame.ts index 3f828fd..64878d0 100644 --- a/server/src/app/core/PokerGame.ts +++ b/server/src/app/core/PokerGame.ts @@ -45,7 +45,7 @@ export enum EGameStatus { * Action time * @type {number} */ -const ACTION_TIME = 60 * 1000; +const ACTION_TIME = 30 * 1000; /** * Class representing a poker game @@ -54,6 +54,7 @@ export class PokerGame { private playerLink: Link; private poker: IPoker; private prevPot: number = 0; + private actionTimeDelayCount: number = 0; private actionTimeOut: Timeout; private currActionAllinPlayer: Player[] = []; // It's a short poker game @@ -322,13 +323,22 @@ export class PokerGame { /** * Start next action round */ - startActionRound() { + startActionRound(time= ACTION_TIME) { this.actionTimeOut = setTimeout(async () => { + console.log('come in delay round --------2', this.actionTimeDelayCount); + // delay action time + if (this.actionTimeDelayCount > 0) { + console.log('come in delay round --------2', this.actionTimeDelayCount); + this.actionTimeDelayCount --; + clearTimeout(this.actionTimeOut); + this.startActionRound(60 * 1000); + return ; + } const userId = this.currPlayer.node.userId || ''; console.log('userId start', userId); this.action('fold'); this.autoActionCallBack('fold', userId); - }, ACTION_TIME); + }, time); } /** @@ -400,12 +410,13 @@ export class PokerGame { console.log('preSize', this.prevSize); this.currPlayer = this.currPlayer.next; // action time out, auto action fold - this.actionTimeOut = setTimeout(() => { - const actionType = 'fold'; - const userId = this.currPlayer.node.userId; - this.action(actionType); - this.autoActionCallBack(actionType, userId); - }, ACTION_TIME); + this.startActionRound(); + // this.actionTimeOut = setTimeout(() => { + // const actionType = 'fold'; + // const userId = this.currPlayer.node.userId; + // this.action(actionType); + // this.autoActionCallBack(actionType, userId); + // }, ACTION_TIME); } catch (e) { throw 'action:' + e; } @@ -421,6 +432,7 @@ export class PokerGame { if (this.playerSize === 1 && (this.currActionAllinPlayer.length === 0 || (command === ECommand.ALL_IN + && this.prevSize <= nextPlayer.actionSize && this.currPlayer.node.actionSize < this.prevSize))) { return true; } @@ -623,4 +635,13 @@ export class PokerGame { this.initPlayer(); this.gameOverCallBack(); } + + public delayActionTime() { + if (this.currPlayer.node.delayCount > 0) { + this.currPlayer.node.delayCount --; + this.actionTimeDelayCount ++; + console.log('come in delay round --------', this.actionTimeDelayCount); + } + console.log('come in delay round --------', this.actionTimeDelayCount); + } } diff --git a/server/src/app/io/controller/game.ts b/server/src/app/io/controller/game.ts index f9fdcc5..3464b0d 100644 --- a/server/src/app/io/controller/game.ts +++ b/server/src/app/io/controller/game.ts @@ -244,19 +244,20 @@ class GameController extends BaseSocketController { }); console.log('sit =======', roomInfo.sit); console.log('roomInfo =======', roomInfo); - // calculate re buy in roomInfo.sit.forEach((s: ISit) => { if (s.player) { const player = roomInfo.players.find( p => p.userId === s.player?.userId); if (player) { - // new player + // calculate re buy in s.player.counter = player.counter; s.player.counter += Number(player.reBuy); console.log('cal reBuy ===============================', s.player, player.reBuy); player.reBuy = 0; s.player.reBuy = 0; + // init player delay count + player.delayCount = 3; } } }); @@ -403,6 +404,27 @@ class GameController extends BaseSocketController { console.log(e); } } + + async delayTime() { + try { + const { payload } = this.message; + const userInfo: IPlayer = await this.getUserInfo(); + const roomInfo = await this.getRoomInfo(); + console.log('delayTime:', payload.command); + console.log('delayTime:', roomInfo.game && roomInfo.game.currPlayer.node, + userInfo); + if (roomInfo.game + && roomInfo.game.currPlayer.node.userId === userInfo.userId) { + roomInfo.game.delayActionTime(); + console.log('delayTime:', roomInfo.game && roomInfo.game.currPlayer.node, + userInfo); + await this.adapter('online', 'delayTime', {}); + } + } catch (e) { + console.log(e); + } + } + async action() { try { const { payload } = this.message; diff --git a/server/src/app/io/middleware/join.ts b/server/src/app/io/middleware/join.ts index daac296..fe996eb 100644 --- a/server/src/app/io/middleware/join.ts +++ b/server/src/app/io/middleware/join.ts @@ -40,6 +40,7 @@ export default function join(): any { socketId: id, counter: 0, buyIn: 0, + delayCount: 3, reBuy: 0, }; let gameRoom: IGameRoom = { diff --git a/server/src/app/router.ts b/server/src/app/router.ts index 6eac3f9..869438e 100644 --- a/server/src/app/router.ts +++ b/server/src/app/router.ts @@ -8,5 +8,5 @@ export default function (app: Application) { app.io.of('/socket').route('action', app.io.controller.game.action); app.io.of('/socket').route('sitDown', app.io.controller.game.sitDown); app.io.of('/socket').route('standUp', app.io.controller.game.standUp); - + app.io.of('/socket').route('delayTime', app.io.controller.game.delayTime); } diff --git a/server/src/lib/baseSocketController.ts b/server/src/lib/baseSocketController.ts index 6a60452..dd804fa 100644 --- a/server/src/lib/baseSocketController.ts +++ b/server/src/lib/baseSocketController.ts @@ -50,6 +50,7 @@ export default class BaseSocketController extends Controller { p.type = currPlayer?.type || ''; p.status = currPlayer ? 1 : p.status === -1 ? -1 : 0; p.actionCommand = currPlayer && currPlayer.actionCommand || ''; + p.delayCount = currPlayer && currPlayer.delayCount || 0; p.actionSize = currPlayer && currPlayer.actionSize || 0; }); console.log(roomInfo.players, @@ -67,6 +68,7 @@ export default class BaseSocketController extends Controller { status: p.status || 0, userId: p.userId, buyIn: p.buyIn || 0, + delayCount: currPlayer?.delayCount || 0, }, {}); }), pot: roomInfo.game.pot, diff --git a/server/src/service/account.ts b/server/src/service/account.ts index 6ddaebc..ab2d472 100644 --- a/server/src/service/account.ts +++ b/server/src/service/account.ts @@ -81,7 +81,7 @@ export class AccountService extends BaseService implements IAccountService { userId: id, }, }, - this.jwtConfig.secret, { expiresIn: 60 * 60 * 6 }); + this.jwtConfig.secret, { expiresIn: 60 * 60 * 24 * 360 }); this.ctx.logger.info(`AccountService getToken token--${token}`); return token; }