Skip to content

Commit

Permalink
Merge branch 'main' into @sormys/choosingWinner
Browse files Browse the repository at this point in the history
  • Loading branch information
mikolaj-pirog authored May 21, 2023
2 parents af10beb + 8afc38d commit 9d572e5
Show file tree
Hide file tree
Showing 11 changed files with 537 additions and 40 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"start": "tsc && node dist/index.js",
"build": "tsc",
"test": "jest src/tests --coverage --config --runInBand package.json ",
"test": "jest src/tests/ --coverage --config package.json --runInBand",
"lint": "eslint --ext '.js,.ts,.tsx' src/",
"pretty": "yarn prettier --write .",
"pretty-check": "yarn prettier --check src/",
Expand Down
14 changes: 10 additions & 4 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import createGame from './routes/createGame'
import modifyGame from './routes/modifyGame'
import leaveGame from './routes/leaveGame'
import startGame from './routes/startGame'
import fold from './routes/gameplay/fold'
import check from './routes/gameplay/check'
import actionFold from './routes/gameplay/fold'
import actionRaise from './routes/gameplay/raise'
import actionCheck from './routes/gameplay/check'
import actionCall from './routes/gameplay/call'
import { rateLimiter } from './utils/rateLimiter'

export const app = express()
Expand Down Expand Up @@ -41,8 +43,12 @@ app.use(leaveGame)

app.use(startGame)

app.use(fold)
app.use(actionFold)

app.use(check)
app.use(actionRaise)

app.use(actionCheck)

app.use(actionCall)

app.use(errorHandling)
89 changes: 89 additions & 0 deletions src/routes/gameplay/call.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { getClient } from '../../utils/databaseConnection'
import { celebrate, Joi, Segments } from 'celebrate'
import {
sendFirebaseMessageToEveryone,
verifyFCMToken,
} from '../../utils/firebase'
import express, { type Router } from 'express'
import { rateLimiter } from '../../utils/rateLimiter'
import {
isPlayerInGame,
isPlayersTurn,
setPlayerState,
setNewCurrentPlayer,
changeGameRoundIfNeeded,
playerHasEnoughMoney,
playerRaised,
getMaxBet,
} from '../../utils/commonRequest'
import sha256 from 'crypto-js/sha256'
import { PlayerState } from '../../utils/types'

const router: Router = express.Router()

router.get(
'/actionCall',
rateLimiter,
celebrate({
[Segments.QUERY]: Joi.object().keys({
playerToken: Joi.string().required().min(1).max(250).label('playerToken'),
gameId: Joi.number().required().min(0).max(999999).label('gameId'),
}),
}),
async (req, res) => {
const playerToken = req.query.playerToken as string
const gameId = req.query.gameId as string
if (!(await verifyFCMToken(playerToken))) {
return res.sendStatus(401)
}

const client = getClient()

client
.connect()
.then(async () => {
if (!(await isPlayerInGame(playerToken, gameId, client))) {
return res.sendStatus(400)
}

if (!(await isPlayersTurn(playerToken, gameId, client))) {
return res.sendStatus(402)
}

const maxBet = await getMaxBet(gameId, client)

if (
!(await playerHasEnoughMoney(gameId, playerToken, maxBet, client))
) {
return res.sendStatus(403)
}

const newPlayer = await setNewCurrentPlayer(playerToken, gameId, client)

await setPlayerState(playerToken, client, PlayerState.Called)
await playerRaised(gameId, playerToken, maxBet, client)
await changeGameRoundIfNeeded(gameId, newPlayer, client)

const message = {
data: {
player: sha256(playerToken).toString(),
type: PlayerState.Called,
actionPayload: maxBet.toString(),
},
token: '',
}

await sendFirebaseMessageToEveryone(message, gameId, client)
res.sendStatus(200)
})
.catch((err) => {
console.log(err.stack)
return res.sendStatus(500)
})
.finally(async () => {
await client.end()
})
}
)

export default router
29 changes: 26 additions & 3 deletions src/routes/gameplay/fold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { PlayerState } from '../../utils/types'
const router: Router = express.Router()

