working state
This commit is contained in:
@@ -20,40 +20,29 @@ export class State {
|
|||||||
this.socket.on('upload', (_, callback) => {
|
this.socket.on('upload', (_, callback) => {
|
||||||
callback(this.playerBoard.board);
|
callback(this.playerBoard.board);
|
||||||
})
|
})
|
||||||
this.socket.on('turn', (id) => {
|
this.socket.on('turnover', (id) => {
|
||||||
this.turn = id == this.socket.id;
|
this.turn = id != this.socket.id;
|
||||||
|
})
|
||||||
|
this.socket.on('attacked', ({ by, at, res }) => {
|
||||||
|
let [i, j] = at;
|
||||||
|
if (by == this.socket.id) {
|
||||||
|
this.opponentBoard.board[i][j] = res ? 'h' : 'm';
|
||||||
|
this.turn = false;
|
||||||
|
} else {
|
||||||
|
this.playerBoard.board[i][j] = res ? 'h' : 'm';
|
||||||
|
this.turn = true;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async attack(i: number, j: number) {
|
attack(i: number, j: number) {
|
||||||
if (!this.turn) return;
|
if (!this.turn) return;
|
||||||
this.turn = false;
|
this.turn = false;
|
||||||
const res = await this.socket.emitWithAck('attack', [i, j]);
|
this.socket.emit('attack', [i, j]);
|
||||||
if (res) {
|
|
||||||
this.opponentBoard.board[i][j] = 'h';
|
|
||||||
} else {
|
|
||||||
this.opponentBoard.board[i][j] = 'm';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createRoom() {
|
createRoom() {
|
||||||
this.socket.emit('create');
|
this.socket.emit('create');
|
||||||
// this.socket.emit('upload', this.playerBoard.board);
|
|
||||||
// send the board to the server
|
|
||||||
// let api = 'http://127.0.0.1:3000/';
|
|
||||||
// await fetch(api, {
|
|
||||||
// method: 'POST',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json',
|
|
||||||
// 'Access-Control-Allow-Origin': '*',
|
|
||||||
// },
|
|
||||||
// body: JSON.stringify(this.playerBoard.board),
|
|
||||||
// }).then((response) => {
|
|
||||||
// console.log(response);
|
|
||||||
// response.json().then((data) => {
|
|
||||||
// console.log(data);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
joinRoom() {
|
joinRoom() {
|
||||||
@@ -72,10 +61,6 @@ export class Board {
|
|||||||
if (!isOpponent) this.randomize();
|
if (!isOpponent) this.randomize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// set(x: number, y: number, type: CellType) {
|
|
||||||
// this.board[x][y] = type;
|
|
||||||
// }
|
|
||||||
|
|
||||||
randomize() {
|
randomize() {
|
||||||
this.board = Array.from({ length: 10 }, () => Array.from({ length: 10 }, () => 'e'));
|
this.board = Array.from({ length: 10 }, () => Array.from({ length: 10 }, () => 'e'));
|
||||||
for (const shipLength of Board.shipTypes) {
|
for (const shipLength of Board.shipTypes) {
|
||||||
|
@@ -3,15 +3,25 @@ CREATE TYPE STAT AS ENUM ('waiting', 'p1turn', 'p2turn');
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS players (
|
CREATE TABLE IF NOT EXISTS players (
|
||||||
id CHAR(16) PRIMARY KEY,
|
id CHAR(16) PRIMARY KEY,
|
||||||
board CHAR(10) [10],
|
board CHAR [10] [10],
|
||||||
room_code CHAR(4)
|
room_code CHAR(4) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS rooms (
|
CREATE TABLE IF NOT EXISTS rooms (
|
||||||
code CHAR(4) PRIMARY KEY,
|
code CHAR(4) PRIMARY KEY,
|
||||||
player1_id CHAR(16),
|
player1_id CHAR(16),
|
||||||
player2_id CHAR(16),
|
player2_id CHAR(16),
|
||||||
stat STAT DEFAULT 'waiting'
|
stat STAT DEFAULT 'waiting' NOT NULL,
|
||||||
|
CHECK (
|
||||||
|
(
|
||||||
|
player1_id IS DISTINCT
|
||||||
|
FROM player2_id
|
||||||
|
)
|
||||||
|
OR (
|
||||||
|
player1_id IS NULL
|
||||||
|
AND player2_id IS NULL
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE players
|
ALTER TABLE players
|
||||||
@@ -24,5 +34,22 @@ SET NULL,
|
|||||||
ADD CONSTRAINT fk_player2 FOREIGN KEY (player2_id) REFERENCES players (id) ON DELETE
|
ADD CONSTRAINT fk_player2 FOREIGN KEY (player2_id) REFERENCES players (id) ON DELETE
|
||||||
SET NULL;
|
SET NULL;
|
||||||
|
|
||||||
|
-- delete room if both players are null
|
||||||
|
CREATE OR REPLACE FUNCTION delete_room() RETURNS TRIGGER AS $$ BEGIN IF (
|
||||||
|
SELECT player1_id IS NULL
|
||||||
|
AND player2_id IS NULL
|
||||||
|
FROM rooms
|
||||||
|
WHERE code = OLD.room_code
|
||||||
|
) THEN
|
||||||
|
DELETE FROM rooms
|
||||||
|
WHERE code = OLD.room_code;
|
||||||
|
END IF;
|
||||||
|
RETURN OLD;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
CREATE TRIGGER delete_room_trigger
|
||||||
|
AFTER DELETE ON players FOR EACH ROW EXECUTE FUNCTION delete_room();
|
||||||
|
|
||||||
CREATE INDEX idx_player_room_code ON players (room_code);
|
CREATE INDEX idx_player_room_code ON players (room_code);
|
||||||
CREATE INDEX idx_room_status ON rooms (stat);
|
CREATE INDEX idx_room_status ON rooms (stat);
|
259
src/game.rs
259
src/game.rs
@@ -1,34 +1,18 @@
|
|||||||
use std::{collections::HashMap, sync::Arc};
|
|
||||||
|
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use socketioxide::socket::Sid;
|
use socketioxide::socket::Sid;
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
pub const ROOM_CODE_LENGTH: usize = 4;
|
pub const ROOM_CODE_LENGTH: usize = 4;
|
||||||
|
|
||||||
// #[derive(Default, Clone)]
|
pub async fn add_room(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<(), sqlx::Error> {
|
||||||
// pub struct Store {
|
sqlx::query!(
|
||||||
// rooms: Arc<RwLock<HashMap<String, Room>>>,
|
r"WITH new_user AS (INSERT INTO players (id, room_code) VALUES ($1, $2) RETURNING id) INSERT INTO rooms (player1_id, code) SELECT $1, $2 FROM new_user",
|
||||||
// sockets: Arc<RwLock<HashMap<Sid, String>>>,
|
sid.as_str(),
|
||||||
// }
|
code
|
||||||
|
)
|
||||||
// impl Store {
|
.execute(pool)
|
||||||
// pub async fn add_room(&self, code: String) {
|
.await?;
|
||||||
// let mut store = self.rooms.write().await;
|
|
||||||
// store.insert(
|
|
||||||
// code.clone(),
|
|
||||||
// Room {
|
|
||||||
// code,
|
|
||||||
// ..Default::default()
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
pub async fn add_room(code: String, pool: &sqlx::PgPool) -> Result<(), sqlx::Error> {
|
|
||||||
sqlx::query!("INSERT INTO rooms (code) VALUES ($1)", code)
|
|
||||||
.execute(pool)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,25 +24,39 @@ pub async fn join_room(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<()
|
|||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let sid = sid.as_str();
|
||||||
|
|
||||||
if room.player1_id.is_some() && room.player2_id.is_some() {
|
if room.player1_id.is_some() && room.player2_id.is_some() {
|
||||||
return Err(sqlx::Error::RowNotFound); // room full
|
return Err(sqlx::Error::RowNotFound); // room full
|
||||||
}
|
}
|
||||||
|
if let Some(id) = room.player1_id.as_ref() {
|
||||||
|
if id == sid {
|
||||||
|
return Err(sqlx::Error::RowNotFound); // already in room
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(id) = room.player2_id.as_ref() {
|
||||||
|
if id == sid {
|
||||||
|
return Err(sqlx::Error::RowNotFound); // already in room
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut txn = pool.begin().await?;
|
let mut txn = pool.begin().await?;
|
||||||
|
|
||||||
|
// create/update player
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"INSERT INTO players (id, room_code) VALUES ($1, $2) ON CONFLICT (id) DO UPDATE SET room_code = $2"#,
|
r#"INSERT INTO players (id, room_code) VALUES ($1, $2) ON CONFLICT (id) DO UPDATE SET room_code = $2"#,
|
||||||
sid.as_str(),
|
sid,
|
||||||
code
|
code
|
||||||
)
|
)
|
||||||
.execute(&mut *txn)
|
.execute(&mut *txn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// add to room
|
||||||
sqlx::query(&format!(
|
sqlx::query(&format!(
|
||||||
"UPDATE rooms SET player{}_id = $1 WHERE code = $2",
|
"UPDATE rooms SET player{}_id = $1 WHERE code = $2",
|
||||||
if room.player1_id.is_none() { "1" } else { "2" }
|
if room.player1_id.is_none() { "1" } else { "2" }
|
||||||
))
|
))
|
||||||
.bind(sid.as_str())
|
.bind(sid)
|
||||||
.bind(code)
|
.bind(code)
|
||||||
.execute(&mut *txn)
|
.execute(&mut *txn)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -66,102 +64,133 @@ pub async fn join_room(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<()
|
|||||||
txn.commit().await?;
|
txn.commit().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
// pub async fn join_room(&self, sid: Sid, code: String) -> Result<(), ()> {
|
|
||||||
// if self.rooms.read().await.get(&code).is_none() {
|
|
||||||
// return Err(());
|
|
||||||
// };
|
|
||||||
// let mut sockets = self.sockets.write().await;
|
|
||||||
// let player = sockets
|
|
||||||
// .entry(sid)
|
|
||||||
// .and_modify(|p| p.room = Some(code.clone()))
|
|
||||||
// .or_insert(Arc::new(Player {
|
|
||||||
// sid,
|
|
||||||
// room: Some(code.clone()),
|
|
||||||
// board: None,
|
|
||||||
// }));
|
|
||||||
// let mut rooms = self.rooms.write().await;
|
|
||||||
// let Some(room) = rooms.get_mut(&code) else {
|
|
||||||
// return Err(());
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if room.player1.is_none() {
|
pub async fn add_board(sid: Sid, board: Board, pool: &sqlx::PgPool) -> Result<(), sqlx::Error> {
|
||||||
// room.player1 = Some(Arc::clone(player));
|
let query = format!(
|
||||||
// }
|
"UPDATE players SET board = ARRAY[{}] WHERE id = '{}'",
|
||||||
// Ok(())
|
board
|
||||||
// }
|
.0
|
||||||
|
.map(|row| {
|
||||||
|
format!(
|
||||||
|
"ARRAY[{}]",
|
||||||
|
row.map(|x| format!("'{x}'"))
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(",")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(","),
|
||||||
|
sid.as_str()
|
||||||
|
);
|
||||||
|
sqlx::query(&query).execute(pool).await.unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// pub async fn add_board(&self, sid: Sid, board: Board) -> Result<(), ()> {
|
pub async fn start(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<(), sqlx::Error> {
|
||||||
// let mut store = self.sockets.write().await;
|
let room = sqlx::query!(
|
||||||
// if let Some(player) = store.get_mut(&sid) {
|
r"SELECT player1_id, player2_id FROM rooms WHERE code = $1",
|
||||||
// player.board = Some(board);
|
code
|
||||||
// } else {
|
)
|
||||||
// return Err(());
|
.fetch_one(pool)
|
||||||
// }
|
.await?;
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub async fn start(&self, code: String, sid: Sid) -> Result<(), ()> {
|
let (Some(player1), Some(player2)) = (room.player1_id, room.player2_id) else {
|
||||||
// let mut store = self.rooms.write().await;
|
return Err(sqlx::Error::RowNotFound); // room not full
|
||||||
// let Some(room) = store.get_mut(&code) else {
|
};
|
||||||
// return Err(());
|
|
||||||
// };
|
|
||||||
// dbg!(&room);
|
|
||||||
// let (Some(player1), Some(player2)) = (room.player1, room.player2) else {
|
|
||||||
// return Err(());
|
|
||||||
// };
|
|
||||||
|
|
||||||
// if player1.sid == sid {
|
let status = if sid.as_str() == player1 {
|
||||||
// room.status = Status::Player1Turn;
|
Status::P2Turn
|
||||||
// } else if player2.sid == sid {
|
} else if sid.as_str() == player2 {
|
||||||
// room.status = Status::Player2Turn;
|
Status::P1Turn
|
||||||
// } else {
|
} else {
|
||||||
// return Err(());
|
return Err(sqlx::Error::RowNotFound); // not in room
|
||||||
// }
|
};
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub async fn attack(&self, sid: Sid, (i, j): (usize, usize)) -> Result<bool, ()> {
|
sqlx::query!(
|
||||||
// let sockets = self.sockets.read().await;
|
r"UPDATE rooms SET stat = $1 WHERE code = $2",
|
||||||
// let Some(player) = sockets.get(&sid) else {
|
status as Status,
|
||||||
// return Err(());
|
code
|
||||||
// };
|
)
|
||||||
// let mut rooms = self.rooms.write().await;
|
.execute(pool)
|
||||||
// let Some(room) = rooms.get_mut(player.room.as_ref().unwrap()) else {
|
.await?;
|
||||||
// return Err(());
|
Ok(())
|
||||||
// };
|
}
|
||||||
|
|
||||||
// match room.status {
|
pub async fn attack(
|
||||||
// Status::Player1Turn if player.sid == room.player1.as_ref().unwrap().sid => {
|
sid: Sid,
|
||||||
// room.status = Status::Player2Turn;
|
(i, j): (usize, usize),
|
||||||
// return Ok(room.player2.as_ref().unwrap().board.as_ref().unwrap().0[i][j] == 's');
|
pool: &sqlx::PgPool,
|
||||||
// }
|
) -> Result<bool, sqlx::Error> {
|
||||||
// Status::Player2Turn if player.sid == room.player2.as_ref().unwrap().sid => {
|
let player = sqlx::query!(r"SELECT room_code FROM players WHERE id = $1", sid.as_str())
|
||||||
// room.status = Status::Player1Turn;
|
.fetch_one(pool)
|
||||||
// return Ok(room.player1.as_ref().unwrap().board.as_ref().unwrap().0[i][j] == 's');
|
.await?;
|
||||||
// }
|
|
||||||
// _ => return Err(()),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Err(())
|
let room = sqlx::query!(
|
||||||
// }
|
r#"SELECT stat AS "stat: Status", player1_id, player2_id FROM rooms WHERE code = $1"#,
|
||||||
// }
|
player.room_code
|
||||||
|
)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// #[derive(Default, Debug)]
|
let (_, other, to_status) = match (room.player1_id, room.player2_id) {
|
||||||
// struct Room {
|
(Some(p1), Some(p2)) if p1 == sid.as_str() && room.stat == Status::P1Turn => {
|
||||||
// code: String,
|
(p1, p2, Status::P2Turn)
|
||||||
// player1: Option<Arc<Player>>,
|
}
|
||||||
// player2: Option<Arc<Player>>,
|
(Some(p1), Some(p2)) if p2 == sid.as_str() && room.stat == Status::P2Turn => {
|
||||||
// status: Status,
|
(p2, p1, Status::P1Turn)
|
||||||
// }
|
}
|
||||||
|
_ => return Err(sqlx::Error::RowNotFound), // room not full
|
||||||
|
};
|
||||||
|
|
||||||
// #[derive(Debug)]
|
let mut txn = pool.begin().await?;
|
||||||
// struct Player {
|
|
||||||
// sid: Sid,
|
|
||||||
// board: Option<Board>,
|
|
||||||
// room: Option<String>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Debug, sqlx::Type)]
|
let turn = sqlx::query!(
|
||||||
|
r"SELECT board[$1][$2] as HIT FROM players WHERE id = $3",
|
||||||
|
i as i32 + 1,
|
||||||
|
j as i32 + 1,
|
||||||
|
other
|
||||||
|
)
|
||||||
|
.fetch_one(&mut *txn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
r#"UPDATE players
|
||||||
|
SET board[$1][$2] = CASE
|
||||||
|
WHEN board[$1][$2] = 's' THEN 'h'
|
||||||
|
WHEN board[$1][$2] = 'e' THEN 'm'
|
||||||
|
ELSE board[$1][$2]
|
||||||
|
END
|
||||||
|
WHERE id = $3"#,
|
||||||
|
i as i32 + 1,
|
||||||
|
j as i32 + 1,
|
||||||
|
other
|
||||||
|
)
|
||||||
|
.execute(&mut *txn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
r#"UPDATE rooms SET stat = $1 WHERE code = $2"#,
|
||||||
|
to_status as Status,
|
||||||
|
player.room_code
|
||||||
|
)
|
||||||
|
.execute(&mut *txn)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
txn.commit().await?;
|
||||||
|
Ok(turn.hit.unwrap() == "s")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn disconnect(sid: Sid, pool: &sqlx::PgPool) -> Result<(), sqlx::Error> {
|
||||||
|
sqlx::query!(r"DELETE FROM players WHERE id = $1", sid.as_str())
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, sqlx::Type, PartialEq)]
|
||||||
#[sqlx(type_name = "STAT", rename_all = "lowercase")]
|
#[sqlx(type_name = "STAT", rename_all = "lowercase")]
|
||||||
enum Status {
|
enum Status {
|
||||||
Waiting,
|
Waiting,
|
||||||
@@ -169,12 +198,6 @@ enum Status {
|
|||||||
P2Turn,
|
P2Turn,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Default for Status {
|
|
||||||
// fn default() -> Self {
|
|
||||||
// Status::Waiting
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Board(pub [[char; 10]; 10]);
|
pub struct Board(pub [[char; 10]; 10]);
|
||||||
|
|
||||||
|
183
src/main.rs
183
src/main.rs
@@ -4,7 +4,7 @@ use std::{str::FromStr, sync::Arc};
|
|||||||
use axum::Router;
|
use axum::Router;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use futures_util::stream::StreamExt;
|
use futures_util::stream::StreamExt;
|
||||||
use game::{join_room, Board, ROOM_CODE_LENGTH};
|
use game::{add_board, add_room, attack, disconnect, join_room, start, Board, ROOM_CODE_LENGTH};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use socketioxide::{
|
use socketioxide::{
|
||||||
@@ -13,6 +13,7 @@ use socketioxide::{
|
|||||||
socket::Sid,
|
socket::Sid,
|
||||||
SocketIo,
|
SocketIo,
|
||||||
};
|
};
|
||||||
|
use sqlx::PgPool;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tower_http::cors::CorsLayer;
|
use tower_http::cors::CorsLayer;
|
||||||
use tracing_subscriber::FmtSubscriber;
|
use tracing_subscriber::FmtSubscriber;
|
||||||
@@ -28,14 +29,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let url = std::env::var("DATABASE_URL")?;
|
let url = std::env::var("DATABASE_URL")?;
|
||||||
let pool = sqlx::postgres::PgPool::connect(&url).await?;
|
let pool = sqlx::postgres::PgPool::connect(&url).await?;
|
||||||
sqlx::migrate!("./migrations").run(&pool).await?;
|
sqlx::migrate!("./migrations").run(&pool).await?;
|
||||||
join_room(
|
|
||||||
Sid::from_str("aaaaaaaaaaaaaaaa").unwrap(),
|
|
||||||
"AAAB".to_string(),
|
|
||||||
&pool,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let (layer, io) = SocketIo::builder().with_state(pool).build_layer();
|
let (layer, io) = SocketIo::builder().with_state(pool).build_layer();
|
||||||
// io.ns("/", on_connect);
|
|
||||||
|
io.ns("/", on_connect);
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
// .route("/", post(game::create_board_route))
|
// .route("/", post(game::create_board_route))
|
||||||
.layer(layer)
|
.layer(layer)
|
||||||
@@ -47,89 +43,98 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn on_connect(socket: SocketRef, io: SocketIo) {
|
fn on_connect(socket: SocketRef, io: SocketIo) {
|
||||||
// tracing::info!("Connected: {:?}", socket.id);
|
tracing::info!("Connected: {:?}", socket.id);
|
||||||
// // tracing::info!(
|
// tracing::info!(
|
||||||
// // "All rooms and sockets: {:?}",
|
// "All rooms and sockets: {:?}",
|
||||||
// // io.rooms()
|
// io.rooms()
|
||||||
// // .unwrap()
|
// .unwrap()
|
||||||
// // .iter()
|
// .iter()
|
||||||
// // .map(|room| { (room, io.within(room.clone()).sockets().unwrap()) })
|
// .map(|room| { (room, io.within(room.clone()).sockets().unwrap()) })
|
||||||
// // );
|
// );
|
||||||
|
|
||||||
// socket.on(
|
socket.on(
|
||||||
// "create",
|
"create",
|
||||||
// |socket: SocketRef, store: State<Store>| async move {
|
|socket: SocketRef, pool: State<PgPool>| async move {
|
||||||
// if !socket.rooms().unwrap().is_empty() {
|
if !socket.rooms().unwrap().is_empty() {
|
||||||
// socket
|
socket
|
||||||
// .emit("created-room", socket.rooms().unwrap().first())
|
.emit("created-room", socket.rooms().unwrap().first())
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
// println!("{} Already in a room", socket.id);
|
println!("{} Already in a room", socket.id);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// let room: String = rand::thread_rng()
|
let room: String = rand::thread_rng()
|
||||||
// .sample_iter(&rand::distributions::Alphanumeric)
|
.sample_iter(&rand::distributions::Alphanumeric)
|
||||||
// .take(ROOM_CODE_LENGTH)
|
.take(ROOM_CODE_LENGTH)
|
||||||
// .map(|x| char::to_ascii_uppercase(&(x as char)))
|
.map(|x| char::to_ascii_uppercase(&(x as char)))
|
||||||
// .collect();
|
.collect();
|
||||||
// tracing::info!("Creating room: {:?}", room);
|
tracing::info!("Creating room: {:?}", room);
|
||||||
// store.add_room(room.clone()).await;
|
add_room(socket.id, room.clone(), &pool).await.unwrap();
|
||||||
// store.join_room(socket.id, room.clone()).await.unwrap();
|
socket.leave_all().unwrap();
|
||||||
// socket.leave_all().unwrap();
|
socket.join(room.clone()).unwrap();
|
||||||
// socket.join(room.clone()).unwrap();
|
socket.emit("created-room", &room).unwrap();
|
||||||
// socket.emit("created-room", &room).unwrap();
|
},
|
||||||
// },
|
);
|
||||||
// );
|
|
||||||
|
|
||||||
// socket.on(
|
socket.on(
|
||||||
// "join",
|
"join",
|
||||||
// |socket: SocketRef, Data::<String>(room), store: State<Store>| async move {
|
|socket: SocketRef, Data::<String>(room), pool: State<PgPool>| async move {
|
||||||
// if room.len() != ROOM_CODE_LENGTH {
|
if room.len() != ROOM_CODE_LENGTH {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// tracing::info!("Joining room: {:?}", room);
|
tracing::info!("Joining room: {:?}", room);
|
||||||
// store.join_room(socket.id, room.clone()).await.unwrap();
|
join_room(socket.id, room.clone(), &pool).await.unwrap();
|
||||||
// socket.leave_all().unwrap();
|
socket.leave_all().unwrap();
|
||||||
// socket.join(room.clone()).unwrap();
|
socket.join(room.clone()).unwrap();
|
||||||
// if socket.within(room.clone()).sockets().unwrap().len() != 2 {
|
if socket.within(room.clone()).sockets().unwrap().len() != 2 {
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// let ack_stream = socket
|
let ack_stream = socket
|
||||||
// .within(room.clone())
|
.within(room.clone())
|
||||||
// .emit_with_ack::<Vec<Board>>("upload", ())
|
.emit_with_ack::<Vec<Board>>("upload", ())
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
// ack_stream
|
ack_stream
|
||||||
// .for_each(|(id, ack)| {
|
.for_each(|(id, ack)| {
|
||||||
// let store = store.clone();
|
let pool = pool.clone();
|
||||||
// async move {
|
async move {
|
||||||
// match ack {
|
match ack {
|
||||||
// Ok(mut ack) => {
|
Ok(mut ack) => {
|
||||||
// store.add_board(id, ack.data.pop().unwrap()).await.unwrap();
|
add_board(id, ack.data.pop().unwrap(), &pool).await.unwrap();
|
||||||
// }
|
}
|
||||||
// Err(err) => tracing::error!("Ack error, {}", err),
|
Err(err) => tracing::error!("Ack error, {}", err),
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// .await;
|
.await;
|
||||||
// store.start(room.clone(), socket.id).await.unwrap();
|
start(socket.id, room.clone(), &pool).await.unwrap();
|
||||||
// tracing::info!("Game started");
|
tracing::info!("Game started");
|
||||||
// socket.within(room.clone()).emit("turn", socket.id).unwrap();
|
socket
|
||||||
// },
|
.within(room.clone())
|
||||||
// );
|
.emit("turnover", socket.id)
|
||||||
|
.unwrap();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// socket.on(
|
socket.on(
|
||||||
// "attack",
|
"attack",
|
||||||
// |socket: SocketRef, Data::<[usize; 2]>([i, j]), ack: AckSender, store: State<Store>| async move {
|
|socket: SocketRef, Data::<[usize; 2]>([i, j]), pool: State<PgPool>| async move {
|
||||||
// let res = store.attack(socket.id, (i, j)).await.unwrap();
|
let res = attack(socket.id, (i, j), &pool).await.unwrap();
|
||||||
// tracing::info!("Attacking at: ({}, {}), result: {}", i, j, res);
|
tracing::info!("Attacking at: ({}, {}), result: {}", i, j, res);
|
||||||
// ack.send(res).unwrap();
|
socket
|
||||||
// },
|
.within(socket.rooms().unwrap().first().unwrap().clone())
|
||||||
// );
|
.emit(
|
||||||
|
"attacked",
|
||||||
|
serde_json::json!({"by": socket.id.as_str(), "at": [i, j], "res": res}),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// socket.on_disconnect(|socket: SocketRef, store: State<Store>| {
|
socket.on_disconnect(|socket: SocketRef, pool: State<PgPool>| async move {
|
||||||
// tracing::info!("Disconnecting: {:?}", socket.id);
|
tracing::info!("Disconnecting: {:?}", socket.id);
|
||||||
// socket.leave_all().unwrap();
|
socket.leave_all().unwrap();
|
||||||
// // TODO: Delete room
|
disconnect(socket.id, &pool).await.unwrap();
|
||||||
// });
|
// TODO: Delete room
|
||||||
// }
|
});
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user