diff --git a/Cargo.lock b/Cargo.lock index bdc3198b..6e4774f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ dependencies = [ "ansi_markup", "nom", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -103,7 +103,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -125,7 +125,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -136,7 +136,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bcrypt" @@ -219,7 +219,7 @@ dependencies = [ "deadpool-postgres", "futures", "humantime", - "itertools 0.12.0", + "itertools 0.12.1", "log", "mockall", "mockall_double", @@ -314,7 +314,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "syn_derive", ] @@ -381,9 +381,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", @@ -391,7 +391,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -411,7 +411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -543,7 +543,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -647,7 +647,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -901,9 +901,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -929,9 +929,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -981,9 +981,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "md-5" @@ -1040,7 +1040,7 @@ checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1067,7 +1067,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1079,7 +1079,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1188,9 +1188,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "ouroboros" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50b637ffd883b2733a8483599fb6136b9dcedaa1850f7ac08b9b6f9f2061208" +checksum = "97b7be5a8a3462b752f4be3ff2b2bf2f7f1d00834902e46be2a4d68b87b0573c" dependencies = [ "aliasable", "ouroboros_macro", @@ -1199,16 +1199,16 @@ dependencies = [ [[package]] name = "ouroboros_macro" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3633d65683f13b9bcfaa3150880b018899fb0e5d0542f4adaea4f503fdb5eabf" +checksum = "b645dcde5f119c2c454a92d0dfa271a2a3b205da92e4292a68ead4bdbfde1f33" dependencies = [ "heck", - "itertools 0.12.0", + "itertools 0.12.1", "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1270,7 +1270,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1299,7 +1299,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1435,7 +1435,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "version_check", "yansi", ] @@ -1564,16 +1564,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1607,9 +1608,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.33.1" +version = "1.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df" dependencies = [ "arrayvec", "borsh", @@ -1662,9 +1663,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -1681,20 +1682,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -1715,9 +1716,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.30" +version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" +checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ "indexmap", "itoa", @@ -1772,7 +1773,7 @@ dependencies = [ "colored", "log", "time", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1803,7 +1804,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1848,9 +1849,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -1866,7 +1867,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1898,7 +1899,7 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1949,9 +1950,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -1962,7 +1963,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1973,7 +1974,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -2110,7 +2111,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -2214,9 +2215,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", "serde", @@ -2310,7 +2311,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-shared", ] @@ -2332,7 +2333,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2381,6 +2382,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.48.5" diff --git a/ansi_macro/Cargo.toml b/ansi_macro/Cargo.toml index 27d3a133..25c39e9b 100644 --- a/ansi_macro/Cargo.toml +++ b/ansi_macro/Cargo.toml @@ -9,5 +9,5 @@ proc-macro = true [dependencies] nom = "7.1.3" quote = "1.0.35" -syn = "2.0.48" +syn = "2.0.52" ansi_markup = { path = "../ansi_markup" } diff --git a/blastmud_game/Cargo.toml b/blastmud_game/Cargo.toml index e6e90812..fcffe903 100644 --- a/blastmud_game/Cargo.toml +++ b/blastmud_game/Cargo.toml @@ -6,40 +6,40 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -base64 = "0.21.5" +base64 = "0.21.7" blastmud_interfaces = { path = "../blastmud_interfaces" } ansi = { path = "../ansi" } ansi_markup = { path = "../ansi_markup" } deadpool = "0.10.0" deadpool-postgres = { version = "0.12.1", features = ["serde"] } futures = "0.3.30" -log = "0.4.20" +log = "0.4.21" nix = { version = "0.27.1", features = ["process", "signal"] } -ring = "0.17.7" -serde = { version = "1.0.195", features = ["derive", "serde_derive"] } -serde_yaml = "0.9.30" +ring = "0.17.8" +serde = { version = "1.0.197", features = ["derive", "serde_derive"] } +serde_yaml = "0.9.32" simple_logger = "4.3.3" -tokio = { version = "1.35.1", features = ["signal", "net", "macros", "rt-multi-thread", "rt", "tokio-macros", "time", "sync", "io-util"] } +tokio = { version = "1.36.0", features = ["signal", "net", "macros", "rt-multi-thread", "rt", "tokio-macros", "time", "sync", "io-util"] } tokio-postgres = { version = "0.7.10", features = ["with-uuid-1", "with-serde_json-1"] } tokio-serde = { version = "0.8.0", features = ["serde", "serde_cbor", "cbor"] } tokio-stream = "0.1.14" tokio-util = { version = "0.7.10", features = ["codec"] } -uuid = { version = "1.6.1", features = ["v4", "serde", "rng"] } -serde_json = "1.0.111" +uuid = { version = "1.7.0", features = ["v4", "serde", "rng"] } +serde_json = "1.0.114" phf = { version = "0.11.2", features = ["macros"] } async-trait = "0.1.77" nom = "7.1.3" -ouroboros = "0.18.2" -chrono = { version = "0.4.31", features = ["serde"] } +ouroboros = "0.18.3" +chrono = { version = "0.4.35", features = ["serde"] } bcrypt = "0.15.0" validator = "0.16.1" -itertools = "0.12.0" +itertools = "0.12.1" once_cell = "1.19.0" rand = "0.8.5" async-recursion = "1.0.5" rand_distr = "0.4.3" humantime = "2.1.0" -rust_decimal = "1.33.1" +rust_decimal = "1.34.3" mockall_double = "0.3.1" [dev-dependencies] diff --git a/blastmud_game/src/db.rs b/blastmud_game/src/db.rs index b23765b2..5b7aa2fe 100644 --- a/blastmud_game/src/db.rs +++ b/blastmud_game/src/db.rs @@ -1091,6 +1091,25 @@ impl DBTrans { Ok(()) } + pub async fn fetch_specific_task<'a>( + &'a self, + task_type: &'a str, + task_code: &'a str, + ) -> DResult> { + match self + .pg_trans()? + .query_opt( + "SELECT details FROM tasks WHERE details->>'task_type' = $1 AND \ + details->>'task_code' = $2", + &[&task_type, &task_code], + ) + .await? + { + None => Ok(None), + Some(row) => Ok(serde_json::from_value(row.get("details"))?), + } + } + pub async fn upsert_task<'a>(&'a self, task: &'a Task) -> DResult<()> { self.pg_trans()? .execute( @@ -1583,7 +1602,7 @@ impl DBTrans { self.pg_trans()? .execute( "DELETE FROM corp_membership WHERE details->>'invited_at' <= $1", - &[&(Utc::now() - chrono::Duration::hours(4)) + &[&(Utc::now() - chrono::TimeDelta::try_hours(4).unwrap()) .to_rfc3339_opts(chrono::SecondsFormat::Nanos, true)], ) .await?; diff --git a/blastmud_game/src/message_handler/user_commands/allow.rs b/blastmud_game/src/message_handler/user_commands/allow.rs index 473bbe93..1f126332 100644 --- a/blastmud_game/src/message_handler/user_commands/allow.rs +++ b/blastmud_game/src/message_handler/user_commands/allow.rs @@ -233,8 +233,10 @@ fn compute_new_consent_state( Some(n) => Some(n.min(60 * 24 * 7)), } }; - new_consent.expires = expires_minutes - .map(|n| chrono::Utc::now() + chrono::Duration::minutes(n.min(60 * 24 * 365 * 25) as i64)); + new_consent.expires = expires_minutes.map(|n| { + chrono::Utc::now() + + chrono::TimeDelta::try_minutes(n.min(60 * 24 * 365 * 25) as i64).unwrap() + }); match their_target_consent .as_ref() .and_then(|c| c.expires) @@ -575,7 +577,8 @@ mod tests { &ConsentDetails::default_for(&ConsentType::Fight), &None, &Some(Consent { - expires: Some(chrono::Utc::now() + chrono::Duration::minutes(60 * 24 * 7)), + expires: Some(chrono::Utc::now() + chrono::TimeDelta::try_minutes(60 * 24 * 7)) + .unwrap(), fight_consent: Some(FightConsent::default()), ..Consent::default() }), @@ -605,7 +608,8 @@ mod tests { ..ConsentDetails::default_for(&ConsentType::Fight) }, &Some(Consent { - expires: Some(chrono::Utc::now() + chrono::Duration::minutes(60 * 24 * 7)), + expires: Some(chrono::Utc::now() + chrono::TimeDelta::try_minutes(60 * 24 * 7)) + .unwrap(), fight_consent: Some(FightConsent { status: ConsentStatus::Active, ..FightConsent::default() @@ -613,7 +617,8 @@ mod tests { ..Consent::default() }), &Some(Consent { - expires: Some(chrono::Utc::now() + chrono::Duration::minutes(60 * 24 * 7)), + expires: Some(chrono::Utc::now() + chrono::TimeDelta::try_minutes(60 * 24 * 7)) + .unwrap(), fight_consent: Some(FightConsent { status: ConsentStatus::Active, ..FightConsent::default() @@ -662,7 +667,8 @@ mod tests { ..ConsentDetails::default_for(&ConsentType::Fight) }, &Some(Consent { - expires: Some(chrono::Utc::now() + chrono::Duration::minutes(60 * 24 * 7)), + expires: Some(chrono::Utc::now() + chrono::TimeDelta::try_minutes(60 * 24 * 7)) + .unwrap(), fight_consent: Some(FightConsent { status: ConsentStatus::Active, ..FightConsent::default() @@ -670,11 +676,15 @@ mod tests { ..Consent::default() }), &Some(Consent { - expires: Some(chrono::Utc::now() + chrono::Duration::minutes(60 * 24 * 7)), + expires: Some(chrono::Utc::now() + chrono::TimeDelta::try_minutes(60 * 24 * 7)) + .unwrap(), fight_consent: Some(FightConsent { status: ConsentStatus::Active, pending_change: Some(Box::new(Consent { - expires: Some(chrono::Utc::now() + chrono::Duration::minutes(60 * 24 * 7)), + expires: Some( + chrono::Utc::now() + chrono::TimeDelta::try_minutes(60 * 24 * 7), + ) + .unwrap(), fight_consent: Some(FightConsent { freely_revoke: true, ..FightConsent::default() diff --git a/blastmud_game/src/message_handler/user_commands/delete.rs b/blastmud_game/src/message_handler/user_commands/delete.rs index 5bf4324f..f258b01f 100644 --- a/blastmud_game/src/message_handler/user_commands/delete.rs +++ b/blastmud_game/src/message_handler/user_commands/delete.rs @@ -164,7 +164,7 @@ impl UserVerb for Verb { .upsert_task(&Task { meta: TaskMeta { task_code: username.clone(), - next_scheduled: Utc::now() + chrono::Duration::days(7), + next_scheduled: Utc::now() + chrono::TimeDelta::try_days(7).unwrap(), ..Default::default() }, details: TaskDetails::DestroyUser { username }, diff --git a/blastmud_game/src/message_handler/user_commands/drop.rs b/blastmud_game/src/message_handler/user_commands/drop.rs index 10b9a1cc..9330a83e 100644 --- a/blastmud_game/src/message_handler/user_commands/drop.rs +++ b/blastmud_game/src/message_handler/user_commands/drop.rs @@ -92,7 +92,7 @@ pub async fn consider_expire_job_for_item(trans: &DBTrans, item: &Item) -> DResu .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", item.item_type, item.item_code), - next_scheduled: Utc::now() + chrono::Duration::hours(1), + next_scheduled: Utc::now() + chrono::TimeDelta::try_hours(1).unwrap(), ..Default::default() }, details: TaskDetails::ExpireItem { diff --git a/blastmud_game/src/message_handler/user_commands/hire.rs b/blastmud_game/src/message_handler/user_commands/hire.rs index f5acd921..6165a1bc 100644 --- a/blastmud_game/src/message_handler/user_commands/hire.rs +++ b/blastmud_game/src/message_handler/user_commands/hire.rs @@ -230,7 +230,8 @@ impl UserVerb for Verb { task_code: npc.item_code.clone(), is_static: false, recurrence: None, // Managed by the handler. - next_scheduled: Utc::now() + Duration::seconds(hire_dat.frequency_secs as i64), + next_scheduled: Utc::now() + + Duration::try_seconds(hire_dat.frequency_secs as i64).unwrap(), ..Default::default() }, details: TaskDetails::ChargeWages { diff --git a/blastmud_game/src/message_handler/user_commands/movement.rs b/blastmud_game/src/message_handler/user_commands/movement.rs index e09154b1..5da13a66 100644 --- a/blastmud_game/src/message_handler/user_commands/movement.rs +++ b/blastmud_game/src/message_handler/user_commands/movement.rs @@ -26,6 +26,7 @@ use crate::{ check_consent, check_one_consent, combat::{change_health, handle_resurrect, stop_attacking_mut}, comms::broadcast_to_room, + environment::ensure_appropriate_environment_handler_after_movement, sharing::stop_conversation_mut, skills::skill_check_and_grind, urges::{recalculate_urge_growth, thirst_changed}, @@ -376,7 +377,7 @@ pub async fn reverse_climb( // Returns true if the move is either complete or still in progress. // Returns false if the move failed. -async fn attempt_move_immediate( +pub async fn attempt_move_immediate( direction: &Direction, ctx: &mut QueuedCommandContext<'_>, source: &MovementSource, @@ -482,6 +483,15 @@ async fn attempt_move_immediate( broadcast_to_room(ctx.trans, &from_room, None, &msg).await?; broadcast_to_room(ctx.trans, &to_room, None, &msg).await?; ctx.item.queue.truncate(0); + if got_there { + if let Some((old_loc_type, old_loc_code)) = use_location.split_once("/") { + check_for_exit_action(ctx, old_loc_type, old_loc_code).await?; + } + + check_for_instant_aggro(&ctx.trans, &mut ctx.item).await?; + check_for_enter_action(ctx).await?; + ensure_appropriate_environment_handler_after_movement(ctx).await?; + } return Ok(got_there); } else if skills <= 0.0 { if climb.height >= 0 { @@ -735,6 +745,7 @@ async fn attempt_move_immediate( check_for_instant_aggro(&ctx.trans, &mut ctx.item).await?; check_for_enter_action(ctx).await?; + ensure_appropriate_environment_handler_after_movement(ctx).await?; Ok(true) } diff --git a/blastmud_game/src/message_handler/user_commands/open.rs b/blastmud_game/src/message_handler/user_commands/open.rs index 7d3b3716..c89c3326 100644 --- a/blastmud_game/src/message_handler/user_commands/open.rs +++ b/blastmud_game/src/message_handler/user_commands/open.rs @@ -188,7 +188,7 @@ pub async fn attempt_open_immediate( .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", &room_1.refstr(), &direction.describe()), - next_scheduled: Utc::now() + chrono::Duration::seconds(120), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(120).unwrap(), ..Default::default() }, details: TaskDetails::SwingShut { diff --git a/blastmud_game/src/message_handler/user_commands/plug.rs b/blastmud_game/src/message_handler/user_commands/plug.rs index fd10665c..b106e3d2 100644 --- a/blastmud_game/src/message_handler/user_commands/plug.rs +++ b/blastmud_game/src/message_handler/user_commands/plug.rs @@ -119,7 +119,7 @@ impl UserVerb for Verb { .upsert_task(&Task { meta: TaskMeta { task_code: refstr.clone(), - next_scheduled: Utc::now() + Duration::minutes(1), + next_scheduled: Utc::now() + Duration::try_minutes(1).unwrap(), ..Default::default() }, details: TaskDetails::ChargeItem { item: refstr }, diff --git a/blastmud_game/src/message_handler/user_commands/recline.rs b/blastmud_game/src/message_handler/user_commands/recline.rs index a422745d..5304ed87 100644 --- a/blastmud_game/src/message_handler/user_commands/recline.rs +++ b/blastmud_game/src/message_handler/user_commands/recline.rs @@ -8,6 +8,7 @@ use crate::{ queue_command_and_save, QueueCommand, QueueCommandHandler, QueuedCommandContext, }, services::{comms::broadcast_to_room, urges::recalculate_urge_growth}, + static_content::room::{room_map_by_code, MaterialType}, }; use async_trait::async_trait; use std::time; @@ -47,6 +48,20 @@ impl QueueCommandHandler for QueueHandler { } _ => {} } + let (loc_type, loc_code) = match ctx.item.location.split_once("/") { + None => user_error("You've ended up in a bad place.".to_owned())?, + Some(v) => v, + }; + if loc_type == "room" { + if let Some(room) = room_map_by_code().get(loc_code) { + match room.material_type { + MaterialType::Underwater | MaterialType::WaterSurface => { + user_error("You're already floating around".to_owned())? + } + _ => {} + } + } + } match item_ref { None => {} Some(item_ref) => { @@ -107,6 +122,20 @@ impl QueueCommandHandler for QueueHandler { } _ => {} } + let (loc_type, loc_code) = match ctx.item.location.split_once("/") { + None => user_error("You've ended up in a bad place.".to_owned())?, + Some(v) => v, + }; + if loc_type == "room" { + if let Some(room) = room_map_by_code().get(loc_code) { + match room.material_type { + MaterialType::Underwater | MaterialType::WaterSurface => { + user_error("You're already floating around".to_owned())? + } + _ => {} + } + } + } let (item, desc) = match item_ref { None => (None, "the floor".to_owned()), Some(item_ref) => { diff --git a/blastmud_game/src/message_handler/user_commands/rent.rs b/blastmud_game/src/message_handler/user_commands/rent.rs index 8ae5c5df..724528bb 100644 --- a/blastmud_game/src/message_handler/user_commands/rent.rs +++ b/blastmud_game/src/message_handler/user_commands/rent.rs @@ -21,7 +21,7 @@ use crate::{ use ansi::ansi; use async_recursion::async_recursion; use async_trait::async_trait; -use chrono::{DateTime, Duration, Utc}; +use chrono::{DateTime, TimeDelta, Utc}; use itertools::Itertools; use log::info; use mockall_double::double; @@ -96,7 +96,7 @@ async fn bill_residential_room( } let mut zone_item_mut = (*zone_item).clone(); zone_item_mut.special_data = Some(ItemSpecialData::DynzoneData { - vacate_after: Some(Utc::now() + Duration::days(1)), + vacate_after: Some(Utc::now() + TimeDelta::try_days(1).unwrap()), zone_exit: match zone_item.special_data.as_ref() { Some(ItemSpecialData::DynzoneData { zone_exit, .. }) => zone_exit.clone(), _ => None, @@ -168,7 +168,7 @@ async fn bill_commercial_room( } let mut zone_item_mut = (*zone_item).clone(); zone_item_mut.special_data = Some(ItemSpecialData::DynzoneData { - vacate_after: Some(Utc::now() + Duration::days(1)), + vacate_after: Some(Utc::now() + TimeDelta::try_days(1).unwrap()), zone_exit: match zone_item.special_data.as_ref() { Some(ItemSpecialData::DynzoneData { zone_exit, .. }) => zone_exit.clone(), _ => None, @@ -493,7 +493,7 @@ impl UserVerb for Verb { task_code: format!("charge_rent/{}", &zonecode), is_static: false, recurrence: None, // Managed by the handler. - next_scheduled: Utc::now() + Duration::days(1), + next_scheduled: Utc::now() + TimeDelta::try_days(1).unwrap(), ..Default::default() }, details: TaskDetails::ChargeRoom { diff --git a/blastmud_game/src/message_handler/user_commands/vacate.rs b/blastmud_game/src/message_handler/user_commands/vacate.rs index 2b366039..77730405 100644 --- a/blastmud_game/src/message_handler/user_commands/vacate.rs +++ b/blastmud_game/src/message_handler/user_commands/vacate.rs @@ -11,7 +11,7 @@ use crate::{ }; use ansi::ansi; use async_trait::async_trait; -use chrono::{Duration, Utc}; +use chrono::{TimeDelta, Utc}; use itertools::Itertools; pub struct Verb; @@ -108,7 +108,9 @@ impl UserVerb for Verb { .save_item_model(&Item { special_data: Some(ItemSpecialData::DynzoneData { zone_exit: ex.clone(), - vacate_after: Some(Utc::now() + Duration::days(1)), + vacate_after: Some( + Utc::now() + TimeDelta::try_days(1).unwrap(), + ), }), ..(*ex_zone).clone() }) diff --git a/blastmud_game/src/models/task.rs b/blastmud_game/src/models/task.rs index 73a1a2e3..58d3fcc1 100644 --- a/blastmud_game/src/models/task.rs +++ b/blastmud_game/src/models/task.rs @@ -80,6 +80,10 @@ pub enum TaskDetails { ChargeItem { item: String, }, + ApplyEnvironmentalEffects { + on_player_type: String, + on_player_code: String, + }, } impl TaskDetails { pub fn name(self: &Self) -> &'static str { @@ -109,6 +113,7 @@ impl TaskDetails { ExpireBuff { .. } => "ExpireBuff", DischargeLight { .. } => "DischargeLight", ChargeItem { .. } => "ChargeItem", + ApplyEnvironmentalEffects { .. } => "ApplyEnvironmentalEffects", // Don't forget to add to TASK_HANDLER_REGISTRY in regular_tasks.rs too. } } @@ -130,7 +135,7 @@ impl Default for TaskMeta { is_static: false, recurrence: None, consecutive_failure_count: 0, - next_scheduled: Utc::now() + chrono::Duration::seconds(3600), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(3600).unwrap(), } } } diff --git a/blastmud_game/src/regular_tasks.rs b/blastmud_game/src/regular_tasks.rs index 83938833..0d2d0c1a 100644 --- a/blastmud_game/src/regular_tasks.rs +++ b/blastmud_game/src/regular_tasks.rs @@ -9,7 +9,7 @@ use crate::{ listener::{ListenerMap, ListenerSend}, message_handler::user_commands::{delete, drop, hire, open, rent}, models::task::Task, - services::{charging, combat, effect, idlepark, sharing, spawn, tempbuff, urges}, + services::{charging, combat, effect, environment, idlepark, sharing, spawn, tempbuff, urges}, static_content::{ npc::{self, computer_museum_npcs}, possession_type::lights, @@ -72,6 +72,7 @@ fn task_handler_registry( ("ExpireBuff", tempbuff::EXPIRE_BUFF_TASK), ("DischargeLight", lights::DISCHARGE_TASK), ("ChargeItem", charging::TASK_HANDLER), + ("ApplyEnvironmentalEffects", environment::TASK_HANDLER), ] .into_iter() .collect() @@ -199,8 +200,8 @@ async fn process_tasks_once(pool: db::DBPool) -> DResult<()> { ) .await?; } else { - task.meta.next_scheduled = - Utc::now() + chrono::Duration::seconds(60); + task.meta.next_scheduled = Utc::now() + + chrono::TimeDelta::try_seconds(60).unwrap(); tx.update_task( &task.details.name(), &task.meta.task_code, @@ -226,7 +227,10 @@ async fn process_tasks_once(pool: db::DBPool) -> DResult<()> { } Some(TaskRecurrence::FixedDuration { seconds }) => { task.meta.next_scheduled = Utc::now() - + chrono::Duration::seconds(seconds as i64); + + chrono::TimeDelta::try_seconds( + seconds as i64, + ) + .unwrap(); tx.update_task( &task.details.name(), &task.meta.task_code, @@ -256,9 +260,9 @@ async fn process_tasks_once(pool: db::DBPool) -> DResult<()> { tx.commit().await?; } Some(TaskRecurrence::FixedDuration { seconds }) => { - task.meta - .next_scheduled - .add_assign(chrono::Duration::seconds(seconds as i64)); + task.meta.next_scheduled.add_assign( + chrono::TimeDelta::try_seconds(seconds as i64).unwrap(), + ); tx.update_task( &task.task_type, &task.meta.task_code, diff --git a/blastmud_game/src/regular_tasks/queued_command.rs b/blastmud_game/src/regular_tasks/queued_command.rs index 8089b9da..0d3e947b 100644 --- a/blastmud_game/src/regular_tasks/queued_command.rs +++ b/blastmud_game/src/regular_tasks/queued_command.rs @@ -340,7 +340,7 @@ pub async fn queue_command( .upsert_task(&Task { meta: TaskMeta { task_code: item.refstr(), - next_scheduled: Utc::now() + chrono::Duration::from_std(dur)?, + next_scheduled: Utc::now() + chrono::TimeDelta::from_std(dur)?, ..Default::default() }, details: TaskDetails::RunQueuedCommand, @@ -387,7 +387,7 @@ pub async fn queue_command_for_npc( .upsert_task(&Task { meta: TaskMeta { task_code: item.refstr(), - next_scheduled: Utc::now() + chrono::Duration::from_std(dur)?, + next_scheduled: Utc::now() + chrono::TimeDelta::from_std(dur)?, ..Default::default() }, details: TaskDetails::RunQueuedCommand, diff --git a/blastmud_game/src/services.rs b/blastmud_game/src/services.rs index 41836d93..e5574ae2 100644 --- a/blastmud_game/src/services.rs +++ b/blastmud_game/src/services.rs @@ -22,6 +22,7 @@ pub mod combat; pub mod comms; pub mod display; pub mod effect; +pub mod environment; pub mod idlepark; pub mod room_effects; pub mod sharing; diff --git a/blastmud_game/src/services/combat.rs b/blastmud_game/src/services/combat.rs index a659d35a..02837b27 100644 --- a/blastmud_game/src/services/combat.rs +++ b/blastmud_game/src/services/combat.rs @@ -35,7 +35,7 @@ use crate::{ use ansi::ansi; use async_recursion::async_recursion; use async_trait::async_trait; -use chrono::{Duration, Utc}; +use chrono::{TimeDelta, Utc}; use mockall_double::double; use rand::{prelude::IteratorRandom, thread_rng, Rng}; use rand_distr::{Distribution, Normal}; @@ -707,7 +707,7 @@ pub async fn handle_death(trans: &DBTrans, whom: &mut Item) -> DResult<()> { .upsert_task(&Task { meta: TaskMeta { task_code: whom.item_code.clone(), - next_scheduled: Utc::now() + chrono::Duration::seconds(600), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(600).unwrap(), ..Default::default() }, details: TaskDetails::RecloneNPC { @@ -979,7 +979,8 @@ pub async fn start_attack_mut( meta: TaskMeta { task_code: format!("{}/{}", by_whom.item_type, by_whom.item_code), next_scheduled: Utc::now() - + chrono::Duration::milliseconds(attack_speed(by_whom).as_millis() as i64), + + chrono::TimeDelta::try_milliseconds(attack_speed(by_whom).as_millis() as i64) + .unwrap(), ..Default::default() }, details: TaskDetails::AttackTick, @@ -1008,7 +1009,7 @@ pub async fn corpsify_item(trans: &DBTrans, base_item: &Item) -> DResult { .upsert_task(&Task { meta: TaskMeta { task_code: new_item.item_code.clone(), - next_scheduled: Utc::now() + chrono::Duration::minutes(5), + next_scheduled: Utc::now() + chrono::TimeDelta::try_minutes(5).unwrap(), ..Default::default() }, details: TaskDetails::RotCorpse { @@ -1045,10 +1046,12 @@ pub async fn switch_to_power_attack(ctx: &VerbContext<'_>, who: &Arc) -> U match who .tactic_use .last_pow - .map(|lp| (lp + Duration::seconds(pow_delay)) - Utc::now()) + .map(|lp| (lp + TimeDelta::try_seconds(pow_delay).unwrap()) - Utc::now()) { None => {} - Some(d) if d < Duration::seconds(0) || who.flags.contains(&ItemFlag::Invincible) => {} + Some(d) + if d < TimeDelta::try_seconds(0).unwrap() + || who.flags.contains(&ItemFlag::Invincible) => {} Some(d) => user_error(format!( "You can't powerattack again for another {} seconds.", d.num_seconds() @@ -1076,8 +1079,12 @@ pub async fn switch_to_power_attack(ctx: &VerbContext<'_>, who: &Arc) -> U .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", &who.item_type, &who.item_code), - next_scheduled: Utc::now() - + chrono::Duration::milliseconds(attack_speed(&who_mut).as_millis() as i64), + next_scheduled: + Utc::now() + + chrono::TimeDelta::try_milliseconds( + attack_speed(&who_mut).as_millis() as i64 + ) + .unwrap(), ..Default::default() }, details: TaskDetails::AttackTick, @@ -1102,10 +1109,10 @@ pub async fn switch_to_feint(ctx: &VerbContext<'_>, who: &Arc) -> UResult< match who .tactic_use .last_feint - .map(|lp| (lp + Duration::seconds(feint_delay)) - Utc::now()) + .map(|lp| (lp + TimeDelta::try_seconds(feint_delay).unwrap()) - Utc::now()) { None => {} - Some(d) if d < Duration::seconds(0) => {} + Some(d) if d < TimeDelta::try_seconds(0).unwrap() => {} Some(d) => user_error(format!( "You can't feint again for another {} seconds.", d.num_seconds() @@ -1173,8 +1180,12 @@ pub async fn switch_to_feint(ctx: &VerbContext<'_>, who: &Arc) -> UResult< .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", &who.item_type, &who.item_code), - next_scheduled: Utc::now() - + chrono::Duration::milliseconds(attack_speed(&who_mut).as_millis() as i64), + next_scheduled: + Utc::now() + + chrono::TimeDelta::try_milliseconds( + attack_speed(&who_mut).as_millis() as i64 + ) + .unwrap(), ..Default::default() }, details: TaskDetails::AttackTick, diff --git a/blastmud_game/src/services/effect.rs b/blastmud_game/src/services/effect.rs index f1139727..3e2064b4 100644 --- a/blastmud_game/src/services/effect.rs +++ b/blastmud_game/src/services/effect.rs @@ -313,7 +313,7 @@ pub async fn run_effects( .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", &actual_target.refstr(), task_ref), - next_scheduled: Utc::now() + chrono::Duration::seconds(dispel_time_secs as i64), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(dispel_time_secs as i64).unwrap(), ..Default::default() }, details: TaskDetails::DispelEffect { @@ -329,7 +329,7 @@ pub async fn run_effects( .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", eff_item, trans.alloc_task_code().await?), - next_scheduled: Utc::now() + chrono::Duration::seconds(l[0].delay as i64), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(l[0].delay as i64).unwrap(), ..Default::default() }, details: TaskDetails::DelayedHealth { @@ -344,7 +344,7 @@ pub async fn run_effects( .upsert_task(&Task { meta: TaskMeta { task_code: format!("{}/{}", eff_item, task_ref), - next_scheduled: Utc::now() + chrono::Duration::seconds(l[0].delay as i64), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(l[0].delay as i64).unwrap(), ..Default::default() }, details: TaskDetails::DelayedMessage { diff --git a/blastmud_game/src/services/environment.rs b/blastmud_game/src/services/environment.rs new file mode 100644 index 00000000..c1df6668 --- /dev/null +++ b/blastmud_game/src/services/environment.rs @@ -0,0 +1,197 @@ +use std::time; + +use async_trait::async_trait; +use chrono::Utc; +use log::warn; +use uuid::Uuid; + +use crate::{ + message_handler::user_commands::{ + movement::attempt_move_immediate, CommandHandlingError, UResult, + }, + models::{ + item::{Item, SkillType}, + task::{Task, TaskDetails, TaskMeta}, + }, + regular_tasks::{ + queued_command::{MovementSource, QueueCommand, QueuedCommandContext}, + TaskHandler, TaskRunContext, + }, + static_content::room::{room_map_by_code, Direction, MaterialType, Room}, + DResult, +}; + +use super::{combat::change_health, comms::broadcast_to_room, skills::skill_check_and_grind}; + +pub struct EnvironmentHandler; + +pub async fn ensure_appropriate_environment_handler_after_movement( + ctx: &mut QueuedCommandContext<'_>, +) -> UResult<()> { + if ctx.item.item_type != "player" { + return Ok(()); + } + let (loc_type, loc_code) = match ctx.item.location.split_once("/") { + None => return Ok(()), + Some(v) => v, + }; + let need_handler = if loc_type != "room" { + false + } else { + let room = match room_map_by_code().get(loc_code) { + None => return Ok(()), + Some(r) => r, + }; + match room.material_type { + MaterialType::WaterSurface | MaterialType::Underwater => true, + _ => false, + } + }; + + let existing_task = ctx + .trans + .fetch_specific_task("ApplyEnvironmentalEffects", &ctx.item.refstr()) + .await?; + if need_handler { + if existing_task.is_none() { + ctx.trans + .upsert_task(&Task { + meta: TaskMeta { + task_code: ctx.item.refstr(), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(10).unwrap(), + ..Default::default() + }, + details: TaskDetails::ApplyEnvironmentalEffects { + on_player_type: ctx.item.item_type.clone(), + on_player_code: ctx.item.item_code.clone(), + }, + }) + .await?; + } + } else { + if existing_task.is_some() { + ctx.trans + .delete_task("ApplyEnvironmentalEffects", &ctx.item.refstr()) + .await?; + } + } + Ok(()) +} + +#[async_trait] +impl TaskHandler for EnvironmentHandler { + async fn do_task(&self, ctx: &mut TaskRunContext) -> DResult> { + let (player_type, player_code) = match &ctx.task.details { + TaskDetails::ApplyEnvironmentalEffects { + on_player_type, + on_player_code, + } => (on_player_type, on_player_code), + x => { + warn!( + "EnvironmentHandler called with bad TaskDetail type: {:#?}", + x + ); + return Ok(None); + } + }; + + let player = match ctx + .trans + .find_item_by_type_code(&player_type, &player_code) + .await? + { + None => return Ok(None), + Some(p) => p, + }; + let mut player = (*player).clone(); + + let (loc_type, loc_code) = match player.location.split_once("/") { + None => return Ok(None), + Some(v) => v, + }; + if loc_type != "room" { + return Ok(None); + }; + + let room = match room_map_by_code().get(loc_code) { + None => return Ok(None), + Some(r) => r, + }; + + let need_save = water_environment_effects(ctx, &room, &mut player).await?; + + if need_save { + ctx.trans.save_item_model(&player).await?; + } + + Ok(Some(time::Duration::from_secs(10))) + } +} + +pub async fn water_environment_effects( + ctx: &mut TaskRunContext<'_>, + room: &Room, + player_item: &mut Item, +) -> DResult { + match room.material_type { + MaterialType::WaterSurface => {} + MaterialType::Underwater => { + if change_health( + &ctx.trans, + -5, + player_item, + &format!( + "{} can't breathe underwater", + player_item.display_for_sentence(1, true) + ), + ) + .await? + { + return Ok(true); + } + } + _ => return Ok(false), + } + match room.exits.iter().find(|v| v.direction == Direction::DOWN) { + None => return Ok(false), + Some(_) => { + if player_item.active_climb.is_some() { + return Ok(false); + } + if skill_check_and_grind(&ctx.trans, player_item, &SkillType::Swim, 9.0).await? > 0.0 { + return Ok(true); + } else { + broadcast_to_room( + &ctx.trans, + &player_item.location, + None, + &format!( + "{} seems to be sinking.\n", + player_item.display_for_sentence(1, true) + ), + ) + .await?; + player_item.queue.truncate(0); + let source = MovementSource::Internal { + event_id: Uuid::new_v4(), + }; + let mut qctx = QueuedCommandContext { + trans: ctx.trans, + command: &QueueCommand::Movement { + direction: Direction::DOWN, + source: source.clone(), + }, + item: player_item, + }; + match attempt_move_immediate(&Direction::DOWN, &mut qctx, &source).await { + Ok(_) => {} + Err(CommandHandlingError::UserError(_)) => {} + Err(CommandHandlingError::SystemError(e)) => return Err(e), + } + } + } + } + Ok(true) +} + +pub static TASK_HANDLER: &'static (dyn TaskHandler + Sync + Send) = &EnvironmentHandler; diff --git a/blastmud_game/src/services/idlepark.rs b/blastmud_game/src/services/idlepark.rs index 7bdf52ea..23fe159d 100644 --- a/blastmud_game/src/services/idlepark.rs +++ b/blastmud_game/src/services/idlepark.rs @@ -55,7 +55,7 @@ pub fn idlepark_tasks() -> Box> { task_code: "IdlePark".to_owned(), is_static: true, recurrence: Some(TaskRecurrence::FixedDuration { seconds: 120 }), - next_scheduled: Utc::now() + chrono::Duration::seconds(120), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(120).unwrap(), ..Default::default() }, details: TaskDetails::IdlePark, diff --git a/blastmud_game/src/services/sharing.rs b/blastmud_game/src/services/sharing.rs index 0460c3ff..0f966c87 100644 --- a/blastmud_game/src/services/sharing.rs +++ b/blastmud_game/src/services/sharing.rs @@ -667,7 +667,7 @@ pub async fn start_conversation( .upsert_task(&Task { meta: TaskMeta { task_code: share_event_name(&initiator, &acceptor), - next_scheduled: Utc::now() + chrono::Duration::milliseconds(5000), + next_scheduled: Utc::now() + chrono::TimeDelta::try_milliseconds(5000).unwrap(), ..Default::default() }, details: TaskDetails::ShareTick, @@ -774,7 +774,7 @@ async fn apply_conversation_buff(trans: &DBTrans, to_player: &mut Item) -> DResu .upsert_task(&Task { meta: TaskMeta { task_code: exp_task_code.clone(), - next_scheduled: Utc::now() + chrono::Duration::seconds(600), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(600).unwrap(), ..Default::default() }, details: TaskDetails::ExpireBuff { diff --git a/blastmud_game/src/services/urges.rs b/blastmud_game/src/services/urges.rs index 654e622c..90e229e9 100644 --- a/blastmud_game/src/services/urges.rs +++ b/blastmud_game/src/services/urges.rs @@ -264,7 +264,7 @@ pub fn urge_tasks() -> Box> { task_code: "tick_urges".to_owned(), is_static: true, recurrence: Some(TaskRecurrence::FixedDuration { seconds: 60 }), - next_scheduled: Utc::now() + chrono::Duration::seconds(60), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(60).unwrap(), ..TaskMeta::default() }, details: TaskDetails::TickUrges, diff --git a/blastmud_game/src/static_content/npc.rs b/blastmud_game/src/static_content/npc.rs index 5ba6ccaa..13367b58 100644 --- a/blastmud_game/src/static_content/npc.rs +++ b/blastmud_game/src/static_content/npc.rs @@ -264,8 +264,9 @@ pub fn npc_static_items() -> Box> { let mut pos_it: Item = spawn_item.what.clone().into(); pos_it.location = npc_ref.clone(); pos_it.action_type = spawn_item.action_type.clone(); - pos_it.action_type_started = - Some(Utc::now() - chrono::Duration::seconds(spawn_item.wear_layer)); + pos_it.action_type_started = Some( + Utc::now() - chrono::TimeDelta::try_seconds(spawn_item.wear_layer).unwrap(), + ); pos_it })) }), @@ -276,29 +277,30 @@ pub fn npc_static_items() -> Box> { pub fn npc_say_tasks() -> Box> { Box::new(npc_list().iter().flat_map(|c| { c.says.iter().map(|say| StaticTask { - task_code: c.code.to_owned() + "_" + say.say_code, - initial_task: Box::new(|| { - let mut rng = thread_rng(); - Task { - meta: TaskMeta { - task_code: c.code.to_owned() + "_" + say.say_code, - is_static: true, - recurrence: Some(TaskRecurrence::FixedDuration { - seconds: say.frequency_secs as u32, - }), - next_scheduled: Utc::now() - + chrono::Duration::seconds( - rng.gen_range(0..say.frequency_secs) as i64 - ), - ..TaskMeta::default() - }, - details: TaskDetails::NPCSay { - npc_code: c.code.to_owned(), - say_code: say.say_code.to_owned(), - }, - } - }), - }) + task_code: c.code.to_owned() + "_" + say.say_code, + initial_task: Box::new(|| { + let mut rng = thread_rng(); + Task { + meta: TaskMeta { + task_code: c.code.to_owned() + "_" + say.say_code, + is_static: true, + recurrence: Some(TaskRecurrence::FixedDuration { + seconds: say.frequency_secs as u32, + }), + next_scheduled: Utc::now() + + chrono::TimeDelta::try_seconds( + rng.gen_range(0..say.frequency_secs) as i64 + ) + .unwrap(), + ..TaskMeta::default() + }, + details: TaskDetails::NPCSay { + npc_code: c.code.to_owned(), + say_code: say.say_code.to_owned(), + }, + } + }), + }) })) } @@ -319,7 +321,8 @@ pub fn npc_wander_tasks() -> Box> { seconds: rng.gen_range(250..350) as u32, }), next_scheduled: Utc::now() - + chrono::Duration::seconds(rng.gen_range(0..300) as i64), + + chrono::TimeDelta::try_seconds(rng.gen_range(0..300) as i64) + .unwrap(), ..TaskMeta::default() }, details: TaskDetails::NPCWander { @@ -352,7 +355,10 @@ pub fn npc_aggro_tasks() -> Box> { seconds: aggro_time as u32, }), next_scheduled: Utc::now() - + chrono::Duration::seconds(rng.gen_range(0..aggro_time) as i64), + + chrono::TimeDelta::try_seconds( + rng.gen_range(0..aggro_time) as i64 + ) + .unwrap(), ..TaskMeta::default() }, details: TaskDetails::NPCAggro { diff --git a/blastmud_game/src/static_content/npc/computer_museum_npcs.rs b/blastmud_game/src/static_content/npc/computer_museum_npcs.rs index 890ff4f8..d87fcce2 100644 --- a/blastmud_game/src/static_content/npc/computer_museum_npcs.rs +++ b/blastmud_game/src/static_content/npc/computer_museum_npcs.rs @@ -265,7 +265,7 @@ impl NPCMessageHandler for DoorbotMsgHandler { .upsert_task(&Task { meta: TaskMeta { task_code: "room/computer_museum_hackers_club/south".to_owned(), - next_scheduled: Utc::now() + chrono::Duration::seconds(120), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(120).unwrap(), ..Default::default() }, details: TaskDetails::SwingShut { @@ -294,7 +294,7 @@ impl NPCMessageHandler for DoorbotMsgHandler { .upsert_task(&Task { meta: TaskMeta { task_code: "reset_hanoi_computer_club".to_owned(), - next_scheduled: Utc::now() + chrono::Duration::seconds(600), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(600).unwrap(), ..Default::default() }, details: TaskDetails::ResetHanoi, diff --git a/blastmud_game/src/static_content/possession_type/lights.rs b/blastmud_game/src/static_content/possession_type/lights.rs index 38e2ee17..02e40dd2 100644 --- a/blastmud_game/src/static_content/possession_type/lights.rs +++ b/blastmud_game/src/static_content/possession_type/lights.rs @@ -61,7 +61,7 @@ impl TurnToggleHandler for LanternHandler { .upsert_task(&Task { meta: TaskMeta { task_code: item_mut.refstr(), - next_scheduled: Utc::now() + chrono::Duration::minutes(5), + next_scheduled: Utc::now() + chrono::TimeDelta::try_minutes(5).unwrap(), ..Default::default() }, details: TaskDetails::DischargeLight { diff --git a/blastmud_game/src/static_content/room/general_hospital.rs b/blastmud_game/src/static_content/room/general_hospital.rs index bf1b62cc..5c3cb93e 100644 --- a/blastmud_game/src/static_content/room/general_hospital.rs +++ b/blastmud_game/src/static_content/room/general_hospital.rs @@ -28,7 +28,7 @@ impl RoomEnterTrigger for EnterERTrigger { .upsert_task(&Task { meta: TaskMeta { task_code: ctx.item.refstr(), - next_scheduled: Utc::now() + chrono::Duration::seconds(60), + next_scheduled: Utc::now() + chrono::TimeDelta::try_seconds(60).unwrap(), ..Default::default() }, details: TaskDetails::HospitalERSeePatient { diff --git a/blastmud_game/src/static_content/room/northern_radfields.yaml b/blastmud_game/src/static_content/room/northern_radfields.yaml index ecae5294..1c7e06ca 100644 --- a/blastmud_game/src/static_content/room/northern_radfields.yaml +++ b/blastmud_game/src/static_content/room/northern_radfields.yaml @@ -16,5 +16,98 @@ z: 0 description: "The start of a deteriorating asphalt road that leads north through a barren dusty environment. The road is blocked by a barrier arm. The arm is attached to a box with a window in it, occupied by a guard in a fluorescent yellow high-visibility vest. The side of the box is painted with a symbol featuring three black wedges arranged circularly around a central black circle, on a yellow background. Beneath it is the text: DANGER - FALLOUT - Ionising Radiation Hazard. Access to the radfields by permit only" exits: + - direction: north - direction: south target: !Custom room/melbs_latrobest_140 +- zone: northern_radfields + code: northrad_s6 + name: Northern Radfields - Melbs outskirts + short: || + grid_coords: + x: 6 + y: 19 + z: 0 + description: "A stretch of deteriorating asphalt road, its once smooth surface now cracked and uneven. Scattered debris litters the sides of the road, remnants of vehicles long abandoned. Ahead, a solitary gum tree stands tall against the elements, its leaves a brilliant green amidst the parched land. It smells like eucalyptus here. To the south you a gatehouse and signs of civilisation in the distance" + exits: + - direction: north + - direction: south +- zone: northern_radfields + code: northrad_r6 + name: Northern Radfields - Outside the abandoned windfarm + short: || + grid_coords: + x: 6 + y: 18 + z: 0 + description: "A crumbling stretch of asphalt road that weaves through a field of giant wind turbines overgrown with noxious weeds, some of which are spilling out and narrowing the road. Some of the turbines seem to be on a lean and, and some have dropped rusted blades, but a few still turn lazily in the wind, emitting a hum as they spin. It smells faintly of ozone" + exits: + - direction: north + - direction: south +- zone: northern_radfields + code: northrad_q6 + name: Northern Radfields - Crystal clear pond + short: || + grid_coords: + x: 6 + y: 17 + z: 0 + description: "A potholed stretch of asphalt road that runs past an abandoned farm, rusting machinery sitting in a barren reddish brown field, all plant life dead. An irrigation pond looks crystal clear, as if something has killed all the algae. A white powdery substance seems to line the sides of the pond, giving off a barely perceptible blue glow. It smells earthy here. The road bends off to the northwest" + exits: + - direction: northwest + - direction: south +- zone: northern_radfields + code: northrad_p5 + name: Northern Radfields - The Bend Community Hall + short: || + grid_coords: + x: 5 + y: 16 + z: 0 + description: "A gravel-covered stretch of road that runs past an collapsing and overgrown community centre, identified by a faded and bent but still standing sign as \"The Bend Community Centre\". It features tennis courts covered in fallout dust, and a hall with a collapsed roof" + exits: + - direction: north + - direction: southeast +- zone: northern_radfields + code: northrad_o5 + name: Northern Radfields - Gorge Southbank + short: || + grid_coords: + x: 5 + y: 15 + z: 0 + description: "A partly washed-out stretch of gravel road that leads up to a gorge with steep rocky sides, with a sheer drop and slowly flowing water at the bottom. Posts and bent metal suggest a bridge was once here, but it is now gone - perhaps under the water! If you want to get across, evidently you'll have to climb down and swim" + exits: + - direction: north + exit_climb: + height: -10 + difficulty: 10 + - direction: south +- zone: northern_radfields + code: northrad_n5 + name: Northern Radfields - Gorge River + short: ~~ + grid_coords: + x: 5 + y: 14 + z: 0 + description: "A river of slowly moving water at the bottom of a gorge. The water is icy cold, and seems quite deep, and the cliffs on either side are high" + material_type: !WaterSurface + exits: + - direction: down + - direction: south + exit_climb: + height: 10 + difficulty: 8 +- zone: northern_radfields + code: northrad_n5_deep + name: Northern Radfields - Beneath the gorge River + short: ~~ + grid_coords: + x: 5 + y: 14 + z: -1 + description: "Beneath the cold deep water you can see the rocky bottom of the gorge. You notice parts of a broken bridge lying on the river bed. An occasional silvery fish swims past" + material_type: !Underwater + exits: + - direction: up + diff --git a/blastmud_interfaces/Cargo.toml b/blastmud_interfaces/Cargo.toml index 33d2f12f..491e3b13 100644 --- a/blastmud_interfaces/Cargo.toml +++ b/blastmud_interfaces/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = { version = "1.0.195", features = ["derive", "serde_derive"] } -uuid = { version = "1.6.1", features = ["serde"] } +serde = { version = "1.0.197", features = ["derive", "serde_derive"] } +uuid = { version = "1.7.0", features = ["serde"] } diff --git a/blastmud_listener/Cargo.toml b/blastmud_listener/Cargo.toml index a6e33c49..637f6321 100644 --- a/blastmud_listener/Cargo.toml +++ b/blastmud_listener/Cargo.toml @@ -8,16 +8,16 @@ edition = "2021" [dependencies] blastmud_interfaces = { path = "../blastmud_interfaces" } futures = "0.3.30" -log = "0.4.20" +log = "0.4.21" nix = "0.27.1" once_cell = "1.19.0" rand = "0.8.5" -serde = { version = "1.0.195", features = ["derive", "serde_derive"] } -serde_yaml = "0.9.30" +serde = { version = "1.0.197", features = ["derive", "serde_derive"] } +serde_yaml = "0.9.32" simple_logger = "4.3.3" -tokio = { version = "1.35.1", features = ["signal", "net", "macros", "rt-multi-thread", "rt", "tokio-macros", "time", "sync", "io-util"] } +tokio = { version = "1.36.0", features = ["signal", "net", "macros", "rt-multi-thread", "rt", "tokio-macros", "time", "sync", "io-util"] } tokio-serde = { version = "0.8.0", features = ["cbor", "serde", "serde_cbor"] } tokio-stream = "0.1.14" tokio-util = { version = "0.7.10", features = ["codec"] } -uuid = { version = "1.6.1", features = ["rng", "serde", "v4"] } +uuid = { version = "1.7.0", features = ["rng", "serde", "v4"] } warp = "0.3.6"