[feat] use eti game.db, commit not working, something is wrong with game.id in the client/frontend

This commit is contained in:
ddidderr 2024-11-12 22:12:49 +01:00
parent ba2177abf0
commit 1388bc2115
Signed by: ddidderr
GPG Key ID: 3841F1C27E6F0E14
17 changed files with 790 additions and 310 deletions

594
Cargo.lock generated
View File

@ -28,6 +28,18 @@ dependencies = [
"version_check",
]
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -185,6 +197,15 @@ dependencies = [
"system-deps",
]
[[package]]
name = "atoi"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
dependencies = [
"num-traits",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
@ -282,6 +303,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bindgen"
version = "0.69.5"
@ -777,6 +804,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const_format"
version = "0.2.33"
@ -871,6 +904,21 @@ dependencies = [
"libc",
]
[[package]]
name = "crc"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
dependencies = [
"crc-catalog",
]
[[package]]
name = "crc-catalog"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc32fast"
version = "1.4.2"
@ -889,6 +937,15 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
@ -1007,6 +1064,17 @@ dependencies = [
"parking_lot_core",
]
[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "deranged"
version = "0.3.11"
@ -1048,7 +1116,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
"subtle",
]
[[package]]
@ -1112,6 +1182,12 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "dotenvy"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "dpi"
version = "0.1.1"
@ -1159,6 +1235,9 @@ name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
dependencies = [
"serde",
]
[[package]]
name = "embed-resource"
@ -1225,6 +1304,28 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "etcetera"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
dependencies = [
"cfg-if",
"home",
"windows-sys 0.48.0",
]
[[package]]
name = "event-listener"
version = "5.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "eyre"
version = "0.6.12"
@ -1235,6 +1336,12 @@ dependencies = [
"once_cell",
]
[[package]]
name = "fastrand"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
[[package]]
name = "fdeflate"
version = "0.3.6"
@ -1396,6 +1503,17 @@ dependencies = [
"futures-util",
]
[[package]]
name = "futures-intrusive"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
dependencies = [
"futures-core",
"lock_api",
"parking_lot",
]
[[package]]
name = "futures-io"
version = "0.3.31"
@ -1795,7 +1913,7 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
"ahash",
"ahash 0.7.8",
]
[[package]]
@ -1803,6 +1921,10 @@ name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash 0.8.11",
"allocator-api2",
]
[[package]]
name = "hashbrown"
@ -1815,6 +1937,15 @@ dependencies = [
"foldhash",
]
[[package]]
name = "hashlink"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
dependencies = [
"hashbrown 0.14.5",
]
[[package]]
name = "heck"
version = "0.4.1"
@ -1845,6 +1976,24 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"
[[package]]
name = "hkdf"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [
"hmac",
]
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]]
name = "home"
version = "0.5.9"
@ -2397,6 +2546,16 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "lanspread-compat"
version = "0.1.0"
dependencies = [
"eyre",
"serde",
"sqlx",
"tracing",
]
[[package]]
name = "lanspread-db"
version = "0.1.0"
@ -2405,6 +2564,7 @@ dependencies = [
"semver",
"serde",
"serde_json",
"tracing",
]
[[package]]
@ -2435,6 +2595,7 @@ dependencies = [
"clap",
"eyre",
"itertools 0.13.0",
"lanspread-compat",
"lanspread-db",
"lanspread-mdns",
"lanspread-proto",
@ -2488,6 +2649,9 @@ name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin",
]
[[package]]
name = "lazycell"
@ -2708,6 +2872,17 @@ dependencies = [
"libc",
]
[[package]]
name = "libsqlite3-sys"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
@ -2806,6 +2981,16 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]]
name = "md-5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"digest",
]
[[package]]
name = "mdns-sd"
version = "0.11.5"
@ -2956,6 +3141,23 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand 0.8.5",
"smallvec",
"zeroize",
]
[[package]]
name = "num-conv"
version = "0.1.0"
@ -2971,6 +3173,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
@ -3337,6 +3550,12 @@ dependencies = [
"system-deps",
]
[[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"
@ -3372,6 +3591,15 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361"
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [
"base64ct",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -3544,6 +3772,27 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.31"
@ -4045,6 +4294,26 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "rsa"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
dependencies = [
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core 0.6.4",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rstml"
version = "0.11.2"
@ -4639,6 +4908,17 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.8"
@ -4684,6 +4964,16 @@ dependencies = [
"libc",
]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core 0.6.4",
]
[[package]]
name = "simd-adler32"
version = "0.3.7"
@ -4732,6 +5022,9 @@ name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
dependencies = [
"serde",
]
[[package]]
name = "socket2"
@ -4800,6 +5093,220 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
]
[[package]]
name = "sqlformat"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790"
dependencies = [
"nom",
"unicode_categories",
]
[[package]]
name = "sqlx"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e"
dependencies = [
"sqlx-core",
"sqlx-macros",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
]
[[package]]
name = "sqlx-core"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e"
dependencies = [
"atoi",
"byteorder",
"bytes",
"crc",
"crossbeam-queue",
"either",
"event-listener",
"futures-channel",
"futures-core",
"futures-intrusive",
"futures-io",
"futures-util",
"hashbrown 0.14.5",
"hashlink",
"hex",
"indexmap 2.6.0",
"log",
"memchr",
"once_cell",
"paste",
"percent-encoding",
"serde",
"serde_json",
"sha2",
"smallvec",
"sqlformat",
"thiserror 1.0.68",
"tokio",
"tokio-stream",
"tracing",
"url",
]
[[package]]
name = "sqlx-macros"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657"
dependencies = [
"proc-macro2",
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 2.0.87",
]
[[package]]
name = "sqlx-macros-core"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5"
dependencies = [
"dotenvy",
"either",
"heck 0.5.0",
"hex",
"once_cell",
"proc-macro2",
"quote",
"serde",
"serde_json",
"sha2",
"sqlx-core",
"sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite",
"syn 2.0.87",
"tempfile",
"tokio",
"url",
]
[[package]]
name = "sqlx-mysql"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a"
dependencies = [
"atoi",
"base64 0.22.1",
"bitflags 2.6.0",
"byteorder",
"bytes",
"crc",
"digest",
"dotenvy",
"either",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"generic-array",
"hex",
"hkdf",
"hmac",
"itoa 1.0.11",
"log",
"md-5",
"memchr",
"once_cell",
"percent-encoding",
"rand 0.8.5",
"rsa",
"serde",
"sha1",
"sha2",
"smallvec",
"sqlx-core",
"stringprep",
"thiserror 1.0.68",
"tracing",
"whoami",
]
[[package]]
name = "sqlx-postgres"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8"
dependencies = [
"atoi",
"base64 0.22.1",
"bitflags 2.6.0",
"byteorder",
"crc",
"dotenvy",
"etcetera",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"hex",
"hkdf",
"hmac",
"home",
"itoa 1.0.11",
"log",
"md-5",
"memchr",
"once_cell",
"rand 0.8.5",
"serde",
"serde_json",
"sha2",
"smallvec",
"sqlx-core",
"stringprep",
"thiserror 1.0.68",
"tracing",
"whoami",
]
[[package]]
name = "sqlx-sqlite"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
dependencies = [
"atoi",
"flume",
"futures-channel",
"futures-core",
"futures-executor",
"futures-intrusive",
"futures-util",
"libsqlite3-sys",
"log",
"percent-encoding",
"serde",
"serde_urlencoded",
"sqlx-core",
"tracing",
"url",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@ -4832,6 +5339,17 @@ dependencies = [
"quote",
]
[[package]]
name = "stringprep"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
dependencies = [
"unicode-bidi",
"unicode-normalization",
"unicode-properties",
]
[[package]]
name = "strsim"
version = "0.11.1"
@ -5249,6 +5767,19 @@ dependencies = [
"toml 0.7.8",
]
[[package]]
name = "tempfile"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
name = "tendril"
version = "0.4.3"
@ -5403,6 +5934,17 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "tokio-stream"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.12"
@ -5487,6 +6029,7 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@ -5642,12 +6185,33 @@ dependencies = [
"unic-common",
]
[[package]]
name = "unicode-bidi"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-normalization"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-properties"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
@ -5660,6 +6224,12 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "unicode_categories"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "untrusted"
version = "0.7.1"
@ -5748,6 +6318,12 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.2.0"
@ -5811,6 +6387,12 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
[[package]]
name = "wasm-bindgen"
version = "0.2.95"
@ -5993,6 +6575,16 @@ dependencies = [
"rustix",
]
[[package]]
name = "whoami"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
dependencies = [
"redox_syscall",
"wasite",
]
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -1,5 +1,6 @@
[workspace]
members = [
"crates/lanspread-compat",
"crates/lanspread-db",
"crates/lanspread-utils",
"crates/lanspread-mdns",

View File

@ -16,14 +16,14 @@ pub enum ClientEvent {
#[derive(Debug)]
pub enum ClientCommand {
ListGames,
GetGame(u64),
GetGame(String),
ServerAddr(SocketAddr),
}
/// # Errors
pub async fn run(
mut rx_control: UnboundedReceiver<ClientCommand>,
tx_event: UnboundedSender<ClientEvent>,
tx_notify_ui: UnboundedSender<ClientEvent>,
) -> eyre::Result<()> {
// blocking wait for remote address
log::debug!("waiting for server address");
@ -75,7 +75,7 @@ pub async fn run(
};
let data = request.encode();
log::error!("encoded data: {}", String::from_utf8_lossy(&data));
log::debug!("encoded data: {}", String::from_utf8_lossy(&data));
let stream = match conn.open_bidirectional_stream().await {
Ok(stream) => stream,
@ -91,22 +91,28 @@ pub async fn run(
log::error!("failed to send request to server {:?}", e);
}
if let Ok(Some(data)) = rx.receive().await {
log::trace!("server response (raw): {}", String::from_utf8_lossy(&data));
let response = Response::decode(&data);
let mut all_data: Vec<u8> = Vec::new();
while let Ok(Some(data)) = rx.receive().await {
log::trace!("msg from server (raw): {}", String::from_utf8_lossy(&data));
all_data.extend_from_slice(&data);
}
log::debug!("{} bytes received from server", all_data.len());
log::trace!(
"server response (decoded): {}",
String::from_utf8_lossy(&data)
"server response (RAW): {}",
String::from_utf8_lossy(&all_data)
);
let response = Response::decode(&all_data);
log::trace!("server response (DECODED): {response:?}");
match response {
Response::Games(games) => {
for game in &games {
log::debug!("{game:?}");
}
if let Err(e) = tx_event.send(ClientEvent::ListGames(games)) {
log::error!("failed to send ClientEvent::ListGames to client {e:?}");
if let Err(e) = tx_notify_ui.send(ClientEvent::ListGames(games)) {
log::debug!("failed to send ClientEvent::ListGames to client {e:?}");
}
}
Response::Game(game) => log::debug!("game received: {game:?}"),
@ -134,61 +140,3 @@ pub async fn run(
}
}
}
// log::info!("server closed connection");
// Ok(())
}
// #[derive(Debug, Parser)]
// struct Cli {
// /// Server IP address.
// #[clap(long, default_value = "127.0.0.1")]
// ip: IpAddr,
// /// Server port.
// #[clap(long, default_value = "13337")]
// port: u16,
// }
// #[tokio::main]
// async fn main() -> eyre::Result<()> {
// let cli = Cli::parse();
// let (tx_control, rx_control) = tokio::sync::mpsc::unbounded_channel::<ControlMessage>();
// // Spawn client in a separate task
// let client_handle = tokio::spawn(async move {
// let remote_addr = SocketAddr::from((cli.ip, cli.port));
// Client::run(remote_addr, rx_control).await
// });
// // Handle stdin commands in the main task
// let mut stdin = BufReader::new(tokio::io::stdin());
// let mut line = String::new();
// loop {
// line.clear();
// if stdin.read_line(&mut line).await? == 0 {
// break; // EOF reached
// }
// // Trim whitespace and handle commands
// match line.trim() {
// "list" => {
// tx_control.send(ControlMessage::ListGames)?;
// }
// cmd if cmd.starts_with("get ") => {
// if let Ok(id) = cmd[4..].trim().parse::<u64>() {
// tx_control.send(ControlMessage::GetGame(id))?;
// } else {
// println!("Invalid game ID");
// }
// }
// "quit" | "exit" => break,
// "" => continue,
// _ => println!("Unknown command. Available commands: list, get <id>, quit"),
// }
// }
// client_handle.await??;
// Ok(())
// }

View File

@ -0,0 +1,10 @@
[package]
name = "lanspread-compat"
version = "0.1.0"
edition = "2021"
[dependencies]
eyre = { workspace = true }
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio"] }
serde = { workspace = true }
tracing = { workspace = true }

View File

@ -0,0 +1,47 @@
use std::path::Path;
use serde::{Deserialize, Serialize};
use sqlx::sqlite::SqlitePool;
#[derive(Clone, Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct EtiGame {
pub game_id: String,
pub game_title: String,
pub game_key: String,
pub game_release: String,
pub game_publisher: String,
pub game_size: f64,
pub game_readme_de: String,
pub game_readme_en: String,
pub game_readme_fr: String,
pub game_maxplayers: u32,
pub game_master_req: i32,
pub genre_de: String,
pub game_version: String,
}
/// # Errors
pub async fn get_games(db: &Path) -> eyre::Result<Vec<EtiGame>> {
let pool = SqlitePool::connect(format!("sqlite:{}", db.to_string_lossy()).as_str()).await?;
let mut games = sqlx::query_as::<_, EtiGame>(
"SELECT
g.game_id, g.game_title, g.game_key, g.game_release,
g.game_publisher, CAST(g.game_size AS REAL) as game_size, g.game_readme_de,
g.game_readme_en, g.game_readme_fr, CAST(g.game_maxplayers AS INTEGER) as game_maxplayers,
g.game_master_req, ge.genre_de, g.game_version
FROM games g
JOIN genre ge ON g.genre_id = ge.genre_id",
)
.fetch_all(&pool)
.await?;
games.sort_by(|a, b| a.game_title.cmp(&b.game_title));
tracing::info!("Found {} games in game.db", games.len());
for game in &games {
tracing::debug!("{}: {}", game.game_id, game.game_title);
}
Ok(games)
}

View File

@ -0,0 +1 @@
pub mod eti;

View File

@ -17,3 +17,4 @@ eyre = { workspace = true}
semver = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tracing = { workspace = true }

View File

@ -1,33 +1,30 @@
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::doc_markdown)]
use std::{
collections::HashMap,
fmt,
fs::{File, OpenOptions},
path::Path,
};
use std::{collections::HashMap, fmt};
use serde::{Deserialize, Serialize};
use crate::serialization::version_serde;
/// A game
#[derive(Clone, Serialize, Deserialize)]
pub struct Game {
/// example: 1
pub id: u64,
/// example: Call of Duty 3
/// example: aoe2
pub id: String,
/// example: Age of Empires 2
pub name: String,
/// example: A shooter game in war.
/// example: Dieses Paket enthält die original AoE 2 Version,...
pub description: String,
/// example: `call_of_duty.tar.zst`
pub install_archive: String,
/// example: 1999
pub release_year: String,
/// Microsoft
pub publisher: String,
/// example: 8
pub max_players: u32,
/// example: 1.0.0
#[serde(with = "version_serde")]
pub version: semver::Version,
/// size (bytes)
/// example: 3.5
pub version: String,
/// example: Echtzeit-Strategie
pub genre: String,
/// size in bytes: example: 3455063152
pub size: u64,
}
@ -35,14 +32,10 @@ impl fmt::Debug for Game {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}: {} {} ({} players) ({}: {} MB) {}",
"{}: {} ({} MB)",
self.id,
self.name,
self.version,
self.max_players,
self.install_archive,
self.size,
self.description,
self.size / 1024 / 1024,
)
}
}
@ -75,8 +68,7 @@ impl Ord for Game {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GameDB {
pub games: HashMap<u64, Game>,
next_id: u64,
pub games: HashMap<String, Game>,
}
impl GameDB {
@ -84,7 +76,6 @@ impl GameDB {
pub fn new() -> Self {
GameDB {
games: HashMap::new(),
next_id: 1,
}
}
@ -92,39 +83,17 @@ impl GameDB {
pub fn from(games: Vec<Game>) -> Self {
let mut db = GameDB::new();
for game in games {
let id = game.id;
db.games.insert(game.id, game);
db.next_id = db.next_id.max(id + 1);
db.games.insert(game.id.clone(), game);
}
db
}
pub fn add_game<S: Into<String>>(
&mut self,
name: S,
description: S,
install_archive: S,
max_players: u32,
version: semver::Version,
) -> u64 {
let id = self.next_id;
self.next_id += 1;
let game = Game {
id,
name: name.into(),
description: description.into(),
install_archive: install_archive.into(),
max_players,
version,
size: 0,
};
self.games.insert(id, game);
id
}
#[must_use]
pub fn get_game_by_id(&self, id: u64) -> Option<&Game> {
self.games.get(&id)
pub fn get_game_by_id<S>(&self, id: S) -> Option<&Game>
where
S: AsRef<str>,
{
self.games.get(id.as_ref())
}
#[must_use]
@ -132,56 +101,10 @@ impl GameDB {
self.games.values().find(|game| game.name == name)
}
pub fn update_game<S: Into<String>>(
&mut self,
id: u64,
name: Option<S>,
description: Option<S>,
install_archive: Option<S>,
) -> bool {
if let Some(game) = self.games.get_mut(&id) {
if let Some(new_name) = name {
game.name = new_name.into();
}
if let Some(new_description) = description {
game.description = new_description.into();
}
if let Some(archive) = install_archive {
game.install_archive = archive.into();
}
true
} else {
false
}
}
pub fn delete_game(&mut self, id: u64) -> bool {
self.games.remove(&id).is_some()
}
#[must_use]
pub fn all_games(&self) -> Vec<&Game> {
self.games.values().collect()
}
pub fn save_to_file(&self, path: &Path) -> eyre::Result<()> {
let file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)?;
let games: Vec<&Game> = self.games.values().collect();
serde_json::to_writer(file, &games)?;
Ok(())
}
pub fn load_from_file(path: &Path) -> eyre::Result<Self> {
let file = File::open(path)?;
let games: Vec<Game> = serde_json::from_reader(file)?;
let db = GameDB::from(games);
Ok(db)
}
}
impl Default for GameDB {

View File

@ -1,2 +1 @@
pub mod db;
mod serialization;

View File

@ -1,19 +0,0 @@
pub(crate) mod version_serde {
use semver::Version;
use serde::{self, Deserialize, Deserializer, Serializer};
pub fn serialize<S>(version: &Version, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&version.to_string())
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Version, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Version::parse(&s).map_err(serde::de::Error::custom)
}
}

View File

@ -6,7 +6,7 @@ use tracing::error;
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
ListGames,
GetGame { id: u64 },
GetGame { id: String },
Invalid(Vec<u8>, String),
}
@ -14,7 +14,7 @@ pub enum Request {
pub enum Response {
Games(Vec<Game>),
Game(Game),
GameNotFound(u64),
GameNotFound(String),
InvalidRequest(Vec<u8>, String),
EncodingError(String),
DecodingError(Vec<u8>, String),

View File

@ -13,6 +13,7 @@ unwrap_used = "warn"
[dependencies]
# local
lanspread-compat = { path = "../lanspread-compat" }
lanspread-db = { path = "../lanspread-db" }
lanspread-mdns = { path = "../lanspread-mdns" }
lanspread-proto = { path = "../lanspread-proto" }

View File

@ -1,11 +1,14 @@
#![allow(clippy::doc_markdown)]
use std::{
net::{IpAddr, SocketAddr},
path::{Path, PathBuf},
path::PathBuf,
sync::Arc,
};
use clap::Parser;
use lanspread_db::db::GameDB;
use lanspread_compat::eti::{self, EtiGame};
use lanspread_db::db::{Game, GameDB};
use lanspread_mdns::{
DaemonEvent,
MdnsAdvertiser,
@ -15,18 +18,13 @@ use lanspread_mdns::{
use lanspread_proto::{Message as _, Request, Response};
use lanspread_utils::maybe_addr;
use s2n_quic::Server as QuicServer;
use testing::generate_test_db;
use tokio::{io::AsyncWriteExt, sync::Mutex};
use tracing_subscriber::EnvFilter;
mod testing;
static KEY_PEM: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../key.pem"));
static CERT_PEM: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../cert.pem"));
pub(crate) struct Server {
db_path: PathBuf,
}
pub(crate) struct Server;
#[derive(Clone, Debug)]
struct ServerCtx {
@ -40,20 +38,14 @@ struct ConnectionCtx {
}
impl Server {
fn new<S: Into<PathBuf>>(db_path: S) -> Self {
Server {
db_path: db_path.into(),
}
}
async fn run(&mut self, addr: SocketAddr) -> eyre::Result<()> {
async fn run(addr: SocketAddr, db: GameDB) -> eyre::Result<()> {
let mut server = QuicServer::builder()
.with_tls((CERT_PEM, KEY_PEM))?
.with_io(addr)?
.start()?;
let server_ctx = Arc::new(ServerCtx {
handler: RequestHandler::new(&self.db_path)?,
handler: RequestHandler::new(db),
});
while let Some(mut connection) = server.accept().await {
@ -126,11 +118,10 @@ struct RequestHandler {
}
impl RequestHandler {
fn new(db_path: &Path) -> eyre::Result<Self> {
let db = GameDB::load_from_file(db_path)?;
Ok(RequestHandler {
db: Arc::new(Mutex::new(db)),
})
fn new(games: GameDB) -> RequestHandler {
RequestHandler {
db: Arc::new(Mutex::new(games)),
}
}
async fn handle_request(&self, request: Request) -> Response {
@ -141,7 +132,7 @@ impl RequestHandler {
}
Request::GetGame { id } => {
let db = self.db.lock().await;
match db.get_game_by_id(id) {
match db.get_game_by_id(&id) {
Some(game) => Response::Game(game.clone()),
None => Response::GameNotFound(id),
}
@ -158,16 +149,33 @@ impl RequestHandler {
}
}
const GAME_DB_PATH: &str = "/home/pfs/shm/game.db";
#[derive(Debug, Parser)]
struct Cli {
/// The IP address to bind to.
#[clap(long, default_value = "127.0.0.1")]
/// IP address to bind to.
#[clap(long)]
ip: IpAddr,
/// The listen port.
#[clap(long, default_value = "13337")]
/// Listen port.
#[clap(long)]
port: u16,
/// Game database path (SQLite).
#[clap(long)]
db: PathBuf,
}
fn eti_game_to_game(eti_game: EtiGame) -> Game {
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
Game {
id: eti_game.game_id,
name: eti_game.game_title,
description: eti_game.game_readme_de,
release_year: eti_game.game_release,
publisher: eti_game.game_publisher,
max_players: eti_game.game_maxplayers,
version: eti_game.game_version,
genre: eti_game.genre_de,
size: (eti_game.game_size * 1024.0 * 1024.0 * 1024.0) as u64,
}
}
#[tokio::main]
@ -178,7 +186,9 @@ async fn main() -> eyre::Result<()> {
let cli = Cli::parse();
generate_test_db(GAME_DB_PATH);
let eti_games = eti::get_games(&cli.db).await?;
let games: Vec<Game> = eti_games.into_iter().map(eti_game_to_game).collect();
let game_db = GameDB::from(games);
let mdns = MdnsAdvertiser::new(
LANSPREAD_SERVICE_TYPE,
@ -190,7 +200,7 @@ async fn main() -> eyre::Result<()> {
while let Ok(event) = mdns.monitor.recv() {
tracing::info!("mDNS: {:?}", &event);
if let DaemonEvent::Error(e) = event {
tracing::info!("Failed: {e}");
tracing::error!("mDNS: {e}");
break;
}
}
@ -198,6 +208,5 @@ async fn main() -> eyre::Result<()> {
tracing::info!("Server listening on {}:{}", cli.ip, cli.port);
let mut server = Server::new(GAME_DB_PATH);
server.run(SocketAddr::from((cli.ip, cli.port))).await
Server::run(SocketAddr::from((cli.ip, cli.port)), game_db).await
}

View File

@ -1,35 +0,0 @@
#![allow(clippy::unwrap_used)]
use std::path::PathBuf;
use lanspread_db::db::GameDB;
pub(crate) fn generate_test_db<P: Into<PathBuf>>(db_path: P) {
let db_path = db_path.into();
let mut db = GameDB::new();
db.add_game(
"Call of Duty 3",
"A shooter game in war.",
"call_of_duty.tar.zst",
64,
semver::Version::new(1, 0, 0),
);
db.add_game(
"Counter-Strike Source",
"Valve's iconic shooter.",
"cstrike.tar.zst",
32,
semver::Version::new(1, 0, 0),
);
db.add_game(
"Factorio",
"Best game of all time, seriously.",
"factorio.tar.zst",
128,
semver::Version::new(1, 0, 0),
);
db.update_game(1, Some("Call of Duty 4"), None, None);
db.save_to_file(&db_path).unwrap();
}

View File

@ -1,4 +1,4 @@
use std::{net::SocketAddr, process::Command};
use std::net::SocketAddr;
use lanspread_client::{ClientCommand, ClientEvent};
use lanspread_mdns::{discover_service, LANSPREAD_INSTANCE_NAME, LANSPREAD_SERVICE_TYPE};
@ -22,24 +22,26 @@ fn request_games(state: tauri::State<LanSpreadState>) {
}
#[tauri::command]
fn run_game_backend(id: u64, state: tauri::State<LanSpreadState>) -> String {
fn run_game_backend(id: String, state: tauri::State<LanSpreadState>) -> String {
log::error!("Running game with id {id}");
let result = Command::new(r#"C:\Users\ddidderr\scoop\apps\mpv\0.39.0\mpv.exe"#).spawn();
// let result = Command::new(r#"C:\Users\ddidderr\scoop\apps\mpv\0.39.0\mpv.exe"#).spawn();
if let Err(e) = state.inner().client_ctrl.send(ClientCommand::GetGame(id)) {
log::error!("Failed to send message to client: {e:?}");
}
if result.is_ok() {
"Ok".to_string()
} else {
"Failed to run game".to_string()
}
"TODO".to_string()
// if result.is_ok() {
// "Ok".to_string()
// } else {
// "Failed to run game".to_string()
// }
}
async fn find_server(app: AppHandle) {
log::error!("Looking for server...");
log::info!("Looking for server...");
loop {
match discover_service(LANSPREAD_SERVICE_TYPE, Some(LANSPREAD_INSTANCE_NAME)) {
@ -73,7 +75,7 @@ pub fn run() {
tauri_plugin_log::TargetKind::Stdout,
))
.level(log::LevelFilter::Info)
.level_for("lanspread_client", log::LevelFilter::Debug)
.level_for("lanspread_client", log::LevelFilter::Trace)
.level_for("lanspread_tauri_leptos_lib", log::LevelFilter::Debug)
.level_for("mdns_sd::service_daemon", log::LevelFilter::Off);
@ -106,7 +108,7 @@ pub fn run() {
let app_handle = app.handle().clone();
tauri::async_runtime::spawn(async move {
while let Some(event) = rx_client_event.recv().await {
log::debug!("Received client event: {event:?}");
log::debug!("Received client event");
match event {
ClientEvent::ListGames(games) => {

View File

@ -16,7 +16,7 @@ extern "C" {
#[derive(Serialize, Deserialize)]
struct RunGameArgs {
id: u64,
id: String,
}
#[derive(Serialize, Deserialize)]
@ -59,14 +59,14 @@ pub fn App() -> impl IntoView {
});
// Call list_games on component mount
create_effect(move |_| {
spawn_local(async move {
let args = serde_wasm_bindgen::to_value(&()).unwrap();
invoke("request_games", args).await;
});
});
// create_effect(move |_| {
// spawn_local(async move {
// let args = serde_wasm_bindgen::to_value(&()).unwrap();
// invoke("request_games", args).await;
// });
// });
let run_game = move |id: u64| {
let run_game = move |id: String| {
log_1(&JsValue::from_str(format!("id={id}").as_str()));
spawn_local(async move {
let args = serde_wasm_bindgen::to_value(&RunGameArgs { id }).unwrap();
@ -87,7 +87,7 @@ pub fn App() -> impl IntoView {
{move || game_items.get().into_iter()
.map(|item|
view! {
<div class="item" on:click=move |_| run_game(item.id)>
<div class="item" on:click=move |_| run_game(item.id.clone())>
<img src="https://via.placeholder.com/200x150" alt="Item Image" />
<div class="item-name">{ &item.name }</div>
<div class="description">

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#export RUST_LOG+=,lanspread_server=debug,lanspread_proto=debug
export RUST_LOG=info,lanspread_mdns=debug,lanspread_db=debug,lanspread_server=debug,lanspread_proto=debug
exec cargo run -p lanspread-server -- "$@"
#RUST_LOG=info exec cargo run --profile release-lto -p lanspread-server