summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/core.rs39
-rw-r--r--src/client/games/manager.rs6
-rw-r--r--src/client/view.rs2
3 files changed, 37 insertions, 10 deletions
diff --git a/src/client/core.rs b/src/client/core.rs
index 21c1cb2..6d8294c 100644
--- a/src/client/core.rs
+++ b/src/client/core.rs
@@ -62,6 +62,8 @@ pub struct ClientCore {
62 logged_in: Option<String>, 62 logged_in: Option<String>,
63 pending: Option<Pending>, 63 pending: Option<Pending>,
64 balance: Option<i64>, 64 balance: Option<i64>,
65 /// Account number from the last `INFO`, shown by both frontends.
66 account: Option<String>,
65 host: Option<String>, 67 host: Option<String>,
66 fingerprint: Option<String>, 68 fingerprint: Option<String>,
67 /// Local anchor for the crash multiplier, set when a round starts. 69 /// Local anchor for the crash multiplier, set when a round starts.
@@ -82,6 +84,7 @@ impl ClientCore {
82 logged_in: None, 84 logged_in: None,
83 pending: None, 85 pending: None,
84 balance: None, 86 balance: None,
87 account: None,
85 host: None, 88 host: None,
86 fingerprint: None, 89 fingerprint: None,
87 crash_started: None, 90 crash_started: None,
@@ -275,15 +278,18 @@ impl ClientCore {
275 } 278 }
276 Some(Pending::Echo) => print_line(format!("Echo: {}", reply.trim())), 279 Some(Pending::Echo) => print_line(format!("Echo: {}", reply.trim())),
277 Some(Pending::Info) => { 280 Some(Pending::Info) => {
281 // The same reply feeds the balance and the account number.
282 let balance = info_balance(reply);
283 if let Some(account) = info_account(reply) {
284 self.account = Some(account);
285 }
286 if let Some(balance) = balance {
287 self.balance = Some(balance);
288 self.game.set_balance(balance);
289 }
278 if self.game.is_in_game() { 290 if self.game.is_in_game() {
279 // Balance fetch while entering a game. A failure is not 291 // A failure is not fatal: the board keeps showing `?`.
280 // fatal: the board keeps showing `?`. 292 self.board_effects()
281 if let Some(balance) = info_balance(reply) {
282 self.balance = Some(balance);
283 self.game.set_balance(balance);
284 return self.board_effects();
285 }
286 Vec::new()
287 } else { 293 } else {
288 vec![Effect::Print(info_lines(reply))] 294 vec![Effect::Print(info_lines(reply))]
289 } 295 }
@@ -405,6 +411,7 @@ impl ClientCore {
405 None => Vec::new(), 411 None => Vec::new(),
406 }, 412 },
407 Command::PlaceBetAt(target) => self.place_roulette_chip_on(target), 413 Command::PlaceBetAt(target) => self.place_roulette_chip_on(target),
414 Command::RemoveBetAt(target) => self.remove_roulette_chip_on(target),
408 Command::ClearBets => { 415 Command::ClearBets => {
409 self.game.set_roulette_bets(&Bets::default()); 416 self.game.set_roulette_bets(&Bets::default());
410 self.game.set_roulette_status("place"); 417 self.game.set_roulette_status("place");
@@ -489,6 +496,12 @@ impl ClientCore {
489 self.place_roulette_bets(bets) 496 self.place_roulette_bets(bets)
490 } 497 }
491 498
499 fn remove_roulette_chip_on(&mut self, target: BetTarget) -> Vec<Effect> {
500 let mut bets = self.game.roulette_bets();
501 bets.reduce(&target, self.game.roulette_chip());
502 self.place_roulette_bets(bets)
503 }
504
492 fn place_roulette_bets(&mut self, bets: Bets) -> Vec<Effect> { 505 fn place_roulette_bets(&mut self, bets: Bets) -> Vec<Effect> {
493 if let Some(balance) = self.balance { 506 if let Some(balance) = self.balance {
494 if bets.total() > balance.max(0) as u64 { 507 if bets.total() > balance.max(0) as u64 {
@@ -782,6 +795,7 @@ impl ClientCore {
782 Screen::Lobby => View::Lobby(LobbyView { 795 Screen::Lobby => View::Lobby(LobbyView {
783 connected: self.connected, 796 connected: self.connected,
784 user: self.logged_in.clone(), 797 user: self.logged_in.clone(),
798 account: self.account.clone(),
785 balance: self.balance, 799 balance: self.balance,
786 games: self.games(), 800 games: self.games(),
787 login_error: self.login_error.clone(), 801 login_error: self.login_error.clone(),
@@ -824,6 +838,15 @@ fn print_line(message: impl Into<String>) -> Vec<Effect> {
824 vec![Effect::Print(vec![message.into()])] 838 vec![Effect::Print(vec![message.into()])]
825} 839}
826 840
841fn info_account(reply: &str) -> Option<String> {
842 let parts: Vec<&str> = reply.split_whitespace().collect();
843 if parts.first() == Some(&"INFO") && parts.len() == 4 {
844 Some(parts[2].to_string()).filter(|account| account != "-")
845 } else {
846 None
847 }
848}
849
827fn info_balance(reply: &str) -> Option<i64> { 850fn info_balance(reply: &str) -> Option<i64> {
828 let parts: Vec<&str> = reply.split_whitespace().collect(); 851 let parts: Vec<&str> = reply.split_whitespace().collect();
829 if parts.first() == Some(&"INFO") && parts.len() == 4 { 852 if parts.first() == Some(&"INFO") && parts.len() == 4 {
diff --git a/src/client/games/manager.rs b/src/client/games/manager.rs
index bb2a8b5..24ceeaa 100644
--- a/src/client/games/manager.rs
+++ b/src/client/games/manager.rs
@@ -353,7 +353,7 @@ impl GameManager {
353 .insert("balance".to_string(), state.balance.to_string()); 353 .insert("balance".to_string(), state.balance.to_string());
354 session 354 session
355 .data 355 .data
356 .insert("multiplier".to_string(), format!("{:.2}", state.multiplier)); 356 .insert("multiplier".to_string(), state.multiplier.to_string());
357 session 357 session
358 .data 358 .data
359 .insert("potential".to_string(), state.potential.to_string()); 359 .insert("potential".to_string(), state.potential.to_string());
@@ -373,9 +373,11 @@ impl GameManager {
373 return; 373 return;
374 }; 374 };
375 let bet = session.bet_amount; 375 let bet = session.bet_amount;
376 // Keep the full value: the terminal rounds for display, but the GUI
377 // charts it and must not draw a staircase.
376 session 378 session
377 .data 379 .data
378 .insert("multiplier".to_string(), format!("{multiplier:.2}")); 380 .insert("multiplier".to_string(), multiplier.to_string());
379 session 381 session
380 .data 382 .data
381 .insert("potential".to_string(), payout(bet, multiplier).to_string()); 383 .insert("potential".to_string(), payout(bet, multiplier).to_string());
diff --git a/src/client/view.rs b/src/client/view.rs
index d2ccadb..4615720 100644
--- a/src/client/view.rs
+++ b/src/client/view.rs
@@ -246,6 +246,7 @@ impl CrashView {
246pub struct LobbyView { 246pub struct LobbyView {
247 pub connected: bool, 247 pub connected: bool,
248 pub user: Option<String>, 248 pub user: Option<String>,
249 pub account: Option<String>,
249 pub balance: Option<i64>, 250 pub balance: Option<i64>,
250 pub games: Vec<(String, String)>, 251 pub games: Vec<(String, String)>,
251 /// Why the last login or registration attempt failed. 252 /// Why the last login or registration attempt failed.
@@ -297,6 +298,7 @@ pub enum Command {
297 MoveCursor(Direction), 298 MoveCursor(Direction),
298 PlaceBet, 299 PlaceBet,
299 PlaceBetAt(BetTarget), 300 PlaceBetAt(BetTarget),
301 RemoveBetAt(BetTarget),
300 ClearBets, 302 ClearBets,
301 SetChip(u64), 303 SetChip(u64),
302 AdjustChip(i64), 304 AdjustChip(i64),