server test is working :)

This commit is contained in:
Rusty Striker 2024-09-30 18:44:36 +03:00
parent 9189d9cd88
commit dd34317d14
Signed by: RustyStriker
GPG key ID: 87E4D691632DFF15
9 changed files with 249 additions and 166 deletions

169
Cargo.lock generated
View file

@ -24,7 +24,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
@ -64,9 +63,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "axum"
version = "0.7.5"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
dependencies = [
"async-trait",
"axum-core",
@ -93,7 +92,7 @@ dependencies = [
"sync_wrapper 1.0.1",
"tokio",
"tokio-tungstenite",
"tower",
"tower 0.5.1",
"tower-layer",
"tower-service",
"tracing",
@ -101,9 +100,9 @@ dependencies = [
[[package]]
name = "axum-core"
version = "0.4.3"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
dependencies = [
"async-trait",
"bytes",
@ -114,7 +113,7 @@ dependencies = [
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper 0.1.2",
"sync_wrapper 1.0.1",
"tower-layer",
"tower-service",
"tracing",
@ -137,9 +136,9 @@ dependencies = [
[[package]]
name = "base64"
version = "0.21.7"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
@ -185,9 +184,12 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cc"
version = "1.0.104"
version = "1.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490"
checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
@ -195,6 +197,15 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "const-oid"
version = "0.9.6"
@ -369,9 +380,14 @@ dependencies = [
[[package]]
name = "event-listener"
version = "2.5.3"
version = "5.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "fastrand"
@ -449,6 +465,17 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.68",
]
[[package]]
name = "futures-sink"
version = "0.3.30"
@ -469,6 +496,7 @@ checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
@ -516,21 +544,18 @@ dependencies = [
[[package]]
name = "hashlink"
version = "0.8.4"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
dependencies = [
"hashbrown",
]
[[package]]
name = "heck"
version = "0.4.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
dependencies = [
"unicode-segmentation",
]
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
@ -649,6 +674,8 @@ dependencies = [
"hyper",
"pin-project-lite",
"tokio",
"tower 0.4.13",
"tower-service",
]
[[package]]
@ -826,9 +853,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libsqlite3-sys"
version = "0.27.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
dependencies = [
"cc",
"pkg-config",
@ -1004,6 +1031,8 @@ name = "open_tavern"
version = "0.1.0"
dependencies = [
"axum",
"futures-util",
"parking_lot",
"serde",
"serde_json",
"sqlx",
@ -1011,6 +1040,12 @@ dependencies = [
"tokio",
]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -1318,6 +1353,12 @@ dependencies = [
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
@ -1351,6 +1392,9 @@ name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
dependencies = [
"serde",
]
[[package]]
name = "socket2"
@ -1393,9 +1437,9 @@ dependencies = [
[[package]]
name = "sqlx"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa"
checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e"
dependencies = [
"sqlx-core",
"sqlx-macros",
@ -1406,11 +1450,10 @@ dependencies = [
[[package]]
name = "sqlx-core"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6"
checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e"
dependencies = [
"ahash",
"atoi",
"byteorder",
"bytes",
@ -1423,6 +1466,7 @@ dependencies = [
"futures-intrusive",
"futures-io",
"futures-util",
"hashbrown",
"hashlink",
"hex",
"indexmap",
@ -1445,22 +1489,22 @@ dependencies = [
[[package]]
name = "sqlx-macros"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127"
checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657"
dependencies = [
"proc-macro2",
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 1.0.109",
"syn 2.0.68",
]
[[package]]
name = "sqlx-macros-core"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5"
dependencies = [
"dotenvy",
"either",
@ -1474,8 +1518,9 @@ dependencies = [
"sha2",
"sqlx-core",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 1.0.109",
"syn 2.0.68",
"tempfile",
"tokio",
"url",
@ -1483,9 +1528,9 @@ dependencies = [
[[package]]
name = "sqlx-mysql"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a"
dependencies = [
"atoi",
"base64",
@ -1525,9 +1570,9 @@ dependencies = [
[[package]]
name = "sqlx-postgres"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8"
dependencies = [
"atoi",
"base64",
@ -1563,9 +1608,9 @@ dependencies = [
[[package]]
name = "sqlx-sqlite"
version = "0.7.4"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
dependencies = [
"atoi",
"flume",
@ -1578,10 +1623,10 @@ dependencies = [
"log",
"percent-encoding",
"serde",
"serde_urlencoded",
"sqlx-core",
"tracing",
"url",
"urlencoding",
]
[[package]]
@ -1768,9 +1813,9 @@ dependencies = [
[[package]]
name = "tokio-tungstenite"
version = "0.21.0"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9"
dependencies = [
"futures-util",
"log",
@ -1791,20 +1836,35 @@ dependencies = [
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper 0.1.2",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
@ -1840,9 +1900,9 @@ dependencies = [
[[package]]
name = "tungstenite"
version = "0.21.0"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
dependencies = [
"byteorder",
"bytes",
@ -1853,7 +1913,6 @@ dependencies = [
"rand",
"sha1",
"thiserror",
"url",
"utf-8",
]
@ -1890,12 +1949,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291"
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
name = "unicode_categories"
version = "0.1.1"
@ -1913,12 +1966,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "utf-8"
version = "0.7.6"

View file

@ -4,9 +4,11 @@ version = "0.1.0"
edition = "2021"
[dependencies]
axum = { version = "0.7.5", features = ["ws"] }
axum = { version = "0.7.7", features = ["ws"] }
serde = "1.*.*"
serde_json = "1.*.*"
tokio = { version = "1.*.*", features = ["full"] }
sqlx = { version = "0.7.4", features = ["runtime-tokio", "sqlite"] }
sqlx = { version = "0.8.2", features = ["runtime-tokio", "sqlite"] }
tavern_macros = { version = "0.1.0", path = "tavern_macros" }
parking_lot = "0.12.3"
futures-util = "0.3.30"

View file

@ -1,77 +1,23 @@
# WTF how do i implement a game???
## Things you need from a game
## Client todo
Characters and character sheet:
[x] Stats and items: get/set/display
[ ] Actions (broken into different tabs, aka: `(&self) -> Vec<InteractionDefinition>`)
[ ] Token status: status icons (with tooltip ffs)/light produced/vision distance(in light level)
[ ] Apply Action `(&mut self, InteractionResult) -> ()`
Spells and items
[ ] implement tavern functions
[ ] token drag & drop
[ ] Chat
[ ] Send new chat messages
[ ] recv new chat messages
[ ] roll a die when chat message requests that
[ ] figure out how to zoom on the mouse instead of the center of the div
[ ] data reqs
[ ]Turn based combat callbakcs:
[ ] Start of turn - `(&mut self) -> Vec<Message>`
[ ] End of turn
InteractionDef -> Player uses -> Interaction in chat (with actions) -> Rolls some dice -> Interaction
Shoot arrow def ->
player A shoots B (rolls attack) -> I
nteraction in chat (with Roll damage button) ->
InteractionResult (damage/double/block/heal actions) ->
Apply InteractionResult ()
```rust
trait Action {}
trait CS<A: Action> {
fn can_use_action(&self, action: &A) -> bool;
}
struct Game<'dec, 'dea, C: CS<A> + Serialize + Deserialize<'dec>, A: Action + Serialize + Deserialize<'dea>> {
_a: std::marker::PhantomData<&'dea A>,
_c: std::marker::PhantomData<&'dec C>,
}
impl<'dec, 'dea, C: CS<A> + Serialize + Deserialize<'dec>, A: Action + Serialize + Deserialize<'dea>> Game<'dec, 'dea, C, A> {
fn read_spell(s: &'dea str) -> A {
serde_json::de::from_str::<A>(s).unwrap()
}
}
#[derive(Serialize, Deserialize)]
struct Spell {
pub mana: i32,
}
impl Action for Spell {}
#[derive(Serialize, Deserialize)]
struct Sheet;
impl CS<Spell> for Sheet {
fn can_use_action(&self, action: &Spell) -> bool {
action.mana > 10
}
}
fn stupid() {
let game = Game::<'_, '_, Sheet, Spell>::read_spell("aaaaaaaa");
}
```
^^^ this looks mad isnt it, but it defines 3 traits, Action, Character sheet and game(which should be a trait actually)
1. Player connects
2. Player gets character data (including all the relevant actions and such)
3. Player acts
1. Player does action
2. Action is printed to chat (with rolls and such)
3. Action button is pressed (optional rolls)
fn use_action(&mut self, entry: &Entry, action: &Action) -> ChatMessage
```rust
struct Action {
pub name: String,
pub roll_result: i32,
}
```
## Server todo
[ ] impl different requests
[ ] actual normal login
[ ] allow sending of old info
[ ] chat history
[ ] send texture (map/token/image)
[ ] force show something
[ ] mouse ping (ideally multiple types)
[ ] data reqs

View file

@ -6,7 +6,7 @@ pub struct LoginRequest {
pub password: String,
}
#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub struct LoginResult {
pub success: bool,
// TODO: Figure out what the user needs on successful login to reduce traffic

View file

@ -4,21 +4,30 @@ pub mod map_actions;
use serde::{Deserialize, Serialize};
use crate::game::chat_message::ChatMessage;
#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "snake_case")]
pub enum Request {
#[default]
Error,
Login(login::LoginRequest)
Login(login::LoginRequest),
Message(ChatMessage),
Quit,
Shutdown
}
#[derive(Serialize)]
#[derive(Serialize, Clone)]
#[serde(rename_all = "snake_case")]
pub enum Response {
Error(RequestError),
Login(login::LoginResult)
Login(login::LoginResult),
Message(ChatMessage),
Quit { id: String },
Shutdown,
}
#[derive(Serialize, Debug)]
#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum RequestError {
InvalidRequest,

View file

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ChatMessage {
/// message text, `{item}` can be used to refer to items and such, where item is of the path such as `items/sword` or `spells/fireball`
pub text: String,
@ -17,7 +17,7 @@ pub struct ChatMessage {
pub targets: Option<Vec<String>>
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RollDialogOption {
/// Field name
pub name: String,

View file

@ -1,5 +1,34 @@
use game::{Game, GameImpl};
use tokio::sync::{broadcast, mpsc};
pub mod user;
pub mod table;
pub mod api;
pub mod game;
pub mod pathfinder2r_impl;
pub mod pathfinder2r_impl;
pub struct GameServer {
game: Game<pathfinder2r_impl::Pathfinder2rCharacterSheet, pathfinder2r_impl::entry::PEntry>
}
impl GameServer {
pub fn new() -> Self {
Self {
game: Game::new(),
}
}
pub async fn server_loop(mut self, mut msgs: mpsc::Receiver<(String, api::Request)>, mut broadcast: broadcast::Sender<api::Response>) {
while let Some(req) = msgs.recv().await {
// TODO: do stuff yo!
let (id, req) = req;
match req {
api::Request::Error => {},
api::Request::Login(_) => {},
api::Request::Message(msg) => { _ = broadcast.send(api::Response::Message(msg)); },
api::Request::Quit => { _ = broadcast.send(api::Response::Quit { id })},
api::Request::Shutdown => todo!(),
}
}
_ = broadcast.send(api::Response::Shutdown);
}
}

View file

@ -1,61 +1,110 @@
use axum::{
extract::ws::{self,Message}, response, routing, Router
};
use futures_util::{stream::{SplitSink, SplitStream}, SinkExt, StreamExt};
use open_tavern::api::{Request, RequestError, Response};
use tokio::sync::{broadcast, mpsc};
#[tokio::main]
async fn main() {
let (bsend, _) = broadcast::channel(10);
let (msend, mrecv) = mpsc::channel(50);
let bsend2 = bsend.clone();
let app = Router::new()
.route("/", routing::get(root))
.route("/socket.js", routing::get(socket))
.route("/ws", routing::get(ws_handler))
;
.route("/ws", routing::get(move |w| ws_handler(w, msend, bsend2.clone().subscribe())));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await.unwrap();
axum::serve(listener, app).await.unwrap();
let game = open_tavern::GameServer::new();
tokio::spawn(game.server_loop(mrecv, bsend));
axum::serve(listener, app).await.expect("axum server crashed, yaaaaay (unless i crashed him that yay)");
}
async fn ws_handler(ws: ws::WebSocketUpgrade) -> impl axum::response::IntoResponse {
ws.on_upgrade(handle_socket)
async fn ws_handler(ws: ws::WebSocketUpgrade, msend: mpsc::Sender<(String, Request)>, brecv: broadcast::Receiver<Response>) -> impl axum::response::IntoResponse {
ws.on_upgrade(|w| handle_socket(w, msend, brecv))
}
async fn handle_socket(mut socket: ws::WebSocket) {
let mut logged_in = false;
println!("Got a new socket");
async fn socket_receiver(mut recv: SplitStream<ws::WebSocket>, msend: mpsc::Sender<(String, Request)>, id: String) {
while let Some(msg) = recv.next().await {
if let Ok(msg) = msg {
match msg {
Message::Text(t) => {
let req = serde_json::from_str::<Request>(&t).unwrap_or_default();
println!("Got message: {:?}", t);
let erred = msend.send((id.clone(), req)).await.is_err();
if erred {
break;
}
}
ws::Message::Binary(_) => todo!(),
ws::Message::Ping(_) => todo!(),
ws::Message::Pong(_) => todo!(),
ws::Message::Close(_) => {
// dont care if we fail the send as we are quitting regardless
_ = msend.send((id.clone(), open_tavern::api::Request::Quit)).await;
break;
},
}
}
}
}
async fn socket_sender(mut send: SplitSink<ws::WebSocket, ws::Message>, mut brecv: broadcast::Receiver<Response>) {
while let Ok(msg) = brecv.recv().await {
let err = send.send(ws::Message::Text(serde_json::to_string(&msg).unwrap())).await.is_err();
if err {
break;
}
}
}
async fn handle_socket(mut socket: ws::WebSocket, msend: mpsc::Sender<(String, Request)>, brecv: broadcast::Receiver<Response>) {
let mut id: Option<String> = None;
loop {
if let Some(msg) = socket.recv().await {
if let Ok(msg) = msg {
let response: Message = match msg {
match msg {
Message::Text(t) => {
let req = serde_json::from_str::<Request>(&t).unwrap_or_default();
println!("Got message: {:?}", t);
match req {
Request::Error => Message::Text(serde_json::to_string(&Response::Error(RequestError::InvalidRequest)).unwrap()),
Request::Login(r) => if !logged_in {
if r.username == "rusty" {
logged_in = true;
Message::Text(serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: true })).unwrap())
}
else {
Message::Text(serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: false })).unwrap())
}
} else {
Message::Text(serde_json::to_string(&Response::Error(open_tavern::api::RequestError::AlreadyLoggedIn)).unwrap())
// TODO: Actual signing in mechanism with multiple ids :)
Request::Login(r) => if r.username == "rusty" {
_ = socket.send(Message::Text(
serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: true })).unwrap()
)).await;
id = Some(String::from("rusty"));
break;
}
else {
_ = socket.send(Message::Text(
serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: false })).unwrap()
)).await;
},
}
_ => {
_ = socket.send(Message::Text(serde_json::to_string(&Response::Error(RequestError::InvalidRequest)).unwrap())).await;
},
}
}
ws::Message::Binary(_) => todo!(),
ws::Message::Ping(_) => todo!(),
ws::Message::Pong(_) => todo!(),
ws::Message::Close(_) => break,
};
socket.send(response).await.expect("failed sending to socket");
}
}
else {
break;
}
}
if let Some(id) = id {
println!("Got id for socket: {}", &id);
let (send, recv) = socket.split();
tokio::spawn(socket_receiver(recv, msend, id));
tokio::spawn(socket_sender(send, brecv));
}
println!("Done with so-cat");
}

View file

@ -1,10 +1,11 @@
use crate::game::{action::{ActionDefinition, ActionResult, GameEntry}, character_sheet::*, chat_message::{ChatMessage, RollDialogOption}};
use serde::Serialize;
use tavern_macros::CharacterSheet;
pub mod entry;
use entry::{PEntry, Weapon};
#[derive(Default, CharacterSheet)]
#[derive(Default, CharacterSheet, Serialize)]
pub struct Pathfinder2rCharacterSheet {
// Genral stuff
#[Input("Name")]