abaunda
This commit is contained in:
parent
67e547a275
commit
d21e25eda9
329
Cargo.lock
generated
329
Cargo.lock
generated
@ -3,46 +3,22 @@
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
name = "anyhow"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
|
||||
|
||||
[[package]]
|
||||
name = "bytebuffer"
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7bfaf7cd08cacd74cdc6b521c37ac39cbc92692e5ab5c21ed5657a749b577c"
|
||||
checksum = "2618ff1f07e000264e355904bff5c0527091fcbad883ff7f71383c5428915f4b"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
@ -53,29 +29,12 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "contracts"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9424f2ca1e42776615720e5746eed6efa19866fdbaac2923ab51c294ac4d1f2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
@ -94,72 +53,34 @@ dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.30"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
|
||||
checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "ignore-result"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "665ff4dce8edd10d490641ccb78949832f1ddbff02c584fb1f85ab888fe0e50c"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
@ -184,15 +105,13 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libyml"
|
||||
version = "0.0.3"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e281a65eeba3d4503a2839252f86374528f9ceafe6fed97c1d3b52e1fb625c1"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@ -204,13 +123,11 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
name = "meexprox"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"ignore-result",
|
||||
"log",
|
||||
"no_deadlocks",
|
||||
"rust_mc_proto",
|
||||
"serde_yml",
|
||||
"simplelog",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@ -222,21 +139,11 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no_deadlocks"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0e0af0e4fcf0d695f224cafbf5e4fb750b85aa1cd1ad0b37d8d0d98c0d2ce5e"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"vector-map",
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -254,36 +161,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
@ -302,77 +185,16 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust_mc_proto"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5392814ae7129d56b0afcbdd5d6d4764ca51273fab7ff604ebe73018dbb562"
|
||||
version = "0.1.16"
|
||||
source = "git+https://github.com/MeexReay/rust_mc_proto#26a78af446bd7ceba54fa2fa34d2f6570e827904"
|
||||
dependencies = [
|
||||
"bytebuffer",
|
||||
"flate2",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
@ -396,35 +218,22 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.120"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yml"
|
||||
version = "0.0.10"
|
||||
version = "0.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ce6afeda22f0b55dde2c34897bce76a629587348480384231205c14b59a01f"
|
||||
checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"libyml",
|
||||
"log",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -438,17 +247,6 @@ dependencies = [
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
@ -460,18 +258,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
@ -514,16 +300,6 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.39.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
@ -532,25 +308,15 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.10.0"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
||||
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
|
||||
|
||||
[[package]]
|
||||
name = "vector-map"
|
||||
version = "1.0.1"
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "550f72ae94a45c0e2139188709e6c4179f0b5ff9bdaa435239ad19048b0cd68c"
|
||||
dependencies = [
|
||||
"contracts",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
@ -633,24 +399,3 @@ name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
14
Cargo.toml
14
Cargo.toml
@ -4,11 +4,13 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde_yml = "0.0.10"
|
||||
rust_mc_proto = "0.1.15"
|
||||
uuid = "1.10.0"
|
||||
serde_yml = "0.0.12"
|
||||
rust_mc_proto = { git = "https://github.com/MeexReay/rust_mc_proto", features = ["atomic_clone"] }
|
||||
uuid = "1.11.0"
|
||||
log = "0.4.22"
|
||||
simplelog = "0.12.2"
|
||||
derivative = "2.2.0"
|
||||
no_deadlocks = "1.3.2"
|
||||
tokio = {version = "1.39.2", features = ["rt"] }
|
||||
# derivative = "2.2.0"
|
||||
# no_deadlocks = "1.3.2"
|
||||
# tokio = {version = "1.39.3", features = ["full"] }
|
||||
# async-trait = "0.1.81"
|
||||
ignore-result = "0.2.0"
|
@ -4,7 +4,7 @@ Proxy for minecraft servers on rust
|
||||
`in developement`
|
||||
|
||||
todo list: (✅ / ❌)
|
||||
- ❌ (deadlock) add methods `connect_to_ip`, `connect_to_server`, `connect_to_stream`, `reconnect`
|
||||
- ❌ add methods `connect_to_ip`, `connect_to_server`, `connect_to_stream`, `reconnect`
|
||||
- ❌ make setting `no_pf_for_ip_connect` working
|
||||
- ❌ make talk server
|
||||
- ❌ create bukkit plugin for player formatting support and talking
|
||||
|
@ -4,7 +4,7 @@ talk_host: 127.0.0.1:12346 # secret host to talk with meexprox (optional)
|
||||
talk_secret: qwerty123456 # secret token for talk with meexprox (optional)
|
||||
|
||||
servers: # verified servers (name -> ip)
|
||||
play: 6.tcp.eu.ngrok.io:17753
|
||||
play: 127.0.0.1:12345
|
||||
|
||||
forced_hosts: # connect to server from connected hostname (name -> hostname) (optional)
|
||||
play: play.localhost
|
||||
|
99
src/main.rs
99
src/main.rs
@ -1,91 +1,18 @@
|
||||
use log::debug;
|
||||
use meexprox::{
|
||||
EventListener, MeexProx, MeexProxMutex, ProxyConfig,
|
||||
ProxyEvent::{self, *},
|
||||
ProxyPlayer,
|
||||
};
|
||||
use rust_mc_proto::DataBufferReader;
|
||||
use simplelog::{
|
||||
ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
fs::{self, File},
|
||||
path::Path,
|
||||
sync::atomic::Ordering,
|
||||
};
|
||||
use std::{fs::{self, File}, path::Path};
|
||||
|
||||
pub struct MyEventListener {}
|
||||
use log::LevelFilter;
|
||||
use meexprox::{config::ProxyConfig, MeexProx};
|
||||
use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger};
|
||||
|
||||
impl EventListener for MyEventListener {
|
||||
fn on_event(
|
||||
&mut self,
|
||||
this: MeexProxMutex,
|
||||
event: &mut ProxyEvent,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
match event {
|
||||
RecvServerPacketEvent { packet, player } => {
|
||||
// debug!("recv server packet event");
|
||||
}
|
||||
SendServerPacketEvent {
|
||||
packet,
|
||||
player,
|
||||
cancel,
|
||||
} => {
|
||||
// debug!("send server packet event");
|
||||
}
|
||||
SendClientPacketEvent {
|
||||
packet,
|
||||
player,
|
||||
cancel,
|
||||
} => {
|
||||
// debug!("send client packet event");
|
||||
}
|
||||
RecvClientPacketEvent { packet, player } => {
|
||||
// debug!("recv client packet event");
|
||||
|
||||
if packet.id() == 0x03 || packet.id() == 0x04 {
|
||||
let command = packet.read_string()?;
|
||||
|
||||
if command == "reconnect" {
|
||||
println!("reconnect wow");
|
||||
ProxyPlayer::reconnect(player.clone(), this.clone(), "localhost", 25565)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
PlayerConnectedEvent { player } => {
|
||||
debug!("player connected");
|
||||
}
|
||||
PlayerConnectingServerEvent {
|
||||
player,
|
||||
server,
|
||||
cancel,
|
||||
} => {
|
||||
debug!("player connecting server");
|
||||
}
|
||||
PlayerConnectingIPEvent { player, ip, cancel } => {
|
||||
debug!("player connecting ip");
|
||||
}
|
||||
PlayerDisconnectedEvent { player } => {
|
||||
debug!("player disconnected");
|
||||
}
|
||||
StatusRequestEvent {
|
||||
status,
|
||||
client_address,
|
||||
server_address,
|
||||
server_port,
|
||||
cancel,
|
||||
} => {
|
||||
debug!("status request");
|
||||
}
|
||||
}
|
||||
// pub struct MyEventListener {}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// impl EventListener for MyEventListener {
|
||||
|
||||
fn main() {
|
||||
// }
|
||||
|
||||
pub fn main() {
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(
|
||||
LevelFilter::Debug,
|
||||
@ -104,15 +31,13 @@ fn main() {
|
||||
let config_path = Path::new("config.yml");
|
||||
|
||||
if !config_path.exists() {
|
||||
fs::write(config_path, include_bytes!("../default_config.yml"))
|
||||
fs::write(config_path, include_bytes!("../config.yml"))
|
||||
.expect("config write error");
|
||||
}
|
||||
|
||||
let config = ProxyConfig::load(config_path).expect("config parse error");
|
||||
|
||||
let mut meexprox = MeexProx::new(config);
|
||||
|
||||
meexprox.add_event_listener(Box::new(MyEventListener {}));
|
||||
|
||||
let meexprox = MeexProx::new(config);
|
||||
// meexprox.add_event_listener(Box::new(MyEventListener {}));
|
||||
meexprox.start();
|
||||
}
|
||||
|
@ -1,45 +1,32 @@
|
||||
use super::ProxyError;
|
||||
|
||||
use serde_yml::Value;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use super::error::ProxyError;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ProxyServer {
|
||||
name: String,
|
||||
host: String,
|
||||
forced_host: Option<String>,
|
||||
pub struct ServerInfo {
|
||||
pub name: String,
|
||||
pub host: String,
|
||||
pub forced_host: Option<String>,
|
||||
}
|
||||
|
||||
impl ProxyServer {
|
||||
pub fn new(name: String, host: String, forced_host: Option<String>) -> ProxyServer {
|
||||
ProxyServer {
|
||||
impl ServerInfo {
|
||||
pub fn new(name: String, host: String, forced_host: Option<String>) -> ServerInfo {
|
||||
ServerInfo {
|
||||
name,
|
||||
host,
|
||||
forced_host,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
pub fn from_host(host: String) -> ServerInfo {
|
||||
ServerInfo {
|
||||
name: host.clone(),
|
||||
host,
|
||||
forced_host: None,
|
||||
}
|
||||
|
||||
pub fn host(&self) -> &str {
|
||||
&self.host
|
||||
}
|
||||
|
||||
pub fn forced_host(&self) -> Option<&String> {
|
||||
self.forced_host.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! extract_string {
|
||||
($data:expr, $key:expr) => {
|
||||
match $data.get(&Value::String($key.to_string())) {
|
||||
Some(Value::String(val)) => Some(val.clone()),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -50,20 +37,20 @@ pub enum PlayerForwarding {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ProxyConfig {
|
||||
host: String,
|
||||
servers: Vec<ProxyServer>,
|
||||
default_server: Option<ProxyServer>,
|
||||
talk_host: Option<String>,
|
||||
talk_secret: Option<String>,
|
||||
player_forwarding: PlayerForwarding,
|
||||
no_pf_for_ip_connect: bool,
|
||||
pub host: String,
|
||||
pub servers: Vec<ServerInfo>,
|
||||
pub default_server: Option<ServerInfo>,
|
||||
pub talk_host: Option<String>,
|
||||
pub talk_secret: Option<String>,
|
||||
pub player_forwarding: PlayerForwarding,
|
||||
pub no_pf_for_ip_connect: bool,
|
||||
}
|
||||
|
||||
impl ProxyConfig {
|
||||
pub fn new(
|
||||
host: String,
|
||||
servers: Vec<ProxyServer>,
|
||||
default_server: Option<ProxyServer>,
|
||||
servers: Vec<ServerInfo>,
|
||||
default_server: Option<ServerInfo>,
|
||||
talk_host: Option<String>,
|
||||
talk_secret: Option<String>,
|
||||
player_forwarding: PlayerForwarding,
|
||||
@ -80,42 +67,15 @@ impl ProxyConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn host(&self) -> &str {
|
||||
&self.host
|
||||
}
|
||||
|
||||
pub fn servers(&self) -> &Vec<ProxyServer> {
|
||||
&self.servers
|
||||
}
|
||||
|
||||
pub fn talk_host(&self) -> Option<&String> {
|
||||
self.talk_host.as_ref()
|
||||
}
|
||||
|
||||
pub fn talk_secret(&self) -> Option<&String> {
|
||||
self.talk_secret.as_ref()
|
||||
}
|
||||
pub fn default_server(&self) -> Option<&ProxyServer> {
|
||||
self.default_server.as_ref()
|
||||
}
|
||||
|
||||
pub fn player_forwarding(&self) -> &PlayerForwarding {
|
||||
&self.player_forwarding
|
||||
}
|
||||
|
||||
pub fn no_pf_for_ip_connect(&self) -> bool {
|
||||
self.no_pf_for_ip_connect
|
||||
}
|
||||
|
||||
pub fn load_data(data: String) -> Result<ProxyConfig, Box<dyn std::error::Error>> {
|
||||
pub fn load_yml(data: String) -> Result<ProxyConfig, Box<dyn std::error::Error>> {
|
||||
let data = serde_yml::from_str::<Value>(&data)?;
|
||||
let data = data.as_mapping().ok_or(ProxyError::ConfigParse)?;
|
||||
|
||||
let host = extract_string!(data, "host").ok_or(ProxyError::ConfigParse)?;
|
||||
let talk_host = extract_string!(data, "talk_host");
|
||||
let talk_secret = extract_string!(data, "talk_secret");
|
||||
let player_forwarding = match extract_string!(data, "player_forwarding") {
|
||||
Some(pf) => match pf.as_str() {
|
||||
let host = data.get("host").map(|o| o.as_str()).flatten().ok_or(ProxyError::ConfigParse)?.to_string();
|
||||
let talk_host = data.get("talk_host").map(|o| o.as_str()).flatten().map(|o| o.to_string());
|
||||
let talk_secret = data.get("talk_secret").map(|o| o.as_str()).flatten().map(|o| o.to_string());
|
||||
let player_forwarding = match data.get("player_forwarding").map(|o| o.as_str()).flatten() {
|
||||
Some(pf) => match pf {
|
||||
"disabled" => PlayerForwarding::Disabled,
|
||||
_ => PlayerForwarding::Handshake,
|
||||
},
|
||||
@ -135,7 +95,7 @@ impl ProxyConfig {
|
||||
{
|
||||
for (name, addr) in servers_map {
|
||||
if let (Value::String(name), Value::String(addr)) = (name, addr) {
|
||||
servers.push(ProxyServer::new(name.clone(), addr.clone(), None));
|
||||
servers.push(ServerInfo::new(name.clone(), addr.clone(), None));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,7 +113,8 @@ impl ProxyConfig {
|
||||
}
|
||||
}
|
||||
|
||||
let default_server = extract_string!(data, "default_server")
|
||||
let default_server = data.get("default_server")
|
||||
.map(|o| o.as_str()).flatten()
|
||||
.and_then(|ds| servers.iter().find(|s| s.name == ds).cloned());
|
||||
|
||||
Ok(ProxyConfig::new(
|
||||
@ -168,10 +129,10 @@ impl ProxyConfig {
|
||||
}
|
||||
|
||||
pub fn load(path: impl AsRef<Path>) -> Result<ProxyConfig, Box<dyn std::error::Error>> {
|
||||
Self::load_data(fs::read_to_string(path)?)
|
||||
Self::load_yml(fs::read_to_string(path)?)
|
||||
}
|
||||
|
||||
pub fn get_server_by_name(&self, name: &str) -> Option<ProxyServer> {
|
||||
pub fn get_server_by_name(&self, name: &str) -> Option<ServerInfo> {
|
||||
for server in &self.servers {
|
||||
if &server.name == name {
|
||||
return Some(server.clone());
|
||||
@ -180,7 +141,7 @@ impl ProxyConfig {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_server_by_forced_host(&self, forced_host: &str) -> Option<ProxyServer> {
|
||||
pub fn get_server_by_forced_host(&self, forced_host: &str) -> Option<ServerInfo> {
|
||||
for server in &self.servers {
|
||||
if let Some(server_forced_host) = &server.forced_host {
|
||||
if server_forced_host == forced_host {
|
||||
|
180
src/meexprox/connection.rs
Normal file
180
src/meexprox/connection.rs
Normal file
@ -0,0 +1,180 @@
|
||||
use std::{net::TcpStream, sync::{Arc, Mutex}, thread};
|
||||
|
||||
use ignore_result::Ignore;
|
||||
use rust_mc_proto::{DataBufferReader, MCConnTcp, Packet};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{config::{ProxyConfig, ServerInfo}, error::{AsProxyResult, ProxyError}};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LoginInfo {
|
||||
protocol_version: u16,
|
||||
server_address: String,
|
||||
server_port: u16,
|
||||
name: String,
|
||||
uuid: Uuid,
|
||||
shared_secret: Option<Vec<u8>>,
|
||||
verify_token: Option<Vec<u8>>
|
||||
}
|
||||
|
||||
impl LoginInfo {
|
||||
pub fn write(&self, config: &ProxyConfig, stream: &mut MCConnTcp) {
|
||||
todo!() // TODO: write login packets sending
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Player {
|
||||
client_conn: Arc<Mutex<MCConnTcp>>,
|
||||
server_conn: Arc<Mutex<MCConnTcp>>,
|
||||
login_info: Option<LoginInfo>,
|
||||
pub name: String,
|
||||
pub uuid: Uuid,
|
||||
pub server: Option<ServerInfo>,
|
||||
pub protocol_version: u16
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub fn read(
|
||||
protocol_version: u16,
|
||||
server_address: String,
|
||||
server_port: u16,
|
||||
server: ServerInfo,
|
||||
mut client_conn: MCConnTcp,
|
||||
mut server_conn: MCConnTcp
|
||||
) -> Result<Player, ProxyError> {
|
||||
let mut packet = client_conn.read_packet().as_proxy()?;
|
||||
|
||||
if packet.id() != 0x00 { return Err(ProxyError::LoginPacket); }
|
||||
|
||||
let name = packet.read_string().as_proxy()?;
|
||||
let uuid = packet.read_uuid().as_proxy()?;
|
||||
|
||||
server_conn.write_packet(&packet).as_proxy()?;
|
||||
|
||||
let mut player = Player {
|
||||
client_conn: Arc::new(Mutex::new(client_conn)),
|
||||
server_conn: Arc::new(Mutex::new(server_conn)),
|
||||
login_info: None,
|
||||
name: name.clone(),
|
||||
uuid,
|
||||
server: Some(server),
|
||||
protocol_version
|
||||
};
|
||||
|
||||
let mut shared_secret = None;
|
||||
let mut verify_token = None;
|
||||
|
||||
loop {
|
||||
let mut packet = player.read_server_packet()?;
|
||||
match packet.id() {
|
||||
0x01 => {
|
||||
player.write_client_packet(&packet)?;
|
||||
let mut packet = player.read_client_packet()?;
|
||||
let i = packet.read_usize_varint().as_proxy()?;
|
||||
shared_secret = Some(packet.read_bytes(i).as_proxy()?);
|
||||
let i = packet.read_usize_varint().as_proxy()?;
|
||||
verify_token = Some(packet.read_bytes(i).as_proxy()?);
|
||||
player.write_server_packet(&packet)?;
|
||||
}
|
||||
0x02 => {
|
||||
player.write_client_packet(&packet)?;
|
||||
break;
|
||||
}
|
||||
0x03 => {
|
||||
player.write_client_packet(&packet)?;
|
||||
let compression = Some(packet.read_usize_varint().as_proxy()?);
|
||||
player.set_server_compression(compression);
|
||||
player.set_client_compression(compression);
|
||||
}
|
||||
_ => {
|
||||
return Err(ProxyError::LoginPacket);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
player.login_info = Some(LoginInfo {
|
||||
protocol_version,
|
||||
server_address,
|
||||
server_port,
|
||||
name,
|
||||
uuid,
|
||||
shared_secret,
|
||||
verify_token
|
||||
});
|
||||
|
||||
player.write_server_packet(&player.read_client_packet()?)?;
|
||||
|
||||
player.client_recv_loop();
|
||||
|
||||
Ok(player)
|
||||
}
|
||||
|
||||
pub fn client_recv_loop(&self) {
|
||||
let mut client: rust_mc_proto::MinecraftConnection<TcpStream> = self.client_conn.clone().lock().unwrap().try_clone().unwrap();
|
||||
let server = self.server_conn.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
while let Ok(packet) = client.read_packet() {
|
||||
while !server.lock().unwrap().is_alive() {}
|
||||
server.lock().unwrap().write_packet(&packet).ignore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn server_recv_loop(&self) {
|
||||
let mut server = self.server_conn.clone().lock().unwrap().try_clone().unwrap();
|
||||
let client = self.client_conn.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
while let Ok(packet) = server.read_packet() {
|
||||
client.lock().unwrap().write_packet(&packet).ignore();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn connect(&self, config: &ProxyConfig, server_conn: TcpStream) -> Result<(), ProxyError> {
|
||||
self.server_conn.lock().unwrap().close();
|
||||
let mut server_conn = MCConnTcp::new(server_conn);
|
||||
if let Some(login_info) = &self.login_info {
|
||||
login_info.write(config, &mut server_conn);
|
||||
}
|
||||
self.server_recv_loop();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn connect_server(&self, config: &ProxyConfig, server: ServerInfo) -> Result<(), ProxyError> {
|
||||
self.connect(config, TcpStream::connect(&server.host).map_err(|_| ProxyError::ServerConnect)?)
|
||||
}
|
||||
|
||||
pub fn write_client_packet(&self, packet: &Packet) -> Result<(), ProxyError> {
|
||||
self.client_conn.lock().unwrap().write_packet(packet).as_proxy()
|
||||
}
|
||||
|
||||
pub fn write_server_packet(&self, packet: &Packet) -> Result<(), ProxyError> {
|
||||
self.server_conn.lock().unwrap().write_packet(packet).as_proxy()
|
||||
}
|
||||
|
||||
fn read_client_packet(&self) -> Result<Packet, ProxyError> {
|
||||
self.client_conn.lock().unwrap().read_packet().as_proxy()
|
||||
}
|
||||
|
||||
fn read_server_packet(&self) -> Result<Packet, ProxyError> {
|
||||
self.server_conn.lock().unwrap().read_packet().as_proxy()
|
||||
}
|
||||
|
||||
fn set_server_compression(&self, threshold: Option<usize>) {
|
||||
self.server_conn.lock().unwrap().set_compression(threshold);
|
||||
}
|
||||
|
||||
fn set_client_compression(&self, threshold: Option<usize>) {
|
||||
self.client_conn.lock().unwrap().set_compression(threshold);
|
||||
}
|
||||
|
||||
pub fn server_compression(&self) -> Option<usize> {
|
||||
self.server_conn.lock().unwrap().compression()
|
||||
}
|
||||
|
||||
pub fn client_compression(&self) -> Option<usize> {
|
||||
self.client_conn.lock().unwrap().compression()
|
||||
}
|
||||
}
|
@ -1,8 +1,14 @@
|
||||
use rust_mc_proto::ProtocolError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProxyError {
|
||||
ConfigParse,
|
||||
ServerConnect,
|
||||
EventChanged,
|
||||
HandshakePacket,
|
||||
LoginPacket,
|
||||
PeerAddr,
|
||||
ProtocolError(ProtocolError)
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ProxyError {
|
||||
@ -12,3 +18,23 @@ impl std::fmt::Display for ProxyError {
|
||||
}
|
||||
|
||||
impl std::error::Error for ProxyError {}
|
||||
|
||||
pub trait AsProxyError {
|
||||
fn as_proxy(self) -> ProxyError;
|
||||
}
|
||||
|
||||
pub trait AsProxyResult<T> {
|
||||
fn as_proxy(self) -> Result<T, ProxyError>;
|
||||
}
|
||||
|
||||
impl AsProxyError for ProtocolError {
|
||||
fn as_proxy(self) -> ProxyError {
|
||||
ProxyError::ProtocolError(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> AsProxyResult<T> for Result<T, ProtocolError> {
|
||||
fn as_proxy(self) -> Result<T, ProxyError> {
|
||||
self.map_err(|o| o.as_proxy())
|
||||
}
|
||||
}
|
@ -1,252 +1,59 @@
|
||||
use super::{MeexProx, MeexProxMutex, PlayerMutex, ProxyServer};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use rust_mc_proto::Packet;
|
||||
use std::{
|
||||
error::Error,
|
||||
net::SocketAddr,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
pub enum ProxyEvent {
|
||||
/// client <- proxy <- server \
|
||||
/// | \
|
||||
/// RecvServerPacketEvent
|
||||
RecvServerPacketEvent {
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
},
|
||||
|
||||
/// client -> proxy -> server \
|
||||
/// | \
|
||||
/// SendServerPacketEvent
|
||||
SendServerPacketEvent {
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
cancel: AtomicBool,
|
||||
},
|
||||
|
||||
/// client <- proxy <- server \
|
||||
/// | \
|
||||
/// SendClientPacketEvent
|
||||
SendClientPacketEvent {
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
cancel: AtomicBool,
|
||||
},
|
||||
|
||||
/// client -> proxy -> server \
|
||||
/// | \
|
||||
/// RecvClientPacketEvent
|
||||
RecvClientPacketEvent {
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
},
|
||||
|
||||
PlayerConnectedEvent {
|
||||
player: PlayerMutex,
|
||||
},
|
||||
|
||||
PlayerDisconnectedEvent {
|
||||
player: PlayerMutex,
|
||||
},
|
||||
|
||||
PlayerConnectingServerEvent {
|
||||
player: PlayerMutex,
|
||||
server: ProxyServer,
|
||||
cancel: AtomicBool,
|
||||
},
|
||||
|
||||
PlayerConnectingIPEvent {
|
||||
player: PlayerMutex,
|
||||
ip: String,
|
||||
cancel: AtomicBool,
|
||||
},
|
||||
|
||||
StatusRequestEvent {
|
||||
status: String,
|
||||
client_address: SocketAddr,
|
||||
server_address: String,
|
||||
server_port: u16,
|
||||
cancel: AtomicBool,
|
||||
},
|
||||
}
|
||||
|
||||
impl ProxyEvent {
|
||||
pub fn status_request(
|
||||
meexprox: MeexProxMutex,
|
||||
status: String,
|
||||
client_address: SocketAddr,
|
||||
server_address: String,
|
||||
server_port: u16,
|
||||
) -> (String, bool) {
|
||||
let ProxyEvent::StatusRequestEvent {
|
||||
status,
|
||||
client_address: _,
|
||||
server_address: _,
|
||||
server_port: _,
|
||||
cancel,
|
||||
} = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::StatusRequestEvent {
|
||||
status: status.clone(),
|
||||
client_address,
|
||||
server_address,
|
||||
server_port,
|
||||
cancel: AtomicBool::from(false),
|
||||
},
|
||||
)
|
||||
else {
|
||||
return (status, false);
|
||||
};
|
||||
(status, cancel.load(Ordering::Relaxed))
|
||||
}
|
||||
|
||||
pub fn player_connecting_ip(
|
||||
meexprox: MeexProxMutex,
|
||||
player: PlayerMutex,
|
||||
ip: String,
|
||||
) -> (String, bool) {
|
||||
let ProxyEvent::PlayerConnectingIPEvent {
|
||||
ip,
|
||||
player: _,
|
||||
cancel,
|
||||
} = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::PlayerConnectingIPEvent {
|
||||
ip: ip.clone(),
|
||||
player,
|
||||
cancel: AtomicBool::from(false),
|
||||
},
|
||||
)
|
||||
else {
|
||||
return (ip, false);
|
||||
};
|
||||
(ip, cancel.load(Ordering::Relaxed))
|
||||
}
|
||||
|
||||
pub fn player_connecting_server(
|
||||
meexprox: MeexProxMutex,
|
||||
player: PlayerMutex,
|
||||
server: ProxyServer,
|
||||
) -> (ProxyServer, bool) {
|
||||
let ProxyEvent::PlayerConnectingServerEvent {
|
||||
server,
|
||||
player: _,
|
||||
cancel,
|
||||
} = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::PlayerConnectingServerEvent {
|
||||
server: server.clone(),
|
||||
player,
|
||||
cancel: AtomicBool::from(false),
|
||||
},
|
||||
)
|
||||
else {
|
||||
return (server, false);
|
||||
};
|
||||
(server, cancel.load(Ordering::Relaxed))
|
||||
}
|
||||
|
||||
pub fn player_disconnected(meexprox: MeexProxMutex, player: PlayerMutex) -> () {
|
||||
let ProxyEvent::PlayerDisconnectedEvent { player: _ } =
|
||||
MeexProx::trigger_event(meexprox, ProxyEvent::PlayerDisconnectedEvent { player })
|
||||
else {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn player_connected(meexprox: MeexProxMutex, player: PlayerMutex) -> () {
|
||||
let ProxyEvent::PlayerConnectedEvent { player: _ } =
|
||||
MeexProx::trigger_event(meexprox, ProxyEvent::PlayerConnectedEvent { player })
|
||||
else {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn send_client_packet(
|
||||
meexprox: MeexProxMutex,
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
) -> (Packet, bool) {
|
||||
let ProxyEvent::SendClientPacketEvent {
|
||||
packet,
|
||||
player: _,
|
||||
cancel,
|
||||
} = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::SendClientPacketEvent {
|
||||
packet: packet.clone(),
|
||||
player,
|
||||
cancel: AtomicBool::from(false),
|
||||
},
|
||||
)
|
||||
else {
|
||||
return (packet, false);
|
||||
};
|
||||
(packet, cancel.load(Ordering::Relaxed))
|
||||
}
|
||||
|
||||
pub fn send_server_packet(
|
||||
meexprox: MeexProxMutex,
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
) -> (Packet, bool) {
|
||||
let ProxyEvent::SendServerPacketEvent {
|
||||
packet,
|
||||
player: _,
|
||||
cancel,
|
||||
} = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::SendServerPacketEvent {
|
||||
packet: packet.clone(),
|
||||
player,
|
||||
cancel: AtomicBool::from(false),
|
||||
},
|
||||
)
|
||||
else {
|
||||
return (packet, false);
|
||||
};
|
||||
(packet, cancel.load(Ordering::Relaxed))
|
||||
}
|
||||
|
||||
pub fn recv_server_packet(
|
||||
meexprox: MeexProxMutex,
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
) -> Packet {
|
||||
let ProxyEvent::RecvServerPacketEvent { packet, player: _ } = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::RecvServerPacketEvent {
|
||||
packet: packet.clone(),
|
||||
player,
|
||||
},
|
||||
) else {
|
||||
return packet;
|
||||
};
|
||||
packet
|
||||
}
|
||||
|
||||
pub fn recv_client_packet(
|
||||
meexprox: MeexProxMutex,
|
||||
packet: Packet,
|
||||
player: PlayerMutex,
|
||||
) -> Packet {
|
||||
let ProxyEvent::RecvClientPacketEvent { packet, player: _ } = MeexProx::trigger_event(
|
||||
meexprox,
|
||||
ProxyEvent::RecvClientPacketEvent {
|
||||
packet: packet.clone(),
|
||||
player,
|
||||
},
|
||||
) else {
|
||||
return packet;
|
||||
};
|
||||
packet
|
||||
}
|
||||
}
|
||||
use super::{config::ServerInfo, connection::Player, error::ProxyError};
|
||||
|
||||
pub trait EventListener {
|
||||
fn on_event(
|
||||
&mut self,
|
||||
meexprox: MeexProxMutex,
|
||||
event: &mut ProxyEvent,
|
||||
) -> Result<(), Box<dyn Error>>;
|
||||
fn on_server_recv_packet(
|
||||
&self,
|
||||
packet: &mut Packet,
|
||||
player: &Player,
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_server_send_packet(
|
||||
&self,
|
||||
packet: &mut Packet,
|
||||
cancel: &mut bool,
|
||||
player: &Player,
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_client_send_packet(
|
||||
&self,
|
||||
packet: &mut Packet,
|
||||
cancel: &mut bool,
|
||||
player: &Player,
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_client_recv_packet(
|
||||
&self,
|
||||
packet: &mut Packet,
|
||||
player: &Player,
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_player_connected(
|
||||
&self,
|
||||
player: &Player,
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_player_disconnected(
|
||||
&self,
|
||||
player: &Player,
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_player_connecting_server(
|
||||
&self,
|
||||
player: &Player,
|
||||
cancel: &mut bool,
|
||||
server: &mut ServerInfo
|
||||
) -> Result<(), ProxyError>;
|
||||
|
||||
fn on_status_request(
|
||||
&self,
|
||||
status: String,
|
||||
client_address: SocketAddr,
|
||||
server_address: String,
|
||||
server_port: u16,
|
||||
cancel: &mut bool,
|
||||
) -> Result<(), ProxyError>;
|
||||
}
|
@ -1,512 +1,74 @@
|
||||
use super::{EventListener, PlayerForwarding, ProxyConfig, ProxyError, ProxyEvent, ProxyServer};
|
||||
use derivative::Derivative;
|
||||
use log::{debug, info};
|
||||
use no_deadlocks::Mutex;
|
||||
use log::{error, info};
|
||||
// use no_deadlocks::Mutex;
|
||||
use rust_mc_proto::{
|
||||
DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError, Zigzag,
|
||||
read_packet, write_packet, DataBufferReader, DataBufferWriter, MCConnTcp, Packet
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
net::{SocketAddr, TcpListener, TcpStream},
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
},
|
||||
thread,
|
||||
Arc, RwLock, RwLockReadGuard
|
||||
}, thread,
|
||||
};
|
||||
use tokio::task::AbortHandle;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct ProxyPlayer {
|
||||
#[derivative(Debug = "ignore")]
|
||||
client_conn: MinecraftConnection<TcpStream>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
server_conn: MinecraftConnection<TcpStream>,
|
||||
connection_threads: Vec<AbortHandle>,
|
||||
name: Option<String>,
|
||||
uuid: Option<Uuid>,
|
||||
protocol_version: u16,
|
||||
server: Option<ProxyServer>,
|
||||
shared_secret: Option<Vec<u8>>,
|
||||
verify_token: Option<Vec<u8>>,
|
||||
}
|
||||
use super::{config::{PlayerForwarding, ProxyConfig}, connection::Player, error::{AsProxyResult, ProxyError}, event::EventListener};
|
||||
|
||||
impl ProxyPlayer {
|
||||
pub fn new(
|
||||
client_conn: MinecraftConnection<TcpStream>,
|
||||
server_conn: MinecraftConnection<TcpStream>,
|
||||
connection_threads: Vec<AbortHandle>,
|
||||
name: Option<String>,
|
||||
uuid: Option<Uuid>,
|
||||
protocol_version: u16,
|
||||
server: Option<ProxyServer>,
|
||||
shared_secret: Option<Vec<u8>>,
|
||||
verify_token: Option<Vec<u8>>,
|
||||
) -> ProxyPlayer {
|
||||
ProxyPlayer {
|
||||
client_conn,
|
||||
server_conn,
|
||||
name,
|
||||
uuid,
|
||||
protocol_version,
|
||||
server,
|
||||
shared_secret,
|
||||
verify_token,
|
||||
connection_threads,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client_conn(&self) -> &MinecraftConnection<TcpStream> {
|
||||
&self.client_conn
|
||||
}
|
||||
|
||||
pub fn server_conn(&self) -> &MinecraftConnection<TcpStream> {
|
||||
&self.server_conn
|
||||
}
|
||||
|
||||
pub fn client_conn_mut(&mut self) -> &mut MinecraftConnection<TcpStream> {
|
||||
&mut self.client_conn
|
||||
}
|
||||
|
||||
pub fn server_conn_mut(&mut self) -> &mut MinecraftConnection<TcpStream> {
|
||||
&mut self.server_conn
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<&String> {
|
||||
self.name.as_ref()
|
||||
}
|
||||
|
||||
pub fn uuid(&self) -> Option<&Uuid> {
|
||||
self.uuid.as_ref()
|
||||
}
|
||||
|
||||
pub fn protocol_version(&self) -> u16 {
|
||||
self.protocol_version
|
||||
}
|
||||
|
||||
pub fn server(&self) -> Option<&ProxyServer> {
|
||||
self.server.as_ref()
|
||||
}
|
||||
|
||||
pub fn shared_secret(&self) -> Option<&Vec<u8>> {
|
||||
self.shared_secret.as_ref()
|
||||
}
|
||||
|
||||
pub fn verify_token(&self) -> Option<&Vec<u8>> {
|
||||
self.verify_token.as_ref()
|
||||
}
|
||||
|
||||
pub fn connection_threads(&mut self) -> &mut Vec<AbortHandle> {
|
||||
&mut self.connection_threads
|
||||
}
|
||||
|
||||
pub fn connect_to_ip(
|
||||
this: PlayerMutex,
|
||||
meexprox: MeexProxMutex,
|
||||
ip: &str,
|
||||
server_address: &str,
|
||||
server_port: u16,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let (ip, cancel) =
|
||||
ProxyEvent::player_connecting_ip(meexprox.clone(), this.clone(), ip.to_string());
|
||||
let ip = &ip;
|
||||
|
||||
if cancel {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for thread in &mut this.lock().unwrap().connection_threads {
|
||||
thread.abort();
|
||||
}
|
||||
|
||||
this.lock().unwrap().server_conn.close();
|
||||
this.lock().unwrap().server_conn = MinecraftConnection::connect(ip)?;
|
||||
|
||||
thread::spawn({
|
||||
let player_forwarding = meexprox.lock().unwrap().config.player_forwarding().clone();
|
||||
let server_address = server_address.to_string();
|
||||
|
||||
move || {
|
||||
let _ = ProxyPlayer::connect(
|
||||
this,
|
||||
meexprox,
|
||||
player_forwarding,
|
||||
&server_address,
|
||||
server_port,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn connect_to_server(
|
||||
this: PlayerMutex,
|
||||
meexprox: MeexProxMutex,
|
||||
server: ProxyServer,
|
||||
server_address: &str,
|
||||
server_port: u16,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let (server, cancel) =
|
||||
ProxyEvent::player_connecting_server(meexprox.clone(), this.clone(), server);
|
||||
|
||||
if cancel {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for thread in &mut this.lock().unwrap().connection_threads {
|
||||
thread.abort();
|
||||
}
|
||||
this.lock().unwrap().server_conn.close();
|
||||
|
||||
this.lock().unwrap().server = Some(server.clone());
|
||||
this.lock().unwrap().server_conn = MinecraftConnection::connect(server.host())?;
|
||||
|
||||
thread::spawn({
|
||||
let player_forwarding = meexprox.lock().unwrap().config.player_forwarding().clone();
|
||||
let server_address = server_address.to_string();
|
||||
|
||||
move || {
|
||||
let _ = ProxyPlayer::connect(
|
||||
this,
|
||||
meexprox,
|
||||
player_forwarding,
|
||||
&server_address,
|
||||
server_port,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn reconnect(
|
||||
this: PlayerMutex,
|
||||
meexprox: MeexProxMutex,
|
||||
server_address: &str,
|
||||
server_port: u16,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
for thread in &mut this.lock().unwrap().connection_threads {
|
||||
thread.abort();
|
||||
}
|
||||
this.lock().unwrap().server_conn.close();
|
||||
|
||||
let server_host = this.lock().unwrap().server().unwrap().host().to_string();
|
||||
this.lock().unwrap().server_conn = MinecraftConnection::connect(&server_host)?;
|
||||
|
||||
thread::spawn({
|
||||
let player_forwarding = meexprox.lock().unwrap().config.player_forwarding().clone();
|
||||
let server_address = server_address.to_string();
|
||||
|
||||
move || {
|
||||
let _ = ProxyPlayer::connect(
|
||||
this,
|
||||
meexprox,
|
||||
player_forwarding,
|
||||
&server_address,
|
||||
server_port,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_handshake(
|
||||
this: PlayerMutex,
|
||||
meexprox: MeexProxMutex,
|
||||
player_forwarding: PlayerForwarding,
|
||||
addr: SocketAddr,
|
||||
server_address: &str,
|
||||
server_port: u16,
|
||||
) -> Result<(), ProtocolError> {
|
||||
let protocol_version = this.lock().unwrap().protocol_version;
|
||||
|
||||
let packet = Packet::build(0x00, move |packet| {
|
||||
packet.write_u16_varint(protocol_version)?;
|
||||
packet.write_string(&server_address)?;
|
||||
packet.write_unsigned_short(server_port)?;
|
||||
packet.write_u8_varint(2)?;
|
||||
|
||||
if let PlayerForwarding::Handshake = player_forwarding {
|
||||
if let SocketAddr::V4(addr) = addr {
|
||||
packet.write_boolean(false)?; // is ipv6
|
||||
packet.write_unsigned_short(addr.port())?; // port
|
||||
packet.write_bytes(&addr.ip().octets())?; // octets
|
||||
} else if let SocketAddr::V6(addr) = addr {
|
||||
packet.write_boolean(true)?;
|
||||
packet.write_unsigned_short(addr.port())?;
|
||||
packet.write_bytes(&addr.ip().octets())?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let (packet, cancel) = ProxyEvent::send_server_packet(meexprox, packet, this.clone());
|
||||
|
||||
if !cancel {
|
||||
this.lock().unwrap().server_conn.write_packet(&packet)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_login(this: PlayerMutex, meexprox: MeexProxMutex) -> Result<(), ProtocolError> {
|
||||
if let Some(player_name) = this.lock().unwrap().name.as_ref() {
|
||||
if let Some(player_uuid) = this.lock().unwrap().uuid.as_ref() {
|
||||
let packet = Packet::build(0x00, move |packet| {
|
||||
packet.write_string(&player_name)?;
|
||||
packet.write_uuid(&player_uuid)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let (packet, cancel) =
|
||||
ProxyEvent::send_server_packet(meexprox, packet, this.clone());
|
||||
|
||||
if !cancel {
|
||||
this.lock().unwrap().server_conn.write_packet(&packet)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn connect(
|
||||
this: PlayerMutex,
|
||||
meexprox: MeexProxMutex,
|
||||
player_forwarding: PlayerForwarding,
|
||||
server_address: &str,
|
||||
server_port: u16,
|
||||
logged: bool,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut client_conn = this.lock().unwrap().client_conn.try_clone().unwrap();
|
||||
let mut server_conn = this.lock().unwrap().server_conn.try_clone().unwrap();
|
||||
|
||||
let addr = client_conn.get_ref().peer_addr().unwrap();
|
||||
let Some(name) = this.lock().unwrap().name.clone() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if !logged {
|
||||
ProxyPlayer::send_handshake(
|
||||
this.clone(),
|
||||
meexprox.clone(),
|
||||
player_forwarding,
|
||||
addr,
|
||||
server_address,
|
||||
server_port,
|
||||
)?;
|
||||
|
||||
ProxyPlayer::send_login(this.clone(), meexprox.clone())?;
|
||||
|
||||
while let Ok(mut packet) = server_conn.read_packet() {
|
||||
if packet.id() == 0x01 {
|
||||
if let Some(shared_secret) = this.lock().unwrap().shared_secret.clone() {
|
||||
if let Some(verify_token) = this.lock().unwrap().verify_token.clone() {
|
||||
let mut enc_response = Packet::empty(0x01);
|
||||
|
||||
enc_response.write_usize_varint(shared_secret.len())?;
|
||||
enc_response.write_bytes(&shared_secret)?;
|
||||
enc_response.write_usize_varint(shared_secret.len())?;
|
||||
enc_response.write_bytes(&verify_token)?;
|
||||
|
||||
let (enc_response, cancel) = ProxyEvent::send_server_packet(
|
||||
meexprox.clone(),
|
||||
enc_response,
|
||||
this.clone(),
|
||||
);
|
||||
|
||||
if !cancel {
|
||||
server_conn.write_packet(&enc_response)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if packet.id() == 0x03 {
|
||||
let threshold = packet.read_isize_varint()?;
|
||||
if threshold >= 0 {
|
||||
let threshold = threshold.zigzag();
|
||||
|
||||
server_conn.set_compression(Some(threshold));
|
||||
client_conn.set_compression(Some(threshold));
|
||||
} else {
|
||||
server_conn.set_compression(None);
|
||||
client_conn.set_compression(None);
|
||||
}
|
||||
}
|
||||
|
||||
if packet.id() == 0x02 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let login_ack = Packet::empty(0x03);
|
||||
|
||||
let (login_ack, cancel) =
|
||||
ProxyEvent::send_server_packet(meexprox.clone(), login_ack, this.clone());
|
||||
|
||||
if !cancel {
|
||||
server_conn.write_packet(&login_ack)?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut handles = Vec::new();
|
||||
|
||||
handles.push(
|
||||
tokio::spawn({
|
||||
let mut client_conn = client_conn.try_clone().unwrap();
|
||||
let mut server_conn = server_conn.try_clone().unwrap();
|
||||
|
||||
let this = this.clone();
|
||||
let meexprox = meexprox.clone();
|
||||
let name = name.clone();
|
||||
let addr = addr.clone();
|
||||
|
||||
async move {
|
||||
while let Ok(packet) = client_conn.read_packet() {
|
||||
let packet =
|
||||
ProxyEvent::recv_client_packet(meexprox.clone(), packet, this.clone());
|
||||
|
||||
let (packet, cancel) =
|
||||
ProxyEvent::send_server_packet(meexprox.clone(), packet, this.clone());
|
||||
|
||||
if !cancel {
|
||||
match server_conn.write_packet(&packet) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if meexprox.lock().unwrap().remove_player(this.clone()) {
|
||||
info!("{} disconnected player {}", addr.to_string(), name);
|
||||
ProxyEvent::player_disconnected(meexprox.clone(), this.clone());
|
||||
}
|
||||
}
|
||||
})
|
||||
.abort_handle(),
|
||||
);
|
||||
|
||||
handles.push(
|
||||
tokio::spawn({
|
||||
let this = this.clone();
|
||||
|
||||
async move {
|
||||
while let Ok(packet) = server_conn.read_packet() {
|
||||
let packet =
|
||||
ProxyEvent::recv_server_packet(meexprox.clone(), packet, this.clone());
|
||||
|
||||
let (packet, cancel) =
|
||||
ProxyEvent::send_client_packet(meexprox.clone(), packet, this.clone());
|
||||
|
||||
if !cancel {
|
||||
match client_conn.write_packet(&packet) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if meexprox.lock().unwrap().remove_player(this.clone()) {
|
||||
info!("{} disconnected player {}", addr.to_string(), name);
|
||||
ProxyEvent::player_disconnected(meexprox.clone(), this.clone());
|
||||
}
|
||||
}
|
||||
})
|
||||
.abort_handle(),
|
||||
);
|
||||
|
||||
this.lock().unwrap().connection_threads = handles;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MeexProx {
|
||||
config: ProxyConfig,
|
||||
players: Vec<PlayerMutex>,
|
||||
event_listeners: Vec<Box<dyn EventListener + Send + Sync>>,
|
||||
players: RwLock<Vec<Player>>,
|
||||
event_listeners: Vec<Box<dyn EventListener + Send + Sync>>
|
||||
}
|
||||
|
||||
impl MeexProx {
|
||||
pub fn new(config: ProxyConfig) -> MeexProx {
|
||||
MeexProx {
|
||||
config,
|
||||
players: Vec::new(),
|
||||
players: RwLock::new(Vec::new()),
|
||||
event_listeners: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_event_listener(&mut self, event_listener: Box<dyn EventListener + Send + Sync>) {
|
||||
pub fn add_event_listener(
|
||||
&mut self,
|
||||
event_listener: Box<dyn EventListener + Send + Sync>,
|
||||
) {
|
||||
self.event_listeners.push(event_listener);
|
||||
}
|
||||
|
||||
pub fn trigger_event(this: MeexProxMutex, mut event: ProxyEvent) -> ProxyEvent {
|
||||
for event_listener in &mut this.lock().unwrap().event_listeners {
|
||||
let _ = event_listener.on_event(this.clone(), &mut event);
|
||||
pub fn trigger_event(
|
||||
&self,
|
||||
trigger: fn(&dyn EventListener) -> Result<(), ProxyError>
|
||||
) -> Result<(), ProxyError> {
|
||||
for event_listener in &self.event_listeners {
|
||||
trigger(event_listener.as_ref())?
|
||||
}
|
||||
event
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_player(&self, uuid: Uuid) -> Option<PlayerMutex> {
|
||||
for player in &self.players {
|
||||
if let Some(player_uuid) = player.lock().unwrap().uuid {
|
||||
if player_uuid == uuid {
|
||||
return Some(player.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
pub async fn get_players(&self) -> RwLockReadGuard<'_, Vec<Player>> {
|
||||
self.players.read().unwrap()
|
||||
}
|
||||
|
||||
pub fn remove_player(&mut self, player: PlayerMutex) -> bool {
|
||||
match self.players.iter().position(|x| Arc::ptr_eq(x, &player)) {
|
||||
Some(i) => {
|
||||
self.players.remove(i);
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
pub fn accept_client(&self, mut client_conn: TcpStream) -> Result<(), ProxyError> {
|
||||
let addr = client_conn.peer_addr().map_err(|_| ProxyError::PeerAddr)?;
|
||||
|
||||
pub fn accept_client(this: MeexProxMutex, stream: TcpStream) -> Result<(), Box<dyn Error>> {
|
||||
let Ok(addr) = stream.peer_addr() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let server_config = this.lock().unwrap().config.clone();
|
||||
|
||||
let mut client_conn = MinecraftConnection::new(stream);
|
||||
|
||||
let mut handshake = client_conn.read_packet()?;
|
||||
let mut handshake = read_packet(&mut client_conn, None).as_proxy()?;
|
||||
|
||||
if handshake.id() != 0x00 {
|
||||
return Ok(());
|
||||
return Err(ProxyError::HandshakePacket);
|
||||
}
|
||||
|
||||
let protocol_version = handshake.read_u16_varint()?;
|
||||
let server_address = handshake.read_string()?;
|
||||
let server_port = handshake.read_unsigned_short()?;
|
||||
let next_state = handshake.read_u8_varint()?;
|
||||
let protocol_version = handshake.read_u16_varint().as_proxy()?;
|
||||
let server_address = handshake.read_string().as_proxy()?;
|
||||
let server_port = handshake.read_unsigned_short().as_proxy()?;
|
||||
let next_state = handshake.read_u8_varint().as_proxy()?;
|
||||
|
||||
let server = server_config
|
||||
let server = self.config
|
||||
.get_server_by_forced_host(&server_address)
|
||||
.or(server_config.default_server().cloned())
|
||||
.or(self.config.default_server.clone())
|
||||
.ok_or(ProxyError::ConfigParse)?;
|
||||
|
||||
let mut server_conn = MinecraftConnection::connect(&server.host())?;
|
||||
let mut server_conn = TcpStream::connect(&server.host).map_err(|_| ProxyError::ServerConnect)?;
|
||||
|
||||
let handshake = Packet::build(0x00, |handshake| {
|
||||
handshake.write_u16_varint(protocol_version)?;
|
||||
@ -514,7 +76,7 @@ impl MeexProx {
|
||||
handshake.write_unsigned_short(server_port)?;
|
||||
handshake.write_u8_varint(next_state)?;
|
||||
|
||||
if let PlayerForwarding::Handshake = server_config.player_forwarding() {
|
||||
if let PlayerForwarding::Handshake = self.config.player_forwarding {
|
||||
if let SocketAddr::V4(addr) = addr {
|
||||
handshake.write_boolean(false)?; // is ipv6
|
||||
handshake.write_unsigned_short(addr.port())?; // port
|
||||
@ -527,148 +89,47 @@ impl MeexProx {
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
}).as_proxy()?;
|
||||
|
||||
server_conn.write_packet(&handshake)?;
|
||||
write_packet(&mut server_conn, None, 0, &handshake).as_proxy()?;
|
||||
|
||||
let mut client_conn = MCConnTcp::new(client_conn);
|
||||
let mut server_conn = MCConnTcp::new(server_conn);
|
||||
|
||||
if next_state == 1 {
|
||||
loop {
|
||||
let client_packet = client_conn.read_packet()?;
|
||||
|
||||
server_conn.write_packet(&client_packet)?;
|
||||
|
||||
let mut server_packet = server_conn.read_packet()?;
|
||||
|
||||
if client_packet.id() == 0x00 {
|
||||
let server_status = server_packet.read_string()?;
|
||||
|
||||
let (status, cancel) = ProxyEvent::status_request(
|
||||
this.clone(),
|
||||
server_status.clone(),
|
||||
addr.clone(),
|
||||
server_address.clone(),
|
||||
server_port,
|
||||
);
|
||||
|
||||
if cancel {
|
||||
break;
|
||||
}
|
||||
|
||||
server_packet = Packet::build(0x00, |p| p.write_string(&status))?;
|
||||
}
|
||||
|
||||
client_conn.write_packet(&server_packet)?;
|
||||
server_conn.write_packet(&client_conn.read_packet().as_proxy()?).as_proxy()?;
|
||||
client_conn.write_packet(&server_conn.read_packet().as_proxy()?).as_proxy()?;
|
||||
}
|
||||
} else if next_state == 2 {
|
||||
let player = Arc::new(Mutex::new(ProxyPlayer::new(
|
||||
client_conn.try_clone().unwrap(),
|
||||
server_conn.try_clone().unwrap(),
|
||||
Vec::new(),
|
||||
None,
|
||||
None,
|
||||
self.players.write().unwrap().push(Player::read(
|
||||
protocol_version,
|
||||
Some(server.clone()),
|
||||
None,
|
||||
None,
|
||||
)));
|
||||
|
||||
let (server, cancel) =
|
||||
ProxyEvent::player_connecting_server(this.clone(), player.clone(), server.clone());
|
||||
|
||||
if cancel {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
player.lock().unwrap().server = Some(server);
|
||||
|
||||
this.lock().unwrap().players.push(player.clone());
|
||||
|
||||
let mut login_start = client_conn.read_packet()?;
|
||||
|
||||
player.lock().unwrap().name = Some(login_start.read_string()?);
|
||||
player.lock().unwrap().uuid = Some(login_start.read_uuid()?);
|
||||
|
||||
server_conn.write_packet(&login_start)?;
|
||||
|
||||
while let Ok(mut packet) = server_conn.read_packet() {
|
||||
client_conn.write_packet(&packet)?;
|
||||
|
||||
if packet.id() == 0x01 {
|
||||
let mut enc_response = client_conn.read_packet()?;
|
||||
|
||||
let shared_secret_length = enc_response.read_usize_varint()?;
|
||||
player.lock().unwrap().shared_secret =
|
||||
Some(enc_response.read_bytes(shared_secret_length)?);
|
||||
let verify_token_length = enc_response.read_usize_varint()?;
|
||||
player.lock().unwrap().verify_token =
|
||||
Some(enc_response.read_bytes(verify_token_length)?);
|
||||
|
||||
server_conn.write_packet(&enc_response)?;
|
||||
}
|
||||
|
||||
if packet.id() == 0x03 {
|
||||
let threshold = packet.read_isize_varint()?;
|
||||
|
||||
if threshold >= 0 {
|
||||
let threshold = threshold.zigzag();
|
||||
|
||||
server_conn.set_compression(Some(threshold));
|
||||
client_conn.set_compression(Some(threshold));
|
||||
} else {
|
||||
server_conn.set_compression(None);
|
||||
client_conn.set_compression(None);
|
||||
}
|
||||
}
|
||||
|
||||
if packet.id() == 0x02 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// println!("lac re");
|
||||
// let login_ack = client_conn.read_packet()?;
|
||||
// println!("lac {}", login_ack.id());
|
||||
// if login_ack.id() != 0x03 {
|
||||
// return Ok(());
|
||||
// }
|
||||
|
||||
let this = this.clone();
|
||||
|
||||
info!(
|
||||
"{} connected player {}",
|
||||
addr.to_string(),
|
||||
player.lock().unwrap().name.clone().unwrap()
|
||||
);
|
||||
ProxyEvent::player_connected(this.clone(), player.clone());
|
||||
|
||||
let _ = ProxyPlayer::connect(
|
||||
player,
|
||||
this,
|
||||
server_config.player_forwarding().clone(),
|
||||
&server_address,
|
||||
server_address,
|
||||
server_port,
|
||||
true,
|
||||
);
|
||||
server,
|
||||
client_conn,
|
||||
server_conn
|
||||
)?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn start(self) {
|
||||
let listener = TcpListener::bind(self.config.host()).expect("invalid host");
|
||||
let listener = TcpListener::bind(&self.config.host).expect("invalid host");
|
||||
|
||||
info!("meexprox started on {}", self.config.host());
|
||||
info!("meexprox started on {}", &self.config.host);
|
||||
|
||||
let mutex_self = Arc::new(Mutex::new(self));
|
||||
let self_arc = Arc::new(self);
|
||||
|
||||
for client in listener.incoming() {
|
||||
if let Ok(client) = client {
|
||||
let mutex_self_clone = mutex_self.clone();
|
||||
let self_arc = self_arc.clone();
|
||||
thread::spawn(move || {
|
||||
match Self::accept_client(mutex_self_clone, client) {
|
||||
match self_arc.accept_client(client) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
// error!("connection error: {:?}", e);
|
||||
Err(e) => {
|
||||
error!("connection error: {:?}", e);
|
||||
}
|
||||
};
|
||||
});
|
||||
@ -676,6 +137,3 @@ impl MeexProx {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type PlayerMutex = Arc<Mutex<ProxyPlayer>>;
|
||||
pub type MeexProxMutex = Arc<Mutex<MeexProx>>;
|
||||
|
@ -2,8 +2,6 @@ pub mod config;
|
||||
pub mod error;
|
||||
pub mod event;
|
||||
pub mod meexprox;
|
||||
pub mod connection;
|
||||
|
||||
pub use config::*;
|
||||
pub use error::*;
|
||||
pub use event::*;
|
||||
pub use meexprox::*;
|
||||
|
Loading…
Reference in New Issue
Block a user