mirror of
https://github.com/mbround18/valheim-docker.git
synced 2021-10-22 21:53:54 +03:00
* Added nexus mods and downloader * Mod downloader ready * Modified to follow redirect information * Slimmed down env * Running with type message fix * dynamic fetch of latest bepinex version * Refactored file * Changes * Dont use barrow * Added support for downloading dll and cfg * Added exit for non zip file
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
.github/
|
||||
.idea/
|
||||
.run/
|
||||
target/
|
||||
tmp/
|
||||
docs/
|
||||
.github/
|
||||
|
||||
|
||||
261
Cargo.lock
generated
261
Cargo.lock
generated
@@ -1,10 +1,10 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
@@ -47,12 +47,39 @@ version = "3.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
|
||||
dependencies = [
|
||||
"bzip2-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bzip2-sys"
|
||||
version = "0.1.10+1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-husky"
|
||||
version = "1.5.0"
|
||||
@@ -65,6 +92,12 @@ version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@@ -129,7 +162,7 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -154,7 +187,7 @@ version = "0.8.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -163,7 +196,7 @@ version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"winapi",
|
||||
@@ -171,11 +204,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.20"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
|
||||
checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
@@ -198,31 +231,37 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.12"
|
||||
name = "fs_extra"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
|
||||
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
|
||||
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
|
||||
checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd"
|
||||
checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
@@ -232,24 +271,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
|
||||
checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
|
||||
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
@@ -269,16 +305,16 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b67e66362108efccd8ac053abafc8b7a8d86a37e6e48fc4f6f7485eb5e9e6a5"
|
||||
checksum = "d832b01df74254fe364568d6ddc294443f61cbec82816b60904303af87efae78"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
@@ -291,7 +327,6 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -403,9 +438,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.1"
|
||||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
|
||||
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
@@ -423,7 +458,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -440,9 +475,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.47"
|
||||
version = "0.3.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65"
|
||||
checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -455,9 +490,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.86"
|
||||
version = "0.2.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
|
||||
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
@@ -480,7 +515,7 @@ version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -489,6 +524,12 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
@@ -503,19 +544,18 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.3"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
|
||||
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.8"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc250d6848c90d719ea2ce34546fb5df7af1d3fd189d10bf7bad80bfcebecd95"
|
||||
checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@@ -574,15 +614,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "odin"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"chrono",
|
||||
"clap",
|
||||
"daemonize",
|
||||
"flate2",
|
||||
"fs_extra",
|
||||
"inflections",
|
||||
"log",
|
||||
"md5",
|
||||
"once_cell",
|
||||
"rand",
|
||||
"reqwest",
|
||||
@@ -592,13 +634,14 @@ dependencies = [
|
||||
"sysinfo",
|
||||
"tar",
|
||||
"which",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.7.0"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a"
|
||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
@@ -623,7 +666,7 @@ version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
@@ -659,9 +702,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.4"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
|
||||
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
@@ -669,6 +712,12 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
@@ -780,9 +829,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34"
|
||||
checksum = "bf12057f289428dbf5c591c74bf10392e4a8003f993405a902f20117019022d4"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -866,18 +915,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.123"
|
||||
version = "1.0.124"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
|
||||
checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.123"
|
||||
version = "1.0.124"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
|
||||
checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -886,9 +935,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.62"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -947,7 +996,7 @@ version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
@@ -966,9 +1015,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.60"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
|
||||
checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -977,11 +1026,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.16.2"
|
||||
version = "0.16.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a474f92030c61f32a21f4b3370c6f25c710e55b2ea9e64dd9ed4f1cd5e734d9b"
|
||||
checksum = "6c280c91abd1aed2e36be1bc8f56fbc7a2acbb2b58fbcac9641510179cc72dd9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"core-foundation-sys",
|
||||
"doc-comment",
|
||||
"libc",
|
||||
@@ -992,9 +1041,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.32"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0313546c01d59e29be4f09687bcb4fb6690cec931cc3607b6aec7a0e417f4cc6"
|
||||
checksum = "c0bcfbd6a598361fda270d82469fff3d65089dc33e175c9a131f7b4cd395f228"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
@@ -1021,18 +1070,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
|
||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
|
||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1066,9 +1115,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a"
|
||||
checksum = "8d56477f6ed99e10225f38f9f75f872f29b8b8bd8c0b946f63345bb144e9eeda"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
@@ -1092,9 +1141,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.3"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b"
|
||||
checksum = "ec31e5cc6b46e653cf57762f36f71d5e6386391d88a72fd6db4508f8f676fb29"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
@@ -1112,11 +1161,11 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.24"
|
||||
version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f77d3842f76ca899ff2dbcf231c5c65813dea431301d6eb686279c15c4464f12"
|
||||
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
@@ -1130,16 +1179,6 @@ dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-futures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"pin-project",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.3"
|
||||
@@ -1230,11 +1269,11 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.70"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
|
||||
checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -1242,9 +1281,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.70"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7"
|
||||
checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@@ -1257,11 +1296,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.20"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3de431a2910c86679c34283a33f66f4e4abd7e0aec27b6669060148872aadf94"
|
||||
checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
@@ -1269,9 +1308,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.70"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c"
|
||||
checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -1279,9 +1318,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.70"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385"
|
||||
checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1292,15 +1331,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.70"
|
||||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
|
||||
checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.47"
|
||||
version = "0.3.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3"
|
||||
checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -1392,3 +1431,17 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bzip2",
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"thiserror",
|
||||
"time",
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "odin"
|
||||
version = "1.3.0"
|
||||
authors = ["mbround18 <12646562+mbround18@users.noreply.github.com>"]
|
||||
version = "1.4.0"
|
||||
authors = ["mbround18"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -19,6 +19,10 @@ flate2 = "1.0"
|
||||
inflections = "1.1.1"
|
||||
reqwest = { version = "0.11.1", default_features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||
chrono = "0.4"
|
||||
md5 = "0.7.0"
|
||||
zip = { version = "0.5" }
|
||||
fs_extra = "1.2.0"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
once_cell = "1.7"
|
||||
|
||||
@@ -10,6 +10,7 @@ FROM mbround18/valheim-odin:${ODIN_IMAGE_VERSION} as runtime
|
||||
FROM cm2network/steamcmd:root
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y \
|
||||
htop net-tools nano gcc g++ gdb \
|
||||
netcat curl wget zip unzip \
|
||||
@@ -45,7 +46,12 @@ ENV PUID=1000 \
|
||||
AUTO_BACKUP_DAYS_TO_LIVE="3" \
|
||||
AUTO_BACKUP_ON_UPDATE="0" \
|
||||
AUTO_BACKUP_ON_SHUTDOWN="0" \
|
||||
UPDATE_ON_STARTUP="1"
|
||||
UPDATE_ON_STARTUP="1" \
|
||||
SAVE_LOCATION="/home/steam/.config/unity3d/IronGate/Valheim" \
|
||||
MODS_LOCATION="/home/steam/staging/mods" \
|
||||
GAME_LOCATION="/home/steam/valheim" \
|
||||
BACKUP_LOCATION="/home/steam/backups" \
|
||||
TYPE="Vanilla"
|
||||
|
||||
COPY ./src/scripts/*.sh /home/steam/scripts/
|
||||
COPY ./src/scripts/entrypoint.sh /entrypoint.sh
|
||||
|
||||
22
README.md
22
README.md
@@ -23,6 +23,18 @@
|
||||
> Modding is not supported by the Valheim developers officially yet; Which means you WILL run into errors. This repo has been tested with running ValheimPlus as a test mod and does not have any issues.
|
||||
> See [Getting started with mods]
|
||||
|
||||
### Download Locations
|
||||
|
||||
#### DockerHub
|
||||
|
||||
<a href="https://hub.docker.com/r/mbround18/valheim"><img alt="DockerHub Valheim" src="https://img.shields.io/badge/DockerHub-Valheim-blue?style=for-the-badge"></a>
|
||||
<a href="https://hub.docker.com/r/mbround18/valheim-odin"><img alt="DockerHub Odin" src="https://img.shields.io/badge/DockerHub-Odin-blue?style=for-the-badge"></a>
|
||||
|
||||
#### GitHub Container Registry
|
||||
|
||||
<a href="https://github.com/users/mbround18/packages/container/package/valheim"><img alt="GHCR Valheim" src="https://img.shields.io/badge/GHCR-Valheim-blue?style=for-the-badge"></a>
|
||||
<a href="https://github.com/users/mbround18/packages/container/package/valheim-odin"><img alt="GHCR Odin" src="https://img.shields.io/badge/GHCR-Odin-blue?style=for-the-badge"></a>
|
||||
|
||||
### Environment Variables
|
||||
|
||||
> See further on down for advanced environment variables.
|
||||
@@ -37,6 +49,8 @@
|
||||
| WORLD | `Dedicated` | TRUE | This is used to generate the name of your world. |
|
||||
| PUBLIC | `1` | FALSE | Sets whether or not your server is public on the server list. |
|
||||
| PASSWORD | `12345` | TRUE | Set this to something unique! |
|
||||
| TYPE | `Vanilla` | FALSE | This can be set to `ValheimPlus`, `BepInEx`, `BepInExFull` or `Vanilla` |
|
||||
| MODS | ` ` | FALSE | This is an array of mods separated by comma and a new line. [Click Here for Examples](./docs/getting_started_with_mods.md) Supported files are `zip`, `dll`, and `cfg`. |
|
||||
| AUTO_UPDATE | `0` | FALSE | Set to `1` if you want your container to auto update! This means at the times indicated by `AUTO_UPDATE_SCHEDULE` it will check for server updates. If there is an update then the server will be shut down, updated, and brought back online if the server was running before. |
|
||||
| AUTO_UPDATE_SCHEDULE | `0 1 * * *` | FALSE | This works in conjunction with `AUTO_UPDATE` and sets the schedule to which it will run an auto update. [If you need help figuring out a cron schedule click here]
|
||||
| AUTO_BACKUP | `0` | FALSE | Set to `1` to enable auto backups. Backups are stored under `/home/steam/backups` which means you will have to add a volume mount for this directory. |
|
||||
@@ -52,7 +66,7 @@
|
||||
|
||||
#### Simple
|
||||
|
||||
> This is a basic example of a docker compose, you can apply any of the variables above to the `environment` section below but be sure to follow each variables description notes!
|
||||
> This is a basic example of a docker compose, you can apply any of the variables above to the `environment` section below but be sure to follow each variables' description notes!
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
@@ -156,7 +170,9 @@ If you would like to have release notifications tied into your Discord server, c
|
||||
- latest (Stable):
|
||||
- [#100] Added backup feature to run based on cronjob.
|
||||
- [#148] Added Mod support
|
||||
- Added webhook configuration and documentation updates [#158]
|
||||
- [#158] Added webhook configuration and documentation updates
|
||||
- [#236] Now [publish to github registry as well](https://github.com/users/mbround18/packages/container/package/valheim)
|
||||
- [#276] Advanced mod support with auto installer
|
||||
- 1.2.0 (Stable):
|
||||
- Readme update to include the versions section and environment variables section.
|
||||
- [#18] Changed to `root` as the default user to allow updated steams User+Group IDs.
|
||||
@@ -183,6 +199,8 @@ If you would like to have release notifications tied into your Discord server, c
|
||||
- Has a bug in which it does not read passed in variables appropriately to Odin. Env variables are not impacted see [#3].
|
||||
|
||||
[//]: <> (Github Issues below...........)
|
||||
[#276]: https://github.com/mbround18/valheim-docker/pull/276
|
||||
[#236]: https://github.com/mbround18/valheim-docker/pull/236
|
||||
[#158]: https://github.com/mbround18/valheim-docker/pull/158
|
||||
[#148]: https://github.com/mbround18/valheim-docker/pull/148
|
||||
[#100]: https://github.com/mbround18/valheim-docker/pull/100
|
||||
|
||||
@@ -4,10 +4,36 @@
|
||||
|
||||
## Steps
|
||||
|
||||
1. Download the mod file, for our example we want the `UnixServer.zip` from `https://github.com/nxPublic/ValheimPlus/releases`
|
||||
2. Place the file in your server volume mount. `cp UnixServer.zip /home/youruser/valheim/server`
|
||||
3. Unzip the archive `unzip UnixServer.zip -d .` hit A to replace all as needed.
|
||||
4. Restart your server.
|
||||
1. Set the variable `TYPE` to be ONne of the following:
|
||||
|
||||
| Type | What it installs |
|
||||
|-------------|------------------|
|
||||
| Vanilla | Default value and the most common installation type. This will run Valheim normally. |
|
||||
| BepInEx | This will install [BepInEx from this package](https://valheim.thunderstore.io/package/denikson/BepInExPack_Valheim/) and is purely just BepInEx with minimally needed components. |
|
||||
| BepInExFull | This will install [BepInEx Full from this package](https://valheim.thunderstore.io/package/1F31A/BepInEx_Valheim_Full/) and contains a modern set of components with some extras for expanded mod compatibility. |
|
||||
| ValheimPlus | This will install [Valheim Plus from this repository](https://github.com/valheimPlus/ValheimPlus) and included BepInEx as a basic version with the most common set of components |
|
||||
|
||||
2. If you wish do not with to use additional mods, you can skip this step. Otherwise, in order to install additional mods you can use the `MODS` variable.
|
||||
|
||||
Example of MODS, this example is slimmed down to go over the `TYPE` and `MODS` variable.
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
valheim:
|
||||
image: mbround18/valheim:latest
|
||||
environment:
|
||||
# The Type variable is used to set which type of server you would like to run.
|
||||
- TYPE=ValheimPlus
|
||||
# The Mods variable is a comma and newline separated string.
|
||||
# It MUST be a link with a command and a new line at the end to be valid.
|
||||
- "MODS=
|
||||
https://cdn.thunderstore.io/live/repository/packages/abearcodes-SimpleRecycling-0.0.10.zip,
|
||||
https://cdn.thunderstore.io/live/repository/packages/abearcodes-CraftingWithContainers-1.0.9.zip
|
||||
"
|
||||
```
|
||||
|
||||
3. Now that you have your compose setup, run `docker-compose up`
|
||||
|
||||
> Odin automatically detects if you are running with BepInEx and adds the environment variables appropriately.
|
||||
>
|
||||
@@ -20,4 +46,5 @@
|
||||
## Valheim Updated Help!!!!
|
||||
|
||||
Mod development is slow, and the more mods you have the more complicated it will be to keep everything up to date.
|
||||
It is a suggestion that you turn off the AUTO_UPDATE variable when you are using mods and refrain from updating your local client until all your mods have been updated.
|
||||
It is a suggestion that you turn off the AUTO_UPDATE variable when you are using mods and refrain from updating your local client until all your mods have been updated.
|
||||
Some mods break on new updates of Valheim while others do not. Be on the look out for mod issues if you update your server.
|
||||
|
||||
13
src/cli.yaml
13
src/cli.yaml
@@ -83,6 +83,8 @@ subcommands:
|
||||
required: true
|
||||
index: 2
|
||||
- update:
|
||||
version: "1.0"
|
||||
author: LovecraftianHorror
|
||||
about: >
|
||||
Attempts to update an existing Valheim server installation. By
|
||||
default this involves checking for an update, if an update is
|
||||
@@ -118,3 +120,14 @@ subcommands:
|
||||
value_name: WEBHOOK_URL
|
||||
about: Sets the webhook to send a notification to, (Can be set with ENV variable WEBHOOK_URL)
|
||||
takes_value: true
|
||||
- mod:install:
|
||||
about: >
|
||||
Installs a mod from a given source by downloading the zip file and then extracting it.
|
||||
Supported platforms are Nexus (with premium account and API key), GitHub, and any other direct download source.
|
||||
version: "1.0"
|
||||
author: mbround18
|
||||
args:
|
||||
- URL:
|
||||
about: Url of the mod to download and install
|
||||
required: true
|
||||
index: 1
|
||||
|
||||
18
src/commands/install_mod.rs
Normal file
18
src/commands/install_mod.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
use crate::mods::ValheimMod;
|
||||
use clap::ArgMatches;
|
||||
use log::{debug, error, info};
|
||||
use std::process::exit;
|
||||
|
||||
pub fn invoke(args: &ArgMatches) {
|
||||
let mut valheim_mod = ValheimMod::new(args.value_of("URL").unwrap());
|
||||
info!("Installing {}", valheim_mod.url);
|
||||
debug!("Mod URL: {}", valheim_mod.url);
|
||||
debug!("Mod staging location: {}", valheim_mod.staging_location);
|
||||
match valheim_mod.download() {
|
||||
Ok(_) => valheim_mod.install(),
|
||||
Err(message) => {
|
||||
error!("{}", message);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod backup;
|
||||
pub mod configure;
|
||||
pub mod install;
|
||||
pub mod install_mod;
|
||||
pub mod notify;
|
||||
pub mod start;
|
||||
pub mod stop;
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
// Odin Specific
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const ODIN_WORKING_DIR: &str = "ODIN_WORKING_DIR";
|
||||
pub const SAVE_LOCATION: &str = "SAVE_LOCATION";
|
||||
pub const MODS_LOCATION: &str = "MODS_LOCATION";
|
||||
pub const GAME_LOCATION: &str = "GAME_LOCATION";
|
||||
// pub const BACKUP_LOCATION: &str = "BACKUP_LOCATION";
|
||||
|
||||
// Valheim
|
||||
pub const VALHEIM_EXECUTABLE_NAME: &str = "valheim_server.x86_64";
|
||||
pub const GAME_ID: i64 = 896660;
|
||||
|
||||
pub const VALHEIM_EXECUTABLE_NAME: &str = "valheim_server.x86_64";
|
||||
|
||||
// BePinEx
|
||||
pub const LD_LIBRARY_PATH_VAR: &str = "LD_LIBRARY_PATH";
|
||||
pub const LD_PRELOAD_VAR: &str = "LD_PRELOAD";
|
||||
pub const ODIN_WORKING_DIR: &str = "ODIN_WORKING_DIR";
|
||||
|
||||
// Mods
|
||||
pub const SUPPORTED_FILE_TYPES: &[&str] = &["zip", "dll", "cfg"];
|
||||
|
||||
63
src/main.rs
63
src/main.rs
@@ -1,4 +1,4 @@
|
||||
use clap::{load_yaml, App};
|
||||
use clap::{load_yaml, App, AppSettings};
|
||||
use log::{debug, info, LevelFilter, SetLoggerError};
|
||||
|
||||
use crate::executable::handle_exit_status;
|
||||
@@ -36,7 +36,9 @@ fn setup_logger(debug: bool) -> Result<(), SetLoggerError> {
|
||||
fn main() {
|
||||
// The YAML file is found relative to the current file, similar to how modules are found
|
||||
let yaml = load_yaml!("cli.yaml");
|
||||
let app = App::from(yaml).version(constants::VERSION);
|
||||
let app = App::from(yaml)
|
||||
.version(constants::VERSION)
|
||||
.setting(AppSettings::SubcommandRequired);
|
||||
let matches = app.get_matches();
|
||||
let debug_mode = matches.is_present("debug") || environment::fetch_var("DEBUG_MODE", "0").eq("1");
|
||||
setup_logger(debug_mode).unwrap();
|
||||
@@ -44,38 +46,31 @@ fn main() {
|
||||
info!("Run with DEBUG_MODE as 1 if you think there is an issue with Odin");
|
||||
}
|
||||
debug!("Debug mode enabled!");
|
||||
if let Some(ref configure_matches) = matches.subcommand_matches("configure") {
|
||||
debug!("Launching configure command...");
|
||||
commands::configure::invoke(configure_matches);
|
||||
if let Some((command_name, _)) = matches.subcommand() {
|
||||
debug!("Launching {} command...", command_name);
|
||||
};
|
||||
if let Some(ref _match) = matches.subcommand_matches("install") {
|
||||
debug!("Launching install command...");
|
||||
let result = commands::install::invoke(constants::GAME_ID);
|
||||
handle_exit_status(result, "Successfully installed Valheim!".to_string())
|
||||
};
|
||||
if let Some(ref start_matches) = matches.subcommand_matches("start") {
|
||||
debug!("Launching start command...");
|
||||
NotificationEvent::Start(EventStatus::Running).send_notification();
|
||||
commands::start::invoke(start_matches);
|
||||
NotificationEvent::Start(EventStatus::Successful).send_notification();
|
||||
};
|
||||
if let Some(ref stop_matches) = matches.subcommand_matches("stop") {
|
||||
debug!("Launching stop command...");
|
||||
NotificationEvent::Stop(EventStatus::Running).send_notification();
|
||||
commands::stop::invoke(stop_matches);
|
||||
NotificationEvent::Stop(EventStatus::Successful).send_notification();
|
||||
};
|
||||
if let Some(ref backup_matches) = matches.subcommand_matches("backup") {
|
||||
debug!("Launching backup command...");
|
||||
commands::backup::invoke(backup_matches);
|
||||
};
|
||||
if let Some(ref notify_matches) = matches.subcommand_matches("notify") {
|
||||
debug!("Launching notify command...");
|
||||
commands::notify::invoke(notify_matches);
|
||||
};
|
||||
|
||||
if let Some(ref update_matches) = matches.subcommand_matches("update") {
|
||||
debug!("Launching update command...");
|
||||
commands::update::invoke(update_matches);
|
||||
match matches.subcommand().expect("Subcommand is required") {
|
||||
("configure", sub_m) => commands::configure::invoke(sub_m),
|
||||
("install", _) => {
|
||||
let result = commands::install::invoke(constants::GAME_ID);
|
||||
handle_exit_status(result, "Successfully installed Valheim!".to_string())
|
||||
}
|
||||
("start", sub_m) => {
|
||||
NotificationEvent::Start(EventStatus::Running).send_notification();
|
||||
commands::start::invoke(sub_m);
|
||||
NotificationEvent::Start(EventStatus::Successful).send_notification();
|
||||
}
|
||||
("stop", sub_m) => {
|
||||
NotificationEvent::Stop(EventStatus::Running).send_notification();
|
||||
commands::stop::invoke(sub_m);
|
||||
NotificationEvent::Stop(EventStatus::Successful).send_notification();
|
||||
}
|
||||
("backup", sub_m) => commands::backup::invoke(sub_m),
|
||||
("notify", sub_m) => commands::notify::invoke(sub_m),
|
||||
("update", sub_m) => commands::update::invoke(sub_m),
|
||||
("mod:install", sub_m) => commands::install_mod::invoke(sub_m),
|
||||
_ => {
|
||||
panic!("No Command Launched!");
|
||||
} // Either no subcommand or one not tested for...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,5 @@ pub fn modding_disclaimer() {
|
||||
info!("By installing mods, you agree that you will do a root cause analysis to why your server is failing before you make a post.");
|
||||
info!("Modding is currently unsupported by the Valheim developers and limited support by the valheim-docker repo.");
|
||||
info!("If you have issues please contact the MOD developer FIRST based on the output logs.");
|
||||
info!("----------------------------------------------------------------");
|
||||
info!("Additional Note: BepInEx does not support SIGINT shutdown, which means you will have to manually save your world before shutting down.");
|
||||
info!("##########################################################################################################################");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::constants;
|
||||
use crate::utils::{environment, get_working_dir, path_exists};
|
||||
use crate::utils::common_paths::{bepinex_directory, game_directory};
|
||||
use crate::utils::{environment, path_exists};
|
||||
use log::{debug, info};
|
||||
use std::ops::Add;
|
||||
use std::process::{Child, Command};
|
||||
@@ -12,29 +13,16 @@ const DOORSTOP_LIBS_VAR: &str = "DOORSTOP_LIBS";
|
||||
const DOORSTOP_INVOKE_DLL_PATH_VAR: &str = "DOORSTOP_INVOKE_DLL_PATH";
|
||||
const DOORSTOP_CORLIB_OVERRIDE_PATH_VAR: &str = "DOORSTOP_CORLIB_OVERRIDE_PATH";
|
||||
|
||||
fn doorstop_lib() -> String {
|
||||
environment::fetch_var(DOORSTOP_LIB_VAR, "libdoorstop_x64.so")
|
||||
}
|
||||
|
||||
fn doorstop_libs() -> String {
|
||||
environment::fetch_var(
|
||||
DOORSTOP_LIBS_VAR,
|
||||
format!("{}/doorstop_libs", get_working_dir()).as_str(),
|
||||
)
|
||||
}
|
||||
|
||||
fn doorstop_insert_lib() -> String {
|
||||
let default = format!("{}/{}", doorstop_libs(), doorstop_lib().replace(":", ""));
|
||||
environment::fetch_var(DYLD_INSERT_LIBRARIES_VAR, default.as_str())
|
||||
}
|
||||
|
||||
fn doorstop_invoke_dll() -> String {
|
||||
environment::fetch_var(
|
||||
DOORSTOP_INVOKE_DLL_PATH_VAR,
|
||||
format!("{}/BepInEx/core/BepInEx.Preloader.dll", get_working_dir()).as_str(),
|
||||
)
|
||||
fn parse_path(env_var: &str, default: String, alt: String) -> String {
|
||||
let output = environment::fetch_var(env_var, &default);
|
||||
if !path_exists(&output) && path_exists(&alt) {
|
||||
String::from(&alt)
|
||||
} else {
|
||||
String::from(&output)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BepInExEnvironment {
|
||||
ld_preload: String,
|
||||
ld_library_path: String,
|
||||
@@ -45,96 +33,91 @@ pub struct BepInExEnvironment {
|
||||
dyld_insert_libraries: String,
|
||||
}
|
||||
|
||||
pub fn build_environment() -> BepInExEnvironment {
|
||||
let ld_preload =
|
||||
environment::fetch_var(constants::LD_PRELOAD_VAR, "").add(doorstop_lib().as_str());
|
||||
let ld_library_path = environment::fetch_var(
|
||||
constants::LD_LIBRARY_PATH_VAR,
|
||||
format!("./linux64:{}", doorstop_libs()).as_str(),
|
||||
);
|
||||
let doorstop_invoke_dll_value = doorstop_invoke_dll();
|
||||
let doorstop_corlib_override_path = environment::fetch_var(
|
||||
DOORSTOP_CORLIB_OVERRIDE_PATH_VAR,
|
||||
format!("{}/{}", get_working_dir(), "unstripped_corlib").as_str(),
|
||||
);
|
||||
let dyld_library_path = environment::fetch_var(DYLD_LIBRARY_PATH_VAR, doorstop_libs().as_str());
|
||||
let dyld_insert_libraries =
|
||||
environment::fetch_var(DYLD_INSERT_LIBRARIES_VAR, doorstop_insert_lib().as_str());
|
||||
info!("Checking for BepInEx Environment...");
|
||||
let environment = BepInExEnvironment {
|
||||
ld_preload,
|
||||
ld_library_path,
|
||||
doorstop_enable: true.to_string().to_uppercase(),
|
||||
doorstop_invoke_dll: doorstop_invoke_dll_value,
|
||||
doorstop_corlib_override_path,
|
||||
dyld_library_path,
|
||||
dyld_insert_libraries,
|
||||
};
|
||||
debug!("LD_PRELOAD: {}", &environment.ld_preload);
|
||||
debug!("LD_LIBRARY_PATH: {}", &environment.ld_library_path);
|
||||
debug!("DOORSTOP_ENABLE: {}", &environment.doorstop_enable);
|
||||
debug!(
|
||||
"DOORSTOP_INVOKE_DLL_PATH: {}",
|
||||
&environment.doorstop_invoke_dll
|
||||
);
|
||||
debug!(
|
||||
"{}: {}",
|
||||
DOORSTOP_CORLIB_OVERRIDE_PATH_VAR, &environment.doorstop_corlib_override_path
|
||||
);
|
||||
debug!("DYLD_LIBRARY_PATH: {}", &environment.dyld_library_path);
|
||||
debug!(
|
||||
"DYLD_INSERT_LIBRARIES: {}",
|
||||
&environment.dyld_insert_libraries
|
||||
);
|
||||
environment
|
||||
}
|
||||
impl BepInExEnvironment {
|
||||
pub fn new() -> BepInExEnvironment {
|
||||
let game_dir = game_directory();
|
||||
let bepinex_dir = bepinex_directory();
|
||||
let bepinex_preloader_dll = format!("{}/core/BepInEx.Preloader.dll", &bepinex_dir);
|
||||
|
||||
pub fn is_bepinex_installed() -> bool {
|
||||
let bepinex_env: BepInExEnvironment = build_environment();
|
||||
debug!("Checking for BepInEx specific files...");
|
||||
let checks = &[
|
||||
bepinex_env.doorstop_corlib_override_path,
|
||||
bepinex_env.dyld_insert_libraries,
|
||||
bepinex_env.dyld_library_path,
|
||||
bepinex_env.doorstop_invoke_dll,
|
||||
];
|
||||
let expected_state = true;
|
||||
let output = checks.iter().all(|ref v| path_exists(&v) == expected_state);
|
||||
if output {
|
||||
debug!("Yay! looks like we found all the required files for BepInEx to run! <3")
|
||||
} else {
|
||||
debug!("Uhh ohh!!! Looks like you are missing something.")
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
pub fn invoke(command: &mut Command, environment: &BepInExEnvironment) -> std::io::Result<Child> {
|
||||
info!("BepInEx found! Setting up Environment...");
|
||||
command
|
||||
// DOORSTOP_ENABLE must not have quotes around it.
|
||||
.env(DOORSTOP_ENABLE_VAR, &environment.doorstop_enable)
|
||||
// DOORSTOP_INVOKE_DLL_PATH must not have quotes around it.
|
||||
.env(
|
||||
DOORSTOP_INVOKE_DLL_PATH_VAR,
|
||||
&environment.doorstop_invoke_dll,
|
||||
)
|
||||
.env(
|
||||
debug!("Parsing Doorstop locations.");
|
||||
let doorstop_lib = environment::fetch_var(DOORSTOP_LIB_VAR, "libdoorstop_x64.so");
|
||||
let doorstop_libs = parse_path(
|
||||
DOORSTOP_LIBS_VAR,
|
||||
format!("{}/doorstop_libs", &game_dir),
|
||||
format!("{}/doorstop", &bepinex_dir),
|
||||
);
|
||||
let doorstop_invoke_dll =
|
||||
environment::fetch_var(DOORSTOP_INVOKE_DLL_PATH_VAR, &bepinex_preloader_dll);
|
||||
let doorstop_corlib_override_path = parse_path(
|
||||
DOORSTOP_CORLIB_OVERRIDE_PATH_VAR,
|
||||
&environment.doorstop_corlib_override_path,
|
||||
)
|
||||
// LD_LIBRARY_PATH must not have quotes around it.
|
||||
.env(constants::LD_LIBRARY_PATH_VAR, &environment.ld_library_path)
|
||||
// LD_PRELOAD must not have quotes around it.
|
||||
.env(constants::LD_PRELOAD_VAR, &environment.ld_preload)
|
||||
// DYLD_LIBRARY_PATH is weird af and MUST have quotes around it.
|
||||
.env(
|
||||
DYLD_LIBRARY_PATH_VAR,
|
||||
format!("\"{}\"", &environment.dyld_library_path),
|
||||
)
|
||||
// DYLD_INSERT_LIBRARIES must not have quotes around it.
|
||||
.env(
|
||||
DYLD_INSERT_LIBRARIES_VAR,
|
||||
&environment.dyld_insert_libraries,
|
||||
)
|
||||
.spawn()
|
||||
format!("{}/unstripped_corlib", &game_dir),
|
||||
format!("{}/core_lib", &bepinex_dir),
|
||||
);
|
||||
let doorstop_base_dll = format!("{}/{}", &doorstop_libs, &doorstop_lib);
|
||||
|
||||
debug!("Parsing LD locations.");
|
||||
let ld_preload = environment::fetch_var(constants::LD_PRELOAD_VAR, "").add(&doorstop_lib);
|
||||
let ld_library_path = environment::fetch_var(
|
||||
constants::LD_LIBRARY_PATH_VAR,
|
||||
format!("./linux64:{}", &doorstop_libs).as_str(),
|
||||
);
|
||||
|
||||
debug!("Parsing LD locations.");
|
||||
let dyld_library_path = environment::fetch_var(DYLD_LIBRARY_PATH_VAR, &doorstop_libs);
|
||||
let dyld_insert_libraries =
|
||||
environment::fetch_var(DYLD_INSERT_LIBRARIES_VAR, &doorstop_base_dll);
|
||||
|
||||
debug!("Returning environment");
|
||||
BepInExEnvironment {
|
||||
ld_preload,
|
||||
ld_library_path,
|
||||
doorstop_enable: true.to_string().to_uppercase(),
|
||||
doorstop_invoke_dll,
|
||||
doorstop_corlib_override_path,
|
||||
dyld_library_path,
|
||||
dyld_insert_libraries,
|
||||
}
|
||||
}
|
||||
pub fn is_installed(&self) -> bool {
|
||||
debug!("Checking for BepInEx specific files...");
|
||||
let checks = &[
|
||||
&self.doorstop_corlib_override_path,
|
||||
&self.dyld_insert_libraries,
|
||||
&self.dyld_library_path,
|
||||
&self.doorstop_invoke_dll,
|
||||
];
|
||||
let expected_state = true;
|
||||
let output = checks.iter().all(|ref v| path_exists(&v) == expected_state);
|
||||
if output {
|
||||
debug!("Yay! looks like we found all the required files for BepInEx to run! <3")
|
||||
} else {
|
||||
debug!("Uhh ohh!!! Looks like you are missing something.")
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
pub fn launch(&self, command: &mut Command) -> std::io::Result<Child> {
|
||||
info!("BepInEx found! Setting up Environment...");
|
||||
command
|
||||
// DOORSTOP_ENABLE must not have quotes around it.
|
||||
.env(DOORSTOP_ENABLE_VAR, &self.doorstop_enable)
|
||||
// DOORSTOP_INVOKE_DLL_PATH must not have quotes around it.
|
||||
.env(DOORSTOP_INVOKE_DLL_PATH_VAR, &self.doorstop_invoke_dll)
|
||||
.env(
|
||||
DOORSTOP_CORLIB_OVERRIDE_PATH_VAR,
|
||||
&self.doorstop_corlib_override_path,
|
||||
)
|
||||
// LD_LIBRARY_PATH must not have quotes around it.
|
||||
.env(constants::LD_LIBRARY_PATH_VAR, &self.ld_library_path)
|
||||
// LD_PRELOAD must not have quotes around it.
|
||||
.env(constants::LD_PRELOAD_VAR, &self.ld_preload)
|
||||
// DYLD_LIBRARY_PATH is weird af and MUST have quotes around it.
|
||||
.env(
|
||||
DYLD_LIBRARY_PATH_VAR,
|
||||
format!("\"{}\"", &self.dyld_library_path),
|
||||
)
|
||||
// DYLD_INSERT_LIBRARIES must not have quotes around it.
|
||||
.env(DYLD_INSERT_LIBRARIES_VAR, &self.dyld_insert_libraries)
|
||||
.spawn()
|
||||
}
|
||||
}
|
||||
|
||||
240
src/mods/mod.rs
240
src/mods/mod.rs
@@ -1 +1,241 @@
|
||||
pub mod bepinex;
|
||||
|
||||
use crate::constants::SUPPORTED_FILE_TYPES;
|
||||
use crate::utils::common_paths::{
|
||||
bepinex_config_directory, bepinex_plugin_directory, game_directory,
|
||||
};
|
||||
use crate::utils::{common_paths, get_md5_hash, parse_file_name, path_exists, url_parse_file_type};
|
||||
use fs_extra::dir;
|
||||
use fs_extra::dir::CopyOptions;
|
||||
use log::{debug, error, info};
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::{create_dir_all, File};
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use zip::result::ZipError;
|
||||
use zip::ZipArchive;
|
||||
|
||||
pub struct ValheimMod {
|
||||
pub(crate) url: String,
|
||||
pub(crate) file_type: String,
|
||||
pub(crate) staging_location: String,
|
||||
pub(crate) installed: bool,
|
||||
pub(crate) downloaded: bool,
|
||||
pub(crate) staged: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Manifest {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl ValheimMod {
|
||||
pub fn new(url: &str) -> ValheimMod {
|
||||
let file_type = url_parse_file_type(url);
|
||||
ValheimMod {
|
||||
url: String::from(url),
|
||||
file_type,
|
||||
staging_location: common_paths::mods_directory(),
|
||||
installed: false,
|
||||
downloaded: false,
|
||||
staged: false,
|
||||
}
|
||||
}
|
||||
// fn uninstall(&self) {}
|
||||
fn try_parse_manifest(&self, archive: &mut ZipArchive<File>) -> Result<Manifest, ZipError> {
|
||||
debug!("Parsing manifest...");
|
||||
let manifest = archive.by_name("manifest.json")?;
|
||||
Ok(serde_json::from_reader(manifest).expect("Failed deserializing manifest"))
|
||||
}
|
||||
|
||||
fn copy_staged_plugin(&mut self, manifest: &Manifest) {
|
||||
if !&self.staged {
|
||||
error!("Zip file not extracted to staging location!!");
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1);
|
||||
}
|
||||
let working_directory = game_directory();
|
||||
let mut staging_output = String::from(&self.staging_location);
|
||||
let sub_dir = format!("{}/{}", &staging_output, &manifest.name);
|
||||
debug!("Manifest suggests sub directory: {}", sub_dir);
|
||||
let mut dir_copy_options = dir::CopyOptions::new();
|
||||
dir_copy_options.overwrite = true;
|
||||
let mut copy_destination = bepinex_plugin_directory();
|
||||
if path_exists(&sub_dir)
|
||||
&& (manifest.name.eq("BepInExPack_Valheim") || manifest.name.eq("BepInEx_Valheim_Full"))
|
||||
{
|
||||
staging_output = format!("{}/{}", &staging_output, &manifest.name);
|
||||
copy_destination = String::from(&working_directory);
|
||||
} else {
|
||||
copy_destination = format!("{}/{}", ©_destination, &manifest.name);
|
||||
debug!("Creating mod directory: {}", ©_destination);
|
||||
match create_dir_all(©_destination) {
|
||||
Ok(_) => info!("Created mod directory: {}", ©_destination),
|
||||
Err(_) => {
|
||||
error!("Failed to create mod directory! {}", ©_destination);
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
debug!(
|
||||
"Copying contents from: \n{}\nInto Directory:\n{}",
|
||||
&staging_output, &working_directory
|
||||
);
|
||||
let source_contents: Vec<_> = std::fs::read_dir(&staging_output)
|
||||
.unwrap()
|
||||
.map(|entry| entry.unwrap().path())
|
||||
.collect();
|
||||
match fs_extra::copy_items(&source_contents, ©_destination, &dir_copy_options) {
|
||||
Ok(_) => info!("Successfully installed {}", &self.url),
|
||||
Err(_) => {
|
||||
error!("Failed to install {}", &self.url);
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn copy_single_file(&self, from: &str, to: String) {
|
||||
let mut dir_options = CopyOptions::new();
|
||||
dir_options.overwrite = true;
|
||||
match fs_extra::copy_items(&[&from], &to, &dir_options) {
|
||||
Ok(_) => debug!("Successfully copied {} to {}", &from, &to),
|
||||
Err(_) => {
|
||||
error!("Failed to install {}", self.url);
|
||||
error!(
|
||||
"File failed to copy from: \n{}To Destination:{}",
|
||||
&from, &to
|
||||
);
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
fn stage_plugin(&mut self, archive: &mut ZipArchive<File>) {
|
||||
let mut staging_output = String::from(
|
||||
Path::new(&self.staging_location)
|
||||
.file_stem()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
);
|
||||
staging_output = format!("{}/{}", common_paths::mods_directory(), &staging_output);
|
||||
debug!(
|
||||
"Extracting contents to staging directory: {}",
|
||||
staging_output
|
||||
);
|
||||
archive.extract(&staging_output).unwrap();
|
||||
self.staging_location = staging_output;
|
||||
self.staged = true;
|
||||
}
|
||||
fn extract_plugin(&self, archive: &mut ZipArchive<File>) {
|
||||
let output_path = if archive
|
||||
.file_names()
|
||||
.any(|file_name| file_name.eq_ignore_ascii_case("winhttp.dll"))
|
||||
{
|
||||
info!("Installing BepInEx...");
|
||||
common_paths::game_directory()
|
||||
} else {
|
||||
info!("Installing Mod...");
|
||||
common_paths::bepinex_plugin_directory()
|
||||
};
|
||||
match archive.extract(output_path) {
|
||||
Ok(_) => info!("Successfully installed {}", &self.url),
|
||||
Err(msg) => {
|
||||
error!(
|
||||
"Failed to install: {}\nDownloaded Archive: {}\n{}",
|
||||
&self.url,
|
||||
&self.staging_location,
|
||||
msg.to_string()
|
||||
);
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn install(&mut self) {
|
||||
if Path::new(&self.staging_location).is_dir() {
|
||||
error!(
|
||||
"Failed to install mod! Staging location is a directory! {}",
|
||||
&self.staging_location
|
||||
);
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1)
|
||||
}
|
||||
if self.file_type.eq("dll") {
|
||||
self.copy_single_file(&self.staging_location, bepinex_plugin_directory());
|
||||
} else if self.file_type.eq("cfg") {
|
||||
self.copy_single_file(&self.staging_location, bepinex_config_directory());
|
||||
} else {
|
||||
let zip_file = std::fs::File::open(&self.staging_location).unwrap();
|
||||
let mut archive = match zip::ZipArchive::new(zip_file) {
|
||||
Ok(file_archive) => {
|
||||
debug!("Successfully parsed zip file {}", &self.staging_location);
|
||||
file_archive
|
||||
}
|
||||
Err(_) => {
|
||||
error!("Failed to parse zip file {}", &self.staging_location);
|
||||
// TODO: Remove Exit Code and provide an Ok or Err.
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
match self.try_parse_manifest(&mut archive) {
|
||||
Ok(manifest) => {
|
||||
debug!("Manifest has name: {}", manifest.name);
|
||||
self.stage_plugin(&mut archive);
|
||||
self.copy_staged_plugin(&manifest);
|
||||
}
|
||||
Err(_) => {
|
||||
self.extract_plugin(&mut archive);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.installed = true
|
||||
}
|
||||
|
||||
pub fn download(&mut self) -> Result<String, String> {
|
||||
debug!("Initializing mod download...");
|
||||
let download_url = &self.url.clone();
|
||||
if !Path::new(&self.staging_location).exists() {
|
||||
error!("Failed to download file to staging location!");
|
||||
return Err(format!(
|
||||
"Directory does not exist! {}",
|
||||
&self.staging_location
|
||||
));
|
||||
}
|
||||
if let Ok(parsed_url) = Url::parse(&download_url) {
|
||||
match reqwest::blocking::get(parsed_url) {
|
||||
Ok(mut response) => {
|
||||
let file_type = url_parse_file_type(&self.url);
|
||||
if !SUPPORTED_FILE_TYPES.contains(&file_type.as_str()) {
|
||||
debug!("Using url (in case of redirect): {}", &self.url);
|
||||
self.url = response.url().to_string();
|
||||
self.file_type = url_parse_file_type(&response.url().to_string())
|
||||
}
|
||||
let file_name = parse_file_name(
|
||||
&Url::parse(&self.url).unwrap(),
|
||||
format!("{}.{}", get_md5_hash(&download_url), &self.file_type).as_str(),
|
||||
);
|
||||
self.staging_location = format!("{}/{}", &self.staging_location, file_name);
|
||||
debug!("Downloading to: {}", &self.staging_location);
|
||||
let mut file = File::create(&self.staging_location).unwrap();
|
||||
response.copy_to(&mut file).expect("Failed saving mod file");
|
||||
self.downloaded = true;
|
||||
debug!("Download Complete!: {}", &self.url);
|
||||
debug!("Download Output: {}", &self.staging_location);
|
||||
Ok(String::from("Successful"))
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to download mod: {}", download_url);
|
||||
Err(err.status().unwrap().to_string())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"Failed to download mod with invalid url: {}",
|
||||
&download_url
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,6 @@ line () {
|
||||
|
||||
line
|
||||
log "Valheim Server - $(date)"
|
||||
log "Starting auto update..."
|
||||
log "
|
||||
Port: ${PORT}
|
||||
Name: ${NAME}
|
||||
World: ${WORLD}
|
||||
Public: ${PUBLIC}
|
||||
Password: (REDACTED)
|
||||
"
|
||||
line
|
||||
|
||||
cd /home/steam/valheim || exit 1
|
||||
|
||||
|
||||
@@ -11,87 +11,118 @@ ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ >/etc/timezone
|
||||
|
||||
# shellcheck disable=SC2039
|
||||
if [ "${EUID}" -ne 0 ]; then
|
||||
log "Please run as root"
|
||||
exit
|
||||
log "Please run as root"
|
||||
exit
|
||||
fi
|
||||
|
||||
log() {
|
||||
PREFIX="[Valheim][root]"
|
||||
printf "%-16s: %s\n" "${PREFIX}" "$1"
|
||||
PREFIX="[Valheim][root]"
|
||||
printf "%-16s: %s\n" "${PREFIX}" "$1"
|
||||
}
|
||||
|
||||
line() {
|
||||
log "###########################################################################"
|
||||
log "###########################################################################"
|
||||
}
|
||||
|
||||
check_version() {
|
||||
file="/home/steam/.version"
|
||||
sha="$(tail -n+1 $file | head -n1)"
|
||||
branch="$(tail -n+2 $file | head -n1)"
|
||||
repository="$(tail -n+3 $file | head -n1)"
|
||||
github_version="$(curl -s "https://api.github.com/repos/${repository}/branches/${branch//refs\/heads\//}" | jq '.commit.sha')"
|
||||
if [ -z "$github_version" ] || [ "$github_version" == "null" ]; then
|
||||
log "You must be in development. Good luck!"
|
||||
elif [ "${github_version//\"/}" != "${sha//\"/}" ]; then
|
||||
log "Hey you! It looks like there is an update on $repository for $branch"
|
||||
log "Please consider running \`docker-compose pull valheim\` or pull the image based on your use case"
|
||||
fi
|
||||
file="/home/steam/.version"
|
||||
sha="$(tail -n+1 $file | head -n1)"
|
||||
branch="$(tail -n+2 $file | head -n1)"
|
||||
repository="$(tail -n+3 $file | head -n1)"
|
||||
github_version="$(curl -s "https://api.github.com/repos/${repository}/branches/${branch//refs\/heads\//}" | jq '.commit.sha')"
|
||||
if [ -z "$github_version" ] || [ "$github_version" == "null" ]; then
|
||||
log "You must be in development. Good luck!"
|
||||
elif [ "${github_version//\"/}" != "${sha//\"/}" ]; then
|
||||
log "Hey you! It looks like there is an update on $repository for $branch"
|
||||
log "Please consider running \`docker-compose pull valheim\` or pull the image based on your use case"
|
||||
fi
|
||||
}
|
||||
|
||||
clean_up() {
|
||||
echo "Safely shutting down..." >>/home/steam/output.log
|
||||
if [[ -n $CRON_PID ]]; then
|
||||
kill $CRON_PID
|
||||
fi
|
||||
echo "Safely shutting down..." >>/home/steam/output.log
|
||||
if [[ -n $CRON_PID ]]; then
|
||||
kill $CRON_PID
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'clean_up' INT TERM
|
||||
|
||||
setup_cron() {
|
||||
set -f
|
||||
CRON_NAME=$1
|
||||
SCRIPT_PATH="/home/steam/scripts/$2"
|
||||
CRON_SCHEDULE=$3
|
||||
CRON_ENV=$4
|
||||
LOG_LOCATION="/home/steam/valheim/logs/$CRON_NAME.out"
|
||||
rm $LOG_LOCATION > /dev/null
|
||||
printf "%s %s /usr/sbin/gosu steam /bin/bash %s >> %s 2>&1" \
|
||||
"${CRON_SCHEDULE}" \
|
||||
"DEBUG_MODE=${DEBUG_MODE:-0} ODIN_CONFIG_FILE=${ODIN_CONFIG_FILE} ODIN_WORKING_DIR=${ODIN_WORKING_DIR} WEBHOOK_URL=${WEBHOOK_URL:-""} ${CRON_ENV}" \
|
||||
"${SCRIPT_PATH}" \
|
||||
"${LOG_LOCATION}" \
|
||||
set -f
|
||||
CRON_NAME=$1
|
||||
SCRIPT_PATH="/home/steam/scripts/$2"
|
||||
CRON_SCHEDULE=$3
|
||||
|
||||
PRESET_ENV="
|
||||
DEBUG_MODE=${DEBUG_MODE:=0}
|
||||
ODIN_CONFIG_FILE=${ODIN_CONFIG_FILE}
|
||||
ODIN_WORKING_DIR=${ODIN_WORKING_DIR}
|
||||
WEBHOOK_URL=${WEBHOOK_URL:-""}
|
||||
|
||||
AUTO_UPDATE=${AUTO_UPDATE}
|
||||
AUTO_BACKUP=${AUTO_BACKUP}
|
||||
AUTO_BACKUP_REMOVE_OLD=${AUTO_BACKUP_REMOVE_OLD}
|
||||
AUTO_BACKUP_DAYS_TO_LIVE=${AUTO_BACKUP_DAYS_TO_LIVE}
|
||||
AUTO_BACKUP_ON_UPDATE=${AUTO_BACKUP_ON_UPDATE}
|
||||
AUTO_BACKUP_ON_SHUTDOWN=${AUTO_BACKUP_ON_SHUTDOWN}
|
||||
UPDATE_ON_STARTUP=${UPDATE_ON_STARTUP}
|
||||
SAVE_LOCATION=${SAVE_LOCATION}
|
||||
MODS_LOCATION=${MODS_LOCATION}
|
||||
GAME_LOCATION=${GAME_LOCATION}
|
||||
BACKUP_LOCATION=${BACKUP_LOCATION}
|
||||
"
|
||||
CRON_ENV="${PRESET_ENV} ${4}"
|
||||
CRON_ENV="$(echo "${CRON_ENV}" | tr '\n' " " )"
|
||||
LOG_LOCATION="/home/steam/valheim/logs/$CRON_NAME.out"
|
||||
rm $LOG_LOCATION >/dev/null
|
||||
printf "%s %s /usr/sbin/gosu steam /bin/bash %s >> %s 2>&1" \
|
||||
"${CRON_SCHEDULE}" \
|
||||
"${CRON_ENV}" \
|
||||
"${SCRIPT_PATH}" \
|
||||
"${LOG_LOCATION}" \
|
||||
>/etc/cron.d/${CRON_NAME}
|
||||
echo "" >>/etc/cron.d/${CRON_NAME}
|
||||
# Give execution rights on the cron job
|
||||
chmod 0644 /etc/cron.d/${CRON_NAME}
|
||||
set +f
|
||||
echo "" >>/etc/cron.d/${CRON_NAME}
|
||||
# Give execution rights on the cron job
|
||||
chmod 0644 /etc/cron.d/${CRON_NAME}
|
||||
set +f
|
||||
}
|
||||
|
||||
setup_filesystem() {
|
||||
log "Setting up file systems"
|
||||
STEAM_UID=${PUID:=1000}
|
||||
STEAM_GID=${PGID:=1000}
|
||||
mkdir -p /home/steam/valheim
|
||||
mkdir -p /home/steam/valheim/logs
|
||||
mkdir -p /home/steam/backups
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} /home/steam/valheim
|
||||
mkdir -p /home/steam/scripts
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} /home/steam/scripts
|
||||
mkdir -p /home/steam/valheim
|
||||
cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} /home/steam/
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} /home/steam/valheim
|
||||
log "Setting up file systems"
|
||||
STEAM_UID=${PUID:=1000}
|
||||
STEAM_GID=${PGID:=1000}
|
||||
|
||||
# Save Files
|
||||
mkdir -p ${SAVE_LOCATION}
|
||||
|
||||
# Mod staging location
|
||||
mkdir -p ${MODS_LOCATION}
|
||||
|
||||
# Backups
|
||||
mkdir -p ${BACKUP_LOCATION}
|
||||
|
||||
# Valheim Server
|
||||
mkdir -p ${GAME_LOCATION}
|
||||
mkdir -p ${GAME_LOCATION}/logs
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} ${GAME_LOCATION}
|
||||
cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim
|
||||
|
||||
|
||||
# Other
|
||||
mkdir -p /home/steam/scripts
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} /home/steam/scripts
|
||||
chown -R ${STEAM_UID}:${STEAM_GID} /home/steam/
|
||||
}
|
||||
|
||||
check_memory() {
|
||||
MEMORY=$(($(getconf _PHYS_PAGES) * $(getconf PAGE_SIZE) / (1024 * 1024)))
|
||||
MESSAGE="Your system has less than 2GB of ram!!\nValheim might not run on your system!!"
|
||||
if [ $MEMORY -lt 2000 ]; then
|
||||
line
|
||||
log "${MESSAGE^^}"
|
||||
line
|
||||
line
|
||||
fi
|
||||
MEMORY=$(($(getconf _PHYS_PAGES) * $(getconf PAGE_SIZE) / (1024 * 1024)))
|
||||
MESSAGE="Your system has less than 2GB of ram!!\nValheim might not run on your system!!"
|
||||
if [ $MEMORY -lt 2000 ]; then
|
||||
line
|
||||
log "${MESSAGE^^}"
|
||||
line
|
||||
line
|
||||
fi
|
||||
}
|
||||
|
||||
line
|
||||
@@ -107,39 +138,37 @@ log "$(usermod -u ${PUID} steam)"
|
||||
# shellcheck disable=SC2086
|
||||
log "$(groupmod -g ${PGID} steam)"
|
||||
|
||||
|
||||
# Configure Cron
|
||||
AUTO_UPDATE="${AUTO_UPDATE:-0}"
|
||||
AUTO_BACKUP="${AUTO_BACKUP:-0}"
|
||||
|
||||
AUTO_UPDATE="${AUTO_UPDATE:=0}"
|
||||
AUTO_BACKUP="${AUTO_BACKUP:=0}"
|
||||
|
||||
if [ "${AUTO_UPDATE}" -eq 1 ]; then
|
||||
log "Auto Update Enabled..."
|
||||
log "Auto Update Schedule: ${AUTO_UPDATE_SCHEDULE}"
|
||||
AUTO_UPDATE_SCHEDULE=$(echo "$AUTO_UPDATE_SCHEDULE" | tr -d '"')
|
||||
setup_cron \
|
||||
log "Auto Update Enabled..."
|
||||
log "Auto Update Schedule: ${AUTO_UPDATE_SCHEDULE}"
|
||||
AUTO_UPDATE_SCHEDULE=$(echo "$AUTO_UPDATE_SCHEDULE" | tr -d '"')
|
||||
setup_cron \
|
||||
"auto-update" \
|
||||
"auto_update.sh" \
|
||||
"${AUTO_UPDATE_SCHEDULE}" \
|
||||
"AUTO_BACKUP_ON_UPDATE=${AUTO_BACKUP_ON_UPDATE:-0}"
|
||||
"AUTO_BACKUP_ON_UPDATE=${AUTO_BACKUP_ON_UPDATE:=0}"
|
||||
fi
|
||||
|
||||
if [ "${AUTO_BACKUP}" -eq 1 ]; then
|
||||
log "Auto Backup Enabled..."
|
||||
log "Auto Backup Schedule: ${AUTO_BACKUP_SCHEDULE}"
|
||||
AUTO_BACKUP_SCHEDULE=$(echo "$AUTO_BACKUP_SCHEDULE" | tr -d '"')
|
||||
setup_cron \
|
||||
"auto-backup" \
|
||||
"auto_backup.sh" \
|
||||
"${AUTO_BACKUP_SCHEDULE}" \
|
||||
log "Auto Backup Enabled..."
|
||||
log "Auto Backup Schedule: ${AUTO_BACKUP_SCHEDULE}"
|
||||
AUTO_BACKUP_SCHEDULE=$(echo "$AUTO_BACKUP_SCHEDULE" | tr -d '"')
|
||||
setup_cron \
|
||||
"auto-backup" \
|
||||
"auto_backup.sh" \
|
||||
"${AUTO_BACKUP_SCHEDULE}" \
|
||||
"AUTO_BACKUP_REMOVE_OLD=${AUTO_BACKUP_REMOVE_OLD} AUTO_BACKUP_DAYS_TO_LIVE=${AUTO_BACKUP_DAYS_TO_LIVE}"
|
||||
fi
|
||||
|
||||
# Apply cron job
|
||||
if [ "${AUTO_BACKUP}" -eq 1 ] || [ "${AUTO_UPDATE}" -eq 1 ]; then
|
||||
cat /etc/cron.d/* | crontab -
|
||||
/usr/sbin/cron -f &
|
||||
export CRON_PID=$!
|
||||
cat /etc/cron.d/* | crontab -
|
||||
/usr/sbin/cron -f &
|
||||
export CRON_PID=$!
|
||||
fi
|
||||
|
||||
# Configure filesystem
|
||||
@@ -149,4 +178,3 @@ setup_filesystem
|
||||
log "Launching as steam..."
|
||||
cd /home/steam/valheim || exit 1
|
||||
exec gosu steam "$@"
|
||||
|
||||
|
||||
@@ -63,6 +63,58 @@ cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim/linux64/
|
||||
log "Initializing Variables...."
|
||||
odin configure || exit 1
|
||||
|
||||
log "Checking for TYPE flag"
|
||||
export TYPE="${TYPE:="vanilla"}"
|
||||
log "Found Type ${TYPE}"
|
||||
export TYPE="${TYPE,,}"
|
||||
export GAME_LOCATION="${GAME_LOCATION:="/home/steam/valheim"}"
|
||||
|
||||
if [ "${TYPE}" = "vanilla" ] && [ -n "${MODS:=""}" ]; then
|
||||
log "Mods supplied but you are running with Vanilla!!!"
|
||||
log "Mods will NOT be installed!."
|
||||
elif \
|
||||
# ValheimPlus not yet installed
|
||||
{ [ "${TYPE}" = "valheimplus" ] && [ ! -d "${GAME_LOCATION}/BepInEx" ] && [ ! -f "${GAME_LOCATION}/BepInEx/plugins/ValheimPlus.dll" ]; } || \
|
||||
# ValheimPlus with update on startup or force install
|
||||
{ [ "${TYPE}" = "valheimplus" ] && { [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; } ; }; then
|
||||
log "Installing ValheimPlus"
|
||||
VALHEIM_PLUS_URL="$(curl https://api.github.com/repos/valheimPlus/ValheimPlus/releases/latest | jq -r '.assets[] | select(.name=="UnixServer.zip") | .browser_download_url')"
|
||||
log "Pulling ValheimPlus from ${VALHEIM_PLUS_URL}"
|
||||
odin mod:install "${VALHEIM_PLUS_URL}"
|
||||
elif \
|
||||
# BepInEx not yet installed
|
||||
{ [ "${TYPE}" = "bepinex" ] && [ ! -d "${GAME_LOCATION}/BepInEx" ] && [ ! -f "${GAME_LOCATION}/BepInEx/core/BepInEx.dll" ]; } || \
|
||||
# BepInEx with update on startup or force install
|
||||
{ [ "${TYPE}" = "bepinex" ] && { [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; } ; }; then
|
||||
log "Installing BepInEx"
|
||||
BEPINEX_URL="$(curl https://valheim.thunderstore.io/api/experimental/package/denikson/BepInExPack_Valheim/ | jq -r '.latest.download_url')"
|
||||
log "Pulling BepInEx from ${BEPINEX_URL}"
|
||||
odin mod:install "${BEPINEX_URL}"
|
||||
elif \
|
||||
# BepInEx not yet installed
|
||||
{ [ "${TYPE}" = "bepinexfull" ] && [ ! -d "${GAME_LOCATION}/BepInEx" ] && [ ! -f "${GAME_LOCATION}/BepInEx/core/BepInEx.dll" ]; } || \
|
||||
# BepInEx with update on startup or force install
|
||||
{ [ "${TYPE}" = "bepinexfull" ] && { [ "${UPDATE_ON_STARTUP:-0}" -eq 1 ] || [ "${FORCE_INSTALL:-0}" -eq 1 ]; } ; }; then
|
||||
log "Installing BepInEx Full"
|
||||
BEPINEX_URL="$(curl https://valheim.thunderstore.io/api/experimental/package/1F31A/BepInEx_Valheim_Full/ | jq -r '.latest.download_url')"
|
||||
log "Pulling BepInEx Full from ${BEPINEX_URL}"
|
||||
odin mod:install "${BEPINEX_URL}"
|
||||
fi
|
||||
|
||||
log "Running with ${TYPE} Valheim <3"
|
||||
|
||||
if [ ! "${TYPE}" = "vanilla" ]; then
|
||||
SAVE_IFS=$IFS # Save current IFS
|
||||
IFS=$',\n' # Change IFS to new line
|
||||
# shellcheck disable=SC2206
|
||||
MODS=(${MODS:=""}) # split to array $names
|
||||
IFS=$SAVE_IFS # Restore IFS
|
||||
|
||||
for mod in "${MODS[@]}"; do
|
||||
log "Installing Mod ${mod}"
|
||||
odin mod:install "${mod}"
|
||||
done
|
||||
fi
|
||||
|
||||
# Setting up script traps
|
||||
trap 'cleanup' INT TERM
|
||||
|
||||
@@ -3,12 +3,13 @@ use log::{debug, info};
|
||||
|
||||
use std::{io, process::Child};
|
||||
|
||||
use crate::mods::bepinex::BepInExEnvironment;
|
||||
use crate::utils::common_paths::saves_directory;
|
||||
use crate::{
|
||||
constants,
|
||||
executable::create_execution,
|
||||
files::{create_file, ValheimArguments},
|
||||
messages,
|
||||
mods::bepinex,
|
||||
utils::{environment, get_working_dir},
|
||||
};
|
||||
|
||||
@@ -24,9 +25,11 @@ pub fn start_daemonized(config: ValheimArguments) -> Result<CommandResult, Daemo
|
||||
.stdout(stdout)
|
||||
.stderr(stderr)
|
||||
.exit_action(|| {
|
||||
if bepinex::is_bepinex_installed() {
|
||||
let bepinex_env = BepInExEnvironment::new();
|
||||
if bepinex_env.is_installed() {
|
||||
info!("Server has been started with BepInEx! Keep in mind this may cause errors!!");
|
||||
messages::modding_disclaimer()
|
||||
messages::modding_disclaimer();
|
||||
debug!("{:#?}", bepinex_env);
|
||||
}
|
||||
info!("Server has been started and Daemonized. It should be online shortly!");
|
||||
info!("Keep an eye out for 'Game server connected' in the log!");
|
||||
@@ -58,16 +61,18 @@ pub fn start(config: &ValheimArguments) -> CommandResult {
|
||||
&config.password.as_str(),
|
||||
"-public",
|
||||
&config.public.as_str(),
|
||||
"-savedir",
|
||||
&saves_directory(),
|
||||
])
|
||||
.env("SteamAppId", environment::fetch_var("APPID", "892970"))
|
||||
.current_dir(get_working_dir());
|
||||
info!("Executable: {}", &config.command);
|
||||
info!("Launching Command...");
|
||||
|
||||
if bepinex::is_bepinex_installed() {
|
||||
let bepinex_env = BepInExEnvironment::new();
|
||||
if bepinex_env.is_installed() {
|
||||
info!("BepInEx detected! Switching to run with BepInEx...");
|
||||
let bepinex_env = bepinex::build_environment();
|
||||
bepinex::invoke(base_command, &bepinex_env)
|
||||
debug!("BepInEx Environment: \n{:#?}", bepinex_env);
|
||||
bepinex_env.launch(base_command)
|
||||
} else {
|
||||
info!("Everything looks good! Running normally!");
|
||||
base_command
|
||||
|
||||
34
src/utils/common_paths.rs
Normal file
34
src/utils/common_paths.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use crate::constants::{GAME_LOCATION, MODS_LOCATION, SAVE_LOCATION};
|
||||
use crate::utils::get_working_dir;
|
||||
use std::env;
|
||||
|
||||
pub fn game_directory() -> String {
|
||||
env::var(GAME_LOCATION).unwrap_or_else(|_| get_working_dir())
|
||||
}
|
||||
|
||||
pub fn bepinex_directory() -> String {
|
||||
format!("{}/BepInEx", game_directory())
|
||||
}
|
||||
|
||||
pub fn bepinex_plugin_directory() -> String {
|
||||
format!("{}/plugins", bepinex_directory())
|
||||
}
|
||||
|
||||
pub fn bepinex_config_directory() -> String {
|
||||
format!("{}/config", bepinex_directory())
|
||||
}
|
||||
|
||||
pub fn mods_directory() -> String {
|
||||
env::var(MODS_LOCATION).unwrap_or_else(|_| format!("{}/mods", get_working_dir()))
|
||||
}
|
||||
|
||||
// pub fn backup_directory() -> String {
|
||||
// env::var(BACKUP_LOCATION).unwrap_or_else(|_| format!("{}/backups", get_working_dir()))
|
||||
// }
|
||||
|
||||
pub fn saves_directory() -> String {
|
||||
env::var(SAVE_LOCATION).unwrap_or_else(|_| match env::var("HOME") {
|
||||
Ok(dir) => format!("{}/.config/unity3d/IronGate/Valheim", dir),
|
||||
Err(_) => format!("{}/backups", get_working_dir()),
|
||||
})
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod common_paths;
|
||||
pub mod environment;
|
||||
|
||||
use clap::ArgMatches;
|
||||
@@ -6,6 +7,7 @@ use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::constants;
|
||||
use reqwest::Url;
|
||||
|
||||
pub fn get_working_dir() -> String {
|
||||
environment::fetch_var(
|
||||
@@ -32,7 +34,7 @@ pub fn get_variable(args: &ArgMatches, name: &str, default: String) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub(crate) fn path_exists(path: &str) -> bool {
|
||||
pub fn path_exists(path: &str) -> bool {
|
||||
let state = Path::new(path).exists();
|
||||
debug!(
|
||||
"Path {} {}",
|
||||
@@ -41,3 +43,34 @@ pub(crate) fn path_exists(path: &str) -> bool {
|
||||
);
|
||||
state
|
||||
}
|
||||
|
||||
pub fn parse_file_name(url: &Url, default: &str) -> String {
|
||||
String::from(
|
||||
url
|
||||
.path_segments()
|
||||
.and_then(|segments| segments.last())
|
||||
.and_then(|name| if name.is_empty() { None } else { Some(name) })
|
||||
.unwrap_or(default),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_md5_hash(context: &str) -> String {
|
||||
format!("{:x}", md5::compute(context.as_bytes()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn hash_str() {
|
||||
assert_eq!(
|
||||
get_md5_hash("abcdefghijklmnopqrstuvwxyz"),
|
||||
"c3fcd3d76192e4007dfb496cca67e13b"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url_parse_file_type(url: &str) -> String {
|
||||
url.split('.').last().unwrap().to_string()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user