improvements
This commit is contained in:
64
src/game.rs
64
src/game.rs
@@ -1,3 +1,4 @@
|
||||
use rand::Rng;
|
||||
use serde::Serialize;
|
||||
use socketioxide::socket::Sid;
|
||||
use thiserror::Error;
|
||||
@@ -20,6 +21,8 @@ pub enum Error {
|
||||
NotInRoom,
|
||||
#[error("Invalid Move")]
|
||||
InvalidMove,
|
||||
#[error("Code Generation Limit Reached")]
|
||||
CodeGenerationLimitReached,
|
||||
#[error("SQL Error\n{0:?}")]
|
||||
Sqlx(#[from] sqlx::Error),
|
||||
}
|
||||
@@ -41,8 +44,28 @@ pub async fn room_if_player_exists(sid: &str, pool: &sqlx::PgPool) -> Result<Opt
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn add_room(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<()> {
|
||||
async fn generate_code(pool: &sqlx::PgPool) -> Result<String> {
|
||||
for _ in 0..50 {
|
||||
let code: String = rand::thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
.take(ROOM_CODE_LENGTH)
|
||||
.map(|x| char::to_ascii_uppercase(&(x as char)))
|
||||
.collect();
|
||||
if sqlx::query!(r"SELECT code FROM rooms WHERE code = $1", code)
|
||||
.fetch_optional(pool)
|
||||
.await?
|
||||
.is_none()
|
||||
{
|
||||
return Ok(code);
|
||||
}
|
||||
}
|
||||
Err(Error::CodeGenerationLimitReached)
|
||||
}
|
||||
|
||||
pub async fn add_room(sid: Sid, pool: &sqlx::PgPool) -> Result<String> {
|
||||
delete_sid(sid.as_str(), pool).await?;
|
||||
let code = generate_code(&pool).await?;
|
||||
|
||||
sqlx::query!(
|
||||
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",
|
||||
sid.as_str(),
|
||||
@@ -50,7 +73,7 @@ pub async fn add_room(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<()>
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
pub async fn join_room(sid: Sid, code: String, pool: &sqlx::PgPool) -> Result<()> {
|
||||
@@ -286,9 +309,13 @@ pub async fn attack(
|
||||
}
|
||||
|
||||
pub async fn update_sid(oldsid: &str, newsid: &str, pool: &sqlx::PgPool) -> Result<()> {
|
||||
sqlx::query!(r"UPDATE players SET id = $1 WHERE id = $2", newsid, oldsid)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
sqlx::query!(
|
||||
r"UPDATE players SET id = $1, abandoned = FALSE WHERE id = $2",
|
||||
newsid,
|
||||
oldsid
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -300,32 +327,17 @@ pub async fn delete_sid(sid: &str, pool: &sqlx::PgPool) -> Result<()> {
|
||||
}
|
||||
|
||||
pub async fn to_delete_sid(sid: &str, pool: &sqlx::PgPool) -> Result<()> {
|
||||
sqlx::query!(
|
||||
r"INSERT INTO abandoned_players (time, id) VALUES (NOW(), $1)",
|
||||
sid
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
sqlx::query!(r"UPDATE players SET abandoned = TRUE WHERE id = $1", sid)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn in_delete_sid(sid: &str, pool: &sqlx::PgPool) -> Result<bool> {
|
||||
Ok(
|
||||
sqlx::query!(r"SELECT id FROM abandoned_players WHERE id = $1", sid)
|
||||
.fetch_optional(pool)
|
||||
sqlx::query!(r"SELECT abandoned FROM players WHERE id = $1", sid)
|
||||
.fetch_one(pool)
|
||||
.await?
|
||||
.is_some(),
|
||||
.abandoned,
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn delete_abandoned(pool: &sqlx::PgPool) -> Result<()> {
|
||||
sqlx::query!(
|
||||
r"DELETE FROM players
|
||||
WHERE id IN (SELECT id FROM abandoned_players
|
||||
ORDER BY time DESC
|
||||
OFFSET 1000)"
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(()) // TODO: REMOVE duliplcates id from abandoned
|
||||
}
|
||||
|
38
src/main.rs
38
src/main.rs
@@ -32,10 +32,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let pool = sqlx::postgres::PgPool::connect(&url).await?;
|
||||
sqlx::migrate!("./migrations").run(&pool).await?;
|
||||
sqlx::query("DELETE FROM players").execute(&pool).await?;
|
||||
sqlx::query("DELETE FROM abandoned_players")
|
||||
.execute(&pool)
|
||||
.await?;
|
||||
sqlx::query("DELETE FROM rooms").execute(&pool).await?;
|
||||
let (layer, io) = SocketIo::builder().with_state(pool).build_layer();
|
||||
|
||||
io.ns("/", on_connect);
|
||||
@@ -90,18 +86,15 @@ async fn on_connect(socket: SocketRef, Data(auth): Data<AuthPayload>, pool: Stat
|
||||
return;
|
||||
}
|
||||
|
||||
let room: String = rand::thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
.take(ROOM_CODE_LENGTH)
|
||||
.map(|x| char::to_ascii_uppercase(&(x as char)))
|
||||
.collect();
|
||||
tracing::info!("Creating room: {:?}", room);
|
||||
// TODO: Handle duplicates
|
||||
let room = match add_room(socket.id, &pool).await {
|
||||
Err(e) => {
|
||||
tracing::error!("{:?}", e);
|
||||
return;
|
||||
}
|
||||
Ok(c) => c,
|
||||
};
|
||||
|
||||
if let Err(e) = add_room(socket.id, room.clone(), &pool).await {
|
||||
tracing::error!("{:?}", e);
|
||||
return;
|
||||
}
|
||||
tracing::info!("Creating room: {:?}", room);
|
||||
socket.leave_all().unwrap();
|
||||
socket.join(room.clone()).unwrap();
|
||||
emit_update_room(
|
||||
@@ -119,7 +112,7 @@ async fn on_connect(socket: SocketRef, Data(auth): Data<AuthPayload>, pool: Stat
|
||||
return;
|
||||
}
|
||||
tracing::info!("Joining room: {:?}", room);
|
||||
let room_error = join_room(socket.id, room.clone(), &pool).await;
|
||||
let room_error = join_room(socket.id, room.clone(), &pool).await;
|
||||
if let Err(e) = &room_error {
|
||||
if let Error::RoomFull(Some(player)) = &e {
|
||||
tracing::warn!("{:?}", e);
|
||||
@@ -202,17 +195,17 @@ async fn on_connect(socket: SocketRef, Data(auth): Data<AuthPayload>, pool: Stat
|
||||
"leave",
|
||||
|socket: SocketRef, pool: State<PgPool>| async move {
|
||||
tracing::info!("Leaving Rooms: {:?}", socket.id);
|
||||
leave_and_inform(&socket, &pool).await;
|
||||
leave_and_inform(&socket, &pool, true).await;
|
||||
},
|
||||
);
|
||||
|
||||
socket.on_disconnect(|socket: SocketRef, pool: State<PgPool>| async move {
|
||||
tracing::info!("Disconnecting: {:?}", socket.id);
|
||||
leave_and_inform(&socket, &pool).await;
|
||||
leave_and_inform(&socket, &pool, false).await;
|
||||
});
|
||||
}
|
||||
|
||||
async fn leave_and_inform(socket: &SocketRef, pool: &PgPool) {
|
||||
async fn leave_and_inform(socket: &SocketRef, pool: &PgPool, delete: bool) {
|
||||
let room = socket
|
||||
.rooms()
|
||||
.unwrap()
|
||||
@@ -225,7 +218,12 @@ async fn leave_and_inform(socket: &SocketRef, pool: &PgPool) {
|
||||
let ops = socket.within(room.clone());
|
||||
socket.leave_all().unwrap();
|
||||
emit_update_room(socket, &room.to_string(), ops.sockets().unwrap().len());
|
||||
if let Err(e) = to_delete_sid(socket.id.as_str(), pool).await {
|
||||
let sid = socket.id.as_str();
|
||||
if let Err(e) = if delete {
|
||||
delete_sid(sid, &pool).await
|
||||
} else {
|
||||
to_delete_sid(sid, &pool).await
|
||||
} {
|
||||
tracing::error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user