0.3.0 Rewrite
All checks were successful
Build and push container image / build (push) Successful in 11m49s
All checks were successful
Build and push container image / build (push) Successful in 11m49s
This commit is contained in:
parent
6c4ef8baeb
commit
13c83591d7
@ -52,5 +52,5 @@ jobs:
|
|||||||
port: ${{ secrets.SSH_PORT }}
|
port: ${{ secrets.SSH_PORT }}
|
||||||
script: |
|
script: |
|
||||||
cd kon && docker compose pull bot && \
|
cd kon && docker compose pull bot && \
|
||||||
docker compose down bot --remove-orphans && docker compose up -d bot && \
|
docker compose down bot && docker compose up -d bot && \
|
||||||
docker image prune -f && docker system prune -f
|
docker image prune -f && docker system prune -f
|
||||||
|
11
.vscode/extensions.json
vendored
Normal file
11
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"fill-labs.dependi",
|
||||||
|
"usernamehw.errorlens",
|
||||||
|
"tamasfe.even-better-toml",
|
||||||
|
"GitHub.vscode-pull-request-github",
|
||||||
|
"rust-lang.rust-analyzer",
|
||||||
|
"redhat.vscode-yaml",
|
||||||
|
"sumneko.lua"
|
||||||
|
]
|
||||||
|
}
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -1,6 +1,4 @@
|
|||||||
{
|
{
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.showUnlinkedFileNotification": false,
|
||||||
"./Cargo.toml"
|
"rust-analyzer.linkedProjects": ["./Cargo.toml"]
|
||||||
],
|
|
||||||
"rust-analyzer.showUnlinkedFileNotification": false
|
|
||||||
}
|
}
|
||||||
|
298
Cargo.lock
generated
298
Cargo.lock
generated
@ -94,6 +94,30 @@ version = "0.22.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bb8"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b10cf871f3ff2ce56432fddc2615ac7acc3aa22ca321f8fea800846fbb32f188"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"futures-util",
|
||||||
|
"parking_lot",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bb8-postgres"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56ac82c42eb30889b5c4ee4763a24b8c566518171ebea648cd7e3bc532c60680"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bb8",
|
||||||
|
"tokio",
|
||||||
|
"tokio-postgres",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@ -139,16 +163,6 @@ version = "1.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bzip2-rs"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "beeb59e7e4c811ab37cc73680c798c7a5da77fc9989c62b09138e31ee740f735"
|
|
||||||
dependencies = [
|
|
||||||
"crc32fast",
|
|
||||||
"tinyvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "camino"
|
name = "camino"
|
||||||
version = "1.1.6"
|
version = "1.1.6"
|
||||||
@ -182,9 +196,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo_toml"
|
name = "cargo_toml"
|
||||||
version = "0.20.2"
|
version = "0.20.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c8cb1d556b8b8f36e5ca74938008be3ac102f5dcb5b68a0477e4249ae2291cd3"
|
checksum = "ad639525b1c67b6a298f378417b060fbc04618bea559482a8484381cce27d965"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"toml",
|
"toml",
|
||||||
@ -576,23 +590,6 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gamedig"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f351da15ad9dd6cafd687c9a016e0128741120884925c53d79c7d20f0f9e6ef9"
|
|
||||||
dependencies = [
|
|
||||||
"byteorder",
|
|
||||||
"bzip2-rs",
|
|
||||||
"crc32fast",
|
|
||||||
"encoding_rs",
|
|
||||||
"phf",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"ureq",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
@ -828,6 +825,23 @@ dependencies = [
|
|||||||
"tokio-rustls 0.24.1",
|
"tokio-rustls 0.24.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-rustls"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"http 1.1.0",
|
||||||
|
"hyper 1.3.1",
|
||||||
|
"hyper-util",
|
||||||
|
"rustls 0.23.7",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls 0.26.0",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-tls"
|
name = "hyper-tls"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@ -875,7 +889,7 @@ dependencies = [
|
|||||||
"iana-time-zone-haiku",
|
"iana-time-zone-haiku",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-core",
|
"windows-core 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -958,13 +972,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kon"
|
name = "kon"
|
||||||
version = "0.2.11"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bb8",
|
||||||
|
"bb8-postgres",
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
"gamedig",
|
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"os_info",
|
||||||
"poise",
|
"poise",
|
||||||
"reqwest 0.12.4",
|
"reqwest 0.12.5",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
@ -982,9 +998,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.154"
|
version = "0.2.155"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
@ -1207,6 +1223,17 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_info"
|
||||||
|
version = "3.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.2"
|
version = "0.12.2"
|
||||||
@ -1242,33 +1269,9 @@ version = "0.11.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"phf_macros",
|
|
||||||
"phf_shared",
|
"phf_shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_generator"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
|
||||||
dependencies = [
|
|
||||||
"phf_shared",
|
|
||||||
"rand",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_macros"
|
|
||||||
version = "0.11.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
|
||||||
dependencies = [
|
|
||||||
"phf_generator",
|
|
||||||
"phf_shared",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.61",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf_shared"
|
name = "phf_shared"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
@ -1533,7 +1536,7 @@ dependencies = [
|
|||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"http-body 0.4.6",
|
"http-body 0.4.6",
|
||||||
"hyper 0.14.28",
|
"hyper 0.14.28",
|
||||||
"hyper-rustls",
|
"hyper-rustls 0.24.2",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
@ -1547,7 +1550,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sync_wrapper",
|
"sync_wrapper 0.1.2",
|
||||||
"system-configuration",
|
"system-configuration",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls 0.24.1",
|
"tokio-rustls 0.24.1",
|
||||||
@ -1564,9 +1567,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.4"
|
version = "0.12.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
|
checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -1578,6 +1581,7 @@ dependencies = [
|
|||||||
"http-body 1.0.0",
|
"http-body 1.0.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.3.1",
|
"hyper 1.3.1",
|
||||||
|
"hyper-rustls 0.27.2",
|
||||||
"hyper-tls",
|
"hyper-tls",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
@ -1592,7 +1596,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sync_wrapper",
|
"sync_wrapper 1.0.1",
|
||||||
"system-configuration",
|
"system-configuration",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
@ -1674,6 +1678,19 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.23.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebbbdb961df0ad3f2652da8f3fdc4b36122f568f968f45ad3316f26c025c677b"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki 0.102.3",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -1804,18 +1821,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.201"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
|
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.201"
|
version = "1.0.204"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
|
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1824,9 +1841,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.117"
|
version = "1.0.120"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
@ -1835,9 +1852,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.5"
|
version = "0.6.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -2021,10 +2038,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysinfo"
|
name = "sync_wrapper"
|
||||||
version = "0.30.12"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae"
|
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysinfo"
|
||||||
|
version = "0.30.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
@ -2032,7 +2055,7 @@ dependencies = [
|
|||||||
"ntapi",
|
"ntapi",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rayon",
|
"rayon",
|
||||||
"windows",
|
"windows 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2076,18 +2099,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.60"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
|
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.60"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2142,27 +2165,29 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokenservice-client"
|
name = "tokenservice-client"
|
||||||
version = "0.2.8"
|
version = "0.3.2"
|
||||||
source = "sparse+https://git.toast-server.net/api/packages/toast/cargo/"
|
source = "sparse+https://git.toast-server.net/api/packages/toast/cargo/"
|
||||||
checksum = "7553919fa2e0356a894cc8e6ef1d72d1a04d95b9323eca01949120080e56b5b6"
|
checksum = "afce7633f840504c54b2d2dfee881e183543ad8945bedbd86ea8fbaeb498bfb8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"reqwest 0.12.4",
|
"reqwest 0.12.5",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"trust-dns-resolver",
|
"trust-dns-resolver",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.37.0"
|
version = "1.38.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
@ -2172,9 +2197,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.2.0"
|
version = "2.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2238,6 +2263,17 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.23.7",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
@ -2269,9 +2305,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.8.12"
|
version = "0.8.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
@ -2281,18 +2317,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.5"
|
version = "0.6.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.12"
|
version = "0.22.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
@ -2519,28 +2555,13 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uptime_lib"
|
name = "uptime_lib"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4e71ddbefed856d5881821d6ada4e606bbb91fd332296963ed596e2ad2100f3"
|
checksum = "9e64b558561f12a171bbea5325c3f24f129db371adee1d7ae93b6e310bd69192"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"windows",
|
"windows 0.57.0",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ureq"
|
|
||||||
version = "2.9.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd"
|
|
||||||
dependencies = [
|
|
||||||
"base64 0.22.1",
|
|
||||||
"flate2",
|
|
||||||
"log",
|
|
||||||
"once_cell",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"url",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2762,7 +2783,17 @@ version = "0.52.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core",
|
"windows-core 0.52.0",
|
||||||
|
"windows-targets 0.52.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows"
|
||||||
|
version = "0.57.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.57.0",
|
||||||
"windows-targets 0.52.5",
|
"windows-targets 0.52.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2775,6 +2806,49 @@ dependencies = [
|
|||||||
"windows-targets 0.52.5",
|
"windows-targets 0.52.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.57.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-result",
|
||||||
|
"windows-targets 0.52.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.57.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.61",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.57.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.61",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
25
Cargo.toml
25
Cargo.toml
@ -1,21 +1,26 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kon"
|
name = "kon"
|
||||||
version = "0.2.11"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cargo_toml = "0.20.2"
|
bb8 = "0.8.5"
|
||||||
gamedig = "0.5.0"
|
bb8-postgres = "0.8.1"
|
||||||
|
cargo_toml = "0.20.4"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
|
os_info = "3.8.2"
|
||||||
poise = "0.6.1"
|
poise = "0.6.1"
|
||||||
reqwest = { version = "0.12.4", features = ["json"] }
|
reqwest = { version = "0.12.5", features = ["json"] }
|
||||||
serde = "1.0.201"
|
serde = "1.0.204"
|
||||||
serde_json = "1.0.117"
|
serde_json = "1.0.120"
|
||||||
sysinfo = "0.30.12"
|
sysinfo = "0.30.13"
|
||||||
tokenservice-client = { version = "0.2.4", registry = "gitea" }
|
tokenservice-client = { version = "0.3.2", registry = "gitea" }
|
||||||
tokio = { version = "1.37.0", features = ["macros", "signal", "rt-multi-thread"] }
|
tokio = { version = "1.38.1", features = ["macros", "signal", "rt-multi-thread"] }
|
||||||
tokio-postgres = "0.7.10"
|
tokio-postgres = "0.7.10"
|
||||||
uptime_lib = "0.3.0"
|
uptime_lib = "0.3.1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
production = []
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "kon"
|
name = "kon"
|
||||||
|
13
Dockerfile
13
Dockerfile
@ -1,8 +1,8 @@
|
|||||||
FROM rust:1.78-alpine3.19@sha256:d4d3f81f3111991353bd7c7fa513ad3725a27027575fd82e24fb7babcd8f26f7 AS chef
|
FROM rust:1.79-alpine3.20 AS chef
|
||||||
ENV RUSTFLAGS -C target-feature=-crt-static
|
ENV RUSTFLAGS="-C target-feature=-crt-static"
|
||||||
ARG CARGO_TOKEN
|
ARG CARGO_TOKEN
|
||||||
RUN apk add --no-cache openssl-dev musl-dev
|
RUN apk add --no-cache openssl-dev musl-dev
|
||||||
RUN cargo install cargo-chef
|
RUN cargo install cargo-chef
|
||||||
WORKDIR /usr/src/kon
|
WORKDIR /usr/src/kon
|
||||||
|
|
||||||
FROM chef AS planner
|
FROM chef AS planner
|
||||||
@ -15,11 +15,10 @@ FROM chef AS builder
|
|||||||
COPY --from=planner /usr/src/kon/recipe.json recipe.json
|
COPY --from=planner /usr/src/kon/recipe.json recipe.json
|
||||||
RUN cargo chef cook --release
|
RUN cargo chef cook --release
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN cargo build -r
|
RUN cargo build -rF production
|
||||||
|
|
||||||
FROM alpine:3.19@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b
|
FROM alpine:3.20
|
||||||
RUN apk add --no-cache libgcc
|
RUN apk add --no-cache libgcc
|
||||||
WORKDIR /kon
|
WORKDIR /kon
|
||||||
COPY --from=builder /usr/src/kon/target/release/kon .
|
COPY --from=builder /usr/src/kon/target/release/kon .
|
||||||
COPY --from=builder /usr/src/kon/Cargo.toml .
|
CMD [ "./kon" ]
|
||||||
CMD ./kon
|
|
||||||
|
@ -3,20 +3,18 @@ services:
|
|||||||
container_name: kon
|
container_name: kon
|
||||||
#image: 'git.toast-server.net/toast/kon:main'
|
#image: 'git.toast-server.net/toast/kon:main'
|
||||||
build: .
|
build: .
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
# depends_on:
|
||||||
- db
|
# - db
|
||||||
db:
|
# db:
|
||||||
container_name: kon-database
|
# container_name: kon-database
|
||||||
image: postgres:16.2-alpine3.19@sha256:951bfda460300925caa3949eaa092ba022e9aec191bbea9056a39e2382260b27
|
# image: postgres:16.2-alpine3.19@sha256:951bfda460300925caa3949eaa092ba022e9aec191bbea9056a39e2382260b27
|
||||||
restart: unless-stopped
|
# restart: unless-stopped
|
||||||
ports:
|
# ports:
|
||||||
- 37930:5432/tcp
|
# - 37930:5432/tcp
|
||||||
volumes:
|
# volumes:
|
||||||
- /var/lib/docker/volumes/kon-database:/var/lib/postgresql/data:rw
|
# - /var/lib/docker/volumes/kon-database:/var/lib/postgresql/data:rw
|
||||||
environment:
|
# environment:
|
||||||
POSTGRES_USER: ${POSTGRES_USER}
|
# POSTGRES_USER: ${POSTGRES_USER}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
# POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
POSTGRES_DB: ${POSTGRES_DB}
|
# POSTGRES_DB: ${POSTGRES_DB}
|
||||||
|
2
run.sh
2
run.sh
@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
export $(grep -v '^#' .env | xargs) && cargo run kon_dev
|
clear && cargo run kon_dev
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
pub mod ping;
|
pub mod ping;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
pub mod uptime;
|
pub mod uptime;
|
||||||
pub mod gameserver;
|
|
@ -1,265 +0,0 @@
|
|||||||
use crate::{
|
|
||||||
Error,
|
|
||||||
internals::utils::EMBED_COLOR,
|
|
||||||
models::gameservers::Gameservers
|
|
||||||
};
|
|
||||||
|
|
||||||
use poise::serenity_prelude::{
|
|
||||||
futures::{
|
|
||||||
stream::iter,
|
|
||||||
future::ready,
|
|
||||||
Stream,
|
|
||||||
StreamExt
|
|
||||||
},
|
|
||||||
builder::CreateActionRow,
|
|
||||||
builder::CreateEmbed,
|
|
||||||
};
|
|
||||||
use poise::{
|
|
||||||
CreateReply,
|
|
||||||
serenity_prelude,
|
|
||||||
serenity_prelude::ButtonStyle,
|
|
||||||
ChoiceParameter
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, ChoiceParameter)]
|
|
||||||
enum GameNames {
|
|
||||||
#[name = "Minecraft"]
|
|
||||||
Minecraft
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Manage the game servers for this guild
|
|
||||||
#[poise::command(
|
|
||||||
slash_command,
|
|
||||||
subcommands("add", "remove", "update", "list"),
|
|
||||||
subcommand_required,
|
|
||||||
guild_only,
|
|
||||||
default_member_permissions = "MANAGE_GUILD",
|
|
||||||
required_permissions = "MANAGE_GUILD" // No clue if this is needed or not. Just leaving it here for now
|
|
||||||
)]
|
|
||||||
pub async fn gameserver(_: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a game server to the database
|
|
||||||
#[poise::command(slash_command)]
|
|
||||||
pub async fn add(
|
|
||||||
ctx: poise::Context<'_, (), Error>,
|
|
||||||
#[description = "Server name as shown in-game or friendly name"] server_name: String,
|
|
||||||
#[description = "Which game is this server running?"] game_name: GameNames,
|
|
||||||
#[description = "IP address/domain of the server (Include the port if it has one, e.g 127.0.0.1:8080)"] ip_address: String
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let action_row = CreateActionRow::Buttons(vec![
|
|
||||||
serenity_prelude::CreateButton::new("add-confirm")
|
|
||||||
.style(ButtonStyle::Success)
|
|
||||||
.label("Yes"),
|
|
||||||
serenity_prelude::CreateButton::new("add-cancel")
|
|
||||||
.style(ButtonStyle::Danger)
|
|
||||||
.label("No")
|
|
||||||
]);
|
|
||||||
|
|
||||||
let reply = CreateReply::default()
|
|
||||||
.embed(CreateEmbed::new()
|
|
||||||
.title("Does this look correct?")
|
|
||||||
.description(format!("
|
|
||||||
**Server name:** `{}`
|
|
||||||
**Game name:** `{}`
|
|
||||||
**IP Address:** `{}`
|
|
||||||
", server_name, game_name.name(), ip_address))
|
|
||||||
.color(EMBED_COLOR)
|
|
||||||
)
|
|
||||||
.components(vec![action_row]);
|
|
||||||
|
|
||||||
ctx.send(reply).await?;
|
|
||||||
|
|
||||||
while let Some(collector) = serenity_prelude::ComponentInteractionCollector::new(ctx)
|
|
||||||
.guild_id(ctx.guild_id().unwrap())
|
|
||||||
.author_id(ctx.author().id)
|
|
||||||
.timeout(std::time::Duration::from_secs(30))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
if collector.data.custom_id == "add-confirm" {
|
|
||||||
let result = Gameservers::add_server(
|
|
||||||
ctx.guild_id().unwrap().into(),
|
|
||||||
server_name.as_str(),
|
|
||||||
game_name.name(),
|
|
||||||
ip_address.as_str()
|
|
||||||
).await;
|
|
||||||
|
|
||||||
let mut msg = collector.message.clone();
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
msg.edit(
|
|
||||||
ctx,
|
|
||||||
serenity_prelude::EditMessage::new()
|
|
||||||
.content("*Confirmed, added the server to database*")
|
|
||||||
.embeds(Vec::new())
|
|
||||||
.components(Vec::new())
|
|
||||||
).await?;
|
|
||||||
},
|
|
||||||
Err(y) => {
|
|
||||||
msg.edit(
|
|
||||||
ctx,
|
|
||||||
serenity_prelude::EditMessage::new()
|
|
||||||
.content(format!("*Error adding server to database:\n`{}`*", y))
|
|
||||||
.embeds(Vec::new())
|
|
||||||
.components(Vec::new())
|
|
||||||
).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if collector.data.custom_id == "add-cancel" {
|
|
||||||
let mut msg = collector.message.clone();
|
|
||||||
|
|
||||||
msg.edit(
|
|
||||||
ctx,
|
|
||||||
serenity_prelude::EditMessage::new()
|
|
||||||
.content("*Command cancelled*")
|
|
||||||
.embeds(Vec::new())
|
|
||||||
.components(Vec::new())
|
|
||||||
).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove a game server from the database
|
|
||||||
#[poise::command(slash_command)]
|
|
||||||
pub async fn remove(
|
|
||||||
ctx: poise::Context<'_, (), Error>,
|
|
||||||
#[description = "Server name"] #[autocomplete = "ac_server_name"] server_name: String
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let reply = CreateReply::default()
|
|
||||||
.embed(CreateEmbed::new()
|
|
||||||
.title("Are you sure you want to remove this server?")
|
|
||||||
.description(format!("**Server name:** `{}`", server_name))
|
|
||||||
.color(EMBED_COLOR)
|
|
||||||
)
|
|
||||||
.components(vec![
|
|
||||||
CreateActionRow::Buttons(vec![
|
|
||||||
serenity_prelude::CreateButton::new("delete-confirm")
|
|
||||||
.style(ButtonStyle::Success)
|
|
||||||
.label("Yes"),
|
|
||||||
serenity_prelude::CreateButton::new("delete-cancel")
|
|
||||||
.style(ButtonStyle::Danger)
|
|
||||||
.label("No")
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
|
|
||||||
ctx.send(reply).await?;
|
|
||||||
|
|
||||||
while let Some(collector) = serenity_prelude::ComponentInteractionCollector::new(ctx)
|
|
||||||
.guild_id(ctx.guild_id().unwrap())
|
|
||||||
.author_id(ctx.author().id)
|
|
||||||
.timeout(std::time::Duration::from_secs(30))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
if collector.data.custom_id == "delete-confirm" {
|
|
||||||
let result = Gameservers::remove_server(ctx.guild_id().unwrap().into(), server_name.as_str()).await;
|
|
||||||
|
|
||||||
let mut msg = collector.message.clone();
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
msg.edit(
|
|
||||||
ctx,
|
|
||||||
serenity_prelude::EditMessage::new()
|
|
||||||
.content("*Confirmed, removed the server from database*")
|
|
||||||
.embeds(Vec::new())
|
|
||||||
.components(Vec::new())
|
|
||||||
).await?;
|
|
||||||
},
|
|
||||||
Err(y) => {
|
|
||||||
msg.edit(
|
|
||||||
ctx,
|
|
||||||
serenity_prelude::EditMessage::new()
|
|
||||||
.content(format!("*Error removing server from database:\n`{}`*", y))
|
|
||||||
.embeds(Vec::new())
|
|
||||||
.components(Vec::new())
|
|
||||||
).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if collector.data.custom_id == "delete-cancel" {
|
|
||||||
let mut msg = collector.message.clone();
|
|
||||||
|
|
||||||
msg.edit(
|
|
||||||
ctx,
|
|
||||||
serenity_prelude::EditMessage::new()
|
|
||||||
.content("*Command cancelled*")
|
|
||||||
.embeds(Vec::new())
|
|
||||||
.components(Vec::new())
|
|
||||||
).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update a game server in the database
|
|
||||||
#[poise::command(slash_command)]
|
|
||||||
pub async fn update(
|
|
||||||
ctx: poise::Context<'_, (), Error>,
|
|
||||||
#[description = "Server name"] #[autocomplete = "ac_server_name"] server_name: String,
|
|
||||||
#[description = "Game name"] game_name: GameNames,
|
|
||||||
#[description = "IP address"] ip_address: String
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let result = Gameservers::update_server(
|
|
||||||
ctx.guild_id().unwrap().into(),
|
|
||||||
&server_name,
|
|
||||||
&game_name.name(),
|
|
||||||
&ip_address
|
|
||||||
).await;
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(_) => {
|
|
||||||
ctx.send(CreateReply::default().content("Updated the server in database.")).await?;
|
|
||||||
},
|
|
||||||
Err(y) => {
|
|
||||||
ctx.send(CreateReply::default().content(format!("Error updating the server in database: {:?}", y))).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List all the available game servers for this guild
|
|
||||||
#[poise::command(slash_command)]
|
|
||||||
pub async fn list(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
|
||||||
let servers = Gameservers::list_servers(ctx.guild_id().unwrap().into()).await?;
|
|
||||||
|
|
||||||
let mut embed_fields = Vec::new();
|
|
||||||
for server in servers {
|
|
||||||
embed_fields.push(
|
|
||||||
(server.server_name, format!("Game: `{}`\nIP: `{}`", server.game_name, server.ip_address), true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.send(CreateReply::default()
|
|
||||||
.embed(CreateEmbed::new()
|
|
||||||
.title("List of registered gameservers")
|
|
||||||
.fields(embed_fields)
|
|
||||||
.color(EMBED_COLOR)
|
|
||||||
)
|
|
||||||
).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn ac_server_name<'a>(
|
|
||||||
ctx: poise::Context<'_, (), Error>,
|
|
||||||
partial: &'a str
|
|
||||||
) -> impl Stream<Item = String> + 'a {
|
|
||||||
let result = Gameservers::get_server_names(ctx.guild_id().unwrap().into()).await;
|
|
||||||
|
|
||||||
let names = match result {
|
|
||||||
Ok(names_vector) => names_vector,
|
|
||||||
Err(y) => {
|
|
||||||
println!("Error retrieving server names: {:?}", y);
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
iter(names)
|
|
||||||
.filter(move |server_name| ready(server_name.starts_with(partial)))
|
|
||||||
.map(|server_name| server_name.to_string())
|
|
||||||
}
|
|
@ -1,41 +1,23 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Error,
|
Error,
|
||||||
models::gameservers::Gameservers,
|
internals::{
|
||||||
commands::gameserver::ac_server_name,
|
config::BINARY_PROPERTIES,
|
||||||
internals::utils::EMBED_COLOR,
|
http::HttpClient,
|
||||||
internals::http::HttpClient,
|
utils::token_path
|
||||||
internals::utils::token_path
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tokio::join;
|
use tokio::join;
|
||||||
use poise::CreateReply;
|
use poise::{
|
||||||
use poise::serenity_prelude::builder::CreateEmbed;
|
CreateReply,
|
||||||
use serde::Deserialize;
|
serenity_prelude::builder::CreateEmbed
|
||||||
use serde_json::Value;
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct MinecraftQueryData {
|
|
||||||
motd: Option<MinecraftMotd>,
|
|
||||||
players: Option<MinecraftPlayers>,
|
|
||||||
version: Option<String>,
|
|
||||||
online: bool
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct MinecraftMotd {
|
|
||||||
clean: Vec<String>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, Copy)]
|
|
||||||
struct MinecraftPlayers {
|
|
||||||
online: i32,
|
|
||||||
max: i32
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn pms_serverstatus(url: &str) -> Result<Vec<(String, Vec<Value>)>, Error> {
|
async fn pms_serverstatus(url: &str) -> Result<Vec<(String, Vec<Value>)>, Error> {
|
||||||
let client = HttpClient::new();
|
let client = HttpClient::new();
|
||||||
let req = client.get(url).await?;
|
let req = client.get(url, "PMS-Status").await?;
|
||||||
|
|
||||||
let response = req.json::<HashMap<String, Value>>().await?;
|
let response = req.json::<HashMap<String, Value>>().await?;
|
||||||
let data = response["data"].as_array().unwrap();
|
let data = response["data"].as_array().unwrap();
|
||||||
@ -84,22 +66,12 @@ fn process_pms_statuses(servers: Vec<(String, Vec<Value>)>) -> Vec<(String, Stri
|
|||||||
statuses
|
statuses
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn gs_query_minecraft(server_ip: &str) -> Result<MinecraftQueryData, Error> {
|
|
||||||
let client = HttpClient::new();
|
|
||||||
let req = client.get(&format!("https://api.mcsrvstat.us/2/{}", server_ip)).await?;
|
|
||||||
|
|
||||||
if req.status().is_success() {
|
|
||||||
let data: MinecraftQueryData = req.json().await?;
|
|
||||||
Ok(data)
|
|
||||||
} else if req.status().is_server_error() {
|
|
||||||
Err(Error::from("Webserver returned a 5xx error."))
|
|
||||||
} else {
|
|
||||||
Err(Error::from("Failed to query the server."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Query the server statuses
|
/// Query the server statuses
|
||||||
#[poise::command(slash_command, subcommands("wg", "gs"), subcommand_required)]
|
#[poise::command(
|
||||||
|
slash_command,
|
||||||
|
subcommands("wg"),
|
||||||
|
subcommand_required
|
||||||
|
)]
|
||||||
pub async fn status(_: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
pub async fn status(_: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -109,7 +81,7 @@ pub async fn status(_: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
|||||||
pub async fn wg(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
pub async fn wg(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
||||||
let pms_asia = token_path().await.wg_pms;
|
let pms_asia = token_path().await.wg_pms;
|
||||||
let pms_eu = pms_asia.replace("asia", "eu");
|
let pms_eu = pms_asia.replace("asia", "eu");
|
||||||
let embed = CreateEmbed::new().color(EMBED_COLOR);
|
let embed = CreateEmbed::new().color(BINARY_PROPERTIES.embed_color);
|
||||||
|
|
||||||
let (servers_asia, servers_eu) = join!(pms_serverstatus(&pms_asia), pms_serverstatus(&pms_eu));
|
let (servers_asia, servers_eu) = join!(pms_serverstatus(&pms_asia), pms_serverstatus(&pms_eu));
|
||||||
let joined_pms_servers = [servers_eu.unwrap(), servers_asia.unwrap()].concat();
|
let joined_pms_servers = [servers_eu.unwrap(), servers_asia.unwrap()].concat();
|
||||||
@ -119,46 +91,3 @@ pub async fn wg(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the given server data from gameservers DB
|
|
||||||
#[poise::command(slash_command, guild_only)]
|
|
||||||
pub async fn gs(
|
|
||||||
ctx: poise::Context<'_, (), Error>,
|
|
||||||
#[description = "Server name"] #[autocomplete = "ac_server_name"] server_name: String
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let server_data = Gameservers::get_server_data(ctx.guild_id().unwrap().into(), &server_name).await?;
|
|
||||||
|
|
||||||
// Extract values from a Vec above
|
|
||||||
let game_name = &server_data[1];
|
|
||||||
let ip_address = &server_data[2];
|
|
||||||
|
|
||||||
match game_name.as_str() {
|
|
||||||
"Minecraft" => {
|
|
||||||
let result = gs_query_minecraft(ip_address).await?;
|
|
||||||
let embed = CreateEmbed::new().color(EMBED_COLOR);
|
|
||||||
|
|
||||||
if result.online {
|
|
||||||
let mut embed_fields = Vec::new();
|
|
||||||
embed_fields.push(("Server IP".to_owned(), ip_address.to_owned(), true));
|
|
||||||
embed_fields.push((format!("\u{200b}"), format!("\u{200b}"), true));
|
|
||||||
embed_fields.push(("MOTD".to_owned(), format!("{}", result.motd.unwrap().clean[0]), true));
|
|
||||||
embed_fields.push(("Players".to_owned(), format!("**{}**/**{}**", result.players.unwrap().online, result.players.clone().unwrap().max), true));
|
|
||||||
embed_fields.push(("Version".to_owned(), result.version.unwrap(), true));
|
|
||||||
|
|
||||||
ctx.send(CreateReply::default()
|
|
||||||
.embed(embed
|
|
||||||
.title(server_name)
|
|
||||||
.fields(embed_fields)
|
|
||||||
)
|
|
||||||
).await?;
|
|
||||||
} else {
|
|
||||||
ctx.send(CreateReply::default()
|
|
||||||
.content(format!("**{}** (`{}`) is currently offline or unreachable.", server_name, ip_address))
|
|
||||||
).await?;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
@ -22,6 +22,10 @@ pub async fn uptime(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
|||||||
let mut sys = System::new_all();
|
let mut sys = System::new_all();
|
||||||
sys.refresh_all();
|
sys.refresh_all();
|
||||||
|
|
||||||
|
// Fetch system's operating system
|
||||||
|
let sys_os_info = os_info::get();
|
||||||
|
let sys_os = format!("{} {}", sys_os_info.os_type(), sys_os_info.version());
|
||||||
|
|
||||||
// Fetch system's uptime
|
// Fetch system's uptime
|
||||||
let sys_uptime = get().unwrap().as_secs();
|
let sys_uptime = get().unwrap().as_secs();
|
||||||
|
|
||||||
@ -37,7 +41,8 @@ pub async fn uptime(ctx: poise::Context<'_, (), Error>) -> Result<(), Error> {
|
|||||||
let stat_msg = vec![
|
let stat_msg = vec![
|
||||||
format!("**{} {}**", _bot.name, BOT_VERSION.as_str()),
|
format!("**{} {}**", _bot.name, BOT_VERSION.as_str()),
|
||||||
format!(">>> System: `{}`", format_duration(sys_uptime)),
|
format!(">>> System: `{}`", format_duration(sys_uptime)),
|
||||||
format!("Process: `{}`", format_duration(proc_uptime))
|
format!("Process: `{}`", format_duration(proc_uptime)),
|
||||||
|
format!("OS: `{}`", sys_os)
|
||||||
];
|
];
|
||||||
ctx.reply(concat_message(stat_msg)).await?;
|
ctx.reply(concat_message(stat_msg)).await?;
|
||||||
|
|
||||||
|
1
src/controllers.rs
Normal file
1
src/controllers.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
// pub mod database;
|
@ -1,37 +1,75 @@
|
|||||||
use crate::internals;
|
use crate::internals::utils::token_path;
|
||||||
|
|
||||||
use poise::serenity_prelude::prelude::TypeMapKey;
|
use once_cell::sync::Lazy;
|
||||||
use tokio_postgres::{Client, NoTls, Error};
|
use bb8::{Pool, PooledConnection};
|
||||||
|
use bb8_postgres::PostgresConnectionManager;
|
||||||
|
use tokio_postgres::{
|
||||||
|
Client,
|
||||||
|
NoTls,
|
||||||
|
Error,
|
||||||
|
config::Config
|
||||||
|
};
|
||||||
|
use tokio::time::{
|
||||||
|
sleep,
|
||||||
|
Duration
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
ops::Deref,
|
||||||
|
str::FromStr,
|
||||||
|
sync::Mutex
|
||||||
|
};
|
||||||
|
|
||||||
|
pub static DATABASE: Lazy<Mutex<Option<DatabaseController>>> = Lazy::new(|| Mutex::new(None));
|
||||||
|
|
||||||
pub struct DatabaseController {
|
pub struct DatabaseController {
|
||||||
pub client: Client
|
pub pool: Pool<PostgresConnectionManager<NoTls>>
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeMapKey for DatabaseController {
|
|
||||||
type Value = DatabaseController;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DatabaseController {
|
impl DatabaseController {
|
||||||
pub async fn new() -> Result<DatabaseController, Error> {
|
pub async fn new() -> Result<(), Error> {
|
||||||
let (client, connection) = tokio_postgres::connect(&internals::utils::token_path().await.postgres_uri, NoTls).await?;
|
let manager = PostgresConnectionManager::new(Config::from_str(token_path().await.postgres_uri.as_str())?, NoTls);
|
||||||
|
let pool = Pool::builder().build(manager).await?;
|
||||||
|
let err_name = "Postgres[Error]";
|
||||||
|
|
||||||
|
let pool_clone = pool.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Err(e) = connection.await {
|
let conn = match Self::attempt_connect(&pool_clone).await {
|
||||||
eprintln!("Connection error: {}", e);
|
Ok(conn) => {
|
||||||
|
println!("Postgres[Info]: Successfully connected");
|
||||||
|
conn
|
||||||
|
},
|
||||||
|
Err(y) => {
|
||||||
|
eprintln!("{}: {}", err_name, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let client: &Client = conn.deref();
|
||||||
|
|
||||||
|
/* if let Err(e) = client.batch_execute("").await {
|
||||||
|
eprintln!("{}: {}", err_name, e);
|
||||||
|
} */ // Uncomment this if bot is going to use a database
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
let controller = Self { pool };
|
||||||
|
*DATABASE.lock().unwrap() = Some(controller);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn attempt_connect<'a>(pool: &'a Pool<PostgresConnectionManager<NoTls>>) -> Result<PooledConnection<'a, PostgresConnectionManager<NoTls>>, bb8::RunError<Error>> {
|
||||||
|
let mut backoff = 1;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match pool.get().await {
|
||||||
|
Ok(conn) => return Ok(conn),
|
||||||
|
Err(y) => {
|
||||||
|
eprintln!("Postgres[ConnError]: {}, retrying in {} seconds", y, backoff);
|
||||||
|
sleep(Duration::from_secs(backoff)).await;
|
||||||
|
if backoff < 64 {
|
||||||
|
backoff *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// Gameservers
|
|
||||||
client.batch_execute("
|
|
||||||
CREATE TABLE IF NOT EXISTS gameservers (
|
|
||||||
server_name VARCHAR(255) NOT NULL,
|
|
||||||
game_name VARCHAR(255) NOT NULL,
|
|
||||||
guild_owner BIGINT NOT NULL,
|
|
||||||
ip_address VARCHAR(255) NOT NULL,
|
|
||||||
PRIMARY KEY (server_name, guild_owner)
|
|
||||||
);
|
|
||||||
").await?;
|
|
||||||
|
|
||||||
Ok(DatabaseController { client })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
pub mod database;
|
|
@ -1,3 +1,4 @@
|
|||||||
pub mod utils;
|
pub mod config;
|
||||||
pub mod http;
|
pub mod http;
|
||||||
pub mod tsclient;
|
pub mod tsclient;
|
||||||
|
pub mod utils;
|
60
src/internals/config.rs
Normal file
60
src/internals/config.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
pub struct ConfigMeta {
|
||||||
|
pub guild_id: u64,
|
||||||
|
pub embed_color: i32,
|
||||||
|
pub ready_notify: u64,
|
||||||
|
pub deploy_commands: bool,
|
||||||
|
pub developers: Vec<u64>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "production")]
|
||||||
|
pub static BINARY_PROPERTIES: Lazy<ConfigMeta> = Lazy::new(|| ConfigMeta::new());
|
||||||
|
|
||||||
|
#[cfg(not(feature = "production"))]
|
||||||
|
pub static BINARY_PROPERTIES: Lazy<ConfigMeta> = Lazy::new(||
|
||||||
|
ConfigMeta::new()
|
||||||
|
.guild_id(865673694184996885)
|
||||||
|
.embed_color(0xf1d63c)
|
||||||
|
.ready_notify(865673694184996888)
|
||||||
|
.deploy_commands(false)
|
||||||
|
);
|
||||||
|
|
||||||
|
impl ConfigMeta {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
guild_id: 865673694184996885,
|
||||||
|
embed_color: 0x5a99c7,
|
||||||
|
ready_notify: 865673694184996888,
|
||||||
|
deploy_commands: false,
|
||||||
|
developers: vec![
|
||||||
|
190407856527376384 // toast.ts
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scalable functions below;
|
||||||
|
#[cfg(not(feature = "production"))]
|
||||||
|
fn guild_id(mut self, guild_id: u64) -> Self {
|
||||||
|
self.guild_id = guild_id;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "production"))]
|
||||||
|
fn embed_color(mut self, color: i32) -> Self {
|
||||||
|
self.embed_color = color;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "production"))]
|
||||||
|
fn ready_notify(mut self, channel_id: u64) -> Self {
|
||||||
|
self.ready_notify = channel_id;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "production"))]
|
||||||
|
fn deploy_commands(mut self, deploy: bool) -> Self {
|
||||||
|
self.deploy_commands = deploy;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +1,26 @@
|
|||||||
use std::sync::Arc;
|
use std::time::Duration;
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use reqwest::{
|
use reqwest::{
|
||||||
Client,
|
Client,
|
||||||
header::USER_AGENT
|
Response,
|
||||||
|
Error
|
||||||
};
|
};
|
||||||
|
|
||||||
static CUSTOM_USER_AGENT: Lazy<String> = Lazy::new(||
|
pub struct HttpClient(Client);
|
||||||
format!("Kon/{}/Rust", super::utils::BOT_VERSION.as_str())
|
|
||||||
);
|
|
||||||
|
|
||||||
pub struct HttpClient {
|
|
||||||
client: Arc<Client>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HttpClient {
|
impl HttpClient {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self(Client::new())
|
||||||
client: Arc::new(Client::new())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get(&self, url: &str) -> Result<reqwest::Response, reqwest::Error> {
|
pub async fn get(&self, url: &str, ua: &str) -> Result<Response, Error> {
|
||||||
let req = self.client.get(url)
|
Ok(
|
||||||
.header(USER_AGENT, CUSTOM_USER_AGENT.as_str())
|
self.0.get(url).header(
|
||||||
|
reqwest::header::USER_AGENT,
|
||||||
|
format!("Kon ({}) - {}/reqwest", super::utils::BOT_VERSION.as_str(), ua)
|
||||||
|
)
|
||||||
|
.timeout(Duration::from_secs(15))
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?
|
||||||
Ok(req)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,36 @@
|
|||||||
use tokenservice_client::{TokenService, TokenServiceApi};
|
use once_cell::sync::Lazy;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
use tokenservice_client::{
|
||||||
|
TokenService,
|
||||||
|
TokenServiceApi
|
||||||
|
};
|
||||||
|
|
||||||
pub struct TSClient {
|
static TS_GLOBAL_CACHE: Lazy<RwLock<Option<TokenServiceApi>>> = Lazy::new(|| RwLock::new(None));
|
||||||
client: TokenService
|
|
||||||
}
|
pub struct TSClient(TokenService);
|
||||||
|
|
||||||
impl TSClient {
|
impl TSClient {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
let service = if args.len() > 1 { args[1].as_str() } else { "kon" };
|
let service = if args.len() > 1 { &args[1] } else { "kon" };
|
||||||
TSClient {
|
Self(TokenService::new(service))
|
||||||
client: TokenService::new(service)
|
}
|
||||||
|
|
||||||
|
pub async fn get(&self) -> Result<TokenServiceApi, crate::Error> {
|
||||||
|
{
|
||||||
|
let cache = TS_GLOBAL_CACHE.read().await;
|
||||||
|
if let Some(ref api) = *cache {
|
||||||
|
return Ok(api.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.0.connect().await {
|
||||||
|
Ok(api) => {
|
||||||
|
let mut cache = TS_GLOBAL_CACHE.write().await;
|
||||||
|
*cache = Some(api.clone());
|
||||||
|
Ok(api)
|
||||||
|
}
|
||||||
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn get(&self) -> Result<TokenServiceApi, Box<dyn std::error::Error>> {
|
|
||||||
let api = self.client.connect().await.unwrap();
|
|
||||||
Ok(api)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use tokenservice_client::TokenServiceApi;
|
use tokenservice_client::TokenServiceApi;
|
||||||
|
use super::tsclient::TSClient;
|
||||||
pub static EMBED_COLOR: i32 = 0x5a99c7;
|
|
||||||
|
|
||||||
pub static BOT_VERSION: Lazy<String> = Lazy::new(|| {
|
pub static BOT_VERSION: Lazy<String> = Lazy::new(|| {
|
||||||
let cargo_version = cargo_toml::Manifest::from_path("./Cargo.toml")
|
let cargo_version = cargo_toml::Manifest::from_str(&include_str!("../../Cargo.toml"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.package
|
.package
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -13,9 +13,10 @@ pub static BOT_VERSION: Lazy<String> = Lazy::new(|| {
|
|||||||
format!("v{}", cargo_version)
|
format!("v{}", cargo_version)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static TSCLIENT: Lazy<Mutex<TSClient>> = Lazy::new(|| Mutex::new(TSClient::new()));
|
||||||
|
|
||||||
pub async fn token_path() -> TokenServiceApi {
|
pub async fn token_path() -> TokenServiceApi {
|
||||||
let client = super::tsclient::TSClient::new().get().await.unwrap();
|
TSCLIENT.lock().await.get().await.unwrap()
|
||||||
client
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn concat_message(messages: Vec<String>) -> String {
|
pub fn concat_message(messages: Vec<String>) -> String {
|
||||||
|
107
src/main.rs
107
src/main.rs
@ -1,57 +1,89 @@
|
|||||||
mod commands;
|
mod commands;
|
||||||
mod controllers;
|
mod controllers;
|
||||||
mod models;
|
|
||||||
mod internals;
|
mod internals;
|
||||||
|
// https://cdn.toast-server.net/RustFSHiearchy.png
|
||||||
|
// Using the new filesystem hierarchy
|
||||||
|
|
||||||
use std::{
|
use crate::{
|
||||||
env::var,
|
internals::{
|
||||||
error
|
utils::token_path,
|
||||||
|
config::BINARY_PROPERTIES
|
||||||
|
},
|
||||||
|
// controllers::database::DatabaseController
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::error;
|
||||||
use poise::serenity_prelude::{
|
use poise::serenity_prelude::{
|
||||||
builder::{
|
builder::{
|
||||||
CreateMessage,
|
CreateMessage,
|
||||||
CreateEmbed,
|
CreateEmbed,
|
||||||
CreateEmbedAuthor
|
CreateEmbedAuthor
|
||||||
},
|
},
|
||||||
Context,
|
|
||||||
Ready,
|
Ready,
|
||||||
|
Context,
|
||||||
|
FullEvent,
|
||||||
ClientBuilder,
|
ClientBuilder,
|
||||||
ChannelId,
|
ChannelId,
|
||||||
Command,
|
Command,
|
||||||
|
UserId,
|
||||||
GatewayIntents
|
GatewayIntents
|
||||||
};
|
};
|
||||||
|
|
||||||
type Error = Box<dyn error::Error + Send + Sync>;
|
type Error = Box<dyn error::Error + Send + Sync>;
|
||||||
|
|
||||||
static BOT_READY_NOTIFY: u64 = 865673694184996888;
|
|
||||||
|
|
||||||
async fn on_ready(
|
async fn on_ready(
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
ready: &Ready,
|
ready: &Ready,
|
||||||
framework: &poise::Framework<(), Error>
|
framework: &poise::Framework<(), Error>
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
println!("Connected to API as {}", ready.user.name);
|
#[cfg(not(feature = "production"))]
|
||||||
|
{
|
||||||
|
println!("Event[Ready][Notice]: Detected a non-production environment!");
|
||||||
|
let gateway = ctx.http.get_bot_gateway().await?;
|
||||||
|
let session = gateway.session_start_limit;
|
||||||
|
println!("Event[Ready][Notice]: Session limit: {}/{}", session.remaining, session.total);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Event[Ready]: Connected to API as {}", ready.user.name);
|
||||||
|
|
||||||
let message = CreateMessage::new();
|
let message = CreateMessage::new();
|
||||||
let ready_embed = CreateEmbed::new()
|
let ready_embed = CreateEmbed::new()
|
||||||
.color(internals::utils::EMBED_COLOR)
|
.color(BINARY_PROPERTIES.embed_color)
|
||||||
.thumbnail(ready.user.avatar_url().unwrap_or_default())
|
.thumbnail(ready.user.avatar_url().unwrap_or_default())
|
||||||
.author(CreateEmbedAuthor::new(format!("{} is ready!", ready.user.name)).clone());
|
.author(CreateEmbedAuthor::new(format!("{} is ready!", ready.user.name)));
|
||||||
|
|
||||||
ChannelId::new(BOT_READY_NOTIFY).send_message(&ctx.http, message.add_embed(ready_embed)).await?;
|
ChannelId::new(BINARY_PROPERTIES.ready_notify).send_message(&ctx.http, message.add_embed(ready_embed)).await?;
|
||||||
|
|
||||||
let register_commands = var("REGISTER_CMDS").unwrap_or_else(|_| String::from("true")).parse::<bool>().unwrap_or(true);
|
if BINARY_PROPERTIES.deploy_commands {
|
||||||
|
|
||||||
if register_commands {
|
|
||||||
let builder = poise::builtins::create_application_commands(&framework.options().commands);
|
let builder = poise::builtins::create_application_commands(&framework.options().commands);
|
||||||
let commands = Command::set_global_commands(&ctx.http, builder).await;
|
let commands = Command::set_global_commands(&ctx.http, builder).await;
|
||||||
|
let mut commands_deployed = std::collections::HashSet::new();
|
||||||
|
|
||||||
match commands {
|
match commands {
|
||||||
Ok(cmdmap) => for command in cmdmap.iter() {
|
Ok(cmdmap) => for command in cmdmap.iter() {
|
||||||
println!("Registered command globally: {}", command.name);
|
commands_deployed.insert(command.name.clone());
|
||||||
},
|
},
|
||||||
Err(why) => println!("Error registering commands: {:?}", why)
|
Err(y) => eprintln!("Error registering commands: {:?}", y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if commands_deployed.len() > 0 {
|
||||||
|
println!("Event[Ready]: Deployed the commands globally:\n- {}", commands_deployed.into_iter().collect::<Vec<_>>().join("\n- "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn event_processor(
|
||||||
|
_ctx: &Context,
|
||||||
|
event: &FullEvent,
|
||||||
|
_framework: poise::FrameworkContext<'_, (), Error>
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
match event {
|
||||||
|
FullEvent::Ratelimit { data } => {
|
||||||
|
println!("Event[Ratelimit]: {:#?}", data);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -59,47 +91,60 @@ async fn on_ready(
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let db = controllers::database::DatabaseController::new().await.expect("Failed to connect to database");
|
// DatabaseController::new().await.expect("Error initializing database");
|
||||||
|
|
||||||
let framework = poise::Framework::builder()
|
let framework = poise::Framework::builder()
|
||||||
.options(poise::FrameworkOptions {
|
.options(poise::FrameworkOptions {
|
||||||
commands: vec![
|
commands: vec![
|
||||||
commands::ping::ping(),
|
commands::ping::ping(),
|
||||||
commands::uptime::uptime(),
|
|
||||||
commands::status::status(),
|
commands::status::status(),
|
||||||
commands::gameserver::gameserver()
|
commands::uptime::uptime()
|
||||||
],
|
],
|
||||||
pre_command: |ctx| Box::pin(async move {
|
pre_command: |ctx| Box::pin(async move {
|
||||||
let get_guild_name = match ctx.guild() {
|
let get_guild_name = match ctx.guild() {
|
||||||
Some(guild) => guild.name.clone(),
|
Some(guild) => guild.name.clone(),
|
||||||
None => String::from("DM")
|
None => String::from("Direct Message")
|
||||||
};
|
};
|
||||||
println!("[{}] {} ran /{}", get_guild_name, ctx.author().name, ctx.command().qualified_name)
|
println!("Discord[{}] {} ran /{}", get_guild_name, ctx.author().name, ctx.command().qualified_name);
|
||||||
}),
|
}),
|
||||||
on_error: |error| Box::pin(async move {
|
on_error: |error| Box::pin(async move {
|
||||||
match error {
|
match error {
|
||||||
poise::FrameworkError::Command { error, ctx, .. } => {
|
poise::FrameworkError::Command { error, ctx, .. } => {
|
||||||
println!("PoiseCommandError({}): {}", ctx.command().qualified_name, error);
|
println!("PoiseCommandError({}): {}", ctx.command().qualified_name, error);
|
||||||
}
|
ctx.reply(format!(
|
||||||
|
"Encountered an error during command execution, ask **{}** to check console for more details!",
|
||||||
|
UserId::new(BINARY_PROPERTIES.developers[0])
|
||||||
|
.to_user(&ctx.http())
|
||||||
|
.await.expect("Error getting user")
|
||||||
|
.nick_in(&ctx.http(), BINARY_PROPERTIES.guild_id)
|
||||||
|
.await.expect("Error getting nickname")
|
||||||
|
)).await.expect("Error sending message");
|
||||||
|
},
|
||||||
|
poise::FrameworkError::EventHandler { error, event, .. } => println!("PoiseEventHandlerError({}): {}", event.snake_case_name(), error),
|
||||||
|
poise::FrameworkError::Setup { error, .. } => println!("PoiseSetupError: {}", error),
|
||||||
|
poise::FrameworkError::UnknownInteraction { interaction, .. } => println!(
|
||||||
|
"PoiseUnknownInteractionError: {} tried to execute an unknown interaction ({})",
|
||||||
|
interaction.user.name,
|
||||||
|
interaction.data.name
|
||||||
|
),
|
||||||
other => println!("PoiseOtherError: {}", other)
|
other => println!("PoiseOtherError: {}", other)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
initialize_owners: true,
|
initialize_owners: true,
|
||||||
|
event_handler: |ctx, event, framework, _| Box::pin(event_processor(ctx, event, framework)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.setup(|ctx, ready, framework| Box::pin(on_ready(ctx, ready, framework)))
|
.setup(|ctx, ready, framework| Box::pin(on_ready(ctx, ready, framework)))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut client = ClientBuilder::new(internals::utils::token_path().await.main, GatewayIntents::GUILDS)
|
let mut client = ClientBuilder::new(
|
||||||
.framework(framework)
|
token_path().await.main,
|
||||||
.await.expect("Error creating client");
|
GatewayIntents::GUILDS
|
||||||
|
)
|
||||||
{
|
.framework(framework)
|
||||||
let mut data = client.data.write().await;
|
.await.expect("Error creating client");
|
||||||
data.insert::<controllers::database::DatabaseController>(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(why) = client.start().await {
|
if let Err(why) = client.start().await {
|
||||||
println!("Client error: {:?}", why);
|
println!("Error starting client: {:#?}", why);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
use crate::controllers::database::DatabaseController;
|
|
||||||
|
|
||||||
pub struct Gameservers {
|
|
||||||
pub server_name: String,
|
|
||||||
pub game_name: String,
|
|
||||||
pub guild_owner: i64,
|
|
||||||
pub ip_address: String
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Gameservers {
|
|
||||||
pub async fn list_servers(guild_id: u64) -> Result<Vec<Self>, tokio_postgres::Error> {
|
|
||||||
let client = DatabaseController::new().await?.client;
|
|
||||||
let rows = client.query("
|
|
||||||
SELECT * FROM gameservers
|
|
||||||
WHERE guild_owner = $1
|
|
||||||
", &[&(guild_id as i64)]).await?;
|
|
||||||
|
|
||||||
let mut servers = Vec::new();
|
|
||||||
for row in rows {
|
|
||||||
servers.push(Self {
|
|
||||||
server_name: row.get("server_name"),
|
|
||||||
game_name: row.get("game_name"),
|
|
||||||
guild_owner: row.get("guild_owner"),
|
|
||||||
ip_address: row.get("ip_address")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(servers)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn add_server(
|
|
||||||
guild_id: u64,
|
|
||||||
server_name: &str,
|
|
||||||
game_name: &str,
|
|
||||||
ip_address: &str
|
|
||||||
) -> Result<(), tokio_postgres::Error> {
|
|
||||||
let client = DatabaseController::new().await?.client;
|
|
||||||
client.execute("
|
|
||||||
INSERT INTO gameservers (server_name, game_name, guild_owner, ip_address)
|
|
||||||
VALUES ($1, $2, $3, $4)
|
|
||||||
", &[&server_name, &game_name, &(guild_id as i64), &ip_address]).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn remove_server(guild_id: u64, server_name: &str) -> Result<(), tokio_postgres::Error> {
|
|
||||||
let client = DatabaseController::new().await?.client;
|
|
||||||
client.execute("
|
|
||||||
DELETE FROM gameservers
|
|
||||||
WHERE guild_owner = $1 AND server_name = $2
|
|
||||||
", &[&(guild_id as i64), &server_name]).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_server(
|
|
||||||
guild_id: u64,
|
|
||||||
server_name: &str,
|
|
||||||
game_name: &str,
|
|
||||||
ip_address: &str
|
|
||||||
) -> Result<(), tokio_postgres::Error> {
|
|
||||||
let client = DatabaseController::new().await?.client;
|
|
||||||
client.execute("
|
|
||||||
UPDATE gameservers
|
|
||||||
SET game_name = $1, ip_address = $2
|
|
||||||
WHERE guild_owner = $3 AND server_name = $4
|
|
||||||
", &[&game_name, &ip_address, &(guild_id as i64), &server_name]).await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_server_names(guild_id: u64) -> Result<Vec<String>, tokio_postgres::Error> {
|
|
||||||
let client = DatabaseController::new().await?.client;
|
|
||||||
let rows = client.query("
|
|
||||||
SELECT server_name FROM gameservers
|
|
||||||
WHERE guild_owner = $1
|
|
||||||
", &[&(guild_id as i64)]).await?;
|
|
||||||
|
|
||||||
let mut servers = Vec::new();
|
|
||||||
for row in rows {
|
|
||||||
servers.push(row.get("server_name"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(servers)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_server_data(guild_id: u64, server_name: &str) -> Result<Vec<String>, tokio_postgres::Error> {
|
|
||||||
let client = DatabaseController::new().await?.client;
|
|
||||||
let rows = client.query("
|
|
||||||
SELECT * FROM gameservers
|
|
||||||
WHERE guild_owner = $1 AND server_name = $2
|
|
||||||
", &[&(guild_id as i64), &server_name]).await?;
|
|
||||||
|
|
||||||
let mut server = Vec::new();
|
|
||||||
for row in rows {
|
|
||||||
server.push(row.get("server_name"));
|
|
||||||
server.push(row.get("game_name"));
|
|
||||||
server.push(row.get("ip_address"))
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(server)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
pub mod gameservers;
|
|
Loading…
Reference in New Issue
Block a user