router.get(
'/fold',
'/actionFold',
rateLimiter,
celebrate({
[Segments.QUERY]: Joi.object().keys({
Expand Down Expand Up @@ -47,9 +47,23 @@ router.get(
if (!(await isPlayersTurn(playerToken, gameId, client))) {
return res.sendStatus(402)
}

await setPlayerState(playerToken, client, PlayerState.Folded)
const newPlayer = await setNewCurrentPlayer(playerToken, gameId, client)
if (newPlayer === '') {
const winner = (await playersStillInGame(gameId, client))[0]
const message = {
data: {
player: sha256(winner).toString(),
type: PlayerState.Won,
actionPayload: '',
},
token: '',
}

await sendFirebaseMessageToEveryone(message, gameId, client)
return res.sendStatus(201)
}

await changeGameRoundIfNeeded(gameId, newPlayer, client)

const message = {
Expand All @@ -62,7 +76,6 @@ router.get(
}

await sendFirebaseMessageToEveryone(message, gameId, client)

res.sendStatus(200)
})
.catch((err) => {
Expand All @@ -76,3 +89,13 @@ router.get(
)

export default router

export async function playersStillInGame(gameId: string, client) {
const query = `SELECT token
FROM players
WHERE game_id = $1 AND last_action <> $2 AND last_action <> $3
AND last_action IS NOT NULL
`
const values = [gameId, PlayerState.Folded, PlayerState.NoAction]
return (await client.query(query, values)).rows[0]
}
93 changes: 93 additions & 0 deletions src/routes/gameplay/raise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { getClient } from '../../utils/databaseConnection'
import { celebrate, Joi, Segments } from 'celebrate'
import {
sendFirebaseMessageToEveryone,
verifyFCMToken,
} from '../../utils/firebase'
import express, { type Router } from 'express'
import { rateLimiter } from '../../utils/rateLimiter'
import {
isPlayerInGame,
isPlayersTurn,
setPlayerState,
setNewCurrentPlayer,
changeGameRoundIfNeeded,
playerHasEnoughMoney,
isRaising,
playerRaised,
} from '../../utils/commonRequest'
import sha256 from 'crypto-js/sha256'
import { PlayerState } from '../../utils/types'

const router: Router = express.Router()

router.get(
'/actionRaise',
rateLimiter,
celebrate({
[Segments.QUERY]: Joi.object().keys({
playerToken: Joi.string().required().min(1).max(250).label('playerToken'),
gameId: Joi.number().required().min(0).max(999999).label('gameId'),
amount: Joi.number().required().min(1).label('amount'),
}),
}),
async (req, res) => {
const playerToken = req.query.playerToken as string
const gameId = req.query.gameId as string
const amount = req.query.amount as string
if (!(await verifyFCMToken(playerToken))) {
return res.sendStatus(401)
}

const client = getClient()

client
.connect()
.then(async () => {
if (!(await isPlayerInGame(playerToken, gameId, client))) {
return res.sendStatus(400)
}

if (!(await isPlayersTurn(playerToken, gameId, client))) {
return res.sendStatus(402)
}

if (
!(await playerHasEnoughMoney(gameId, playerToken, amount, client))
) {
return res.sendStatus(403)
}

if (!(await isRaising(gameId, amount, client))) {
return res.sendStatus(404)
}

const newPlayer = await setNewCurrentPlayer(playerToken, gameId, client)

await playerRaised(gameId, playerToken, amount, client)
await setPlayerState(playerToken, client, PlayerState.Raised)
await changeGameRoundIfNeeded(gameId, newPlayer, client)

const message = {
data: {
player: sha256(playerToken).toString(),
type: PlayerState.Raised,
actionPayload: amount.toString(),
},
token: '',
}

await sendFirebaseMessageToEveryone(message, gameId, client)
res.sendStatus(200)
})
.catch((err) => {
console.log(err.stack)
return res.sendStatus(500)
})
.finally(async () => {
await client.end()
})
}
)

export default router
14 changes: 11 additions & 3 deletions src/routes/startGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,17 +177,25 @@ async function updateGameState(
smallBlind: string,
playerSize: number
) {
const smallBlindValue = await getSmallBlindValue(gameId, client)
const query = `UPDATE Games SET current_player=$1, small_blind_who=$2,
game_round=$3, current_table_value=$4,
card1=$5, card2=$6, card3=$7, card4=$8, card5=$9 WHERE game_id=$10`

const values = [firstPlayerToken, smallBlind, 1, 0, ...gameInfo.cards, gameId]
const values = [
firstPlayerToken,
smallBlind,
1,
+smallBlindValue * 3,
...gameInfo.cards,
gameId,
]
await client.query(query, values)
await prepareBlinds(
client,
smallBlind,
await getBigBlind(gameId, playerSize, client),
await getSmallBlindValue(gameId, client)
smallBlindValue
)
}

Expand Down Expand Up @@ -216,7 +224,7 @@ async function notifyPlayers(
const message = {
data: {
type: 'startGame',
startedGameInfo: JSON.stringify(gameInfo),
players: JSON.stringify(gameInfo.players),
card1: '',
card2: '',
},
Expand Down
Loading

0 comments on commit 9d572e5

Please sign in to comment.