Compare commits

...

25 Commits
v0.4.1 ... main

Author SHA1 Message Date
renovate[bot] d5b238f153 fix(deps): update rust crate async-trait to 0.1.63 2023-01-23 04:59:48 +00:00
renovate[bot] 91ab6cb607 fix(deps): update rust crate async-trait to 0.1.61 2023-01-09 04:20:42 +00:00
renovate[bot] de5e26bbf2 fix(deps): update all non-major dependencies 2022-12-19 03:30:40 +00:00
renovate[bot] 09f7d14bcc fix(deps): update all non-major dependencies 2022-12-12 03:57:24 +00:00
renovate[bot] ce546a0c69 fix(deps): update rust crate libloading to 0.7.4 2022-11-07 05:40:58 +00:00
renovate[bot] 619ed0b41d fix(deps): update rust crate clap to 3.2.23 2022-10-31 05:13:52 +00:00
renovate[bot] 5a103de793 fix(deps): update all non-major dependencies 2022-10-24 04:12:45 +00:00
renovate[bot] 0d4ff8041b fix(deps): update all non-major dependencies 2022-10-10 05:19:25 +00:00
renovate[bot] eb462622eb fix(deps): update all non-major dependencies 2022-09-19 03:37:23 +00:00
MedzikUser b56357c085
fix(server): change from task::spawn to thread::spawn
Changed to thread::spawn due to task::spawn spawn max 2 tasks (accept max 2 clients) if your cpu has 2 cores.
2022-09-14 21:03:49 +02:00
renovate[bot] fd4121b0d2 fix(deps): update all non-major dependencies 2022-09-05 05:42:10 +00:00
MedzikUser 032ec88ed6
chore: add some comments in code
Moved `PluginsManager` and `PluginsManagerType` from `servers::plugin::manager` to the `servers::plugin` module.
Added some comments in code.
Implemented function `into()` to the `PluginsManager` struct.
2022-08-22 13:23:08 +02:00
MedzikUser 501cbc74b7
fix(clippy): change `< 1` to .is_empty()
Replaced `args.len() < 1` with `args.is_empty()`.
2022-08-20 15:01:48 +02:00
MedzikUser db6e068926
chore(plugin): change to cdylib
Probably better.
2022-08-20 14:58:32 +02:00
MedzikUser 212223c568
ci(release): build binaries for gnu instead of musl
Musl currently doesn't support dylib.
2022-08-20 14:48:41 +02:00
MedzikUser d15ec0c93e
feat(command): add /broadcast
The `/broadcast` command has been added, which can send a message to all connected clients.
2022-08-19 22:27:42 +02:00
MedzikUser 9f66c2b9d2
fix(cli): update long arguments
Changed clap long attributes from --host to host and --port to port.
2022-08-19 12:16:02 +02:00
MedzikUser 95d0e15786
chore(release): v0.6.0 2022-08-17 22:07:12 +02:00
MedzikUser d31e0fff2f
fix(plugin): execute `on_load` function
Now function `on_load` will be executed if the plugin is loads.
Added span to the logger on TRACE level in plugin loader.
Fixed clippy warning from previous commit.
2022-08-17 22:05:27 +02:00
MedzikUser 67fb1a0a3c
feat(server): add `onCommand` event and handle errors in message processing
Added `OnCommand` event e.g. to disable command for client. (BREAKING CHANGES IN EVENT PLUGINS)
Added function for error handling in message process.
2022-08-17 21:44:06 +02:00
MedzikUser 56e16145f6
chore(release): v0.5.0 2022-08-17 15:45:36 +02:00
MedzikUser 7da5daf522
feat(client): HashMap add Mutex and functions
Changed map type in Client struct to Arc<Mutex<HashMap<String, ClientMapValue>>>.
Implemented functions insert_key, get_value and delete_key to the Client type.
Re-export servers::server::ClientMapValue in servers::plugins::prelude.
2022-08-17 15:40:11 +02:00
MedzikUser bf1c3c4092
chore(release): v0.4.2
- **fix**: update anyhow to v1.0.62
2022-08-17 11:56:29 +02:00
MedzikUser 5d2afe3719
ci(release): delete compress binaries 2022-08-17 11:47:26 +02:00
MedzikUser 83f2961aee
chore(release): v0.4.1 2022-08-16 23:35:31 +02:00
16 changed files with 348 additions and 173 deletions

