Merge pull request #3 from kleo-dev/simple-working
Simple working server and protocol
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
target/
|
target/
|
||||||
plugins/
|
plugins/
|
||||||
config.json
|
config.json
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
|
*.db
|
||||||
+4
-1
@@ -5,11 +5,14 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.99"
|
anyhow = "1.0.99"
|
||||||
|
base64 = "0.22.1"
|
||||||
|
chrono = "0.4.42"
|
||||||
libloading = { version = "0.8.8", optional = true }
|
libloading = { version = "0.8.8", optional = true }
|
||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
|
rusqlite = "0.37.0"
|
||||||
serde = { version = "1.0.219", features = ["serde_derive"] }
|
serde = { version = "1.0.219", features = ["serde_derive"] }
|
||||||
serde_json = "1.0.143"
|
serde_json = "1.0.143"
|
||||||
tungstenite = "0.27.0"
|
sha1 = "0.10.6"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
Generated
+286
-133
@@ -2,12 +2,39 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.99"
|
version = "1.0.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
@@ -18,10 +45,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bumpalo"
|
||||||
version = "1.10.1"
|
version = "3.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
|
||||||
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -29,6 +66,19 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cli"
|
name = "cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -36,6 +86,12 @@ dependencies = [
|
|||||||
"voxa-server",
|
"voxa-server",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
@@ -55,12 +111,6 @@ dependencies = [
|
|||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "data-encoding"
|
|
||||||
version = "2.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
@@ -72,10 +122,28 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fallible-iterator"
|
||||||
version = "1.0.7"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
@@ -88,33 +156,46 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "hashbrown"
|
||||||
version = "0.3.3"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"foldhash",
|
||||||
"libc",
|
|
||||||
"r-efi",
|
|
||||||
"wasi",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "hashlink"
|
||||||
version = "1.3.1"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"hashbrown",
|
||||||
"fnv",
|
|
||||||
"itoa",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "iana-time-zone"
|
||||||
version = "1.10.1"
|
version = "0.1.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
@@ -122,6 +203,16 @@ version = "1.0.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.78"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.175"
|
version = "0.2.175"
|
||||||
@@ -138,6 +229,16 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.35.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.27"
|
version = "0.4.27"
|
||||||
@@ -150,6 +251,15 @@ version = "2.7.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
@@ -157,13 +267,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "pkg-config"
|
||||||
version = "0.2.21"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
dependencies = [
|
|
||||||
"zerocopy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
@@ -184,39 +291,24 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "r-efi"
|
name = "rusqlite"
|
||||||
version = "5.3.0"
|
version = "0.37.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha",
|
"bitflags",
|
||||||
"rand_core",
|
"fallible-iterator",
|
||||||
|
"fallible-streaming-iterator",
|
||||||
|
"hashlink",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rustversion"
|
||||||
version = "0.9.0"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
@@ -267,6 +359,18 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.106"
|
version = "2.0.106"
|
||||||
@@ -278,43 +382,6 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "2.0.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "2.0.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tungstenite"
|
|
||||||
version = "0.27.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"data-encoding",
|
|
||||||
"http",
|
|
||||||
"httparse",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"sha1",
|
|
||||||
"thiserror",
|
|
||||||
"utf-8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
@@ -328,10 +395,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf-8"
|
name = "vcpkg"
|
||||||
version = "0.7.6"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
@@ -344,20 +411,108 @@ name = "voxa-server"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"base64",
|
||||||
|
"chrono",
|
||||||
"libloading",
|
"libloading",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tungstenite",
|
"sha1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasm-bindgen"
|
||||||
version = "0.14.3+wasi-0.2.4"
|
version = "0.2.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
|
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wit-bindgen",
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link 0.2.0",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -366,13 +521,37 @@ version = "0.1.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.53.3"
|
version = "0.53.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link",
|
"windows-link 0.1.3",
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu",
|
||||||
@@ -430,29 +609,3 @@ name = "windows_x86_64_msvc"
|
|||||||
version = "0.53.0"
|
version = "0.53.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wit-bindgen"
|
|
||||||
version = "0.45.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerocopy"
|
|
||||||
version = "0.8.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
|
|
||||||
dependencies = [
|
|
||||||
"zerocopy-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerocopy-derive"
|
|
||||||
version = "0.8.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use voxa_server::{ServerConfig, vfs};
|
use voxa_server::{ServerConfig, utils::vfs};
|
||||||
|
|
||||||
fn main() -> voxa_server::Result<()> {
|
fn main() -> voxa_server::Result<()> {
|
||||||
let root = PathBuf::from("");
|
let root = PathBuf::from("");
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import readline from 'readline';
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
|
||||||
|
const ws = new WebSocket('ws://localhost:7080');
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('WebSocket connection established');
|
||||||
|
console.log('Initializing handshake');
|
||||||
|
ws.send(JSON.stringify({ version: '0.0.1', auth_token: '<placeholder>' }))
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
const message = JSON.parse(event.data);
|
||||||
|
console.log('Received:', message);
|
||||||
|
// ws.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
function sendMessage(message) {
|
||||||
|
ws.send(JSON.stringify({ type: 'send_message', params: {
|
||||||
|
channel_id: 'general',
|
||||||
|
contents: message
|
||||||
|
}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function ask(question) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
rl.question(question, resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const message = await ask('');
|
||||||
|
sendMessage(message);
|
||||||
|
}
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
use std::{
|
|
||||||
hash::{Hash, Hasher},
|
|
||||||
net::TcpStream,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
use tungstenite::{Message, WebSocket, accept};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Client(Arc<Mutex<WebSocket<TcpStream>>>);
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
pub fn new_ws(ws: WebSocket<TcpStream>) -> Self {
|
|
||||||
Self(Arc::new(Mutex::new(ws)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_tcp(ws: TcpStream) -> crate::Result<Self> {
|
|
||||||
Ok(Self(Arc::new(Mutex::new(accept(ws)?))))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Client {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
Arc::ptr_eq(&self.0, &other.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for Client {}
|
|
||||||
|
|
||||||
impl Hash for Client {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
std::ptr::hash(Arc::as_ptr(&self.0), state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
pub fn read(&self) -> crate::Result<Message> {
|
|
||||||
self.0.lock().unwrap().read().map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send(&self, m: Message) -> crate::Result<()> {
|
|
||||||
self.0.lock().unwrap().send(m).map_err(|e| e.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+57
-33
@@ -5,23 +5,22 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod client;
|
|
||||||
#[cfg(feature = "loader")]
|
|
||||||
pub mod loader;
|
|
||||||
pub mod logger;
|
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
pub mod plugin;
|
pub mod requests;
|
||||||
pub mod vfs;
|
pub mod types;
|
||||||
|
pub mod utils;
|
||||||
|
|
||||||
pub use anyhow::Result;
|
pub use anyhow::Result;
|
||||||
pub use tungstenite;
|
|
||||||
|
|
||||||
use crate::{client::Client, plugin::DynPlugin};
|
use crate::{utils::client::Client, utils::plugin::DynPlugin};
|
||||||
pub use once_cell;
|
pub use once_cell;
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
|
server_name: String,
|
||||||
|
server_id: String,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
channels: Vec<types::data::Channel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -30,11 +29,17 @@ pub struct Server {
|
|||||||
config: ServerConfig,
|
config: ServerConfig,
|
||||||
plugins: Mutex<Vec<DynPlugin>>,
|
plugins: Mutex<Vec<DynPlugin>>,
|
||||||
clients: Mutex<HashSet<Client>>,
|
clients: Mutex<HashSet<Client>>,
|
||||||
|
pub db: utils::database::Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { port: 7080 }
|
Self {
|
||||||
|
port: 7080,
|
||||||
|
server_name: format!("Server Name"),
|
||||||
|
server_id: format!("offline-server"),
|
||||||
|
channels: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,16 +53,12 @@ impl Server {
|
|||||||
logger!(LOGGER "Server");
|
logger!(LOGGER "Server");
|
||||||
|
|
||||||
pub fn new(root: &Path) -> Arc<Self> {
|
pub fn new(root: &Path) -> Arc<Self> {
|
||||||
Arc::new(Self {
|
Self::new_config(root, ServerConfig::default())
|
||||||
plugins: Mutex::new(Vec::new()),
|
|
||||||
root: root.to_path_buf(),
|
|
||||||
config: ServerConfig::default(),
|
|
||||||
clients: Mutex::new(HashSet::new()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_config(root: &Path, config: ServerConfig) -> Arc<Self> {
|
pub fn new_config(root: &Path, config: ServerConfig) -> Arc<Self> {
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
|
db: utils::database::Database::new(&config).unwrap(),
|
||||||
plugins: Mutex::new(Vec::new()),
|
plugins: Mutex::new(Vec::new()),
|
||||||
root: root.to_path_buf(),
|
root: root.to_path_buf(),
|
||||||
config,
|
config,
|
||||||
@@ -68,7 +69,7 @@ impl Server {
|
|||||||
pub fn run(self: &Arc<Self>) -> Result<()> {
|
pub fn run(self: &Arc<Self>) -> Result<()> {
|
||||||
// Load plugins
|
// Load plugins
|
||||||
#[cfg(feature = "loader")]
|
#[cfg(feature = "loader")]
|
||||||
loader::load_plugins(
|
utils::loader::load_plugins(
|
||||||
&mut *self.plugins.lock().unwrap(),
|
&mut *self.plugins.lock().unwrap(),
|
||||||
&self.root.join("./plugins"),
|
&self.root.join("./plugins"),
|
||||||
)?;
|
)?;
|
||||||
@@ -109,32 +110,55 @@ impl Server {
|
|||||||
fn handle_client(self: &Arc<Self>, stream: TcpStream) -> anyhow::Result<()> {
|
fn handle_client(self: &Arc<Self>, stream: TcpStream) -> anyhow::Result<()> {
|
||||||
Self::LOGGER.info(format!("New connection: {}", stream.peer_addr()?));
|
Self::LOGGER.info(format!("New connection: {}", stream.peer_addr()?));
|
||||||
// Initialize client
|
// Initialize client
|
||||||
let client = Client::new_tcp(stream)?;
|
let client = Client::new(stream)?;
|
||||||
|
|
||||||
|
// Initialize handshake
|
||||||
|
self.wrap_err(
|
||||||
|
&client,
|
||||||
|
client.send(types::handshake::ServerDetails {
|
||||||
|
name: self.config.server_name.clone(),
|
||||||
|
id: self.config.server_id.clone(),
|
||||||
|
version: format!("0.0.1"),
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
match self.wrap_err(&client, client.read_t::<types::handshake::ClientDetails>())? {
|
||||||
|
Some(types::WsMessage::Message(_)) => {
|
||||||
|
// Do auth stuff
|
||||||
|
self.wrap_err(
|
||||||
|
&client,
|
||||||
|
client.send(types::ServerMessage::Authenticated {
|
||||||
|
user_id: format!("<placeholder>"),
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Some(_) => {
|
||||||
|
self.wrap_err(
|
||||||
|
&client,
|
||||||
|
client.send(types::ResponseError::InvalidHandshake(format!(
|
||||||
|
"Invalid handshake"
|
||||||
|
))),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
// Insert to the set of all connected clients
|
// Insert to the set of all connected clients
|
||||||
self.clients.lock().unwrap().insert(client.clone());
|
self.clients.lock().unwrap().insert(client.clone());
|
||||||
|
|
||||||
// The main req/res loop
|
// The main req/res loop
|
||||||
loop {
|
'outer: loop {
|
||||||
let req = client.read()?;
|
let req = client.read()?;
|
||||||
|
if let Some(r) = &req {
|
||||||
for plugin in self.plugins.lock().unwrap().iter_mut() {
|
for p in self.plugins.lock().unwrap().iter_mut() {
|
||||||
plugin.on_request(&req, self);
|
if p.on_request(r, &client, self) {
|
||||||
}
|
continue 'outer;
|
||||||
|
}
|
||||||
if req.is_close() {
|
|
||||||
self.clients.lock().unwrap().remove(&client);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for c in self.clients.lock().unwrap().iter() {
|
|
||||||
if c != &client {
|
|
||||||
self.wrap_err(&client, c.send(req.clone()))?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.call_request(r, &client)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When there is a error it removes the client
|
/// When there is a error it removes the client
|
||||||
|
|||||||
+7
-7
@@ -2,7 +2,7 @@
|
|||||||
macro_rules! export_plugin {
|
macro_rules! export_plugin {
|
||||||
($p:expr) => {
|
($p:expr) => {
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn load_plugin() -> $crate::plugin::DynPlugin {
|
pub extern "C" fn load_plugin() -> $crate::utils::plugin::DynPlugin {
|
||||||
$p
|
$p
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -11,20 +11,20 @@ macro_rules! export_plugin {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! logger {
|
macro_rules! logger {
|
||||||
(const $i:ident $name:expr) => {
|
(const $i:ident $name:expr) => {
|
||||||
const $i: $crate::once_cell::sync::Lazy<$crate::logger::Logger> =
|
pub const $i: $crate::once_cell::sync::Lazy<$crate::utils::logger::Logger> =
|
||||||
$crate::once_cell::sync::Lazy::new(|| $crate::logger::Logger::new($name));
|
$crate::once_cell::sync::Lazy::new(|| $crate::utils::logger::Logger::new($name));
|
||||||
};
|
};
|
||||||
|
|
||||||
($i:ident $name:expr) => {
|
($i:ident $name:expr) => {
|
||||||
const $i: $crate::once_cell::sync::Lazy<$crate::logger::Logger> =
|
pub const $i: $crate::once_cell::sync::Lazy<$crate::utils::logger::Logger> =
|
||||||
$crate::once_cell::sync::Lazy::new(|| $crate::logger::Logger::new($name));
|
$crate::once_cell::sync::Lazy::new(|| $crate::utils::logger::Logger::new($name));
|
||||||
};
|
};
|
||||||
|
|
||||||
(const $name:expr) => {
|
(const $name:expr) => {
|
||||||
$crate::once_cell::sync::Lazy::new(|| $crate::logger::Logger::new($name))
|
$crate::once_cell::sync::Lazy::new(|| $crate::utils::logger::Logger::new($name))
|
||||||
};
|
};
|
||||||
|
|
||||||
($name:expr) => {
|
($name:expr) => {
|
||||||
$crate::logger::Logger::new($name)
|
$crate::logger::utils::Logger::new($name)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use tungstenite::Message;
|
|
||||||
|
|
||||||
use crate::Server;
|
|
||||||
|
|
||||||
pub type DynPlugin = Box<dyn Plugin + Send + Sync>;
|
|
||||||
|
|
||||||
pub trait Plugin {
|
|
||||||
fn init(&mut self, server: &Arc<Server>);
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn on_request(&mut self, msg: &Message, server: &Arc<Server>) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{Server, types, utils::client::Client};
|
||||||
|
|
||||||
|
crate::logger!(LOGGER "Message Manager");
|
||||||
|
|
||||||
|
pub fn send(
|
||||||
|
server: &Arc<Server>,
|
||||||
|
client: &Client,
|
||||||
|
channel_id: &str,
|
||||||
|
contents: &str,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
LOGGER.info(format!("SendMessage to {channel_id}: {contents}"));
|
||||||
|
|
||||||
|
if contents.is_empty() {
|
||||||
|
server.wrap_err(
|
||||||
|
&client,
|
||||||
|
client.send(types::ResponseError::InvalidRequest(format!(
|
||||||
|
"Invalid message: empty message"
|
||||||
|
))),
|
||||||
|
)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = server.wrap_err(
|
||||||
|
&client,
|
||||||
|
server.db.insert_message(
|
||||||
|
&channel_id,
|
||||||
|
"idk",
|
||||||
|
&contents,
|
||||||
|
chrono::Utc::now().timestamp(),
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
for c in server.clients.lock().unwrap().iter() {
|
||||||
|
server.wrap_err(&c, c.send(types::ServerMessage::MessageCreate(msg.clone())))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn edit(
|
||||||
|
_server: &Arc<Server>,
|
||||||
|
_client: &Client,
|
||||||
|
message_id: usize,
|
||||||
|
new_contents: &str,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
LOGGER.info(format!("EditMessage {message_id}: {new_contents}"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(_server: &Arc<Server>, _client: &Client, message_id: usize) -> crate::Result<()> {
|
||||||
|
LOGGER.info(format!("DeleteMessage {message_id}"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
pub mod message;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
Server,
|
||||||
|
types::{ClientMessage, WsMessage},
|
||||||
|
utils::client::Client,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl Server {
|
||||||
|
pub fn call_request(
|
||||||
|
self: &Arc<Self>,
|
||||||
|
req: &WsMessage<ClientMessage>,
|
||||||
|
client: &Client,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
match req {
|
||||||
|
WsMessage::Message(req) => match req {
|
||||||
|
ClientMessage::SendMessage {
|
||||||
|
channel_id,
|
||||||
|
contents,
|
||||||
|
} => {
|
||||||
|
message::send(self, client, channel_id, contents)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientMessage::EditMessage {
|
||||||
|
message_id,
|
||||||
|
new_contents,
|
||||||
|
} => message::edit(self, client, *message_id, new_contents)?,
|
||||||
|
|
||||||
|
ClientMessage::DeleteMessage { message_id } => {
|
||||||
|
message::delete(self, client, *message_id)?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
WsMessage::Binary(b) => {
|
||||||
|
Self::LOGGER.info(format!("Binary message: {b:?}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
WsMessage::String(s) => {
|
||||||
|
Self::LOGGER.info(format!("String message: {s}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
+120
@@ -0,0 +1,120 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Messages sent *from the client* (user’s app) to the server
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
|
||||||
|
pub enum ClientMessage {
|
||||||
|
/// Send a message to a channel
|
||||||
|
SendMessage {
|
||||||
|
channel_id: String,
|
||||||
|
contents: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Edit a message (if allowed)
|
||||||
|
EditMessage {
|
||||||
|
message_id: usize,
|
||||||
|
new_contents: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Delete a message (if allowed)
|
||||||
|
DeleteMessage { message_id: usize },
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Messages sent *from the server* to the client
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
|
||||||
|
pub enum ServerMessage {
|
||||||
|
/// Successful authentication
|
||||||
|
Authenticated { user_id: String },
|
||||||
|
|
||||||
|
TempMessage {
|
||||||
|
message: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// A new message in a channel
|
||||||
|
MessageCreate(data::Message),
|
||||||
|
|
||||||
|
/// A message was edited
|
||||||
|
MessageUpdate(data::Message),
|
||||||
|
|
||||||
|
/// A message was deleted
|
||||||
|
MessageDelete {
|
||||||
|
channel_id: String,
|
||||||
|
message_id: usize,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Presence updates
|
||||||
|
PresenceUpdate {
|
||||||
|
user_id: String,
|
||||||
|
status: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Typing indicator
|
||||||
|
Typing {
|
||||||
|
user_id: String,
|
||||||
|
channel_id: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "error", content = "message", rename_all = "snake_case")]
|
||||||
|
pub enum ResponseError {
|
||||||
|
InvalidRequest(String),
|
||||||
|
InvalidHandshake(String),
|
||||||
|
Unauthorized(String),
|
||||||
|
NotFound(String),
|
||||||
|
InternalError(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// WebSocket wrapper
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum WsMessage<T: Serialize + for<'de> Deserialize<'de>> {
|
||||||
|
Message(T),
|
||||||
|
Binary(Vec<u8>),
|
||||||
|
String(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shared data structures
|
||||||
|
pub mod data {
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Message {
|
||||||
|
pub id: i64,
|
||||||
|
pub channel_id: String,
|
||||||
|
pub from: String,
|
||||||
|
pub contents: String,
|
||||||
|
pub timestamp: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Channel {
|
||||||
|
pub id: String,
|
||||||
|
pub name: String,
|
||||||
|
pub kind: ChannelKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum ChannelKind {
|
||||||
|
Text,
|
||||||
|
Voice,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod handshake {
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ServerDetails {
|
||||||
|
pub version: String,
|
||||||
|
pub name: String,
|
||||||
|
pub id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ClientDetails {
|
||||||
|
pub version: String,
|
||||||
|
pub auth_token: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
use std::{
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
io::{self, Read, Write},
|
||||||
|
net::TcpStream,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{ClientMessage, WsMessage};
|
||||||
|
|
||||||
|
pub mod handshake {
|
||||||
|
use base64::Engine;
|
||||||
|
use base64::engine::general_purpose::STANDARD as Base64;
|
||||||
|
use sha1::{Digest, Sha1};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::io::{BufRead, BufReader, Write};
|
||||||
|
use std::net::TcpStream;
|
||||||
|
|
||||||
|
const WS_GUID: &str = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
|
|
||||||
|
pub fn handle_websocket_handshake(stream: &mut TcpStream) -> std::io::Result<()> {
|
||||||
|
let mut reader = BufReader::new(stream.try_clone()?);
|
||||||
|
let mut request_line = String::new();
|
||||||
|
reader.read_line(&mut request_line)?;
|
||||||
|
|
||||||
|
if !request_line.starts_with("GET") {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Invalid HTTP method",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut headers = HashMap::new();
|
||||||
|
let mut line = String::new();
|
||||||
|
loop {
|
||||||
|
line.clear();
|
||||||
|
let bytes = reader.read_line(&mut line)?;
|
||||||
|
if bytes == 0 || line == "\r\n" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if let Some((k, v)) = line.split_once(':') {
|
||||||
|
headers.insert(k.trim().to_lowercase(), v.trim().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let key = headers.get("sec-websocket-key").ok_or_else(|| {
|
||||||
|
std::io::Error::new(std::io::ErrorKind::InvalidData, "Missing Sec-WebSocket-Key")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if headers.get("upgrade").map(|v| v.to_lowercase()) != Some("websocket".to_string()) {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Missing or invalid Upgrade header",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !headers
|
||||||
|
.get("connection")
|
||||||
|
.map(|v| v.to_lowercase().contains("upgrade"))
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Missing or invalid Connection header",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: validate Sec-WebSocket-Version == 13 (most common)
|
||||||
|
if let Some(ver) = headers.get("sec-websocket-version") {
|
||||||
|
if ver.trim() != "13" {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Unsupported Sec-WebSocket-Version",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute accept key
|
||||||
|
let mut hasher = Sha1::new();
|
||||||
|
hasher.update(key.as_bytes());
|
||||||
|
hasher.update(WS_GUID.as_bytes());
|
||||||
|
let hash = hasher.finalize();
|
||||||
|
let accept_key = Base64.encode(hash);
|
||||||
|
|
||||||
|
// Note: include Sec-WebSocket-Protocol handling if you support subprotocols
|
||||||
|
let response = format!(
|
||||||
|
"HTTP/1.1 101 Switching Protocols\r\n\
|
||||||
|
Upgrade: websocket\r\n\
|
||||||
|
Connection: Upgrade\r\n\
|
||||||
|
Sec-WebSocket-Accept: {}\r\n\
|
||||||
|
Sec-WebSocket-Version: 13\r\n\r\n",
|
||||||
|
accept_key
|
||||||
|
);
|
||||||
|
|
||||||
|
stream.write_all(response.as_bytes())?;
|
||||||
|
stream.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Client(pub TcpStream);
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a client with no timeouts
|
||||||
|
pub fn new(mut stream: TcpStream) -> crate::Result<Self> {
|
||||||
|
handshake::handle_websocket_handshake(&mut stream)?;
|
||||||
|
Ok(Client(stream))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a client and set read/write timeouts (useful in prod)
|
||||||
|
pub fn with_timeouts(
|
||||||
|
mut stream: TcpStream,
|
||||||
|
read_timeout: Option<Duration>,
|
||||||
|
write_timeout: Option<Duration>,
|
||||||
|
) -> crate::Result<Self> {
|
||||||
|
if let Some(t) = read_timeout {
|
||||||
|
stream.set_read_timeout(Some(t))?;
|
||||||
|
}
|
||||||
|
if let Some(t) = write_timeout {
|
||||||
|
stream.set_write_timeout(Some(t))?;
|
||||||
|
}
|
||||||
|
handshake::handle_websocket_handshake(&mut stream)?;
|
||||||
|
Ok(Client(stream))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a close frame and flush. `code` is a WebSocket close code (e.g., 1000 normal).
|
||||||
|
pub fn send_close(&self, code: u16, reason: &str) -> crate::Result<()> {
|
||||||
|
let mut stream = self.0.try_clone()?;
|
||||||
|
|
||||||
|
// control frames must be <= 125 bytes
|
||||||
|
let mut payload = Vec::new();
|
||||||
|
payload.extend_from_slice(&code.to_be_bytes());
|
||||||
|
payload.extend_from_slice(reason.as_bytes());
|
||||||
|
if payload.len() > 125 {
|
||||||
|
return Err(anyhow!("close reason too long").into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut frame = Vec::with_capacity(2 + payload.len());
|
||||||
|
frame.push(0x88); // FIN=1, opcode=0x8 (Close)
|
||||||
|
frame.push(payload.len() as u8); // server->client MUST NOT mask
|
||||||
|
frame.extend_from_slice(&payload);
|
||||||
|
|
||||||
|
stream.write_all(&frame)?;
|
||||||
|
stream.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a pong with given payload (control frames must be <=125)
|
||||||
|
fn send_pong(&self, payload: &[u8]) -> crate::Result<()> {
|
||||||
|
let mut stream = self.0.try_clone()?;
|
||||||
|
|
||||||
|
if payload.len() > 125 {
|
||||||
|
return Err(anyhow!("pong payload too long").into());
|
||||||
|
}
|
||||||
|
let mut frame = Vec::with_capacity(2 + payload.len());
|
||||||
|
frame.push(0x8A); // FIN=1, opcode=0xA (Pong)
|
||||||
|
frame.push(payload.len() as u8);
|
||||||
|
frame.extend_from_slice(payload);
|
||||||
|
stream.write_all(&frame)?;
|
||||||
|
stream.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a text/binary frame (server->client must NOT mask)
|
||||||
|
pub fn send<T: Serialize>(&self, m: T) -> crate::Result<()> {
|
||||||
|
let mut stream = self.0.try_clone()?;
|
||||||
|
|
||||||
|
let payload = serde_json::to_string(&m)?;
|
||||||
|
let payload_bytes = payload.as_bytes();
|
||||||
|
let len = payload_bytes.len();
|
||||||
|
|
||||||
|
let mut header = Vec::new();
|
||||||
|
header.push(0x81); // FIN=1, opcode=0x1 (text)
|
||||||
|
|
||||||
|
if len < 126 {
|
||||||
|
header.push(len as u8);
|
||||||
|
} else if len <= 65535 {
|
||||||
|
header.push(126);
|
||||||
|
header.extend_from_slice(&(len as u16).to_be_bytes());
|
||||||
|
} else {
|
||||||
|
header.push(127);
|
||||||
|
header.extend_from_slice(&(len as u64).to_be_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.write_all(&header)?;
|
||||||
|
stream.write_all(payload_bytes)?;
|
||||||
|
stream.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a full WebSocket message, handling fragmentation and control frames.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// - Ok(Some(WsMessage)) on an application message (text/binary)
|
||||||
|
/// - Ok(None) if the connection should be closed (close received / read EOF)
|
||||||
|
/// - Err on protocol or IO errors.
|
||||||
|
pub fn read_t<T: Serialize + for<'de> Deserialize<'de>>(
|
||||||
|
&self,
|
||||||
|
) -> crate::Result<Option<WsMessage<T>>> {
|
||||||
|
let mut stream = self.0.try_clone()?;
|
||||||
|
|
||||||
|
let mut message_payload = Vec::new();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// read the 2-byte header
|
||||||
|
let mut header = [0u8; 2];
|
||||||
|
if let Err(e) = stream.read_exact(&mut header) {
|
||||||
|
if e.kind() == io::ErrorKind::UnexpectedEof || e.kind() == io::ErrorKind::BrokenPipe
|
||||||
|
{
|
||||||
|
return Ok(None); // treat EOF as closed
|
||||||
|
}
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let fin = header[0] & 0x80 != 0;
|
||||||
|
let opcode = header[0] & 0x0F;
|
||||||
|
let masked = header[1] & 0x80 != 0;
|
||||||
|
let mut payload_len = (header[1] & 0x7F) as u64;
|
||||||
|
|
||||||
|
// Extended payload lengths
|
||||||
|
if payload_len == 126 {
|
||||||
|
let mut ext_len = [0u8; 2];
|
||||||
|
stream.read_exact(&mut ext_len)?;
|
||||||
|
payload_len = u16::from_be_bytes(ext_len) as u64;
|
||||||
|
} else if payload_len == 127 {
|
||||||
|
let mut ext_len = [0u8; 8];
|
||||||
|
stream.read_exact(&mut ext_len)?;
|
||||||
|
payload_len = u64::from_be_bytes(ext_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask key (client→server MUST be masked)
|
||||||
|
let mut mask = [0u8; 4];
|
||||||
|
if masked {
|
||||||
|
stream.read_exact(&mut mask)?;
|
||||||
|
} else {
|
||||||
|
let _ = self.send_close(1002, "Client frames must be masked");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control frame checks
|
||||||
|
if matches!(opcode, 0x8 | 0x9 | 0xA) {
|
||||||
|
if payload_len > 125 {
|
||||||
|
let _ = self.send_close(1002, "Control frame too large");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
if !fin {
|
||||||
|
let _ = self.send_close(1002, "Control frames must not be fragmented");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read payload + unmask
|
||||||
|
let mut payload = vec![0u8; payload_len as usize];
|
||||||
|
if payload_len > 0 {
|
||||||
|
stream.read_exact(&mut payload)?;
|
||||||
|
for i in 0..payload.len() {
|
||||||
|
payload[i] ^= mask[i % 4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match opcode {
|
||||||
|
0x0 | 0x1 | 0x2 => {
|
||||||
|
// Continuation / Text / Binary
|
||||||
|
message_payload.extend(payload);
|
||||||
|
if fin {
|
||||||
|
break; // got full message
|
||||||
|
} else {
|
||||||
|
continue; // wait for more fragments
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0x8 => {
|
||||||
|
// Close
|
||||||
|
let (code, reason) = if payload.len() >= 2 {
|
||||||
|
let code = u16::from_be_bytes([payload[0], payload[1]]);
|
||||||
|
let reason = if payload.len() > 2 {
|
||||||
|
String::from_utf8_lossy(&payload[2..]).into_owned()
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
(code, reason)
|
||||||
|
} else {
|
||||||
|
(1000, String::new())
|
||||||
|
};
|
||||||
|
let _ = self.send_close(code, &reason);
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
0x9 => {
|
||||||
|
// Ping → respond with Pong
|
||||||
|
let _ = self.send_pong(&payload);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
0xA => {
|
||||||
|
// Pong → ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let _ = self.send_close(1002, "Unsupported opcode");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try parsing JSON into ClientMessage
|
||||||
|
let message = match String::from_utf8(message_payload.clone()) {
|
||||||
|
Ok(text) => match serde_json::from_str(&text) {
|
||||||
|
Ok(msg) => WsMessage::Message(msg),
|
||||||
|
Err(_) => WsMessage::String(text),
|
||||||
|
},
|
||||||
|
Err(_) => WsMessage::Binary(message_payload),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Some(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a full WebSocket message, handling fragmentation and control frames.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// - Ok(Some(WsMessage)) on an application message (text/binary)
|
||||||
|
/// - Ok(None) if the connection should be closed (close received / read EOF)
|
||||||
|
/// - Err on protocol or IO errors.
|
||||||
|
pub fn read(&self) -> crate::Result<Option<WsMessage<ClientMessage>>> {
|
||||||
|
self.read_t()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Client {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Client(self.0.try_clone().expect("failed to clone TcpStream"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Client {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.0.peer_addr().unwrap() == other.0.peer_addr().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Client {}
|
||||||
|
|
||||||
|
impl Hash for Client {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.0.peer_addr().unwrap().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
use crate::{ServerConfig, types::data::Message};
|
||||||
|
use rusqlite::{Connection, Result, params};
|
||||||
|
|
||||||
|
pub struct Database(pub Connection);
|
||||||
|
|
||||||
|
// General use case
|
||||||
|
impl Database {
|
||||||
|
pub fn new(_config: &ServerConfig) -> Option<Self> {
|
||||||
|
let conn = Connection::open("main.db").ok()?;
|
||||||
|
|
||||||
|
conn.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS chat (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
channel_id TEXT NOT NULL,
|
||||||
|
user_id TEXT NOT NULL,
|
||||||
|
contents TEXT NOT NULL,
|
||||||
|
timestamp INTEGER NOT NULL
|
||||||
|
)",
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
Some(Database(conn))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For chat messages
|
||||||
|
impl Database {
|
||||||
|
/// Insert a message into the DB
|
||||||
|
pub fn insert_message(
|
||||||
|
&self,
|
||||||
|
channel_id: &str,
|
||||||
|
user_id: &str,
|
||||||
|
contents: &str,
|
||||||
|
timestamp: i64,
|
||||||
|
) -> Result<Message> {
|
||||||
|
self.0.execute(
|
||||||
|
"INSERT INTO chat (channel_id, user_id, contents, timestamp)
|
||||||
|
VALUES (?1, ?2, ?3, ?4)",
|
||||||
|
params![channel_id, user_id, contents, timestamp],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let id = self.0.last_insert_rowid();
|
||||||
|
|
||||||
|
Ok(Message {
|
||||||
|
id,
|
||||||
|
channel_id: channel_id.to_string(),
|
||||||
|
from: user_id.to_string(),
|
||||||
|
contents: contents.to_string(),
|
||||||
|
timestamp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a message by its ID
|
||||||
|
pub fn get_message_by_id(&self, message_id: usize) -> Result<Option<Message>> {
|
||||||
|
let mut stmt = self.0.prepare(
|
||||||
|
"SELECT id, channel_id, user_id, contents, timestamp
|
||||||
|
FROM chat
|
||||||
|
WHERE id = ?1",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut rows = stmt.query_map(params![message_id], |row| {
|
||||||
|
Ok((
|
||||||
|
row.get::<_, i64>(0)?, // id
|
||||||
|
row.get::<_, String>(1)?, // channel_id
|
||||||
|
row.get::<_, String>(2)?, // user_id
|
||||||
|
row.get::<_, String>(3)?, // contents
|
||||||
|
row.get::<_, i64>(4)?, // timestamp
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(row) = rows.next() {
|
||||||
|
let (id, channel_id, user_id, contents, timestamp) = row?;
|
||||||
|
return Ok(Some(Message {
|
||||||
|
id,
|
||||||
|
channel_id,
|
||||||
|
from: user_id,
|
||||||
|
contents,
|
||||||
|
timestamp,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Database {}
|
||||||
|
unsafe impl Sync for Database {}
|
||||||
@@ -2,7 +2,7 @@ use std::path::Path;
|
|||||||
|
|
||||||
use libloading::{Library, Symbol};
|
use libloading::{Library, Symbol};
|
||||||
|
|
||||||
use crate::{logger, plugin::DynPlugin, vfs};
|
use crate::{logger, utils::plugin::DynPlugin, utils::vfs};
|
||||||
|
|
||||||
logger! {
|
logger! {
|
||||||
const LOGGER "Loader"
|
const LOGGER "Loader"
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
pub mod client;
|
||||||
|
pub mod database;
|
||||||
|
#[cfg(feature = "loader")]
|
||||||
|
pub mod loader;
|
||||||
|
pub mod logger;
|
||||||
|
pub mod plugin;
|
||||||
|
pub mod vfs;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
Server,
|
||||||
|
types::{ClientMessage, WsMessage},
|
||||||
|
utils::client::Client,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type DynPlugin = Box<dyn Plugin + Send + Sync>;
|
||||||
|
|
||||||
|
pub trait Plugin {
|
||||||
|
fn init(&mut self, server: &Arc<Server>);
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
fn on_request(
|
||||||
|
&mut self,
|
||||||
|
req: &WsMessage<ClientMessage>,
|
||||||
|
client: &Client,
|
||||||
|
server: &Arc<Server>,
|
||||||
|
) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+272
-119
@@ -2,12 +2,39 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.99"
|
version = "1.0.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
@@ -18,10 +45,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bumpalo"
|
||||||
version = "1.10.1"
|
version = "3.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
|
||||||
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -29,6 +66,25 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
@@ -48,12 +104,6 @@ dependencies = [
|
|||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "data-encoding"
|
|
||||||
version = "2.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
@@ -65,10 +115,28 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fallible-iterator"
|
||||||
version = "1.0.7"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
@@ -81,33 +149,46 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "hashbrown"
|
||||||
version = "0.3.3"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"foldhash",
|
||||||
"libc",
|
|
||||||
"r-efi",
|
|
||||||
"wasi",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "hashlink"
|
||||||
version = "1.3.1"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"hashbrown",
|
||||||
"fnv",
|
|
||||||
"itoa",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "iana-time-zone"
|
||||||
version = "1.10.1"
|
version = "0.1.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
@@ -115,12 +196,32 @@ version = "1.0.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.78"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.175"
|
version = "0.2.175"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.35.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.27"
|
version = "0.4.27"
|
||||||
@@ -133,6 +234,15 @@ version = "2.7.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
@@ -140,13 +250,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "pkg-config"
|
||||||
version = "0.2.21"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
dependencies = [
|
|
||||||
"zerocopy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
@@ -167,39 +274,24 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "r-efi"
|
name = "rusqlite"
|
||||||
version = "5.3.0"
|
version = "0.37.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha",
|
"bitflags",
|
||||||
"rand_core",
|
"fallible-iterator",
|
||||||
|
"fallible-streaming-iterator",
|
||||||
|
"hashlink",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rustversion"
|
||||||
version = "0.9.0"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
@@ -250,6 +342,18 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.106"
|
version = "2.0.106"
|
||||||
@@ -268,43 +372,6 @@ dependencies = [
|
|||||||
"voxa-server",
|
"voxa-server",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "2.0.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "2.0.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tungstenite"
|
|
||||||
version = "0.27.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"data-encoding",
|
|
||||||
"http",
|
|
||||||
"httparse",
|
|
||||||
"log",
|
|
||||||
"rand",
|
|
||||||
"sha1",
|
|
||||||
"thiserror",
|
|
||||||
"utf-8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
@@ -318,10 +385,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf-8"
|
name = "vcpkg"
|
||||||
version = "0.7.6"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
@@ -334,43 +401,129 @@ name = "voxa-server"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"base64",
|
||||||
|
"chrono",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tungstenite",
|
"sha1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasm-bindgen"
|
||||||
version = "0.14.3+wasi-0.2.4"
|
version = "0.2.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
|
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wit-bindgen",
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.45.0"
|
version = "0.2.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
|
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zerocopy"
|
|
||||||
version = "0.8.26"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerocopy-derive",
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy-derive"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.8.26"
|
version = "0.2.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
|
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|||||||
+28
-1
@@ -1,5 +1,5 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use voxa_server::{Server, export_plugin, logger, plugin::Plugin};
|
use voxa_server::{Server, export_plugin, logger, utils::plugin::Plugin};
|
||||||
|
|
||||||
logger! {
|
logger! {
|
||||||
const LOGGER "My Plugin"
|
const LOGGER "My Plugin"
|
||||||
@@ -12,6 +12,33 @@ impl Plugin for MyPlugin {
|
|||||||
fn init(&mut self, _server: &Arc<Server>) {
|
fn init(&mut self, _server: &Arc<Server>) {
|
||||||
LOGGER.info("MyPlugin initialized!");
|
LOGGER.info("MyPlugin initialized!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_request(
|
||||||
|
&mut self,
|
||||||
|
msg: &voxa_server::types::WsMessage<voxa_server::types::ClientMessage>,
|
||||||
|
client: &voxa_server::utils::client::Client,
|
||||||
|
_server: &Arc<Server>,
|
||||||
|
) -> bool {
|
||||||
|
LOGGER.info(&format!("Received message: {:?}", msg));
|
||||||
|
match msg {
|
||||||
|
voxa_server::types::WsMessage::Message(
|
||||||
|
voxa_server::types::ClientMessage::SendMessage { contents, .. },
|
||||||
|
) => {
|
||||||
|
if contents == "ping" {
|
||||||
|
LOGGER.info("Pong!");
|
||||||
|
client
|
||||||
|
.send(voxa_server::types::ServerMessage::TempMessage {
|
||||||
|
message: "pong".to_string(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export_plugin!(Box::new(MyPlugin));
|
export_plugin!(Box::new(MyPlugin));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use voxa_server::{ServerConfig, vfs};
|
use voxa_server::{ServerConfig, utils::vfs};
|
||||||
|
|
||||||
fn main() -> voxa_server::Result<()> {
|
fn main() -> voxa_server::Result<()> {
|
||||||
let root = PathBuf::from("./");
|
let root = PathBuf::from("./");
|
||||||
|
|||||||
Reference in New Issue
Block a user