Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@aetn23/call #53

Merged
merged 26 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d768d69
Added check request
sormys May 21, 2023
b0bbae6
Added tests for check
sormys May 21, 2023
91444c4
Raise skeleton
mikolaj-pirog May 21, 2023
3cada4d
Fixed tests
sormys May 21, 2023
b9e28a3
Kinda working raise
mikolaj-pirog May 21, 2023
51624c3
Apply sugestion, kinda fix tests
mikolaj-pirog May 21, 2023
0c87762
Minor changes
sormys May 21, 2023
25ade31
Merge resolve
mikolaj-pirog May 21, 2023
a025f1c
Merge
mikolaj-pirog May 21, 2023
9bf96c3
Remove wron line
mikolaj-pirog May 21, 2023
3f4b160
remove logs
mikolaj-pirog May 21, 2023
48e6518
Fixes to compatibility with Android app
Kwasow May 21, 2023
f2a0e3b
Add blinds to table in smart game
mikolaj-pirog May 21, 2023
c9e8c4e
Merge branch '@aetn23/raise' of github.com:poker-io/pokerio-server in…
mikolaj-pirog May 21, 2023
4ed0be0
Add blind rasing logic
mikolaj-pirog May 21, 2023
f241042
call, and modify logic for checkinfg if blidns have enough money
mikolaj-pirog May 21, 2023
776d3fe
some tests
mikolaj-pirog May 21, 2023
aebbf60
AA
mikolaj-pirog May 21, 2023
7037b75
Mergegi
mikolaj-pirog May 21, 2023
18b1c53
fixed fold
sormys May 21, 2023
d353a41
ADD Miising
mikolaj-pirog May 21, 2023
5378ae4
Merge branch '@aetn23/call' of github.com:poker-io/pokerio-server int…
mikolaj-pirog May 21, 2023
b2a6871
Fixing fold
sormys May 21, 2023
1399387
Merge branch '@aetn23/call' of github.com:poker-io/pokerio-server int…
sormys May 21, 2023
ebd97df
asdasd
mikolaj-pirog May 21, 2023
4ff49c3
Merge branch '@aetn23/call' of github.com:poker-io/pokerio-server int…
mikolaj-pirog May 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import startGame from './routes/startGame'
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 @@ -48,4 +49,6 @@ 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
13 changes: 12 additions & 1 deletion src/routes/gameplay/fold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ router.get(
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(newPlayer).toString(),
player: sha256(winner).toString(),
type: PlayerState.Won,
actionPayload: '',
},
Expand Down Expand Up @@ -88,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]
}
98 changes: 98 additions & 0 deletions src/tests/call.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { app } from '../app'
import request from 'supertest'
import { getClient } from '../utils/databaseConnection'
import type { NewGameInfo } from '../utils/types'
import { getGameIdAndStatus, getPlayersInGame } from '../utils/commonRequest'