View File

@ -17,8 +17,8 @@ jobs:
matrix: matrix:
target: target:
- x86_64-unknown-linux-musl - x86_64-unknown-linux-gnu
- aarch64-unknown-linux-musl - aarch64-unknown-linux-gnu
- x86_64-pc-windows-msvc - x86_64-pc-windows-msvc
- x86_64-apple-darwin - x86_64-apple-darwin
- aarch64-apple-darwin - aarch64-apple-darwin
@ -26,21 +26,17 @@ jobs:
include: include:
- os: ubuntu-latest - os: ubuntu-latest
target: x86_64-unknown-linux-musl target: x86_64-unknown-linux-gnu
artifact_name: target/x86_64-unknown-linux-musl/release/servers artifact_name: target/x86_64-unknown-linux-gnu/release/servers
release_name: x86_64-unknown-linux-musl release_name: x86_64-unknown-linux-gnu
cross: true cross: true
strip: true
compress: true
cargo_flags: "" cargo_flags: ""
- os: ubuntu-latest - os: ubuntu-latest
target: aarch64-unknown-linux-musl target: aarch64-unknown-linux-gnu
artifact_name: target/aarch64-unknown-linux-musl/release/servers artifact_name: target/aarch64-unknown-linux-gnu/release/servers
release_name: aarch64-unknown-linux-musl release_name: aarch64-unknown-linux-gnu
cross: true cross: true
strip: false
compress: true
cargo_flags: "" cargo_flags: ""
- os: windows-latest - os: windows-latest
@ -48,8 +44,6 @@ jobs:
artifact_name: target/x86_64-pc-windows-msvc/release/servers.exe artifact_name: target/x86_64-pc-windows-msvc/release/servers.exe
release_name: x86_64-pc-windows-msvc.exe release_name: x86_64-pc-windows-msvc.exe
cross: false cross: false
strip: true
compress: true
cargo_flags: "" cargo_flags: ""
- os: macos-latest - os: macos-latest
@ -57,8 +51,6 @@ jobs:
artifact_name: target/x86_64-apple-darwin/release/servers artifact_name: target/x86_64-apple-darwin/release/servers
release_name: x86_64-apple-darwin release_name: x86_64-apple-darwin
cross: false cross: false
strip: true
compress: true
cargo_flags: "" cargo_flags: ""
- os: macos-latest - os: macos-latest
@ -66,8 +58,6 @@ jobs:
artifact_name: target/aarch64-apple-darwin/release/servers artifact_name: target/aarch64-apple-darwin/release/servers
release_name: aarch64-apple-darwin release_name: aarch64-apple-darwin
cross: false cross: false
strip: true
compress: true
cargo_flags: "" cargo_flags: ""
- os: ubuntu-latest - os: ubuntu-latest
@ -75,8 +65,6 @@ jobs:
artifact_name: target/x86_64-unknown-freebsd/release/servers artifact_name: target/x86_64-unknown-freebsd/release/servers
release_name: x86_64-unknown-freebsd release_name: x86_64-unknown-freebsd
cross: true cross: true
strip: false
compress: false
cargo_flags: "" cargo_flags: ""
name: ${{ matrix.os }} for ${{ matrix.target }} name: ${{ matrix.os }} for ${{ matrix.target }}
@ -99,24 +87,12 @@ jobs:
args: --release --target=${{ matrix.target }} ${{ matrix.cargo_flags }} args: --release --target=${{ matrix.target }} ${{ matrix.cargo_flags }}
use-cross: ${{ matrix.cross }} use-cross: ${{ matrix.cross }}
- name: Compress binaries
uses: svenstaro/upx-action@v2
with:
file: ${{ matrix.artifact_name }}
args: --lzma
strip: ${{ matrix.strip }}
if: ${{ matrix.compress }}
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: ${{ matrix.target }} name: ${{ matrix.target }}
path: ${{ matrix.artifact_name }} path: ${{ matrix.artifact_name }}
###
# Below this line, steps will only be ran if a tag was pushed.
###
- name: Get tag name - name: Get tag name
id: tag_name id: tag_name
run: | run: |

