server test is working :)
This commit is contained in:
parent
9189d9cd88
commit
dd34317d14
9 changed files with 249 additions and 166 deletions
169
Cargo.lock
generated
169
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
90
readme.md
90
readme.md
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
29
src/lib.rs
29
src/lib.rs
|
@ -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 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);
|
||||
}
|
||||
}
|
87
src/main.rs
87
src/main.rs
|
@ -1,46 +1,90 @@
|
|||
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())
|
||||
// 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 {
|
||||
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())
|
||||
_ = 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;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -49,13 +93,18 @@ async fn handle_socket(mut socket: ws::WebSocket) {
|
|||
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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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")]
|
||||
|
|
Loading…
Reference in a new issue