test('Call, correct arguments 1', async () => {
const gameMasterToken = 'CALLTEST'
const gameMasterNick = 'CALLNICK'
const playerToken = 'CALLTEST2'
const playerNick = 'CALLNICK2'
const player2Token = 'CALLTEST3'
const player2Nick = 'CALLNICK3'

const client = getClient()
await client.connect()
const res = await request(app)
.get(
`/createGame?creatorToken=${gameMasterToken}&nickname=${gameMasterNick}`
)
.expect(200)

const key = (res.body as NewGameInfo).gameId
await request(app)
.get(
`/joinGame?playerToken=${playerToken}&nickname=${playerNick}&gameId=${key}`
)
.expect(200)

await request(app)
.get(
`/joinGame?playerToken=${player2Token}&nickname=${player2Nick}&gameId=${key}`
)
.expect(200)

await request(app)
.get(`/startGame?creatorToken=${gameMasterToken}`)
.expect(200)

const gameId =
(await getGameIdAndStatus(gameMasterToken, client)).gameId ?? ''
const players = await getPlayersInGame(gameId, client)
console.log(players)

await request(app)
.get(
`/actionRaise?playerToken=${players[1].token}&gameId=${gameId}&amount=5`
)
.expect(402)

await request(app)
.get(
`/actionRaise?playerToken=${players[0].token}&gameId=${gameId}&amount=300`
)
.expect(200)
await request(app)
.get(`/actionCall?playerToken=${players[1].token}&gameId=${gameId}`)
.expect(200)
const getRound = 'SELECT game_round FROM Games WHERE game_id=$1'

expect(
await (
await client.query(getRound, [gameId])
).rows[0].game_round
).toEqual('1') // Player 2 can still act

await request(app)
.get(
`/actionRaise?playerToken=${players[2].token}&gameId=${gameId}&amount=2`
)
.expect(404)

await request(app)
.get(
`/actionRaise?playerToken=${players[2].token}&gameId=${gameId}&amount=2000000000`
)
.expect(403)

await request(app)
.get(
`/actionRaise?playerToken=${players[2].token}&gameId=${gameId}&amount=400`
)
.expect(200)

await request(app)
.get(`/actionCall?playerToken=${players[0].token}&gameId=${gameId}`)
.expect(200)

await request(app)
.get(`/actionFold?playerToken=${players[1].token}&gameId=${gameId}`)
.expect(200)

await request(app)
.get(`/actionFold?playerToken=${players[2].token}&gameId=${gameId}`)
.expect(402) // round ended

await client.end()
}, 20000)
34 changes: 30 additions & 4 deletions src/utils/commonRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ export async function setPlayerState(
await client.query(query, [state, playerToken])
}

export async function getPlayerState(playerToken: string, client: Client) {
const query = 'SELECT last_action FROM Players WHERE player_token=$1'
await client.query(query, [playerToken])
export async function getPlayerState(
playerToken: string,
client: Client
): Promise<string> {
const query = 'SELECT last_action FROM Players WHERE token=$1'
return (await client.query(query, [playerToken])).rows[0].last_action
}

export async function setNewCurrentPlayer(
Expand Down Expand Up @@ -92,6 +95,7 @@ export async function setNewCurrentPlayer(
playersTurns.rows[i].token,
gameId,
])
console.log(playersTurns.rows[i].token)
return playersTurns.rows[i].token
}
}
Expand All @@ -100,6 +104,7 @@ export async function setNewCurrentPlayer(
playersTurns.rows[0].token,
gameId,
])
console.log(playersTurns.rows[0].token)
return playersTurns.rows[0].token
}
}
Expand Down Expand Up @@ -197,7 +202,20 @@ export async function playerHasEnoughMoney(
amount: string,
client: Client
): Promise<boolean> {
const query = 'SELECT 1 FROM Players WHERE token=$1 AND funds+bet>=$2'
const smallBlindValue = await getSmallBlindValue(gameId, client)
const playerSize = (await getPlayersInGame(gameId, client)).length
const smallBlind = await getSmallBlind(gameId, playerSize, client)
const smallBlindState = await getPlayerState(smallBlind, client)
const bigBlind = await getBigBlind(gameId, playerSize, client)
const bigBlindState = await getPlayerState(bigBlind, client)

if (playerToken === smallBlind && smallBlindState == null) {
amount = (+amount - +smallBlindValue).toString()
} else if (playerToken === bigBlind && bigBlindState == null) {
amount = (+amount - +smallBlindValue * 2).toString()
}

const query = 'SELECT 1 FROM Players WHERE token=$1 AND funds>=$2'
return (await client.query(query, [playerToken, amount])).rowCount !== 0
}

Expand Down Expand Up @@ -227,3 +245,11 @@ export async function playerRaised(
await client.query(setNewBet, [amount, playerToken])
await client.query(putMoneyToTable, [parseInt(amount) - oldBet, gameId])
}

export async function getMaxBet(
gameId: string,
client: Client
): Promise<string> {
const query = 'SELECT MAX(bet) as max FROM Players WHERE game_id=$1'
return (await client.query(query, [gameId])).rows[0].max
}