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

View file

@ -4,9 +4,11 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
axum = { version = "0.7.5", features = ["ws"] } axum = { version = "0.7.7", features = ["ws"] }
serde = "1.*.*" serde = "1.*.*"
serde_json = "1.*.*" serde_json = "1.*.*"
tokio = { version = "1.*.*", features = ["full"] } 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" } 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??? # WTF how do i implement a game???
## Things you need from a game ## Client todo
Characters and character sheet: [ ] implement tavern functions
[x] Stats and items: get/set/display [ ] token drag & drop
[ ] Actions (broken into different tabs, aka: `(&self) -> Vec<InteractionDefinition>`) [ ] Chat
[ ] Token status: status icons (with tooltip ffs)/light produced/vision distance(in light level) [ ] Send new chat messages
[ ] Apply Action `(&mut self, InteractionResult) -> ()` [ ] recv new chat messages
Spells and items [ ] 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: ## Server todo
[ ] 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,
}
```
[ ] 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, pub password: String,
} }
#[derive(Serialize)] #[derive(Serialize, Clone)]
pub struct LoginResult { pub struct LoginResult {
pub success: bool, pub success: bool,
// TODO: Figure out what the user needs on successful login to reduce traffic // 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 serde::{Deserialize, Serialize};
use crate::game::chat_message::ChatMessage;
#[derive(Serialize, Deserialize, Default, Debug)] #[derive(Serialize, Deserialize, Default, Debug)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum Request { pub enum Request {
#[default] #[default]
Error, Error,
Login(login::LoginRequest) Login(login::LoginRequest),
Message(ChatMessage),
Quit,
Shutdown
} }
#[derive(Serialize)] #[derive(Serialize, Clone)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum Response { pub enum Response {
Error(RequestError), 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")] #[serde(rename_all = "snake_case")]
pub enum RequestError { pub enum RequestError {
InvalidRequest, InvalidRequest,

View file

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ChatMessage { 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` /// 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, pub text: String,
@ -17,7 +17,7 @@ pub struct ChatMessage {
pub targets: Option<Vec<String>> pub targets: Option<Vec<String>>
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RollDialogOption { pub struct RollDialogOption {
/// Field name /// Field name
pub name: String, pub name: String,

View file

@ -1,5 +1,34 @@
use game::{Game, GameImpl};
use tokio::sync::{broadcast, mpsc};
pub mod user; pub mod user;
pub mod table; pub mod table;
pub mod api; pub mod api;
pub mod game; 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::{ use axum::{
extract::ws::{self,Message}, response, routing, Router extract::ws::{self,Message}, response, routing, Router
}; };
use futures_util::{stream::{SplitSink, SplitStream}, SinkExt, StreamExt};
use open_tavern::api::{Request, RequestError, Response}; use open_tavern::api::{Request, RequestError, Response};
use tokio::sync::{broadcast, mpsc};
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let (bsend, _) = broadcast::channel(10);
let (msend, mrecv) = mpsc::channel(50);
let bsend2 = bsend.clone();
let app = Router::new() let app = Router::new()
.route("/", routing::get(root)) .route("/", routing::get(root))
.route("/socket.js", routing::get(socket)) .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(); 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 { async fn ws_handler(ws: ws::WebSocketUpgrade, msend: mpsc::Sender<(String, Request)>, brecv: broadcast::Receiver<Response>) -> impl axum::response::IntoResponse {
ws.on_upgrade(handle_socket) ws.on_upgrade(|w| handle_socket(w, msend, brecv))
} }
async fn handle_socket(mut socket: ws::WebSocket) { async fn socket_receiver(mut recv: SplitStream<ws::WebSocket>, msend: mpsc::Sender<(String, Request)>, id: String) {
let mut logged_in = false; while let Some(msg) = recv.next().await {
println!("Got a new socket"); 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 { loop {
if let Some(msg) = socket.recv().await { if let Some(msg) = socket.recv().await {
if let Ok(msg) = msg { if let Ok(msg) = msg {
let response: Message = match msg { match msg {
Message::Text(t) => { Message::Text(t) => {
let req = serde_json::from_str::<Request>(&t).unwrap_or_default(); let req = serde_json::from_str::<Request>(&t).unwrap_or_default();
println!("Got message: {:?}", t); println!("Got message: {:?}", t);
match req { match req {
Request::Error => Message::Text(serde_json::to_string(&Response::Error(RequestError::InvalidRequest)).unwrap()), // TODO: Actual signing in mechanism with multiple ids :)
Request::Login(r) => if !logged_in { Request::Login(r) => if r.username == "rusty" {
if r.username == "rusty" { _ = socket.send(Message::Text(
logged_in = true; serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: true })).unwrap()
Message::Text(serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: true })).unwrap()) )).await;
} id = Some(String::from("rusty"));
else { break;
Message::Text(serde_json::to_string(&Response::Login(open_tavern::api::login::LoginResult { success: false })).unwrap()) }
} else {
} else { _ = socket.send(Message::Text(
Message::Text(serde_json::to_string(&Response::Error(open_tavern::api::RequestError::AlreadyLoggedIn)).unwrap()) 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::Binary(_) => todo!(),
ws::Message::Ping(_) => todo!(), ws::Message::Ping(_) => todo!(),
ws::Message::Pong(_) => todo!(), ws::Message::Pong(_) => todo!(),
ws::Message::Close(_) => break, ws::Message::Close(_) => break,
}; };
socket.send(response).await.expect("failed sending to socket");
} }
} }
else { else {
break; 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"); 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 crate::game::{action::{ActionDefinition, ActionResult, GameEntry}, character_sheet::*, chat_message::{ChatMessage, RollDialogOption}};
use serde::Serialize;
use tavern_macros::CharacterSheet; use tavern_macros::CharacterSheet;
pub mod entry; pub mod entry;
use entry::{PEntry, Weapon}; use entry::{PEntry, Weapon};
#[derive(Default, CharacterSheet)] #[derive(Default, CharacterSheet, Serialize)]
pub struct Pathfinder2rCharacterSheet { pub struct Pathfinder2rCharacterSheet {
// Genral stuff // Genral stuff
#[Input("Name")] #[Input("Name")]