mirror of https://github.com/MedzikUser/servers
Compare commits
22 Commits
Author | SHA1 | Date |
---|---|---|
renovate[bot] | d5b238f153 | |
renovate[bot] | 91ab6cb607 | |
renovate[bot] | de5e26bbf2 | |
renovate[bot] | 09f7d14bcc | |
renovate[bot] | ce546a0c69 | |
renovate[bot] | 619ed0b41d | |
renovate[bot] | 5a103de793 | |
renovate[bot] | 0d4ff8041b | |
renovate[bot] | eb462622eb | |
MedzikUser | b56357c085 | |
renovate[bot] | fd4121b0d2 | |
MedzikUser | 032ec88ed6 | |
MedzikUser | 501cbc74b7 | |
MedzikUser | db6e068926 | |
MedzikUser | 212223c568 | |
MedzikUser | d15ec0c93e | |
MedzikUser | 9f66c2b9d2 | |
MedzikUser | 95d0e15786 | |
MedzikUser | d31e0fff2f | |
MedzikUser | 67fb1a0a3c | |
MedzikUser | 56e16145f6 | |
MedzikUser | 7da5daf522 |
|
@ -17,8 +17,8 @@ jobs:
|
|||
|
||||
matrix:
|
||||
target:
|
||||
- x86_64-unknown-linux-musl
|
||||
- aarch64-unknown-linux-musl
|
||||
- x86_64-unknown-linux-gnu
|
||||
- aarch64-unknown-linux-gnu
|
||||
- x86_64-pc-windows-msvc
|
||||
- x86_64-apple-darwin
|
||||
- aarch64-apple-darwin
|
||||
|
@ -26,16 +26,16 @@ jobs:
|
|||
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: x86_64-unknown-linux-musl
|
||||
artifact_name: target/x86_64-unknown-linux-musl/release/servers
|
||||
release_name: x86_64-unknown-linux-musl
|
||||
target: x86_64-unknown-linux-gnu
|
||||
artifact_name: target/x86_64-unknown-linux-gnu/release/servers
|
||||
release_name: x86_64-unknown-linux-gnu
|
||||
cross: true
|
||||
cargo_flags: ""
|
||||
|
||||
- os: ubuntu-latest
|
||||
target: aarch64-unknown-linux-musl
|
||||
artifact_name: target/aarch64-unknown-linux-musl/release/servers
|
||||
release_name: aarch64-unknown-linux-musl
|
||||
target: aarch64-unknown-linux-gnu
|
||||
artifact_name: target/aarch64-unknown-linux-gnu/release/servers
|
||||
release_name: aarch64-unknown-linux-gnu
|
||||
cross: true
|
||||
cargo_flags: ""
|
||||
|
||||
|
@ -93,10 +93,6 @@ jobs:
|
|||
name: ${{ matrix.target }}
|
||||
path: ${{ matrix.artifact_name }}
|
||||
|
||||
###
|
||||
# Below this line, steps will only be ran if a tag was pushed.
|
||||
###
|
||||
|
||||
- name: Get tag name
|
||||
id: tag_name
|
||||
run: |
|
||||
|
|
|
@ -2,20 +2,11 @@
|
|||
# It is not intended for manual editing.
|
||||
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]]
|
||||
name = "anyhow"
|
||||
version = "1.0.62"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
|
||||
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
|
||||
|
||||
[[package]]
|
||||
name = "async-attributes"
|
||||
|
@ -131,9 +122,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.57"
|
||||
version = "0.1.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
|
||||
checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -236,9 +227,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.17"
|
||||
version = "3.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b"
|
||||
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
@ -253,9 +244,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.17"
|
||||
version = "3.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa"
|
||||
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
|
@ -323,9 +314,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.3"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
|
@ -364,9 +355,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa"
|
||||
checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -379,9 +370,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -389,15 +380,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528"
|
||||
checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -406,9 +397,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
|
@ -427,9 +418,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -438,21 +429,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.23"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -605,9 +596,9 @@ checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
|||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.3"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
|
@ -635,6 +626,16 @@ version = "2.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
|
@ -657,6 +658,12 @@ version = "6.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.0.0"
|
||||
|
@ -781,7 +788,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "servers"
|
||||
version = "0.4.2"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
|
@ -796,10 +803,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.10.0"
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
|
@ -868,9 +875,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
|
@ -918,9 +925,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.36"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
|
@ -930,9 +937,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.22"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
|
||||
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -941,9 +948,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.29"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7"
|
||||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
|
@ -962,11 +969,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.15"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b"
|
||||
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"nu-ansi-term",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
|
@ -976,9 +983,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.17.3"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
|
||||
checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
|
@ -987,7 +994,7 @@ dependencies = [
|
|||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"sha-1",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
"url",
|
||||
"utf-8",
|
||||
|
|
18
Cargo.toml
18
Cargo.toml
|
@ -4,7 +4,7 @@ resolver = "2"
|
|||
|
||||
[package]
|
||||
name = "servers"
|
||||
version = "0.4.2"
|
||||
version = "0.6.0"
|
||||
description = "TCP and WebSocket server for Clients written in Rust"
|
||||
homepage = "https://github.com/MedzikUser/servers"
|
||||
repository = "https://github.com/MedzikUser/servers.git"
|
||||
|
@ -12,13 +12,13 @@ license = "MIT"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.62"
|
||||
anyhow = "1.0.68"
|
||||
async-std = { version = "1.12.0", features = ["attributes"] }
|
||||
async-trait = "0.1.57"
|
||||
clap = { version = "3.2.17", features = ["derive"] }
|
||||
libloading = "0.7.3"
|
||||
tracing = "0.1.36"
|
||||
tracing-subscriber = "0.3.15"
|
||||
tungstenite = "0.17.3"
|
||||
futures = "0.3.23"
|
||||
async-trait = "0.1.63"
|
||||
clap = { version = "3.2.23", features = ["derive"] }
|
||||
libloading = "0.7.4"
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = "0.3.16"
|
||||
tungstenite = "0.18.0"
|
||||
futures = "0.3.25"
|
||||
lazy_static = "1.4.0"
|
||||
|
|
|
@ -3,10 +3,8 @@ name = "plugin_test"
|
|||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
crate-type = ["dylib"]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
servers = { path = ".." }
|
||||
|
|
|
@ -42,7 +42,7 @@ impl Event for PluginTest {
|
|||
EventType::OnConnect
|
||||
}
|
||||
|
||||
async fn execute(&self, client: &Client) -> anyhow::Result<()> {
|
||||
async fn execute(&self, client: &Client, _data: EventData) -> anyhow::Result<()> {
|
||||
client.send("Hello!")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use servers::server::MAX_PACKET_LEN;
|
|||
struct Cli {
|
||||
#[clap(
|
||||
short = 'i',
|
||||
long = "--host",
|
||||
long = "host",
|
||||
help = "Server host",
|
||||
default_value = "0.0.0.0",
|
||||
display_order = 1
|
||||
|
@ -26,7 +26,7 @@ struct Cli {
|
|||
|
||||
#[clap(
|
||||
short = 'p',
|
||||
long = "--port",
|
||||
long = "port",
|
||||
help = "Server port",
|
||||
default_value = "9999",
|
||||
display_order = 2
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
use crate::plugins::prelude::*;
|
||||
|
||||
pub struct ID;
|
||||
pub struct Id;
|
||||
|
||||
#[async_trait]
|
||||
impl Command for ID {
|
||||
impl Command for Id {
|
||||
fn name(&self) -> &'static str {
|
||||
"/id"
|
||||
}
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
//! Default servers commands.
|
||||
//!
|
||||
//! List of commands:
|
||||
//! - /broadcast
|
||||
//! - /disconnect
|
||||
//! - /help
|
||||
//! - /id
|
||||
|
||||
mod broadcast;
|
||||
mod disconnect;
|
||||
mod help;
|
||||
mod id;
|
||||
|
||||
use self::{disconnect::Disconnect, help::Help, id::ID};
|
||||
use self::{broadcast::Broadcast, disconnect::Disconnect, help::Help, id::Id};
|
||||
use crate::plugins::prelude::*;
|
||||
|
||||
/// Register default commands
|
||||
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),
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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 tracing::{info, trace};
|
||||
use tracing::{info, span, trace, Level};
|
||||
|
||||
use crate::{
|
||||
commands,
|
||||
|
@ -11,6 +12,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
/// Load all plugins, commands and events.
|
||||
pub fn loader(plugins_dir: &str) -> anyhow::Result<PluginsManagerType> {
|
||||
// if plugins directory doesn't exists, create it
|
||||
if !Path::new(plugins_dir).exists() {
|
||||
|
@ -23,13 +25,17 @@ pub fn loader(plugins_dir: &str) -> anyhow::Result<PluginsManagerType> {
|
|||
// init a plugins manager
|
||||
let mut plugins_manager = PluginsManager::new();
|
||||
|
||||
// add default commands
|
||||
// register default commands
|
||||
plugins_manager.commands = commands::register_commands();
|
||||
|
||||
for plugin_path in plugins_files {
|
||||
let path = plugin_path?.path();
|
||||
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);
|
||||
|
||||
// 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())
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ use std::sync::Arc;
|
|||
|
||||
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)]
|
||||
pub struct PluginsManager {
|
||||
/// Vector with all loaded plugins.
|
||||
|
@ -14,14 +18,19 @@ pub struct PluginsManager {
|
|||
}
|
||||
|
||||
impl PluginsManager {
|
||||
/// Returns an empty PluginsManager
|
||||
pub fn new() -> PluginsManager {
|
||||
/// Returns an empty instance of [PluginsManager]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
plugins: Vec::new(),
|
||||
commands: Vec::new(),
|
||||
events: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the instance in [PluginsManagerType].
|
||||
pub fn into(self) -> PluginsManagerType {
|
||||
Arc::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PluginsManager {
|
||||
|
@ -33,5 +42,3 @@ impl fmt::Debug for PluginsManager {
|
|||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub type PluginsManagerType = Arc<PluginsManager>;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
//! Plugin infrastructure.
|
||||
|
||||
mod load;
|
||||
pub mod manager;
|
||||
mod manager;
|
||||
pub mod types;
|
||||
|
||||
pub use load::*;
|
||||
pub use manager::*;
|
||||
|
||||
/// Crates and types required in plugins.
|
||||
pub mod prelude {
|
||||
use super::*;
|
||||
|
||||
|
@ -12,5 +16,5 @@ pub mod prelude {
|
|||
pub use async_trait::async_trait;
|
||||
|
||||
pub use self::types::*;
|
||||
pub use crate::server::Client;
|
||||
pub use crate::server::{Client, ClientMapValue};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
//! Types used for creating plugins.
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::{plugins::manager::PluginsManager, server::Client};
|
||||
|
||||
// A main plugin trait.
|
||||
/// A main plugin trait.
|
||||
#[async_trait]
|
||||
pub trait Plugin: Any + Send + Sync {
|
||||
/// Name of the plugin.
|
||||
|
@ -29,12 +31,23 @@ pub trait Command: Any + Send + Sync {
|
|||
}
|
||||
|
||||
/// All possible to run events.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EventType {
|
||||
/// On client connected.
|
||||
OnConnect,
|
||||
/// On client sent message.
|
||||
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.
|
||||
|
@ -43,9 +56,10 @@ pub trait Event: Any + Send + Sync {
|
|||
/// Type of the event.
|
||||
fn event(&self) -> EventType;
|
||||
/// 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 {
|
||||
/// Function to register plugins.
|
||||
fn register_plugins(&mut self, plugin: Box<dyn Plugin>);
|
||||
|
|
|
@ -6,10 +6,14 @@ use std::{
|
|||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use tracing::info;
|
||||
use tungstenite::{accept, Message, WebSocket};
|
||||
|
||||
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
|
||||
pub const MAX_PACKET_LEN: usize = 65536;
|
||||
|
@ -22,7 +26,7 @@ pub struct Client {
|
|||
/// Connection stream of the client
|
||||
pub stream: ClientStream,
|
||||
/// Custom Client Map
|
||||
pub map: HashMap<String, ClientMapValue>,
|
||||
pub map: Arc<Mutex<HashMap<String, ClientMapValue>>>,
|
||||
/// Plugins Manager
|
||||
pub plugins_manager: PluginsManagerType,
|
||||
}
|
||||
|
@ -38,15 +42,10 @@ pub struct Client {
|
|||
/// Value type of the client map entry
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ClientMapValue {
|
||||
/// String type
|
||||
String(String),
|
||||
/// Vector with String type
|
||||
Array(Vec<String>),
|
||||
/// bool type
|
||||
Bool(bool),
|
||||
/// isize type
|
||||
Int(isize),
|
||||
/// usize type
|
||||
UInt(usize),
|
||||
}
|
||||
|
||||
|
@ -64,7 +63,7 @@ impl From<TcpStream> for Client {
|
|||
Self {
|
||||
id: 0,
|
||||
stream: ClientStream::TCP(Arc::new(stream)),
|
||||
map: HashMap::new(),
|
||||
map: Arc::new(Mutex::new(HashMap::new())),
|
||||
plugins_manager: PLUGINS_MANAGER.clone(),
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +74,7 @@ impl From<WebSocket<TcpStream>> for Client {
|
|||
Self {
|
||||
id: 0,
|
||||
stream: ClientStream::WebSocket(Arc::new(Mutex::new(stream))),
|
||||
map: HashMap::new(),
|
||||
map: Arc::new(Mutex::new(HashMap::new())),
|
||||
plugins_manager: PLUGINS_MANAGER.clone(),
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +132,8 @@ impl Client {
|
|||
msg.pop();
|
||||
}
|
||||
|
||||
info!("[Recieved]: {}", msg);
|
||||
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
|
@ -152,10 +153,12 @@ impl Client {
|
|||
match &self.stream {
|
||||
ClientStream::TCP(stream) => stream.as_ref().write_all(buf)?,
|
||||
ClientStream::WebSocket(stream) => {
|
||||
stream.lock().unwrap().write_message(Message::from(msg))?
|
||||
stream.lock().unwrap().write_message(Message::from(buf))?
|
||||
},
|
||||
}
|
||||
|
||||
info!("[Sent]: {}", msg);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -189,10 +192,38 @@ impl Client {
|
|||
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() {
|
||||
if event.event() == event_type {
|
||||
event.execute(self).await?;
|
||||
event.execute(self, event_data.clone()).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Server infrastructure.
|
||||
|
||||
mod client;
|
||||
mod run;
|
||||
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
use std::net::TcpListener;
|
||||
use std::{net::TcpListener, thread};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use async_std::task;
|
||||
use futures::join;
|
||||
use lazy_static::lazy_static;
|
||||
use tracing::{error, info, span, Level};
|
||||
|
||||
use crate::{
|
||||
plugins::{self, manager::PluginsManagerType, prelude::EventType},
|
||||
plugins::{
|
||||
self,
|
||||
prelude::{EventData, EventType},
|
||||
PluginsManagerType,
|
||||
},
|
||||
server::Client,
|
||||
CLIENTS, CLIENT_NEXT,
|
||||
};
|
||||
|
||||
/// Plugins directory.
|
||||
pub const PLUGINS_DIR: &str = "plugins";
|
||||
|
||||
lazy_static! {
|
||||
|
@ -47,40 +53,74 @@ async fn process(client: Client) -> anyhow::Result<()> {
|
|||
info!("Processing client connection: {}", client_addr);
|
||||
|
||||
// run `onConnect` events
|
||||
client.run_events(EventType::OnConnect).await?;
|
||||
client
|
||||
.run_events(EventType::OnConnect, EventData::None)
|
||||
.await?;
|
||||
|
||||
loop {
|
||||
let buf = client.read()?;
|
||||
|
||||
// run `onSend` events
|
||||
client.run_events(EventType::OnSend).await?;
|
||||
// functions for error handling see `if` below function
|
||||
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 args.is_empty() {
|
||||
client.send("empty buffer")?;
|
||||
continue;
|
||||
// if client sent an empty buffer
|
||||
if args.is_empty() {
|
||||
client.send("empty buffer")?;
|
||||
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
|
||||
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 let Some((_i, cmd)) = command {
|
||||
cmd.execute(&client, args).await?;
|
||||
} else {
|
||||
client.send("unknown command")?;
|
||||
// client disconnect e.g. using ctrl + c
|
||||
if err.contains("Broken pipe") {
|
||||
return Err(anyhow!("disconnected"));
|
||||
} else {
|
||||
error!("Unexpected error in message handler: {}", err);
|
||||
client.send("Unexpected error")?;
|
||||
}
|
||||
}
|
||||
|
||||
client.flush()?;
|
||||
|
@ -101,7 +141,7 @@ async fn start_tcp(host: String) -> anyhow::Result<()> {
|
|||
// add one to next id
|
||||
*CLIENT_NEXT.lock().unwrap() += 1;
|
||||
|
||||
task::spawn(async move {
|
||||
thread::spawn(move || {
|
||||
// get id for the client and add one to next 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 _enter = span.enter();
|
||||
|
||||
if let Err(err) = process(client).await {
|
||||
error!("{}", err);
|
||||
if let Err(err) = task::block_on(process(client)) {
|
||||
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
|
||||
|
@ -138,18 +185,27 @@ async fn start_websocket(host: String) -> anyhow::Result<()> {
|
|||
// add one to next id
|
||||
*CLIENT_NEXT.lock().unwrap() += 1;
|
||||
|
||||
task::spawn(async move {
|
||||
thread::spawn(move || {
|
||||
let client = Client::new_websocket(stream, id).unwrap();
|
||||
|
||||
// insert the cloned client to CLIENTS
|
||||
CLIENTS.lock().unwrap().insert(id, client.clone());
|
||||
|
||||
// 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();
|
||||
|
||||
if let Err(err) = process(client).await {
|
||||
error!("{}", err);
|
||||
if let Err(err) = task::block_on(process(client)) {
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue