source: pages/api/postgre/index.js@ 55701f0

main
Last change on this file since 55701f0 was 55701f0, checked in by anastasovv <simon@…>, 23 months ago

Added 1 second update_state calls in blackjack

  • Property mode set to 100644
File size: 23.9 KB
Line 
1import { v4 as uuidv4 } from 'uuid';
2
3import axios from 'axios';
4
5require('dotenv').config();
6
7const crypto = require('crypto');
8
9import { progressRoundTillTheEnd } from '../poker/tableSpecific';
10
11const Pool = require('pg').Pool
12const pool = new Pool({
13 connectionString: `postgres://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}/${process.env.POSTGRES_DB}`
14});
15
16export default function handler(req, res) {
17 /**
18 * GET method
19 */
20 if (req.method === 'GET') {
21 /**
22 * /---------------------- GET ----------------------/
23 * If the player won credits, update them in the database.
24 * Also, update the stats in the database.
25 * @action give_credits
26 * @param session_id
27 * @param credits
28 */
29 if (req.query?.action === 'add_credits' && req.query?.session_id && req.query?.credits) {
30 const session_id = req.query.session_id
31 const session = sessions.find(session => session.id === session_id)
32
33 if (session) {
34 session.lastActivity = Date.now();
35
36 if (parseInt(req.query.credits) > 0) {
37 session.credits = session.credits + parseInt(req.query.credits)
38
39 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
40 if (error) throw error;
41 });
42 }
43
44 if (req.query?.dont_update_stats) {
45 // continue
46 } else {
47 pool.query('SELECT * FROM stats WHERE username = $1', [session.username], (error, results) => {
48 if (error) throw error;
49
50 if (results.rows.length > 0) {
51 const stats = results.rows[0]
52
53 if (parseInt(req.query.credits) > 0) {
54 pool.query('UPDATE stats SET money_earned = $1 WHERE username = $2', [parseInt(stats.money_earned) + parseInt(req.query.credits), session.username], (error, results) => {
55 if (error) throw error;
56 });
57 }
58
59 if (req.query?.game === 'blackjack') {
60 if (req.query?.outcome === 'player_busted' || req.query?.outcome === 'player_lost') {
61 pool.query('UPDATE stats SET blackjack_games = $1 WHERE username = $2', [parseInt(stats.blackjack_games) + 1, session.username], (error, results) => {
62 if (error) throw error;
63 });
64 }
65 else if (req.query?.outcome === 'dealer_busted' || req.query?.outcome === 'player_won') {
66 pool.query('UPDATE stats SET blackjack_games = $1, blackjack_won_games = $2 WHERE username = $3', [parseInt(stats.blackjack_games) + 1, parseInt(stats.blackjack_won_games) + 1, session.username], (error, results) => {
67 if (error) throw error;
68 });
69 }
70 }
71 else if (req.query?.game === 'roulette') {
72 if (req.query?.outcome === 'lost') {
73 pool.query('UPDATE stats SET roulette_games = $1 WHERE username = $2', [parseInt(stats.roulette_games) + 1, session.username], (error, results) => {
74 if (error) throw error;
75 });
76 }
77 else if (req.query?.outcome === 'won') {
78 pool.query('UPDATE stats SET roulette_games = $1, roulette_won_games = $2 WHERE username = $3', [parseInt(stats.roulette_games) + 1, parseInt(stats.roulette_won_games) + 1, session.username], (error, results) => {
79 if (error) throw error;
80 });
81 }
82 }
83 else if (req.query?.game === 'poker') {
84 if (req.query?.outcome === 'lost') {
85 pool.query('UPDATE stats SET poker_games = $1 WHERE username = $2', [parseInt(stats.poker_games) + 1, session.username], (error, results) => {
86 if (error) throw error;
87 });
88 }
89 else if (req.query?.outcome === 'won') {
90 pool.query('UPDATE stats SET poker_games = $1, poker_won_games = $2 WHERE username = $3', [parseInt(stats.poker_games) + 1, parseInt(stats.poker_won_games) + 1, session.username], (error, results) => {
91 if (error) throw error;
92 });
93 }
94 }
95 }
96 });
97 }
98
99 update_sessions_to_database();
100
101 res.json({
102 success: true,
103 credits: session.credits,
104 })
105
106 return ;
107 }
108
109 res.json({
110 success: false,
111 })
112 }
113
114 /**
115 * /---------------------- GET ----------------------/
116 * The player lost credits, update this in the database.
117 * @action take_credits
118 * @param session_id
119 * @param credits
120 */
121 if (req.query?.action === 'take_credits' && req.query?.session_id && req.query?.credits) {
122 const session_id = req.query.session_id
123 const session = sessions.find(session => session.id === session_id)
124
125 let takeWhatYouCan = false;
126 if (req.query?.takeWhatYouCan === "true") takeWhatYouCan = true;
127
128 if (session) {
129 session.lastActivity = Date.now();
130
131 if (session.credits < parseInt(req.query.credits)) {
132 if (takeWhatYouCan) {
133 session.credits = 0;
134 }
135 else {
136 res.json({
137 success: false,
138 });
139
140 return ;
141 }
142 }
143 else {
144 session.credits = session.credits - parseInt(req.query.credits)
145 }
146
147 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
148 if (error) throw error;
149 });
150
151 pool.query('SELECT * FROM stats WHERE username = $1', [session.username], (error, results) => {
152 if (error) throw error;
153
154 if (results.rows.length > 0) {
155 const stats = results.rows[0]
156
157 pool.query('UPDATE stats SET money_bet = $1 WHERE username = $2', [parseInt(stats.money_bet) + parseInt(req.query.credits), session.username], (error, results) => {
158 if (error) throw error;
159 });
160 }
161 });
162
163 update_sessions_to_database();
164
165 res.json({
166 success: true,
167 credits: session.credits,
168 })
169 return ;
170 }
171
172 res.json({
173 success: false,
174 })
175 }
176
177 /**
178 * /---------------------- GET ----------------------/
179 * Get stats for the player, so we can display them in the front end.
180 * @action get_stats
181 * @param session_id
182 */
183 if (req.query?.action === 'get_stats' && req.query?.session_id) {
184 const session_id = req.query.session_id
185 const session = sessions.find(session => session.id === session_id)
186
187 if (session) {
188 session.lastActivity = Date.now();
189
190 pool.query('SELECT * FROM stats WHERE username = $1', [session.username], (error, results) => {
191 if (error) throw error;
192
193 if (results.rows.length > 0) {
194 res.json({
195 success: true,
196 stats: results.rows[0],
197 })
198 }
199 else {
200 res.json({
201 success: false,
202 })
203 }
204 });
205
206 return ;
207 }
208
209 res.json({
210 success: false,
211 })
212 }
213
214 /**
215 * /---------------------- GET ----------------------/
216 * Checks if the player is logged in, and returns his session if so.
217 * @action check_if_logged_in
218 * @param session_id
219 */
220 if (req.query?.action === 'check_if_logged_in' && req.query?.session_id) {
221 const session_id = req.query.session_id
222 const session = sessions.find(session => session.id === session_id)
223
224 if (session) {
225 res.json({
226 success: true,
227 displayName: session.displayName,
228 session_id: session.id,
229 credits: session.credits,
230 })
231 return ;
232 }
233
234 res.json({
235 success: false,
236 })
237 }
238
239 /**
240 * /---------------------- GET ----------------------/
241 * Takes the credits in the player's session, and updates the database.
242 * Logs the player out and kills the session.
243 * @action logout
244 * @param session_id
245 */
246 if (req.query?.action === 'logout' && req.query?.session_id) {
247 const session_id = req.query.session_id
248 const session = sessions.find(session => session.id === session_id)
249
250 if (session) {
251 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
252 if (error) throw error;
253 });
254
255 sessions.splice(sessions.indexOf(session), 1);
256
257 axios.get(`${process.env.HOME_URL}/api/blackjack/?action=remove_room&session_id=${session_id}`);
258
259 update_sessions_to_database();
260 }
261
262 res.json({
263 success: true,
264 message: 'Successfully logged out',
265 })
266 }
267 }
268
269 /**
270 * POST method
271 */
272 if (req.method === 'POST') {
273 const { body } = req;
274
275 /**
276 * /---------------------- POST ----------------------/
277 * Deposits money from credit card to game account.
278 * @action register
279 * @param session_id
280 * @param data
281 */
282 if (body?.action === 'deposit') {
283 // checks
284 if (body?.session_id == "undefined" || body?.session_id == "null" || body?.session_id == "") {
285 res.json({
286 success: false,
287 message: 'You are not logged in. Please log in first.',
288 });
289 return ;
290 }
291 if (body?.data?.name == "undefined" || body?.data?.name == "null" || body?.data?.name == "") {
292 res.json({
293 success: false,
294 message: 'Name field cannot be empty',
295 });
296 return ;
297 }
298 if (body?.data?.card == "undefined" || body?.data?.card == "null" || body?.data?.card == "") {
299 res.json({
300 success: false,
301 message: 'Card numbers field cannot be empty',
302 });
303 return ;
304 }
305 if (body?.data?.expire == "undefined" || body?.data?.expire == "null" || body?.data?.expire == "") {
306 res.json({
307 success: false,
308 message: 'Expiration date field cannot be empty',
309 });
310 return ;
311 }
312 if (body?.data?.ccv == "undefined" || body?.data?.ccv == "null" || body?.data?.ccv == "") {
313 res.json({
314 success: false,
315 message: 'CCV field cannot be empty',
316 });
317 return ;
318 }
319 if (body?.data?.amount == "undefined" || body?.data?.amount == "null" || body?.data?.amount == "") {
320 res.json({
321 success: false,
322 message: 'Amount field cannot be empty',
323 });
324 return ;
325 }
326 if (parseInt(body?.data?.amount) > 5000) {
327 res.json({
328 success: false,
329 message: 'Failed to deposit. Insufficient credit on card.',
330 });
331 return ;
332 }
333
334 let session = sessions.find(session => session.id === body?.session_id)
335
336 if (session) {
337 if (parseInt(body.data.amount) > 0) {
338 session.credits = session.credits + parseInt(body.data.amount)
339
340 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
341 if (error) throw error;
342
343 res.json({
344 success: true,
345 credits: session.credits
346 })
347
348 update_sessions_to_database();
349 });
350 }
351 }
352 }
353
354 /**
355 * /---------------------- POST ----------------------/
356 * Withdraws money from game account to personal account.
357 * @action register
358 * @param session_id
359 * @param data
360 */
361 if (body?.action === 'withdraw') {
362 // checks
363 if (body?.session_id == "undefined" || body?.session_id == "null" || body?.session_id == "") {
364 res.json({
365 success: false,
366 message: 'You are not logged in. Please log in first.',
367 });
368 return ;
369 }
370 if (body?.data?.citibank == "undefined" || body?.data?.citibank == "null" || body?.data?.citibank == "") {
371 res.json({
372 success: false,
373 message: 'Bank name field cannot be empty',
374 });
375 return ;
376 }
377 if (body?.data?.iban == "undefined" || body?.data?.iban == "null" || body?.data?.iban == "") {
378 res.json({
379 success: false,
380 message: 'IBAN code field cannot be empty',
381 });
382 return ;
383 }
384 if (body?.data?.bic == "undefined" || body?.data?.bic == "null" || body?.data?.bic == "") {
385 res.json({
386 success: false,
387 message: 'BIC code field cannot be empty',
388 });
389 return ;
390 }
391 if (body?.data?.beneficiary == "undefined" || body?.data?.beneficiary == "null" || body?.data?.beneficiary == "") {
392 res.json({
393 success: false,
394 message: 'Beneficiary name field cannot be empty',
395 });
396 return ;
397 }
398 if (body?.data?.address == "undefined" || body?.data?.address == "null" || body?.data?.address == "") {
399 res.json({
400 success: false,
401 message: 'Bank address field cannot be empty',
402 });
403 return ;
404 }
405 if (body?.data?.amount == "undefined" || body?.data?.amount == "null" || body?.data?.amount == "") {
406 res.json({
407 success: false,
408 message: 'Amount field cannot be empty',
409 });
410 return ;
411 }
412
413 let session = sessions.find(session => session.id === body?.session_id)
414
415 if (session) {
416 if (parseInt(body.data.amount) > 0) {
417 session.credits = Math.max(session.credits - parseInt(body.data.amount), 0)
418
419 pool.query('UPDATE players SET credits = $1 WHERE username = $2', [session.credits, session.username], (error, results) => {
420 if (error) throw error;
421
422 res.json({
423 success: true,
424 credits: session.credits
425 })
426
427 update_sessions_to_database();
428 });
429 }
430 }
431 }
432
433 /**
434 * /---------------------- POST ----------------------/
435 * Sends a complaint.
436 * @action complain
437 * @param session_id
438 * @param description
439 */
440 if (body?.action === 'complain') {
441 // checks
442 if (body?.session_id == "undefined" || body?.session_id == "null" || body?.session_id == "") {
443 res.json({
444 success: false,
445 message: 'You are not logged in. Please log in first.',
446 });
447 return ;
448 }
449 if (body?.description == "undefined" || body?.description == "null" || body?.description == "") {
450 res.json({
451 success: false,
452 message: 'You cannot submit an empty complaint.',
453 });
454 return ;
455 }
456
457 let session = sessions.find(session => session.id === body.session_id)
458
459 if (session) {
460 // date, by, description, answered
461 const date = new Date();
462 pool.query('INSERT INTO complaints (date, by, description, answered) VALUES ($1, $2, $3, $4)', [date, session.username, body.description, false], (error, complaintResults) => {
463 if (error) throw error;
464
465 res.json({
466 success: true,
467 })
468 });
469 }
470 }
471
472 /**
473 * /---------------------- POST ----------------------/
474 * Checks if the entered account info is good, and registers a new user in the database if so.
475 * @action register
476 * @param username
477 * @param displayName
478 * @param password
479 */
480 if (body?.action === 'register') {
481 // checks
482 if (body?.username == "undefined" || body?.username == "null" || body?.username == "") {
483 res.json({
484 success: false,
485 message: 'Username is required',
486 });
487 return ;
488 }
489 if (/[^a-zA-Z]/g.test(body?.username)) {
490 res.json({
491 success: false,
492 message: 'Username must contain only letters',
493 })
494 return ;
495 }
496 if (body?.displayName == "undefined" || body?.displayName == "null" || body?.displayName == "") {
497 res.json({
498 success: false,
499 message: 'Display name is required',
500 });
501 return ;
502 }
503 if (body?.displayName?.toLowerCase() === "guest") {
504 res.json({
505 success: false,
506 message: 'Display name cannot be guest',
507 });
508 return ;
509 }
510 if (body?.password == "undefined" || body?.password == "null" || body?.password == "") {
511 res.json({
512 success: false,
513 message: 'Password is required',
514 });
515 return ;
516 }
517
518 // everything's okay
519 body.username = body.username.toLowerCase()
520
521 // hash password
522 const salt = crypto.randomBytes(16).toString('hex');
523 const hashedPassword = crypto.pbkdf2Sync(body.password, salt, 1000, 64, 'sha512').toString('hex');
524
525 // check if user already exists
526 pool.query('SELECT * FROM users WHERE username = $1', [body.username], (error, results) => {
527 if (error) throw error;
528
529 if (results.rows.length > 0) {
530 res.json({
531 success: false,
532 message: 'Username already exists',
533 });
534 return ;
535 }
536
537 // store user in database
538 pool.query('INSERT INTO users (username, password, salt) VALUES ($1, $2, $3)', [body.username, hashedPassword, salt], (error, usersResults) => {
539 if (error) throw error;
540
541 pool.query('INSERT INTO players (username, display_name, credits) VALUES ($1, $2, $3)', [body.username, body.displayName, 1000], (error, playersResults) => {
542 if (error) throw error;
543
544 pool.query('INSERT INTO stats (username, blackjack_games, roulette_games, poker_games, blackjack_won_games, roulette_won_games, poker_won_games, money_bet, money_earned) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)', [body.username, 0, 0, 0, 0, 0, 0, 0, 0], (error, statsResults) => {
545 if (error) throw error;
546
547 res.json({
548 success: true,
549 message: 'Registration successful',
550 });
551 return ;
552 });
553 });
554 });
555 });
556 }
557
558 /**
559 * /---------------------- POST ----------------------/
560 * Checks if the entered account info is good, and logs the user in if so.
561 * @action login
562 * @param username
563 * @param password
564 */
565 if (body?.action === 'login') {
566 // checks
567 if (body?.username == "undefined" || body?.username == "null" || body?.username == "") {
568 res.json({
569 success: false,
570 message: 'Username is required',
571 });
572 return ;
573 }
574 if (/[^a-zA-Z]/g.test(body?.username)) {
575 res.json({
576 success: false,
577 message: 'Username must contain only letters',
578 })
579 return ;
580 }
581 if (body?.password == "undefined" || body?.password == "null" || body?.password == "") {
582 res.json({
583 success: false,
584 message: 'Password is required',
585 });
586 return ;
587 }
588
589 // everything's okay
590 body.username = body.username.toLowerCase();
591
592 // check if user exists
593 pool.query('SELECT * FROM users WHERE username = $1', [body.username], (error, usersResults) => {
594 if (error) throw error;
595
596 if (usersResults.rows.length === 0) {
597 res.json({
598 success: false,
599 message: 'User does not exist. Try Registering instead.',
600 });
601 return ;
602 }
603 else {
604 if (usersResults.rows.length > 0) {
605 const user = usersResults.rows[0];
606 const salt = user.salt;
607 const hashedPassword = crypto.pbkdf2Sync(body.password, salt, 1000, 64, 'sha512').toString('hex');
608
609 if (hashedPassword === user.password) {
610 pool.query('SELECT * FROM players WHERE username = $1', [body.username], (error, playersResults) => {
611 if (playersResults.rows.length > 0) {
612 let session = sessions.find(session => session.username === playersResults.rows[0].username)
613
614 if (session) {
615 // Already logged in
616 res.json({
617 success: true,
618 message: 'Login successful',
619 session: session,
620 })
621 }
622 else {
623 // create a session
624 session = {
625 id: uuidv4(),
626 displayName: playersResults.rows[0].display_name,
627 username: playersResults.rows[0].username,
628 credits: playersResults.rows[0].credits,
629 lastActivity: Date.now(),
630 }
631
632 sessions.push(session);
633
634 update_sessions_to_database();
635
636 res.json({
637 success: true,
638 message: 'Login successful',
639 session: session,
640 })
641 }
642
643 return ;
644 }
645 });
646 }
647 else {
648 res.json({
649 success: false,
650 message: 'Username and password do not match.',
651 });
652 }
653 }
654 }
655 });
656 }
657 }
658}
659
660
661/**
662 * User session data
663 */
664export var sessions = []
665
666export function update_sessions_to_database() {
667 pool.query('UPDATE sessions SET data = $1 WHERE identifier = $2', [JSON.stringify(sessions), 'sessions_data'], (error, results) => {
668 if (error) throw error;
669 });
670}
671
672export function load_sessions_from_database() {
673 pool.query('SELECT data FROM sessions WHERE identifier = $1', ['sessions_data'], (error, results) => {
674 if (error) throw error;
675
676 sessions = JSON.parse(results?.rows[0]?.data || []);
677 });
678}
679load_sessions_from_database();
680
681/**
682 * Poker game data
683 */
684export var tables = []
685
686export function cleanTables() {
687 tables = [];
688}
689
690export function update_tables_to_database() {
691 tables = tables.map(table => ({...table, turnTimeout: null}));
692
693 pool.query('UPDATE poker SET data = $1 WHERE identifier = $2', [JSON.stringify(tables), 'poker_data'], (error, results) => {
694 if (error) throw error;
695 });
696}
697
698export async function load_tables_from_database() {
699 pool.query('SELECT data FROM poker WHERE identifier = $1', ['poker_data'], (error, results) => {
700 if (error) throw error;
701
702 tables = JSON.parse(results?.rows[0]?.data || []);
703
704 tables.forEach(table => {
705 if (table.started) {
706 progressRoundTillTheEnd(table.id);
707 }
708 })
709
710 cleanTables();
711
712 update_tables_to_database();
713 });
714}
715load_tables_from_database();
716
717/**
718 * Roulette game data
719 */
720export var game = {}
721
722export function update_game_to_database() {
723 pool.query('UPDATE roulette SET data = $1 WHERE identifier = $2', [JSON.stringify(game), 'roulette_data'], (error, results) => {
724 if (error) throw error;
725 });
726}
727
728export async function load_game_from_database() {
729 pool.query('SELECT data FROM roulette WHERE identifier = $1', ['roulette_data'], (error, results) => {
730 if (error) throw error;
731
732 game = JSON.parse(results?.rows[0]?.data || []);
733
734 game.loaded = true;
735 });
736}
737load_game_from_database();
738
739/**
740 * Blackjack game data
741 */
742export var rooms = []
743
744export function update_rooms_to_database() {
745 let tmpRooms = [];
746
747 for (let key in rooms) {
748 if (key === "loaded") continue ;
749
750 tmpRooms.push(rooms[key]);
751 tmpRooms[tmpRooms.length - 1].id = key;
752 }
753
754 pool.query('UPDATE blackjack SET data = $1 WHERE identifier = $2', [JSON.stringify(tmpRooms), 'blackjack_data'], (error, results) => {
755 if (error) throw error;
756 });
757}
758
759export async function load_rooms_from_database() {
760 pool.query('SELECT data FROM blackjack WHERE identifier = $1', ['blackjack_data'], (error, results) => {
761 if (error) throw error;
762
763 if (results?.rows[0]?.data) {
764 const tmpRooms = JSON.parse(results.rows[0].data);
765
766 tmpRooms.forEach(room => {
767 rooms[room.id] = {...room, id: ''}
768 })
769
770 rooms["loaded"] = true;
771 }
772 });
773}
774load_rooms_from_database();
Note: See TracBrowser for help on using the repository browser.