Skip to content

Commit

Permalink
fixed games getting out of sync
Browse files Browse the repository at this point in the history
  • Loading branch information
sdbondi committed Mar 29, 2022
1 parent aff5fc9 commit c5fdc3d
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 43 deletions.
3 changes: 2 additions & 1 deletion channel/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod channel;

pub use channel::{channel, MessageChannel, SendError, TryRecvError};
pub use channel::{channel, MessageChannel, SendError, TryRecvError, TrySendError};
use tari_comms::types::CommsPublicKey;

#[derive(Debug, Clone)]
Expand All @@ -17,4 +17,5 @@ pub enum OperationType {
NewGame { player: u8 },
MovePlayed { mv: u16, board: String },
Resign,
Sync { board: String },
}
41 changes: 30 additions & 11 deletions networking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::{

use anyhow::anyhow;
use p2p_chess_channel::{ChessOperation, MessageChannel, OperationType};
use rand::{rngs::OsRng, Rng};
use rand::{rngs::OsRng, Rng, RngCore};
// Re-exports
pub use tari_comms::{
multiaddr::Multiaddr,
Expand All @@ -31,7 +31,7 @@ use tari_comms_dht::{
use tari_shutdown::ShutdownSignal;
use tokio::{sync::mpsc, task};

use crate::message::{Message, MessageType, MoveMsg, NewGameMsg, ProtoMessage, ResignMsg};
use crate::message::{Message, MessageType, MoveMsg, NewGameMsg, ProtoMessage, ResignMsg, SyncMsg};

pub struct Networking {
dht: Dht,
Expand All @@ -51,12 +51,11 @@ impl Networking {
fs::create_dir_all(base_path.as_ref())?;
let tor_identity = load_json(base_path.as_ref().join("tor.json"))?;
// TODO
let seed_peers = vec![
peer_from_str(
"c2eca9cf32261a1343e21ed718e79f25bfc74386e9305350b06f62047f519347::/onion3/6yxqk2ybo43u73ukfhyc42qn25echn4zegjpod2ccxzr2jd5atipwzqd:18141",
)
.unwrap(),
];
let seed_peers = vec![peer_from_str(
"c2eca9cf32261a1343e21ed718e79f25bfc74386e9305350b06f62047f519347::/onion3/\
6yxqk2ybo43u73ukfhyc42qn25echn4zegjpod2ccxzr2jd5atipwzqd:18141",
)
.unwrap()];
let port = OsRng.gen_range(15000..50000);
let (node, dht, in_msg) = node::create(
node_identity.clone(),
Expand Down Expand Up @@ -126,6 +125,13 @@ impl Networking {
self.broadcast_msg(op.to, Message::new(op.game_id, op.seq, MessageType::Resign, ResignMsg))
.await?;
},
OperationType::Sync { board } => {
self.broadcast_msg(
op.to,
Message::new(op.game_id, op.seq, MessageType::Sync, SyncMsg { board }),
)
.await?;
},
}

Ok(())
Expand Down Expand Up @@ -177,6 +183,18 @@ impl Networking {
operation: OperationType::Resign,
}
},
MessageType::Sync => {
let msg = Message::<SyncMsg>::try_from(msg)?;
ChessOperation {
game_id: msg.id,
seq: msg.seq,
to: self.node_identity.public_key().clone(),
from: src_public_key,
operation: OperationType::Sync {
board: msg.payload.board,
},
}
},
};

self.channel.send(op).await?;
Expand All @@ -195,13 +213,14 @@ impl Networking {
msg: Message<T>,
) -> anyhow::Result<()> {
let msg = msg.to_proto_message();
let num = OsRng.next_u32() as i32;
self.dht
.outbound_requester()
.propagate(
.broadcast(
public_key.clone().into(),
OutboundEncryption::EncryptFor(Box::new(public_key)),
OutboundEncryption::EncryptFor(Box::new(public_key.clone())),
vec![],
OutboundDomainMessage::new(999, msg),
OutboundDomainMessage::new(num, msg.clone()),
)
.await?;

Expand Down
8 changes: 8 additions & 0 deletions networking/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub enum MessageType {
NewGame = 0,
PlayMove = 1,
Resign = 2,
Sync = 3,
}

impl ProtoMessage {
Expand All @@ -40,6 +41,7 @@ impl TryFrom<i32> for MessageType {
0 => Ok(MessageType::NewGame),
1 => Ok(MessageType::PlayMove),
2 => Ok(MessageType::Resign),
3 => Ok(MessageType::Sync),
_ => Err(anyhow!("Invalid message type {}", value)),
}
}
Expand Down Expand Up @@ -98,3 +100,9 @@ pub struct MoveMsg {

#[derive(Clone, prost::Message)]
pub struct ResignMsg;

#[derive(Clone, prost::Message)]
pub struct SyncMsg{
#[prost(string, tag = "1")]
pub board: String,
}
9 changes: 9 additions & 0 deletions ui/src/game_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ impl GameScreen {
self.id
}

pub fn set_seq(&mut self, seq: u32) -> &mut Self {
self.seq = seq;
self
}

pub fn next_seq(&mut self) -> u32 {
self.seq += 1;
self.seq
Expand Down Expand Up @@ -108,6 +113,10 @@ impl GameScreen {
self.board.apply_move(mv);
}

pub fn seq(&self) -> u32 {
self.seq
}

pub fn opponent(&self) -> &CommsPublicKey {
&self.opponent
}
Expand Down
100 changes: 69 additions & 31 deletions ui/src/screen_manager.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{
fs,
path::Path,
time::{SystemTime, UNIX_EPOCH},
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
};

use anyhow::anyhow;
use minifb::Window;
use p2p_chess_channel::{ChessOperation, MessageChannel, OperationType, TryRecvError};
use p2p_chess_channel::{ChessOperation, MessageChannel, OperationType, TryRecvError, TrySendError};
use pleco::{BitMove, Player};
use rand::{rngs::OsRng, RngCore};
use tari_comms::types::CommsPublicKey;
Expand All @@ -30,6 +30,7 @@ pub struct ScreenManager {
public_key: CommsPublicKey,
channel: MessageChannel<ChessOperation>,
games: GameCollection,
last_sync: Instant,
}

impl ScreenManager {
Expand All @@ -47,6 +48,7 @@ impl ScreenManager {
clipboard,
channel,
games,
last_sync: Instant::now(),
})
}

Expand All @@ -71,17 +73,16 @@ impl ScreenManager {
last_activity: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
});
self.save_games().unwrap();
self.channel
.try_send(ChessOperation {
game_id: id,
seq: 0,
to: opponent,
from: self.public_key.clone(),
operation: OperationType::NewGame {
player: Player::Black as u8,
},
})
.unwrap();
self.send_message(ChessOperation {
game_id: id,
seq: 0,
to: opponent,
from: self.public_key.clone(),
operation: OperationType::NewGame {
player: Player::Black as u8,
},
})
.unwrap();
}

pub fn render(&mut self, window: &Window, buf: &mut FrameBuffer) {
Expand Down Expand Up @@ -123,18 +124,17 @@ impl ScreenManager {
game.update(&window);
if let Some(mv) = game.take_last_move_played() {
dbg!("move played", mv);
self.channel
.try_send(ChessOperation {
game_id: game.game_id(),
seq: game.next_seq(),
to: game.opponent().clone(),
from: self.public_key.clone(),
operation: OperationType::MovePlayed {
mv: mv.get_raw(),
board: game.to_board_fen(),
},
})
.unwrap();
let msg = ChessOperation {
game_id: game.game_id(),
seq: game.next_seq(),
to: game.opponent().clone(),
from: self.public_key.clone(),
operation: OperationType::MovePlayed {
mv: mv.get_raw(),
board: game.to_board_fen(),
},
};
self.channel.try_send(msg).unwrap();
if let Some(game_mut) = self.games.get_mut(game.game_id()) {
game_mut.board_fen = game.to_board_fen();
game_mut.last_activity = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
Expand All @@ -145,14 +145,29 @@ impl ScreenManager {
buf.clear(Color::black());
self.active_screen =
Screen::Start(StartScreen::new(self.clipboard.clone(), self.public_key.clone()));
} else if self.last_sync.elapsed() > Duration::from_secs(10) {
let msg = ChessOperation {
game_id: game.game_id(),
seq: game.seq(),
to: game.opponent().clone(),
from: self.public_key.clone(),
operation: OperationType::Sync {
board: game.to_board_fen(),
},
};
self.send_message(msg).unwrap();
self.last_sync = Instant::now();
}
},
}

let _ = self.save_games();
if let Err(err) = self.save_games() {
log::error!("save failed: {}", err);
}

match self.channel.try_recv() {
Ok(op) => {
self.last_sync = Instant::now();
dbg!(&op);
if let Err(err) = self.apply_operation(op) {
log::error!("apply operation failed: {}", err);
Expand Down Expand Up @@ -195,18 +210,15 @@ impl ScreenManager {
}
// TODO: This requires a lot of honesty :P
game_mut.board_fen = board.clone();
game_mut.seq += 1;
game_mut.seq = op.seq;
game_mut.last_activity = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
self.save_games()?;
if let Screen::Game(ref mut screen) = self.active_screen {
dbg!(screen.game_id(), op.game_id);
if screen.game_id() == op.game_id {
let mv = BitMove::new(*mv);
log::info!("Move played for active game {}", mv);
screen.set_board_fen(&board);
// screen.apply_move(mv);
// TODO: not great
screen.next_seq();
screen.set_board_fen(&board).set_seq(op.seq);
}
}
}
Expand All @@ -216,11 +228,37 @@ impl ScreenManager {
game_mut.result = GameResult::TheyResigned;
}
},
OperationType::Sync { board } => {
if let Some(game_mut) = self.games.get_mut(op.game_id) {
if op.seq < game_mut.seq {
// Send a message back with our state
let msg = ChessOperation {
game_id: game_mut.id,
seq: game_mut.seq,
to: game_mut.opponent.clone(),
from: self.public_key.clone(),
operation: OperationType::Sync {
board: game_mut.board_fen.clone(),
},
};
self.send_message(msg).unwrap();
} else {
// Update our game state
game_mut.board_fen = board.clone();
game_mut.seq = op.seq;
self.save_games()?;
}
}
},
}

Ok(())
}

fn send_message(&mut self, msg: ChessOperation) -> Result<(), TrySendError<ChessOperation>> {
self.channel.try_send(msg)
}

fn save_games(&mut self) -> anyhow::Result<()> {
self.games.clean_up();
// TODO: decouple
Expand Down

0 comments on commit c5fdc3d

Please sign in to comment.