basic lobby joinage logic

This commit is contained in:
Tao Tien 2026-02-08 00:10:10 -08:00
parent 655123b055
commit 78c199b61e
16 changed files with 708 additions and 167 deletions

View file

@ -1,7 +1,7 @@
[package]
name = "jongline"
version = "0.1.0"
edition = "2021"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -1,23 +1,45 @@
use spacetimedb::{rand::seq::SliceRandom, reducer, table, Identity, ReducerContext, Table};
use log::info;
use spacetimedb::{Identity, ReducerContext, Table, rand::seq::SliceRandom, reducer, table};
use jong_types::*;
#[table(name = player)]
#[derive(Debug)]
#[table(name = player, public)]
pub struct Player {
#[primary_key]
identity: Identity,
#[auto_inc]
#[index(direct)]
#[unique]
id: u32,
name: Option<String>,
#[index(btree)]
lobby_id: u32,
}
#[table(name = bot)]
pub struct Bot {
#[primary_key]
#[auto_inc]
id: u32,
#[index(btree)]
lobby_id: u32,
}
#[derive(Debug)]
#[table(name = lobby, public)]
pub struct Lobby {
#[primary_key]
#[auto_inc]
id: u32,
host: Identity,
#[index(direct)]
#[unique]
host_id: u32,
}
#[table(name = wall)]
@ -26,6 +48,10 @@ pub struct Wall {
#[auto_inc]
id: u32,
#[index(direct)]
#[unique]
lobby_id: u32,
tiles: Vec<Tile>,
}
@ -42,47 +68,75 @@ pub struct Pond {
tiles: Vec<Tile>,
}
#[reducer]
pub fn add_player(ctx: &ReducerContext, name: Option<String>) {
let identity = ctx.identity();
ctx.db.player().insert(Player {
identity,
name,
lobby_id: 0,
});
}
#[reducer(client_connected)]
pub fn login_or_add_player(ctx: &ReducerContext) {
let identity = ctx.sender;
#[reducer]
pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> {
if name.is_empty() {
return Err("names must not be empty".into());
}
if let Some(player) = ctx.db.player().identity().find(ctx.sender) {
ctx.db.player().identity().update(Player {
name: Some(name),
..player
});
Ok(())
// TODO remove player on disconnect
if let Ok(player) = ctx.db.player().try_insert(Player {
identity,
id: 0,
name: None,
lobby_id: 0,
}) {
info!("added player: {:?}", player);
} else {
Err("Cannot set name for unknown user".into())
let player = ctx.db.player().identity().find(identity).unwrap();
info!("player {:?} has reconnected", player)
}
}
#[reducer]
pub fn join_or_create_lobby(ctx: &ReducerContext, lobby: Option<u32>) -> Result<(), String> {
let player = ctx.db.player().identity().find(ctx.sender).unwrap();
let mut player = ctx
.db
.player()
.identity()
.find(ctx.sender)
.ok_or(format!("cannot find player {}", ctx.sender))?;
todo!()
let lobby_id = lobby.unwrap_or_else(|| {
let lobby = ctx.db.lobby().insert(Lobby {
id: 0,
host_id: player.id,
});
info!("created lobby: {:?}", lobby);
lobby.id
});
player.lobby_id = lobby_id;
let player = ctx.db.player().identity().update(player);
info!("player {} joined lobby {}", player.id, lobby_id);
Ok(())
}
#[reducer]
pub fn insert_wall(ctx: &ReducerContext, player_ids: Vec<u32>) {
let tiles: Vec<Tile> = tiles();
ctx.db.wall().insert(Wall { id: 0, tiles });
pub fn add_bot(ctx: &ReducerContext, lobby_id: u32) -> Result<(), String> {
if lobby_id == 0 {
Err("cannot add a bot without a lobby".into())
} else if let Some(lobby) = ctx.db.lobby().id().find(lobby_id)
&& (ctx.db.player().lobby_id().filter(lobby_id).count()
+ ctx.db.bot().lobby_id().filter(lobby_id).count()
<= 4)
{
let bot = ctx.db.bot().insert(Bot { id: 0, lobby_id });
info!("added bot {} to lobby {}", bot.id, lobby_id);
Ok(())
} else {
Err("lobby doesn't exist".into())
}
}
#[reducer]
pub fn shuffle_wall(ctx: &ReducerContext) {
// if let Some(wall) =
// let mut rng = ctx.rng();
// let mut wall = tiles();
// wall.shuffle(&mut rng);
todo!()
}
@ -123,3 +177,19 @@ pub fn sort_hand(ctx: &ReducerContext) {
// }
// log::info!("Hello, World!");
// }
// #[reducer]
// pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> {
// if name.is_empty() {
// return Err("names must not be empty".into());
// }
// if let Some(player) = ctx.db.player().identity().find(ctx.sender) {
// ctx.db.player().identity().update(Player {
// name: Some(name),
// ..player
// });
// Ok(())
// } else {
// Err("cannot set name for unknown user".into())
// }
// }