summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-10-29 22:16:15 +0100
committersalmonik <salmonik@tuta.io>2026-10-29 22:16:15 +0100
commitbc0de9955c375cf27d52c9934403964205afc182 (patch)
tree42799fb426fb0ec164f44c92a63525003c582f35 /src/server
parentinitial connection timeout set to 10s (diff)
downloadzagan-bet-bc0de9955c375cf27d52c9934403964205afc182.tar.gz
zagan-bet-bc0de9955c375cf27d52c9934403964205afc182.zip
formatting
Diffstat (limited to '')
-rw-r--r--src/server/core.rs45
-rw-r--r--src/server/games/blackjack.rs4
-rw-r--r--src/server/games/roulette.rs10
-rw-r--r--src/server/games/slots.rs4
-rw-r--r--src/server/setup.rs20
5 files changed, 25 insertions, 58 deletions
diff --git a/src/server/core.rs b/src/server/core.rs
index e0f0ff2..4b68ccb 100644
--- a/src/server/core.rs
+++ b/src/server/core.rs
@@ -49,11 +49,7 @@ impl ServerCore {
49 Self::with_registry(conn, GameRegistry::with_defaults(), DEFAULT_COST) 49 Self::with_registry(conn, GameRegistry::with_defaults(), DEFAULT_COST)
50 } 50 }
51 51
52 pub fn with_registry( 52 pub fn with_registry(conn: Connection, registry: GameRegistry, bcrypt_cost: u32) -> Self {
53 conn: Connection,
54 registry: GameRegistry,
55 bcrypt_cost: u32,
56 ) -> Self {
57 Self { 53 Self {
58 conn, 54 conn,
59 sessions: SessionManager::new(), 55 sessions: SessionManager::new(),
@@ -115,8 +111,7 @@ impl ServerCore {
115 } 111 }
116 "GAME_INFO" => { 112 "GAME_INFO" => {
117 if parts.len() != 2 { 113 if parts.len() != 2 {
118 "ERROR Invalid GAME_INFO format. Usage: GAME_INFO <game_type>" 114 "ERROR Invalid GAME_INFO format. Usage: GAME_INFO <game_type>".to_string()
119 .to_string()
120 } else { 115 } else {
121 match self.registry.get_game(parts[1]) { 116 match self.registry.get_game(parts[1]) {
122 Some(game) => format!( 117 Some(game) => format!(
@@ -143,16 +138,14 @@ impl ServerCore {
143 } 138 }
144 "CRASH_CASHOUT" => { 139 "CRASH_CASHOUT" => {
145 if parts.len() != 2 { 140 if parts.len() != 2 {
146 "ERROR Invalid CRASH_CASHOUT format. Usage: CRASH_CASHOUT <session>" 141 "ERROR Invalid CRASH_CASHOUT format. Usage: CRASH_CASHOUT <session>".to_string()
147 .to_string()
148 } else { 142 } else {
149 self.handle_crash_end(state, parts[1], false) 143 self.handle_crash_end(state, parts[1], false)
150 } 144 }
151 } 145 }
152 "CRASH_FORFEIT" => { 146 "CRASH_FORFEIT" => {
153 if parts.len() != 2 { 147 if parts.len() != 2 {
154 "ERROR Invalid CRASH_FORFEIT format. Usage: CRASH_FORFEIT <session>" 148 "ERROR Invalid CRASH_FORFEIT format. Usage: CRASH_FORFEIT <session>".to_string()
155 .to_string()
156 } else { 149 } else {
157 self.handle_crash_end(state, parts[1], true) 150 self.handle_crash_end(state, parts[1], true)
158 } 151 }
@@ -351,12 +344,8 @@ impl ServerCore {
351 if hand.player.len() != 2 { 344 if hand.player.len() != 2 {
352 return "ERROR Double is only allowed on the first two cards".to_string(); 345 return "ERROR Double is only allowed on the first two cards".to_string();
353 } 346 }
354 if database::extend_reservation( 347 if database::extend_reservation(&mut self.conn, session_id, hand.base_bet as i64)
355 &mut self.conn, 348 .is_err()
356 session_id,
357 hand.base_bet as i64,
358 )
359 .is_err()
360 { 349 {
361 return "ERROR Insufficient balance".to_string(); 350 return "ERROR Insufficient balance".to_string();
362 } 351 }
@@ -515,7 +504,12 @@ impl ServerCore {
515 504
516 /// Cash out or forfeit. The multiplier comes from the server clock at the 505 /// Cash out or forfeit. The multiplier comes from the server clock at the
517 /// moment the request is handled; the client never supplies one. 506 /// moment the request is handled; the client never supplies one.
518 fn handle_crash_end(&mut self, state: &ConnectionState, session_id: &str, forfeit: bool) -> String { 507 fn handle_crash_end(
508 &mut self,
509 state: &ConnectionState,
510 session_id: &str,
511 forfeit: bool,
512 ) -> String {
519 let Some(user) = state.user.as_deref() else { 513 let Some(user) = state.user.as_deref() else {
520 return "ERROR Not logged in".to_string(); 514 return "ERROR Not logged in".to_string();
521 }; 515 };
@@ -698,11 +692,7 @@ impl ServerCore {
698 .get("number") 692 .get("number")
699 .cloned() 693 .cloned()
700 .unwrap_or_default(); 694 .unwrap_or_default();
701 let color = result 695 let color = result.result_data.get("color").cloned().unwrap_or_default();
702 .result_data
703 .get("color")
704 .cloned()
705 .unwrap_or_default();
706 let bets = result 696 let bets = result
707 .result_data 697 .result_data
708 .get("bets") 698 .get("bets")
@@ -712,11 +702,7 @@ impl ServerCore {
712 "ROULETTE_RESULT {session_id} {winnings} {bet_amount} {new_balance} {number} {color} {bets}" 702 "ROULETTE_RESULT {session_id} {winnings} {bet_amount} {new_balance} {number} {color} {bets}"
713 ) 703 )
714 } else { 704 } else {
715 let reels = result 705 let reels = result.result_data.get("reels").cloned().unwrap_or_default();
716 .result_data
717 .get("reels")
718 .cloned()
719 .unwrap_or_default();
720 let win_type = result 706 let win_type = result
721 .result_data 707 .result_data
722 .get("win_type") 708 .get("win_type")
@@ -753,8 +739,7 @@ impl ServerCore {
753 if let Ok(mut hand) = BlackjackHand::from_json(raw) { 739 if let Ok(mut hand) = BlackjackHand::from_json(raw) {
754 if !hand.is_done() { 740 if !hand.is_done() {
755 hand.forfeit(); 741 hand.forfeit();
756 let balance = 742 let balance = database::get_balance(&self.conn, user).unwrap_or(0);
757 database::get_balance(&self.conn, user).unwrap_or(0);
758 let final_state = hand.state(&session.session_id, balance); 743 let final_state = hand.state(&session.session_id, balance);
759 let details = serde_json::to_string(&final_state) 744 let details = serde_json::to_string(&final_state)
760 .unwrap_or_else(|_| "{}".to_string()); 745 .unwrap_or_else(|_| "{}".to_string());
diff --git a/src/server/games/blackjack.rs b/src/server/games/blackjack.rs
index df5a6ac..cea817a 100644
--- a/src/server/games/blackjack.rs
+++ b/src/server/games/blackjack.rs
@@ -1,7 +1,5 @@
1use super::traits::{Game, GameError, GamePhase, GameResult, GameState}; 1use super::traits::{Game, GameError, GamePhase, GameResult, GameState};
2use crate::blackjack::{ 2use crate::blackjack::{card_value, fresh_shoe, hand_total, is_blackjack, BlackjackState};
3 card_value, fresh_shoe, hand_total, is_blackjack, BlackjackState,
4};
5use rand::seq::SliceRandom; 3use rand::seq::SliceRandom;
6use rand::thread_rng; 4use rand::thread_rng;
7use serde::{Deserialize, Serialize}; 5use serde::{Deserialize, Serialize};
diff --git a/src/server/games/roulette.rs b/src/server/games/roulette.rs
index 7beb8c9..0a58323 100644
--- a/src/server/games/roulette.rs
+++ b/src/server/games/roulette.rs
@@ -65,17 +65,15 @@ impl Game for RouletteGame {
65 65
66 match action { 66 match action {
67 "spin" => { 67 "spin" => {
68 if state.phase != GamePhase::WaitingToStart 68 if state.phase != GamePhase::WaitingToStart && state.phase != GamePhase::Playing {
69 && state.phase != GamePhase::Playing
70 {
71 return Err(GameError::InvalidAction( 69 return Err(GameError::InvalidAction(
72 "Cannot spin in current phase".to_string(), 70 "Cannot spin in current phase".to_string(),
73 )); 71 ));
74 } 72 }
75 73
76 let payload = params 74 let payload = params.first().ok_or(GameError::InvalidAction(
77 .first() 75 "Missing roulette bets".to_string(),
78 .ok_or(GameError::InvalidAction("Missing roulette bets".to_string()))?; 76 ))?;
79 let bets: Bets = serde_json::from_str(payload) 77 let bets: Bets = serde_json::from_str(payload)
80 .map_err(|error| GameError::InvalidAction(format!("Invalid bets: {error}")))?; 78 .map_err(|error| GameError::InvalidAction(format!("Invalid bets: {error}")))?;
81 79
diff --git a/src/server/games/slots.rs b/src/server/games/slots.rs
index 298cd4c..caced24 100644
--- a/src/server/games/slots.rs
+++ b/src/server/games/slots.rs
@@ -175,9 +175,7 @@ impl Game for SlotsGame {
175 175
176 match action { 176 match action {
177 "spin" => { 177 "spin" => {
178 if state.phase != GamePhase::WaitingToStart 178 if state.phase != GamePhase::WaitingToStart && state.phase != GamePhase::Playing {
179 && state.phase != GamePhase::Playing
180 {
181 return Err(GameError::InvalidAction( 179 return Err(GameError::InvalidAction(
182 "Cannot spin in current phase".to_string(), 180 "Cannot spin in current phase".to_string(),
183 )); 181 ));
diff --git a/src/server/setup.rs b/src/server/setup.rs
index 96982c5..023e6ed 100644
--- a/src/server/setup.rs
+++ b/src/server/setup.rs
@@ -47,19 +47,8 @@ pub fn init_identity(dir: &Path, common_name: &str) -> Result<SetupReport, Strin
47 run_openssl( 47 run_openssl(
48 dir, 48 dir,
49 &[ 49 &[
50 "req", 50 "req", "-x509", "-newkey", "rsa:2048", "-keyout", "key.pem", "-out", "cert.pem",
51 "-x509", 51 "-days", "3650", "-nodes", "-subj", &subject,
52 "-newkey",
53 "rsa:2048",
54 "-keyout",
55 "key.pem",
56 "-out",
57 "cert.pem",
58 "-days",
59 "3650",
60 "-nodes",
61 "-subj",
62 &subject,
63 ], 52 ],
64 "generate the certificate", 53 "generate the certificate",
65 &manual, 54 &manual,
@@ -98,9 +87,8 @@ pub fn init_identity(dir: &Path, common_name: &str) -> Result<SetupReport, Strin
98 .map_err(|error| format!("Could not inspect {}: {error}", path.display()))?; 87 .map_err(|error| format!("Could not inspect {}: {error}", path.display()))?;
99 let mut permissions = metadata.permissions(); 88 let mut permissions = metadata.permissions();
100 permissions.set_mode(0o600); 89 permissions.set_mode(0o600);
101 std::fs::set_permissions(path, permissions).map_err(|error| { 90 std::fs::set_permissions(path, permissions)
102 format!("Could not protect {}: {error}", path.display()) 91 .map_err(|error| format!("Could not protect {}: {error}", path.display()))?;
103 })?;
104 } 92 }
105 } 93 }
106 94