133
Cargo.lock generated
View File

@ -2,20 +2,11 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.61" version = "1.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
[[package]] [[package]]
name = "async-attributes" name = "async-attributes"
@ -131,9 +122,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.57" version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -236,9 +227,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.2.17" version = "3.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
@ -253,9 +244,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "3.2.17" version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error", "proc-macro-error",
@ -323,9 +314,9 @@ dependencies = [
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.3" version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [ dependencies = [
"block-buffer", "block-buffer",
"crypto-common", "crypto-common",
@ -364,9 +355,9 @@ dependencies = [
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@ -379,9 +370,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@ -389,15 +380,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@ -406,9 +397,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
[[package]] [[package]]
name = "futures-lite" name = "futures-lite"
@ -427,9 +418,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -438,21 +429,21 @@ dependencies = [
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.23" version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@ -599,15 +590,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.131" version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.7.3" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"winapi", "winapi",
@ -635,6 +626,16 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.13.1" version = "1.13.1"
@ -647,15 +648,21 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.13.0" version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
[[package]] [[package]]
name = "os_str_bytes" name = "os_str_bytes"
version = "6.2.0" version = "6.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]] [[package]]
name = "parking" name = "parking"
@ -781,7 +788,7 @@ dependencies = [
[[package]] [[package]]
name = "servers" name = "servers"
version = "0.4.0" version = "0.6.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-std", "async-std",
@ -796,10 +803,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "sha-1" name = "sha1"
version = "0.10.0" version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
@ -868,9 +875,9 @@ dependencies = [
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.15.0" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
@ -918,9 +925,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.36" version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"pin-project-lite", "pin-project-lite",
@ -930,9 +937,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-attributes" name = "tracing-attributes"
version = "0.1.22" version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -941,9 +948,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.29" version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"valuable", "valuable",
@ -962,11 +969,11 @@ dependencies = [
[[package]] [[package]]
name = "tracing-subscriber" name = "tracing-subscriber"
version = "0.3.15" version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
dependencies = [ dependencies = [
"ansi_term", "nu-ansi-term",
"sharded-slab", "sharded-slab",
"smallvec", "smallvec",
"thread_local", "thread_local",
@ -976,9 +983,9 @@ dependencies = [
[[package]] [[package]]
name = "tungstenite" name = "tungstenite"
version = "0.17.3" version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788"
dependencies = [ dependencies = [
"base64", "base64",
"byteorder", "byteorder",
@ -987,7 +994,7 @@ dependencies = [
"httparse", "httparse",
"log", "log",
"rand", "rand",
"sha-1", "sha1",
"thiserror", "thiserror",
"url", "url",
"utf-8", "utf-8",

View File

@ -4,7 +4,7 @@ resolver = "2"
[package] [package]
name = "servers" name = "servers"
version = "0.4.0" version = "0.6.0"
description = "TCP and WebSocket server for Clients written in Rust" description = "TCP and WebSocket server for Clients written in Rust"
homepage = "https://github.com/MedzikUser/servers" homepage = "https://github.com/MedzikUser/servers"
repository = "https://github.com/MedzikUser/servers.git" repository = "https://github.com/MedzikUser/servers.git"
@ -12,13 +12,13 @@ license = "MIT"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.61" anyhow = "1.0.68"
async-std = { version = "1.12.0", features = ["attributes"] } async-std = { version = "1.12.0", features = ["attributes"] }
async-trait = "0.1.57" async-trait = "0.1.63"
clap = { version = "3.2.17", features = ["derive"] } clap = { version = "3.2.23", features = ["derive"] }
libloading = "0.7.3" libloading = "0.7.4"
tracing = "0.1.36" tracing = "0.1.37"
tracing-subscriber = "0.3.15" tracing-subscriber = "0.3.16"
tungstenite = "0.17.3" tungstenite = "0.18.0"
futures = "0.3.23" futures = "0.3.25"
lazy_static = "1.4.0" lazy_static = "1.4.0"

View File

@ -3,10 +3,8 @@ name = "plugin_test"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib] [lib]
crate-type = ["dylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
servers = { path = ".." } servers = { path = ".." }

View File

@ -42,7 +42,7 @@ impl Event for PluginTest {
EventType::OnConnect EventType::OnConnect
} }
async fn execute(&self, client: &Client) -> anyhow::Result<()> { async fn execute(&self, client: &Client, _data: EventData) -> anyhow::Result<()> {
client.send("Hello!") client.send("Hello!")
} }
} }

View File

@ -17,7 +17,7 @@ use servers::server::MAX_PACKET_LEN;
struct Cli { struct Cli {
#[clap( #[clap(
short = 'i', short = 'i',
long = "--host", long = "host",
help = "Server host", help = "Server host",
default_value = "0.0.0.0", default_value = "0.0.0.0",
display_order = 1 display_order = 1
@ -26,7 +26,7 @@ struct Cli {
#[clap( #[clap(
short = 'p', short = 'p',
long = "--port", long = "port",
help = "Server port", help = "Server port",
default_value = "9999", default_value = "9999",
display_order = 2 display_order = 2

54
src/commands/broadcast.rs Normal file
View File

@ -0,0 +1,54 @@
use async_std::task;
use crate::{plugins::prelude::*, CLIENTS};
pub struct Broadcast;
#[async_trait]
impl Command for Broadcast {
fn name(&self) -> &'static str {
"/broadcast"
}
fn aliases(&self) -> Vec<&'static str> {
vec![]
}
fn help(&self) -> &'static str {
"Send message to all connected clients"
}
fn usage(&self) -> &'static str {
"/broadcast <message>"
}
async fn execute(&self, client: &Client, args: Vec<&str>) -> anyhow::Result<()> {
if args.is_empty() || args.join(" ").is_empty() {
client.send("Missing message")?;
return Ok(());
}
let msg = args.join(" ");
let mut children = Vec::new();
// send message to all connected clients
for (_i, client) in CLIENTS.lock().unwrap().clone() {
let msg = msg.clone();
let child = task::spawn(async move {
client
.send(msg)
.expect("failed to send broadcast message to client")
});
children.push(child);
}
// wait for all task to complete
for child in children {
child.await;
}
Ok(())
}
}

View File

@ -1,9 +1,9 @@
use crate::plugins::prelude::*; use crate::plugins::prelude::*;
pub struct ID; pub struct Id;
#[async_trait] #[async_trait]
impl Command for ID { impl Command for Id {
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
"/id" "/id"
} }

View File

@ -1,11 +1,25 @@
//! Default servers commands.
//!
//! List of commands:
//! - /broadcast
//! - /disconnect
//! - /help
//! - /id
mod broadcast;
mod disconnect; mod disconnect;
mod help; mod help;
mod id; mod id;
use self::{disconnect::Disconnect, help::Help, id::ID}; use self::{broadcast::Broadcast, disconnect::Disconnect, help::Help, id::Id};
use crate::plugins::prelude::*; use crate::plugins::prelude::*;
/// Register default commands /// Register default commands
pub fn register_commands() -> Vec<Box<dyn Command>> { pub fn register_commands() -> Vec<Box<dyn Command>> {
vec![Box::new(Help), Box::new(Disconnect), Box::new(ID)] vec![
Box::new(Broadcast),
Box::new(Disconnect),
Box::new(Help),
Box::new(Id),
]
} }

View File

@ -1,7 +1,8 @@
use std::{fs, path::Path, sync::Arc}; use std::{fs, path::Path};
use async_std::task;
use libloading::{Library, Symbol}; use libloading::{Library, Symbol};
use tracing::{info, trace}; use tracing::{info, span, trace, Level};
use crate::{ use crate::{
commands, commands,
@ -11,6 +12,7 @@ use crate::{
}, },
}; };
/// Load all plugins, commands and events.
pub fn loader(plugins_dir: &str) -> anyhow::Result<PluginsManagerType> { pub fn loader(plugins_dir: &str) -> anyhow::Result<PluginsManagerType> {
// if plugins directory doesn't exists, create it // if plugins directory doesn't exists, create it
if !Path::new(plugins_dir).exists() { if !Path::new(plugins_dir).exists() {
@ -23,13 +25,17 @@ pub fn loader(plugins_dir: &str) -> anyhow::Result<PluginsManagerType> {
// init a plugins manager // init a plugins manager
let mut plugins_manager = PluginsManager::new(); let mut plugins_manager = PluginsManager::new();
// add default commands // register default commands
plugins_manager.commands = commands::register_commands(); plugins_manager.commands = commands::register_commands();
for plugin_path in plugins_files { for plugin_path in plugins_files {
let path = plugin_path?.path(); let path = plugin_path?.path();
let path_str = path.to_str().unwrap(); let path_str = path.to_str().unwrap();
// add span to logger
let span = span!(Level::TRACE, "", plugin_path = path_str);
let _enter = span.enter();
info!("Loading plugin {}", path_str); info!("Loading plugin {}", path_str);
// loading library from .so is unsafe // loading library from .so is unsafe
@ -48,5 +54,11 @@ pub fn loader(plugins_dir: &str) -> anyhow::Result<PluginsManagerType> {
} }
} }
Ok(Arc::new(plugins_manager)) for plugin in plugins_manager.plugins.iter() {
// execute the `on_load` function from the plugin
task::block_on(async { plugin.on_load().await });
info!("Loaded plugin {}.", plugin.name());
}
Ok(plugins_manager.into())
} }

View File

@ -3,6 +3,10 @@ use std::sync::Arc;
use crate::plugins::prelude::*; use crate::plugins::prelude::*;
/// Plugins manager struct with Clone derive added by Arc.
pub type PluginsManagerType = Arc<PluginsManager>;
/// A plugins manager that stores all plugins, commands and events.
#[derive(Default)] #[derive(Default)]
pub struct PluginsManager { pub struct PluginsManager {
/// Vector with all loaded plugins. /// Vector with all loaded plugins.
@ -14,14 +18,19 @@ pub struct PluginsManager {
} }
impl PluginsManager { impl PluginsManager {
/// Returns an empty PluginsManager /// Returns an empty instance of [PluginsManager]
pub fn new() -> PluginsManager { pub fn new() -> Self {
Self { Self {
plugins: Vec::new(), plugins: Vec::new(),
commands: Vec::new(), commands: Vec::new(),
events: Vec::new(), events: Vec::new(),
} }
} }
/// Returns the instance in [PluginsManagerType].
pub fn into(self) -> PluginsManagerType {
Arc::new(self)
}
} }
impl fmt::Debug for PluginsManager { impl fmt::Debug for PluginsManager {
@ -33,5 +42,3 @@ impl fmt::Debug for PluginsManager {
.finish() .finish()
} }
} }
pub type PluginsManagerType = Arc<PluginsManager>;

View File

@ -1,9 +1,13 @@
//! Plugin infrastructure.
mod load; mod load;
pub mod manager; mod manager;
pub mod types; pub mod types;
pub use load::*; pub use load::*;
pub use manager::*;
/// Crates and types required in plugins.
pub mod prelude { pub mod prelude {
use super::*; use super::*;
@ -12,5 +16,5 @@ pub mod prelude {
pub use async_trait::async_trait; pub use async_trait::async_trait;
pub use self::types::*; pub use self::types::*;
pub use crate::server::Client; pub use crate::server::{Client, ClientMapValue};
} }

View File

@ -1,10 +1,12 @@
//! Types used for creating plugins.
use std::any::Any; use std::any::Any;
use async_trait::async_trait; use async_trait::async_trait;
use crate::{plugins::manager::PluginsManager, server::Client}; use crate::{plugins::manager::PluginsManager, server::Client};
// A main plugin trait. /// A main plugin trait.
#[async_trait] #[async_trait]
pub trait Plugin: Any + Send + Sync { pub trait Plugin: Any + Send + Sync {
/// Name of the plugin. /// Name of the plugin.
@ -29,12 +31,23 @@ pub trait Command: Any + Send + Sync {
} }
/// All possible to run events. /// All possible to run events.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventType { pub enum EventType {
/// On client connected. /// On client connected.
OnConnect, OnConnect,
/// On client sent message. /// On client sent message.
OnSend, OnSend,
/// Event executed before command execute (e.g. for disable command).
OnCommand,
}
/// All possible to run events.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventData {
/// for `onCommand` event
Command(String),
/// No data
None,
} }
/// Add a event to the plugin. /// Add a event to the plugin.
@ -43,9 +56,10 @@ pub trait Event: Any + Send + Sync {
/// Type of the event. /// Type of the event.
fn event(&self) -> EventType; fn event(&self) -> EventType;
/// Event function. /// Event function.
async fn execute(&self, client: &Client) -> anyhow::Result<()>; async fn execute(&self, client: &Client, data: EventData) -> anyhow::Result<()>;
} }
/// A plugin registrar trait.
pub trait Registrar { pub trait Registrar {
/// Function to register plugins. /// Function to register plugins.
fn register_plugins(&mut self, plugin: Box<dyn Plugin>); fn register_plugins(&mut self, plugin: Box<dyn Plugin>);

View File

@ -6,10 +6,14 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use tracing::info;
use tungstenite::{accept, Message, WebSocket}; use tungstenite::{accept, Message, WebSocket};
use super::run::PLUGINS_MANAGER; use super::run::PLUGINS_MANAGER;
use crate::plugins::{manager::PluginsManagerType, prelude::EventType}; use crate::plugins::{
prelude::{EventData, EventType},
PluginsManagerType,
};
/// Max length of a TCP and UDP packet /// Max length of a TCP and UDP packet
pub const MAX_PACKET_LEN: usize = 65536; pub const MAX_PACKET_LEN: usize = 65536;
@ -22,7 +26,7 @@ pub struct Client {
/// Connection stream of the client /// Connection stream of the client
pub stream: ClientStream, pub stream: ClientStream,
/// Custom Client Map /// Custom Client Map
pub map: HashMap<String, ClientMapValue>, pub map: Arc<Mutex<HashMap<String, ClientMapValue>>>,
/// Plugins Manager /// Plugins Manager
pub plugins_manager: PluginsManagerType, pub plugins_manager: PluginsManagerType,
} }
@ -38,15 +42,10 @@ pub struct Client {
/// Value type of the client map entry /// Value type of the client map entry
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ClientMapValue { pub enum ClientMapValue {
/// String type
String(String), String(String),
/// Vector with String type
Array(Vec<String>), Array(Vec<String>),
/// bool type
Bool(bool), Bool(bool),
/// isize type
Int(isize), Int(isize),
/// usize type
UInt(usize), UInt(usize),
} }
@ -64,7 +63,7 @@ impl From<TcpStream> for Client {
Self { Self {
id: 0, id: 0,
stream: ClientStream::TCP(Arc::new(stream)), stream: ClientStream::TCP(Arc::new(stream)),
map: HashMap::new(), map: Arc::new(Mutex::new(HashMap::new())),
plugins_manager: PLUGINS_MANAGER.clone(), plugins_manager: PLUGINS_MANAGER.clone(),
} }
} }
@ -75,7 +74,7 @@ impl From<WebSocket<TcpStream>> for Client {
Self { Self {
id: 0, id: 0,
stream: ClientStream::WebSocket(Arc::new(Mutex::new(stream))), stream: ClientStream::WebSocket(Arc::new(Mutex::new(stream))),
map: HashMap::new(), map: Arc::new(Mutex::new(HashMap::new())),
plugins_manager: PLUGINS_MANAGER.clone(), plugins_manager: PLUGINS_MANAGER.clone(),
} }
} }
@ -133,6 +132,8 @@ impl Client {
msg.pop(); msg.pop();
} }
info!("[Recieved]: {}", msg);
Ok(msg) Ok(msg)
} }
@ -152,10 +153,12 @@ impl Client {
match &self.stream { match &self.stream {
ClientStream::TCP(stream) => stream.as_ref().write_all(buf)?, ClientStream::TCP(stream) => stream.as_ref().write_all(buf)?,
ClientStream::WebSocket(stream) => { ClientStream::WebSocket(stream) => {
stream.lock().unwrap().write_message(Message::from(msg))? stream.lock().unwrap().write_message(Message::from(buf))?
}, },
} }
info!("[Sent]: {}", msg);
Ok(()) Ok(())
} }
@ -189,10 +192,38 @@ impl Client {
Ok(()) Ok(())
} }
pub async fn run_events(&self, event_type: EventType) -> anyhow::Result<()> { /// Inserts a key-value pair into the map.
pub fn insert_key<S>(&self, key: S, value: ClientMapValue) -> Option<ClientMapValue>
where
S: ToString,
{
self.map.lock().unwrap().insert(key.to_string(), value)
}
/// Returns the value from the key.
pub fn get_value<S>(&self, key: S) -> Option<ClientMapValue>
where
S: ToString,
{
self.map.lock().unwrap().get(&key.to_string()).cloned()
}
/// Delete key from the map.
pub fn delete_key<S>(&self, key: S) -> Option<ClientMapValue>
where
S: ToString,
{
self.map.lock().unwrap().remove(&key.to_string())
}
pub async fn run_events(
&self,
event_type: EventType,
event_data: EventData,
) -> anyhow::Result<()> {
for event in self.plugins_manager.events.iter() { for event in self.plugins_manager.events.iter() {
if event.event() == event_type { if event.event() == event_type {
event.execute(self).await?; event.execute(self, event_data.clone()).await?;
} }
} }

View File

@ -1,3 +1,5 @@
//! Server infrastructure.
mod client; mod client;
mod run; mod run;

View File

@ -1,16 +1,22 @@
use std::net::TcpListener; use std::{net::TcpListener, thread};
use anyhow::anyhow;
use async_std::task; use async_std::task;
use futures::join; use futures::join;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use tracing::{error, info, span, Level}; use tracing::{error, info, span, Level};
use crate::{ use crate::{
plugins::{self, manager::PluginsManagerType, prelude::EventType}, plugins::{
self,
prelude::{EventData, EventType},
PluginsManagerType,
},
server::Client, server::Client,
CLIENTS, CLIENT_NEXT, CLIENTS, CLIENT_NEXT,
}; };
/// Plugins directory.
pub const PLUGINS_DIR: &str = "plugins"; pub const PLUGINS_DIR: &str = "plugins";
lazy_static! { lazy_static! {
@ -47,40 +53,74 @@ async fn process(client: Client) -> anyhow::Result<()> {
info!("Processing client connection: {}", client_addr); info!("Processing client connection: {}", client_addr);
// run `onConnect` events // run `onConnect` events
client.run_events(EventType::OnConnect).await?; client
.run_events(EventType::OnConnect, EventData::None)
.await?;
loop { loop {
let buf = client.read()?; let buf = client.read()?;
// run `onSend` events // functions for error handling see `if` below function
client.run_events(EventType::OnSend).await?; async fn handle(client: &Client, buf: String) -> anyhow::Result<()> {
// run `onSend` events
client
.run_events(EventType::OnSend, EventData::None)
.await?;
let mut args: Vec<&str> = buf.split_ascii_whitespace().collect(); let mut args: Vec<&str> = buf.split_ascii_whitespace().collect();
// if client sent an empty buffer // if client sent an empty buffer
if args.is_empty() { if args.is_empty() {
client.send("empty buffer")?; client.send("empty buffer")?;
continue; return Ok(());
}
let cmd = args[0];
// remove command name from args
args = args[1..args.len()].to_vec();
// find command
let command = client
.plugins_manager
.commands
.iter()
.enumerate()
.find(|&(_i, command)| command.name() == cmd || command.aliases().contains(&cmd));
// execute command, if command isn't blocked
// to block a command return error in the `onCommand` event
if let Some((_i, cmd)) = command {
// run `onCommand` events
if client
.run_events(
EventType::OnCommand,
EventData::Command(cmd.name().to_string()),
)
.await
.is_ok()
{
// execute command
cmd.execute(client, args).await?;
}
} else {
client.send("unknown command")?;
}
Ok(())
} }
let cmd = args[0]; // handle errors from message processing
if let Err(err) = handle(&client, buf).await {
let err = err.to_string();
// remove command name from args // client disconnect e.g. using ctrl + c
args = args[1..args.len()].to_vec(); if err.contains("Broken pipe") {
return Err(anyhow!("disconnected"));
// find command } else {
let command = client error!("Unexpected error in message handler: {}", err);
.plugins_manager client.send("Unexpected error")?;
.commands }
.iter()
.enumerate()
.find(|&(_i, command)| command.name() == cmd || command.aliases().contains(&cmd));
// execute command
if let Some((_i, cmd)) = command {
cmd.execute(&client, args).await?;
} else {
client.send("unknown command")?;
} }
client.flush()?; client.flush()?;
@ -101,7 +141,7 @@ async fn start_tcp(host: String) -> anyhow::Result<()> {
// add one to next id // add one to next id
*CLIENT_NEXT.lock().unwrap() += 1; *CLIENT_NEXT.lock().unwrap() += 1;
task::spawn(async move { thread::spawn(move || {
// get id for the client and add one to next id // get id for the client and add one to next id
let client = Client::new_tcp(stream, id); let client = Client::new_tcp(stream, id);
@ -112,8 +152,15 @@ async fn start_tcp(host: String) -> anyhow::Result<()> {
let span = span!(Level::ERROR, "TCP", id = client.id); let span = span!(Level::ERROR, "TCP", id = client.id);
let _enter = span.enter(); let _enter = span.enter();
if let Err(err) = process(client).await { if let Err(err) = task::block_on(process(client)) {
error!("{}", err); let err = err.to_string();
// client disconnect e.g. using ctrl + c
if err == "disconnected" {
info!("Client disconnected")
} else {
error!("{}", err);
}
} }
// delete the client from CLIENTS map // delete the client from CLIENTS map
@ -138,18 +185,27 @@ async fn start_websocket(host: String) -> anyhow::Result<()> {
// add one to next id // add one to next id
*CLIENT_NEXT.lock().unwrap() += 1; *CLIENT_NEXT.lock().unwrap() += 1;
task::spawn(async move { thread::spawn(move || {
let client = Client::new_websocket(stream, id).unwrap(); let client = Client::new_websocket(stream, id).unwrap();
// insert the cloned client to CLIENTS // insert the cloned client to CLIENTS
CLIENTS.lock().unwrap().insert(id, client.clone()); CLIENTS.lock().unwrap().insert(id, client.clone());
// add span to logger // add span to logger
let span = span!(Level::ERROR, "UDP", id = client.id); let span = span!(Level::ERROR, "WS", id = client.id);
let _enter = span.enter(); let _enter = span.enter();
if let Err(err) = process(client).await { if let Err(err) = task::block_on(process(client)) {
error!("{}", err); let err = err.to_string();
// client disconnect e.g. using ctrl + c
if err == "disconnected"
|| err.contains("Connection reset without closing handshake")
{
info!("Client disconnected")
} else {
error!("{}", err);
}
} }
// delete the client from CLIENTS map // delete the client from CLIENTS map